From ac6d0e6d7df9255081a7b0af3356d75db941dd3a Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 12 Jan 2022 08:28:27 +0100 Subject: [PATCH 001/305] Correctly account for scaling factors in participant models --- CHANGELOG.md | 6 +- gradle/scripts/tests.gradle | 7 + .../load/LoadAgentFundamentals.scala | 42 +- .../simona/model/participant/ChpModel.scala | 35 +- .../model/participant/FixedFeedInModel.scala | 1 - .../simona/model/participant/HpModel.scala | 36 +- .../model/participant/SystemParticipant.scala | 11 +- .../participant/load/FixedLoadModel.scala | 29 +- .../load/profile/ProfileLoadModel.scala | 75 +-- .../load/random/RandomLoadModel.scala | 7 +- .../model/participant/ChpModelTest.groovy | 9 +- .../model/participant/HpModelTest.groovy | 8 +- .../load/ProfileLoadModelTest.groovy | 247 -------- .../load/RandomLoadModelTest.groovy | 189 ------ .../load/LoadModelScalingSpec.scala | 588 ++++++++++++++++++ .../participant/load/LoadModelSpec.scala | 9 +- .../load/ProfileLoadModelSpec.scala | 127 ++++ .../load/RandomLoadModelSpec.scala | 161 +++++ .../edu/ie3/simona/test/common/TestTags.scala | 16 + .../test/matchers/QuantityMatchers.scala | 146 ++++- .../test/matchers/QuantityMatchersSpec.scala | 77 +++ 21 files changed, 1267 insertions(+), 559 deletions(-) delete mode 100644 src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy delete mode 100644 src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy create mode 100644 src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/test/common/TestTags.scala create mode 100644 src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index c47d5ac600..0a9d0f9649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed -- Improving code readability in EvcsAgent by moving FreeLotsRequest to separate methods +- Improving code readability in `EvcsAgent` by moving FreeLotsRequest to separate methods +- Respect for scaling factor when simulating the system participants +- Harmonize participant model instantiation -[Unreleased]: https://github.com/ie3-institute/simona +[Unreleased]: https://github.com/ie3-institute/simona/compare/a14a093239f58fca9b2b974712686b33e5e5f939...HEAD diff --git a/gradle/scripts/tests.gradle b/gradle/scripts/tests.gradle index ccccb3ac33..1b44201880 100644 --- a/gradle/scripts/tests.gradle +++ b/gradle/scripts/tests.gradle @@ -7,6 +7,13 @@ test { /* Register scala test with the overall test task */ test.dependsOn(scalatest) +/* Exclude slow tests */ +scalatest { + tags { + exclude "edu.ie3.simona.test.common.TestTags.SnailTest" + } +} + // test task performance improvements, see -> https://docs.gradle.org/current/userguide/performance.html tasks.withType(Test).configureEach { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index 9242bffa18..6a6ebfbc44 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -186,12 +186,13 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ inputModel.getOperationTime ) val reference = LoadReference(inputModel, modelConfig) - buildModel(inputModel, operationInterval, reference) + buildModel(inputModel, operationInterval, modelConfig, reference) } protected def buildModel( inputModel: LoadInput, operationInterval: OperationInterval, + modelConfig: LoadRuntimeConfig, reference: LoadReference ): LM @@ -287,12 +288,15 @@ case object LoadAgentFundamentals { override def buildModel( inputModel: LoadInput, operationInterval: OperationInterval, + modelConfig: LoadRuntimeConfig, reference: LoadReference - ): FixedLoadModel = { - val model = FixedLoadModel(inputModel, operationInterval, 1d, reference) - model.enable() - model - } + ): FixedLoadModel = + FixedLoadModel( + inputModel, + modelConfig.scaling, + operationInterval, + reference + ) /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) @@ -328,12 +332,15 @@ case object LoadAgentFundamentals { override def buildModel( inputModel: LoadInput, operationInterval: OperationInterval, + modelConfig: LoadRuntimeConfig, reference: LoadReference - ): ProfileLoadModel = { - val model = ProfileLoadModel(inputModel, operationInterval, 1d, reference) - model.enable() - model - } + ): ProfileLoadModel = + ProfileLoadModel( + inputModel, + operationInterval, + modelConfig.scaling, + reference + ) /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) @@ -366,12 +373,15 @@ case object LoadAgentFundamentals { override def buildModel( inputModel: LoadInput, operationInterval: OperationInterval, + modelConfig: LoadRuntimeConfig, reference: LoadReference - ): RandomLoadModel = { - val model = RandomLoadModel(inputModel, operationInterval, 1d, reference) - model.enable() - model - } + ): RandomLoadModel = + RandomLoadModel( + inputModel, + operationInterval, + modelConfig.scaling, + reference + ) /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 36d976119b..d182796c4f 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -7,19 +7,22 @@ package edu.ie3.simona.model.participant import java.util.UUID - import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.system.ChpInput +import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.ChpModel._ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.{MutableStorage, ThermalStorage} import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities + import javax.measure.quantity.{Energy, Power, Time} import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities.getQuantity import tech.units.indriya.unit.Units +import java.time.ZonedDateTime + /** Model of a combined heat and power plant (CHP) with a [[ThermalStorage]] * medium and its current [[ChpState]]. * @@ -338,10 +341,14 @@ case object ChpModel { * * @param chpInput * instance of [[ChpInput]] this chp model should be built from - * @param operationInterval - * operation interval of the simulation + * @param simulationStartDate + * wall-clock time, the simulation starts + * @param simulationEndDate + * wall-clock time, the simulation ends * @param qControl - * (no usage) + * Strategy to control the reactive power output + * @param scalingFactor + * Scale the output of this asset by the given factor * @param thermalStorage * instance of [[ThermalStorage]] used as thermal storage * @return @@ -349,19 +356,31 @@ case object ChpModel { */ def apply( chpInput: ChpInput, - operationInterval: OperationInterval, + simulationStartDate: ZonedDateTime, + simulationEndDate: ZonedDateTime, qControl: QControl, + scalingFactor: Double, thermalStorage: ThermalStorage with MutableStorage - ): ChpModel = - new ChpModel( + ): ChpModel = { + val operationInterval = SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + chpInput.getOperationTime + ) + + val model = new ChpModel( chpInput.getUuid, chpInput.getId, operationInterval, - scalingFactor = 1.0, + scalingFactor, qControl, chpInput.getType.getsRated, chpInput.getType.getCosPhiRated, chpInput.getType.getpThermal, thermalStorage ) + + model.enable() + model + } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index 660a4154cc..5cba4de67b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -69,7 +69,6 @@ final case class FixedFeedInModel( sRated .multiply(-1) .multiply(cosPhiRated) - .multiply(scalingFactor) .to(MEGAWATT) } diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 394ec16ad8..334e94c504 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -7,18 +7,21 @@ package edu.ie3.simona.model.participant import java.util.UUID - import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.system.HpInput +import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.HpModel._ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.ThermalHouse import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities + import javax.measure.quantity.{Power, Temperature, Time} import tech.units.indriya.ComparableQuantity import edu.ie3.simona.util.TickUtil.TickLong +import java.time.ZonedDateTime + /** Model of a heat pump (HP) with a [[ThermalHouse]] medium and its current * [[HpState]]. * @@ -65,7 +68,6 @@ final case class HpModel( private val pRated: ComparableQuantity[Power] = sRated .multiply(cosPhiRated) - .multiply(scalingFactor) .to(StandardUnits.ACTIVE_POWER_IN) /** As this is a state-full model (with respect to the current operation @@ -138,7 +140,7 @@ final case class HpModel( private def calcState(hpData: HpData, isRunning: Boolean): HpState = { val (newActivePower, newThermalPower) = if (isRunning) - (pRated, pThermal.multiply(scalingFactor)) + (pRated, pThermal) else (DefaultQuantities.zeroKW, DefaultQuantities.zeroKW) val duration: ComparableQuantity[Time] = @@ -207,10 +209,14 @@ case object HpModel { * * @param hpInput * instance of [[HpInput]] this chp model should be built from - * @param operationInterval - * operation interval of the simulation + * @param simulationStartDate + * wall-clock time, the simulation starts + * @param simulationEndDate + * wall-clock time, the simulation ends * @param qControl - * (no usage) + * Strategy to control the reactive power output + * @param scalingFactor + * Scale the output of this asset by the given factor * @param thermalHouse * thermal house defining transmission coefficient and heat energy storage * capacity @@ -219,21 +225,31 @@ case object HpModel { */ def apply( hpInput: HpInput, - operationInterval: OperationInterval, + simulationStartDate: ZonedDateTime, + simulationEndDate: ZonedDateTime, qControl: QControl, + scalingFactor: Double, thermalHouse: ThermalHouse ): HpModel = { - new HpModel( + val operationInterval = SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + hpInput.getOperationTime + ) + + val model = new HpModel( hpInput.getUuid, hpInput.getId, operationInterval, - scalingFactor = 1.0, + scalingFactor, qControl, hpInput.getType.getsRated, hpInput.getType.getCosPhiRated, hpInput.getType.getpThermal, thermalHouse ) - } + model.enable() + model + } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 3331b2280d..602af82ab1 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -75,7 +75,10 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( val activePower = calculateActivePower(data).to(MEGAWATT) val reactivePower = calculateReactivePower(activePower, voltage).to(MEGAVAR) - ApparentPower(activePower, reactivePower) + ApparentPower( + activePower.multiply(scalingFactor), + reactivePower.multiply(scalingFactor) + ) } else { ApparentPower( Quantities.getQuantity(0d, MEGAWATT), @@ -105,11 +108,7 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( def activeToReactivePowerFunc( nodalVoltage: ComparableQuantity[Dimensionless] ): ComparableQuantity[Power] => ComparableQuantity[Power] = - qControl.activeToReactivePowerFunc( - sRated.multiply(scalingFactor), - cosPhiRated, - nodalVoltage - ) + qControl.activeToReactivePowerFunc(sRated, cosPhiRated, nodalVoltage) /** Calculate the reactive power of the model * diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 30664dfa97..86f6ae9835 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -7,6 +7,7 @@ package edu.ie3.simona.model.participant.load import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData @@ -77,7 +78,7 @@ final case class FixedLoadModel( */ override protected def calculateActivePower( data: FixedLoadRelevantData.type = FixedLoadRelevantData - ): ComparableQuantity[Power] = activePower.multiply(scalingFactor) + ): ComparableQuantity[Power] = activePower } @@ -86,17 +87,21 @@ case object FixedLoadModel { def apply( input: LoadInput, - operationInterval: OperationInterval, scalingFactor: Double, + operationInterval: OperationInterval, reference: LoadReference - ): FixedLoadModel = FixedLoadModel( - input.getUuid, - input.getId, - operationInterval, - scalingFactor, - QControl(input.getqCharacteristics()), - input.getsRated(), - input.getCosPhiRated, - reference - ) + ): FixedLoadModel = { + val model = FixedLoadModel( + input.getUuid, + input.getId, + operationInterval, + scalingFactor, + QControl(input.getqCharacteristics()), + input.getsRated(), + input.getCosPhiRated, + reference + ) + model.enable() + model + } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index 6cb73ff089..cf93779362 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -8,6 +8,7 @@ package edu.ie3.simona.model.participant.load.profile import edu.ie3.datamodel.models.StandardLoadProfile import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ @@ -111,7 +112,7 @@ final case class ProfileLoadModel( .multiply(energyReferenceScalingFactor) .asType(classOf[Power]) } - activePower.multiply(scalingFactor) + activePower } } @@ -125,40 +126,44 @@ case object ProfileLoadModel { operationInterval: OperationInterval, scalingFactor: Double, reference: LoadReference - ): ProfileLoadModel = reference match { - case LoadReference.ActivePower(power) => - val sRatedPowerScaled = LoadModel.scaleSRatedActivePower(input, power) - ProfileLoadModel( - input.getUuid, - input.getId, - operationInterval, - scalingFactor, - QControl.apply(input.getqCharacteristics()), - sRatedPowerScaled, - input.getCosPhiRated, - input.getStandardLoadProfile, - reference - ) + ): ProfileLoadModel = { + val model = reference match { + case LoadReference.ActivePower(power) => + val sRatedPowerScaled = LoadModel.scaleSRatedActivePower(input, power) + ProfileLoadModel( + input.getUuid, + input.getId, + operationInterval, + scalingFactor, + QControl.apply(input.getqCharacteristics()), + sRatedPowerScaled, + input.getCosPhiRated, + input.getStandardLoadProfile, + reference + ) - case LoadReference.EnergyConsumption(energyConsumption) => - val loadProfileMax = - LoadProfileStore().maxPower(input.getStandardLoadProfile) - val sRatedEnergy = LoadModel.scaleSRatedEnergy( - input, - energyConsumption, - loadProfileMax, - LoadProfileStore.defaultLoadProfileEnergyScaling - ) - ProfileLoadModel( - input.getUuid, - input.getId, - operationInterval, - scalingFactor, - QControl.apply(input.getqCharacteristics()), - sRatedEnergy, - input.getCosPhiRated, - input.getStandardLoadProfile, - reference - ) + case LoadReference.EnergyConsumption(energyConsumption) => + val loadProfileMax = + LoadProfileStore().maxPower(input.getStandardLoadProfile) + val sRatedEnergy = LoadModel.scaleSRatedEnergy( + input, + energyConsumption, + loadProfileMax, + LoadProfileStore.defaultLoadProfileEnergyScaling + ) + ProfileLoadModel( + input.getUuid, + input.getId, + operationInterval, + scalingFactor, + QControl.apply(input.getqCharacteristics()), + sRatedEnergy, + input.getCosPhiRated, + input.getStandardLoadProfile, + reference + ) + } + model.enable() + model } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 1cd37b1b7d..21513f93a0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -9,6 +9,7 @@ package edu.ie3.simona.model.participant.load.random import de.lmu.ifi.dbs.elki.math.statistics.distribution.GeneralizedExtremeValueDistribution import de.lmu.ifi.dbs.elki.utilities.random.RandomFactory import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ @@ -121,7 +122,7 @@ final case class RandomLoadModel( .multiply(energyReferenceScalingFactor) .asType(classOf[Power]) } - activePower.multiply(scalingFactor) + activePower } } @@ -193,7 +194,7 @@ case object RandomLoadModel { scalingFactor: Double, reference: LoadReference ): RandomLoadModel = { - reference match { + val model = reference match { case ActivePower(power) => val sRatedPowerScaled = LoadModel.scaleSRatedActivePower(input, power, 1.1) @@ -227,5 +228,7 @@ case object RandomLoadModel { reference ) } + model.enable() + model } } diff --git a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy index 1a1097bb48..a6fcf1e4c2 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy @@ -15,8 +15,7 @@ import edu.ie3.datamodel.models.input.system.type.ChpTypeInput import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.simona.model.participant.ChpModel.ChpState import edu.ie3.simona.model.thermal.CylindricalThermalStorage -import edu.ie3.simona.model.thermal.CylindricalThermalStorage$ -import edu.ie3.util.scala.OperationInterval +import edu.ie3.util.TimeUtil import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll @@ -214,10 +213,14 @@ class ChpModelTest extends Specification { when: def thermalStorage = buildThermalStorage(storageInput, 90) def chpModelCaseClass = buildChpModel(thermalStorage) + def startDate = TimeUtil.withDefaults.toZonedDateTime("2021-01-01 00:00:00") + def endDate = startDate.plusSeconds(86400L) def chpModelCaseObject = ChpModel.apply( chpInput, - OperationInterval.apply(0L, 86400L), + startDate, + endDate, null, + 1.0, thermalStorage) then: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy index caa2beeeeb..412e681977 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy @@ -16,8 +16,8 @@ import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput import edu.ie3.simona.model.participant.HpModel.HpData import edu.ie3.simona.model.participant.HpModel.HpState import edu.ie3.simona.model.thermal.ThermalHouse +import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.QuantityUtil -import edu.ie3.util.scala.OperationInterval import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll @@ -153,10 +153,14 @@ class HpModelTest extends Specification { when: def thermalHouse = buildThermalHouse(18, 22) def hpModelCaseClass = buildStandardModel(thermalHouse) + def startDate = TimeUtil.withDefaults.toZonedDateTime("2021-01-01 00:00:00") + def endDate = startDate.plusSeconds(86400L) def hpModelCaseObject = HpModel.apply( hpInput, - OperationInterval.apply(0L, 86400L), + startDate, + endDate, null, + 1.0, thermalHouse) then: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy deleted file mode 100644 index a645ef9f6d..0000000000 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy +++ /dev/null @@ -1,247 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.load - -import edu.ie3.datamodel.models.OperationTime -import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.OperatorInput -import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel -import edu.ie3.util.TimeUtil -import spock.lang.Specification -import tech.units.indriya.ComparableQuantity -import tech.units.indriya.quantity.Quantities - -import javax.measure.quantity.Energy -import java.time.temporal.ChronoUnit -import java.util.stream.Collectors - -import static edu.ie3.datamodel.models.BdewLoadProfile.* -import static edu.ie3.simona.model.participant.load.LoadReference.ActivePower -import static edu.ie3.simona.model.participant.load.LoadReference.EnergyConsumption -import static edu.ie3.util.quantities.PowerSystemUnits.* -import static org.apache.commons.math3.util.FastMath.abs -import static tech.units.indriya.unit.Units.MINUTE -import static tech.units.indriya.unit.Units.WATT - -class ProfileLoadModelTest extends Specification { - def loadInput = - new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) - - def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) - def testingTolerance = 1e-6 // Equals to 1 W power - - def "A profile load model should be instantiated from valid input correctly"() { - when: - def actual = ProfileLoadModel.apply( - loadInput.copy().standardLoadProfile(profile).build(), - foreSeenOperationInterval, - 1.0, - reference) - - then: - abs((actual.sRated() * actual.cosPhiRated()).subtract(expectedsRated).to(MEGAWATT).value.doubleValue()) < testingTolerance - - where: - profile | reference || expectedsRated - H0 | new ActivePower(Quantities.getQuantity(268.6, WATT)) || Quantities.getQuantity(268.6, WATT) - H0 | new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) || Quantities.getQuantity(805.8089, WATT) - L0 | new ActivePower(Quantities.getQuantity(268.6, WATT)) || Quantities.getQuantity(268.6, WATT) - L0 | new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) || Quantities.getQuantity(721.2, WATT) - G0 | new ActivePower(Quantities.getQuantity(268.6, WATT)) || Quantities.getQuantity(268.6, WATT) - G0 | new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) || Quantities.getQuantity(721.2, WATT) - } - - def "A profile load model should reach the targeted maximum power within a year"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - profile, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - def relevantData = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def max = relevantData.stream().mapToDouble({ data -> - dut.calculateActivePower(data).to(MEGAWATT).value.doubleValue() - }).max().getAsDouble() - - then: - abs(max - expectedMax) < testingTolerance - - where: - profile || expectedMax - H0 || 268.0029932985852E-6 - L0 || 268.0029932985852E-6 - G0 || 268.0029932985852E-6 - } - - def "A profile load model should account for the (global) scaling factor correctly when scaling to maximum power within a year"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - globalScaling, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - H0, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def max = relevantDatas.stream().mapToDouble({ relevantData -> - dut.calculateActivePower(relevantData).to(MEGAWATT).value.doubleValue() - }).max().getAsDouble() - - then: - abs(max - expectedMax) < testingTolerance - - where: - globalScaling || expectedMax - 0.25 || 67.00074832464630E-6 - 0.5 || 134.0014966492930E-6 - 0.75 || 201.0022449739390E-6 - 1.0 || 268.0029932985852E-6 - 1.25 || 335.0037416232310E-6 - 1.5 || 402.0044899478780E-6 - 1.75 || 469.0052382725240E-6 - 2.0 || 536.0059865971700E-6 - } - - def "A profile load model should reach the targeted annual energy consumption"() { - given: - /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles - * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % - * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach - * this accuracy. */ - def testingTolerance = 0.02 - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - profile, - new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)) as ComparableQuantity).to(KILOWATTHOUR).value.doubleValue() - }).sum() - - then: - abs(annualEnergy - expectedEnergy) / expectedEnergy < testingTolerance - - where: - profile || expectedEnergy - H0 || 3000d - L0 || 3000d - G0 || 3000d - } - - def "A profile load model should account for the (global) scaling factor correctly when scaling to annual energy consumption"() { - given: - /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles - * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % - * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach - * this accuracy. */ - def testingTolerance = 0.02 - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - globalScaling, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - H0, - new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)) as ComparableQuantity).to(KILOWATTHOUR).value.doubleValue() - }).sum() - - then: - abs(annualEnergy - expectedEnergy) / expectedEnergy < testingTolerance - - where: - globalScaling || expectedEnergy - 0.25 || 750d - 0.5 || 1500d - 0.75 || 2250d - 1.0 || 3000d - 1.25 || 3750d - 1.5 || 4500d - 1.75 || 5250d - 2.0 || 6000d - } -} diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy deleted file mode 100644 index 5089d7da95..0000000000 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ /dev/null @@ -1,189 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.load - -import edu.ie3.datamodel.models.OperationTime -import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.OperatorInput -import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.random.RandomLoadModel -import edu.ie3.simona.model.participant.load.random.RandomLoadParameters -import edu.ie3.util.TimeUtil -import spock.lang.Specification -import tech.units.indriya.quantity.Quantities - -import javax.measure.quantity.Energy -import java.time.temporal.ChronoUnit -import java.util.stream.Collectors - -import static edu.ie3.datamodel.models.BdewLoadProfile.H0 -import static edu.ie3.simona.model.participant.load.LoadReference.ActivePower -import static edu.ie3.simona.model.participant.load.LoadReference.EnergyConsumption -import static edu.ie3.util.quantities.PowerSystemUnits.* -import static org.apache.commons.math3.util.FastMath.abs -import static tech.units.indriya.unit.Units.MINUTE -import static tech.units.indriya.unit.Units.WATT - -class RandomLoadModelTest extends Specification { - def loadInput = - new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) - - def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) - def testingTolerance = 1e-6 // Equals to 1 W power - - def "A random load model should be instantiated from valid input correctly"() { - when: - def actual = RandomLoadModel.apply( - loadInput, - foreSeenOperationInterval, - 1.0, - reference - ) - - then: - abs(actual.sRated().subtract(expSRated).getValue().doubleValue()) < testingTolerance - - where: - reference || expSRated - new ActivePower(Quantities.getQuantity(268.6, WATT)) || Quantities.getQuantity(311.0105263157895, VOLTAMPERE) - new EnergyConsumption(Quantities.getQuantity(2000d, KILOWATTHOUR)) || Quantities.getQuantity(467.156124576697, VOLTAMPERE) - } - - def "A random load model is able to deliver the correct distribution on request"() { - given: - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - /* Working day, 61th quarter hour */ - def queryDate = TimeUtil.withDefaults.toZonedDateTime('2019-07-19 15:21:00') - def expectedParams = new RandomLoadParameters(0.405802458524704, 0.0671483352780342, 0.0417016632854939) - - when: - /* First query leeds to generation of distribution */ - def firstHit = dut.getGevDistribution(queryDate) - - then: - firstHit.with { - assert k == expectedParams.k() - assert mu == expectedParams.my() - assert sigma == expectedParams.sigma() - } - - when: - /* Second query is only look up in storage */ - def secondHit = dut.getGevDistribution(queryDate) - - then: - secondHit == firstHit - } - - def "A random load model should approx. reach the targeted annual energy consumption"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new RandomLoadModel.RandomRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def avgEnergy = (0..10).parallelStream().mapToDouble( - { runCnt -> - relevantDatas.parallelStream().mapToDouble( - { relevantData -> - (dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)).asType(Energy).to(KILOWATTHOUR).value.doubleValue() - }).sum() - }).average().orElse(0d) - - then: - abs(avgEnergy - 3000) / 3000 < 0.01 - } - - def "A random load model should approx. reach the targeted maximum power"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new RandomLoadModel.RandomRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def powers = (0..10).parallelStream().flatMap({ runCnt -> - relevantDatas.stream().parallel().map({ data -> - dut.calculateActivePower(data).to(WATT).getValue().doubleValue() - }) - }).sorted().toArray() as Double[] - def quantilePower = get95Quantile(powers) - - then: - abs(quantilePower - 268.6) / 268.6 < 0.01 - } - - def get95Quantile(Double[] sortedArray) { - def quantIdx = sortedArray.length * 0.95 as int - sortedArray[quantIdx] - } -} \ No newline at end of file diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala new file mode 100644 index 0000000000..6f31894485 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -0,0 +1,588 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.load + +import breeze.numerics.abs +import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} +import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} +import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} +import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel +import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData +import edu.ie3.simona.model.participant.load.random.RandomLoadModel +import edu.ie3.simona.test.common.TestTags.SnailTest +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.util.TimeUtil +import edu.ie3.util.quantities.PowerSystemUnits +import org.scalatest.prop.TableDrivenPropertyChecks +import tech.units.indriya.quantity.Quantities +import tech.units.indriya.unit.Units + +import java.time.temporal.ChronoUnit +import java.util.UUID +import javax.measure.quantity.{Dimensionless, Energy} + +class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { + "Testing correct scaling of load models" when { + val simulationStartDate = + TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") + val simulationEndDate = + TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") + val testingTolerance = 1e-6 // Equals to 1 W power + + "having a profile load model" should { + val profileLoadInput = + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PowerSystemUnits.PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + BdewLoadProfile.H0, + false, + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), + Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), + 0.95 + ) + val foreSeenOperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + profileLoadInput.getOperationTime + ) + + val targetEnergyConsumption = + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + "reach the targeted annual energy consumption" taggedAs SnailTest in { + /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles + * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % + * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach + * this accuracy. */ + + forAll( + Table( + "profile", + BdewLoadProfile.H0, + BdewLoadProfile.L0, + BdewLoadProfile.G0 + ) + ) { profile => + val dut = ProfileLoadModel( + profileLoadInput.getUuid, + profileLoadInput.getId, + foreSeenOperationInterval, + 1.0, + QControl.apply(profileLoadInput.getqCharacteristics()), + profileLoadInput.getsRated(), + profileLoadInput.getCosPhiRated, + profile, + EnergyConsumption(targetEnergyConsumption) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .reduce((l, r) => l.add(r)) + } + .reduce((l, r) => l.add(r)) + .divide(totalRuns) + + Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(targetEnergyConsumption) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) should beLessThanWithTolerance( + Quantities.getQuantity(2d, Units.PERCENT), + 1e-1 + ) + } + } + + "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { + val scalingFactor = 1.5 + val expectedEnergy = + Quantities.getQuantity(4500d, PowerSystemUnits.KILOWATTHOUR) + + val dut = ProfileLoadModel( + profileLoadInput.getUuid, + profileLoadInput.getId, + foreSeenOperationInterval, + scalingFactor, + QControl.apply(profileLoadInput.getqCharacteristics()), + profileLoadInput.getsRated(), + profileLoadInput.getCosPhiRated, + BdewLoadProfile.H0, + EnergyConsumption(targetEnergyConsumption) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .reduce((l, r) => l.add(r)) + } + .reduce((l, r) => l.add(r)) + .divide(totalRuns) + + Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(expectedEnergy) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) should beLessThanWithTolerance( + Quantities.getQuantity(2d, Units.PERCENT), + 1e-1 + ) + } + + val targetMaximumPower = + Quantities.getQuantity(268.6, Units.WATT) + "approximately reach the maximum power" taggedAs SnailTest in { + + forAll( + Table( + "profile", + BdewLoadProfile.H0, + BdewLoadProfile.L0, + BdewLoadProfile.G0 + ) + ) { profile => + val dut = ProfileLoadModel( + profileLoadInput.getUuid, + profileLoadInput.getId, + foreSeenOperationInterval, + 1.0, + QControl.apply(profileLoadInput.getqCharacteristics()), + profileLoadInput.getsRated(), + profileLoadInput.getCosPhiRated, + profile, + ActivePower(targetMaximumPower) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + (0 until totalRuns).flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + }.maxOption match { + case Some(maximumPower) => + maximumPower should equalWithTolerance( + targetMaximumPower.to(PowerSystemUnits.MEGAWATT), + testingTolerance + ) + case None => fail("Unable to determine maximum power.") + } + } + } + + "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { + val scalingFactor = 1.5 + val expectedMaximum = + Quantities.getQuantity(402.0044899478780, Units.WATT) + + val dut = ProfileLoadModel( + profileLoadInput.getUuid, + profileLoadInput.getId, + foreSeenOperationInterval, + scalingFactor, + QControl.apply(profileLoadInput.getqCharacteristics()), + profileLoadInput.getsRated(), + profileLoadInput.getCosPhiRated, + BdewLoadProfile.H0, + ActivePower(targetMaximumPower) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + (0 until totalRuns).flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + }.maxOption match { + case Some(maximumPower) => + maximumPower should equalWithTolerance( + expectedMaximum.to(PowerSystemUnits.MEGAWATT), + testingTolerance + ) + case None => fail("Unable to determine maximum power.") + } + } + } + + "having a random load model" should { + val randomLoadInput = + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PowerSystemUnits.PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + BdewLoadProfile.H0, + false, + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), + Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), + 0.95 + ) + val foreSeenOperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + randomLoadInput.getOperationTime + ) + + val targetEnergyConsumption = + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + "reach the targeted annual energy consumption" taggedAs SnailTest in { + val dut = RandomLoadModel( + randomLoadInput.getUuid, + randomLoadInput.getId, + foreSeenOperationInterval, + 1.0, + QControl.apply(randomLoadInput.getqCharacteristics()), + randomLoadInput.getsRated(), + randomLoadInput.getCosPhiRated, + EnergyConsumption(targetEnergyConsumption) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .reduce((l, r) => l.add(r)) + } + .reduce((l, r) => l.add(r)) + .divide(totalRuns) + + Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(targetEnergyConsumption) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) should beLessThanWithTolerance( + Quantities.getQuantity(1d, Units.PERCENT), + 1e-1 + ) + } + + "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { + val scalingFactor = 1.5 + val expectedEnergy = + Quantities.getQuantity(4500d, PowerSystemUnits.KILOWATTHOUR) + + val dut = RandomLoadModel( + randomLoadInput.getUuid, + randomLoadInput.getId, + foreSeenOperationInterval, + scalingFactor, + QControl.apply(randomLoadInput.getqCharacteristics()), + randomLoadInput.getsRated(), + randomLoadInput.getCosPhiRated, + EnergyConsumption(targetEnergyConsumption) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .reduce((l, r) => l.add(r)) + } + .reduce((l, r) => l.add(r)) + .divide(totalRuns) + + Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(expectedEnergy) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) should beLessThanWithTolerance( + Quantities.getQuantity(2d, Units.PERCENT), + 1e-1 + ) + } + + val targetMaximumPower = Quantities.getQuantity(268.6, Units.WATT) + "approximately reach the maximum power" taggedAs SnailTest in { + val dut = RandomLoadModel( + randomLoadInput.getUuid, + randomLoadInput.getId, + foreSeenOperationInterval, + 1.0, + QControl.apply(randomLoadInput.getqCharacteristics()), + randomLoadInput.getsRated(), + randomLoadInput.getCosPhiRated, + ActivePower(targetMaximumPower) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + .sorted + .toArray + + val quantile95 = RandomLoadModelSpec.get95Quantile(powers) + + Quantities.getQuantity( + abs( + 100 - + quantile95 + .divide(targetMaximumPower) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) should beLessThanWithTolerance( + Quantities.getQuantity(1d, Units.PERCENT), + 1e-1 + ) + } + + "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { + val scalingFactor = 1.5 + val expectedMaximum = targetMaximumPower.multiply(scalingFactor) + + val dut = RandomLoadModel( + randomLoadInput.getUuid, + randomLoadInput.getId, + foreSeenOperationInterval, + scalingFactor, + QControl.apply(randomLoadInput.getqCharacteristics()), + randomLoadInput.getsRated(), + randomLoadInput.getCosPhiRated, + ActivePower(targetMaximumPower) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(1d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + .sorted + .toArray + /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the + * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ + RandomLoadModelSpec.get95Quantile(powers) should equalWithTolerance( + expectedMaximum.to(PowerSystemUnits.MEGAWATT), + 1e-5 + ) + } + } + } +} diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala index 467214b051..a6b700b5db 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala @@ -6,18 +6,15 @@ package edu.ie3.simona.model.participant.load +import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.input.LoadInputTestData -import edu.ie3.simona.util.ConfigUtil -import edu.ie3.util.quantities.PowerSystemUnits.{KILOWATTHOUR, MEGAVOLTAMPERE} +import edu.ie3.util.quantities.PowerSystemUnits.KILOWATTHOUR import edu.ie3.util.quantities.{PowerSystemUnits, QuantityUtil} + import javax.measure.Quantity import javax.measure.quantity.Power import org.scalatest.PrivateMethodTester diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala new file mode 100644 index 0000000000..a4140fab4b --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -0,0 +1,127 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.load + +import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} +import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.util.TimeUtil +import edu.ie3.util.quantities.PowerSystemUnits +import org.scalatest.prop.TableDrivenPropertyChecks +import tech.units.indriya.quantity.Quantities +import tech.units.indriya.unit.Units + +import java.util.UUID + +class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { + "Having a profile load model" when { + val loadInput = + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PowerSystemUnits.PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + BdewLoadProfile.H0, + false, + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), + Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), + 0.95 + ) + + val simulationStartDate = + TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") + val simulationEndDate = + TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") + val foreSeenOperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + loadInput.getOperationTime + ) + val testingTolerance = 1e-6 // Equals to 1 W power + + "instantiating it" should { + "deliver a proper model" in { + forAll( + Table( + ("profile", "reference", "expectedsRated"), + ( + BdewLoadProfile.H0, + ActivePower(Quantities.getQuantity(268.6, Units.WATT)), + Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ), + ( + BdewLoadProfile.H0, + EnergyConsumption( + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + ), + Quantities.getQuantity(848.22, PowerSystemUnits.VOLTAMPERE) + ), + ( + BdewLoadProfile.L0, + ActivePower(Quantities.getQuantity(268.6, Units.WATT)), + Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ), + ( + BdewLoadProfile.L0, + EnergyConsumption( + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + ), + Quantities.getQuantity(759.158, PowerSystemUnits.VOLTAMPERE) + ), + ( + BdewLoadProfile.G0, + ActivePower(Quantities.getQuantity(268.6, Units.WATT)), + Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ), + ( + BdewLoadProfile.G0, + EnergyConsumption( + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + ), + Quantities.getQuantity(759.158, PowerSystemUnits.VOLTAMPERE) + ) + ) + ) { (profile, reference, expectedSRated) => + val actual = ProfileLoadModel( + loadInput.copy().standardLoadProfile(profile).build(), + foreSeenOperationInterval, + 1.0, + reference + ) + + actual.sRated should equalWithTolerance( + expectedSRated.to(PowerSystemUnits.MEGAVOLTAMPERE), + testingTolerance + ) + } + } + } + } +} diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala new file mode 100644 index 0000000000..a32cc4e5a9 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -0,0 +1,161 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.load + +import de.lmu.ifi.dbs.elki.math.statistics.distribution.GeneralizedExtremeValueDistribution +import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} +import edu.ie3.simona.model.participant.load.random.{ + RandomLoadModel, + RandomLoadParameters +} +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.matchers.QuantityMatchers +import edu.ie3.util.TimeUtil +import edu.ie3.util.quantities.PowerSystemUnits +import org.scalatest.prop.TableDrivenPropertyChecks +import tech.units.indriya.ComparableQuantity +import tech.units.indriya.quantity.Quantities +import tech.units.indriya.unit.Units + +import java.time.temporal.ChronoUnit +import java.util.UUID +import javax.measure.quantity.{Dimensionless, Energy, Power} + +class RandomLoadModelSpec + extends UnitSpec + with TableDrivenPropertyChecks + with QuantityMatchers { + "Having a random load model" when { + val loadInput = + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PowerSystemUnits.PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + BdewLoadProfile.H0, + false, + Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), + Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), + 0.95 + ) + + val simulationStartDate = + TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") + val simulationEndDate = + TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") + val foreSeenOperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + loadInput.getOperationTime + ) + val testingTolerance = 1e-6 // Equals to 1 W power + + "instantiating it" should { + "deliver a proper model" in { + forAll( + Table( + ("reference", "expectedSRated"), + ( + ActivePower(Quantities.getQuantity(268.6, Units.WATT)), + Quantities + .getQuantity(311.0105263157895, PowerSystemUnits.VOLTAMPERE) + ), + ( + EnergyConsumption( + Quantities.getQuantity(2000d, PowerSystemUnits.KILOWATTHOUR) + ), + Quantities + .getQuantity(467.156124576697, PowerSystemUnits.VOLTAMPERE) + ) + ) + ) { (reference, expectedSRated) => + val actual = RandomLoadModel( + loadInput, + foreSeenOperationInterval, + 1.0, + reference + ) + + actual.sRated should equalWithTolerance( + expectedSRated.to(PowerSystemUnits.MEGAVOLTAMPERE), + testingTolerance + ) + } + } + } + + "calculating results" should { + "deliver the correct distribution on request" in { + val dut = new RandomLoadModel( + loadInput.getUuid, + loadInput.getId, + foreSeenOperationInterval, + 1.0, + QControl.apply(loadInput.getqCharacteristics()), + loadInput.getsRated(), + loadInput.getCosPhiRated, + new ActivePower(Quantities.getQuantity(268.6, Units.WATT)) + ) + /* Working day, 61th quarter hour */ + val queryDate = + TimeUtil.withDefaults.toZonedDateTime("2019-07-19 15:21:00") + val expectedParams = new RandomLoadParameters( + 0.405802458524704, + 0.0671483352780342, + 0.0417016632854939 + ) + + /* First query leeds to generation of distribution */ + val getGevDistribution = + PrivateMethod[GeneralizedExtremeValueDistribution]( + Symbol("getGevDistribution") + ) + + def firstHit = dut invokePrivate getGevDistribution(queryDate) + + firstHit.getK shouldBe expectedParams.k + firstHit.getMu shouldBe expectedParams.my + firstHit.getSigma shouldBe expectedParams.sigma + + /* Second query is only look up in storage */ + def secondHit = dut invokePrivate getGevDistribution(queryDate) + + secondHit shouldBe firstHit + } + } + } +} + +object RandomLoadModelSpec { + def get95Quantile[V](sortedArray: Array[V]): V = sortedArray( + (sortedArray.length * 0.95).toInt + ) +} diff --git a/src/test/scala/edu/ie3/simona/test/common/TestTags.scala b/src/test/scala/edu/ie3/simona/test/common/TestTags.scala new file mode 100644 index 0000000000..07ce3a25b8 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/test/common/TestTags.scala @@ -0,0 +1,16 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.test.common + +import org.scalatest.Tag + +sealed trait TestTags +object TestTags { + object SnailTest + extends Tag("edu.ie3.simona.test.common.TestTags.SnailTest") + with TestTags +} diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala index 1afb07811d..8cf7edf16e 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala @@ -6,38 +6,144 @@ package edu.ie3.simona.test.matchers +import edu.ie3.simona.test.matchers.QuantityMatchers.{ + EqualMatcher, + GreaterMatcher, + LessMatcher +} import edu.ie3.util.quantities.QuantityUtil + import javax.measure.Quantity import org.scalatest.matchers.{MatchResult, Matcher} +import tech.units.indriya.ComparableQuantity +import tech.units.indriya.quantity.Quantities /** Trait, to simplify test coding, that is reliant on [[Quantity]] s */ trait QuantityMatchers { - class QuantityMatcher[Q <: Quantity[Q]](right: Quantity[Q], tolerance: Double) - extends Matcher[Quantity[Q]] - with QuantityMatchers { - override def apply(left: Quantity[Q]): MatchResult = MatchResult( - QuantityUtil.equals(left, right, tolerance), - QuantityMatchers.assembleRawFailureMessage(left, right, tolerance), - QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance) - ) - } - def equalWithTolerance[Q <: Quantity[Q]]( right: Quantity[Q], tolerance: Double = 1e-10 - ) = new QuantityMatcher(right, tolerance) + ) = new EqualMatcher(right, tolerance) + + def beLessThanWithTolerance[Q <: Quantity[Q]]( + right: ComparableQuantity[Q], + tolerance: Double = 1e-10 + ) = new LessMatcher[Q](right, tolerance) + + def beGreaterThanWithTolerance[Q <: Quantity[Q]]( + right: ComparableQuantity[Q], + tolerance: Double = 1e-10 + ) = new GreaterMatcher[Q](right, tolerance) } -case object QuantityMatchers extends QuantityMatchers { - private def assembleRawFailureMessage[Q <: Quantity[Q]]( - lhs: Quantity[Q], - rhs: Quantity[Q], +object QuantityMatchers { + class EqualMatcher[Q <: Quantity[Q]](right: Quantity[Q], tolerance: Double) + extends Matcher[Quantity[Q]] { + override def apply(left: Quantity[Q]): MatchResult = MatchResult( + QuantityUtil.equals(left, right, tolerance), + s"The quantities $left and $right differ more than $tolerance in value", + s"The quantities $left and $right differ less than $tolerance in value" + ) + } + + class LessMatcher[Q <: Quantity[Q]]( + right: ComparableQuantity[Q], tolerance: Double - ) = s"The quantities $lhs and $rhs differ more than $tolerance in value" - private def assembleNegatedFailureMessage[Q <: Quantity[Q]]( - lhs: Quantity[Q], - rhs: Quantity[Q], + ) extends Matcher[ComparableQuantity[Q]] { + override def apply(left: ComparableQuantity[Q]): MatchResult = compare( + left, + right, + tolerance, + (right: ComparableQuantity[Q], tolerance: ComparableQuantity[Q]) => + right.add(tolerance), + (left: ComparableQuantity[Q], right: ComparableQuantity[Q]) => + left.isLessThan(right), + ( + lhs: ComparableQuantity[Q], + rhs: ComparableQuantity[Q], + toleranceQuantity: ComparableQuantity[Q] + ) => s"The quantity $lhs is not less than $rhs + $toleranceQuantity.", + ( + lhs: ComparableQuantity[Q], + rhs: ComparableQuantity[Q], + toleranceQuantity: ComparableQuantity[Q] + ) => s"The quantity $lhs is less than $rhs + $toleranceQuantity." + ) + } + + class GreaterMatcher[Q <: Quantity[Q]]( + right: ComparableQuantity[Q], tolerance: Double - ) = s"The quantities $lhs and $rhs differ less than $tolerance in value" + ) extends Matcher[ComparableQuantity[Q]] { + override def apply(left: ComparableQuantity[Q]): MatchResult = compare( + left, + right, + tolerance, + (right: ComparableQuantity[Q], tolerance: ComparableQuantity[Q]) => + right.subtract(tolerance), + (left: ComparableQuantity[Q], right: ComparableQuantity[Q]) => + left.isGreaterThan(right), + ( + lhs: ComparableQuantity[Q], + rhs: ComparableQuantity[Q], + toleranceQuantity: ComparableQuantity[Q] + ) => s"The quantity $lhs is not greater than $rhs - $toleranceQuantity.", + ( + lhs: ComparableQuantity[Q], + rhs: ComparableQuantity[Q], + toleranceQuantity: ComparableQuantity[Q] + ) => s"The quantity $lhs is greater than $rhs - $toleranceQuantity." + ) + } + + /** Compares two Quantities with tolerance + * + * @param left + * Left hand side of the comparison + * @param right + * Right hand side of the comparison + * @param tolerance + * Numerical tolerance to be applied to the right hand side + * @param rightWithToleranceFun + * Function, how to build the right hand side with tolerance + * @param compareFun + * Compare function (lhs, rhs) => Condition + * @param rawFailureMessage + * Failure message in case condition is not satisfied + * @param rawNegatedFailureMessage + * Failure message in case the condition is negated + * @tparam Q + * Type of [[ComparableQuantity]] to compare + * @return + * A [[MatchResult]] + */ + private def compare[Q <: Quantity[Q]]( + left: ComparableQuantity[Q], + right: ComparableQuantity[Q], + tolerance: Double, + rightWithToleranceFun: ( + ComparableQuantity[Q], + ComparableQuantity[Q] + ) => ComparableQuantity[Q], + compareFun: (ComparableQuantity[Q], ComparableQuantity[Q]) => Boolean, + rawFailureMessage: ( + ComparableQuantity[Q], + ComparableQuantity[Q], + ComparableQuantity[Q] + ) => String, + rawNegatedFailureMessage: ( + ComparableQuantity[Q], + ComparableQuantity[Q], + ComparableQuantity[Q] + ) => String + ): MatchResult = { + val toleranceQuantity = Quantities.getQuantity(tolerance, right.getUnit) + val rightWithTolerance = rightWithToleranceFun(right, toleranceQuantity) + MatchResult( + compareFun(left, rightWithTolerance), + rawFailureMessage(left, right, toleranceQuantity), + rawNegatedFailureMessage(left, right, toleranceQuantity) + ) + } } diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala new file mode 100644 index 0000000000..ceae05e4f9 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala @@ -0,0 +1,77 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.test.matchers + +import edu.ie3.simona.test.common.UnitSpec +import tech.units.indriya.quantity.Quantities +import tech.units.indriya.unit.Units + +import javax.measure.quantity.Length + +class QuantityMatchersSpec extends UnitSpec { + "Testing quantities with custom quantity matchers" when { + val a = Quantities.getQuantity(5d, Units.METRE) + val b = Quantities.getQuantity(6d, Units.METRE) + val toleranceQuantity = Quantities.getQuantity(1e-10, Units.METRE) + + "testing for equality" should { + "pass if quantities are exactly the same" in { + a should equalWithTolerance(a, 1e-10) + } + + "pass if quantities are approximately the same" in { + a should equalWithTolerance( + a.add(toleranceQuantity.multiply(0.9)), + 1e-10 + ) + } + + "detect mismatch on tolerance exceeding" in { + a should not( + equalWithTolerance(a.add(toleranceQuantity.multiply(1.1)), 1e-10) + ) + } + } + + "testing for less than" should { + "pass if the quantity is really less" in { + a should beLessThanWithTolerance(b, 1e-10) + } + + "pass if the quantity is less with tolerance" in { + a.add(toleranceQuantity.multiply(0.9)) should beLessThanWithTolerance( + a, + 1e-10 + ) + } + + "detect mismatch on tolerance exceeding" in { + a.add(toleranceQuantity.multiply(1.1)) should not( + beLessThanWithTolerance(a, 1e-10) + ) + } + } + + "testing for greater than" should { + "pass if the quantity is really greater" in { + b should beGreaterThanWithTolerance(a, 1e-10) + } + + "pass if the quantity is greater with tolerance" in { + a.subtract( + toleranceQuantity.multiply(0.9) + ) should beGreaterThanWithTolerance(a, 1e-10) + } + + "detect mismatch on tolerance exceeding" in { + a.subtract(toleranceQuantity.multiply(1.1)) should not( + beGreaterThanWithTolerance(a, 1e-10) + ) + } + } + } +} From 07071baa884dfd5825a8183e8c6d009d7544cec2 Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 12 Jan 2022 10:48:24 +0100 Subject: [PATCH 002/305] Add config possibility for transformer control groups --- CHANGELOG.md | 5 +- build.gradle | 2 +- .../vn_146_lv_small/vn_146_lv_small.conf | 4 +- input/samples/vn_simona/vn_simona.conf | 22 ++- ...plate.conf => simona-config-template.conf} | 17 +++ .../ie3/simona/config/ConfigFailFast.scala | 63 +++++++-- .../ie3/simona/config/RefSystemParser.scala | 4 +- .../edu/ie3/simona/config/SimonaConfig.scala | 111 ++++++++++++++- .../control/TransformerControlGroup.scala | 75 ++++++++++ .../model/participant/SystemParticipant.scala | 6 +- .../simona/config/ConfigFailFastSpec.scala | 111 ++++++++++----- .../simona/config/RefSystemParserSpec.scala | 48 +++++-- .../control/TransformerControlGroupSpec.scala | 132 ++++++++++++++++++ 13 files changed, 524 insertions(+), 76 deletions(-) rename src/main/resources/config/{config-template.conf => simona-config-template.conf} (94%) create mode 100644 src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala create mode 100644 src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index c47d5ac600..06328de446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Config possibility for transformer control groups + ### Changed - Improving code readability in EvcsAgent by moving FreeLotsRequest to separate methods -[Unreleased]: https://github.com/ie3-institute/simona +[Unreleased]: https://github.com/ie3-institute/simona/compare/a14a093239f58fca9b2b974712686b33e5e5f939...HEAD diff --git a/build.gradle b/build.gradle index 846faff953..d3fa53145d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ ext { scalaVersion = '2.13' scalaBinaryVersion = '2.13.7' akkaVersion = '2.6.18' - tscfgVersion = '0.9.996' + tscfgVersion = '0.9.995' scriptsLocation = 'gradle' + File.separator + 'scripts' + File.separator // location of script plugins } diff --git a/input/samples/vn_146_lv_small/vn_146_lv_small.conf b/input/samples/vn_146_lv_small/vn_146_lv_small.conf index 9d86cffc3b..b12b6c5776 100644 --- a/input/samples/vn_146_lv_small/vn_146_lv_small.conf +++ b/input/samples/vn_146_lv_small/vn_146_lv_small.conf @@ -93,8 +93,8 @@ simona.event.listener = [] simona.gridConfig.refSystems = [ - {sNom="100 kVA", vNom="0.4 kV", voltLvls = ["{NS, 0.4 kV}"]}, - {sNom="500 MVA", vNom="20 kV", voltLvls = ["{MS, 20 kV}"]} + {sNom="100 kVA", vNom="0.4 kV", voltLvls = [{id = "NS", vNom = "0.4 kV"}]}, + {sNom="500 MVA", vNom="20 kV", voltLvls = [{id = "MS", vNom = "20 kV"}]} ] ################################################################## diff --git a/input/samples/vn_simona/vn_simona.conf b/input/samples/vn_simona/vn_simona.conf index f259b25306..3ac3f20448 100644 --- a/input/samples/vn_simona/vn_simona.conf +++ b/input/samples/vn_simona/vn_simona.conf @@ -144,10 +144,10 @@ simona.event.listener = [] ################################################################## simona.gridConfig.refSystems = [ - {sNom = "100 kVA", vNom = "0.4 kV", voltLvls = ["{NS, 0.4 kV}"]}, - {sNom = "60 MVA", vNom = "20 kV", voltLvls = ["{MS, 20 kV}"]}, - {sNom = "600 MVA", vNom = "110 kV", voltLvls = ["{HS, 110 kV}"]}, - {sNom = "1000 MVA", vNom = "380 kV", voltLvls = ["{HoeS, 380 kV}"]} + {sNom = "100 kVA", vNom = "0.4 kV", voltLvls = [{id = "NS", vNom = "0.4 kV"}]}, + {sNom = "60 MVA", vNom = "20 kV", voltLvls = [{id = "MS", vNom = "20 kV"}]}, + {sNom = "600 MVA", vNom = "110 kV", voltLvls = [{id = "HS", vNom = "110 kV"}]}, + {sNom = "1000 MVA", vNom = "380 kV", voltLvls = [{id = "HoeS", vNom = "380 kV"}]} ] ################################################################## @@ -157,3 +157,17 @@ simona.powerflow.maxSweepPowerDeviation = 1E-5 // the maximum allowed deviation simona.powerflow.newtonraphson.epsilon = [1E-12] simona.powerflow.newtonraphson.iterations = 50 simona.powerflow.resolution = "3600s" + +simona.control.transformer = [ + { + transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"], + measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"], + vMin = 0.98, + vMax = 1.02 + }, { + transformers = ["1132dbf4-e8a1-44ae-8415-f42d4497aa1d"], + measurements = ["7686b818-a0ba-465c-8e4e-f7d3c4e171fc"], + vMin = 0.98, + vMax = 1.02 + } +] diff --git a/src/main/resources/config/config-template.conf b/src/main/resources/config/simona-config-template.conf similarity index 94% rename from src/main/resources/config/config-template.conf rename to src/main/resources/config/simona-config-template.conf index 8e6952e8f0..19c349a525 100644 --- a/src/main/resources/config/config-template.conf +++ b/src/main/resources/config/simona-config-template.conf @@ -69,6 +69,15 @@ GridOutputConfig { transformers3w: boolean | false } +#@define +TransformerControlGroup { + transformers: [string] + measurements: [string] + # TODO: Currently, only limit prevention is configurable. Should be an interface, when it is allowed by tscfg + vMin: Double + vMax: Double +} + ################################################################## # Agentsim ################################################################## @@ -263,3 +272,11 @@ simona.event.listener = [ eventsToProcess = [string] } ] + +################################################################## +# Configuration of Control Schemes +################################################################## +#@optional +simona.control = { + transformer = [TransformerControlGroup] +} diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index ddc7c37704..61b6c10eed 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -9,7 +9,12 @@ package edu.ie3.simona.config import com.typesafe.config.{Config, ConfigException} import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.InfluxDb1x -import edu.ie3.simona.config.SimonaConfig.{BaseOutputConfig, RefSystemConfig} +import edu.ie3.simona.config.SimonaConfig.{ + BaseOutputConfig, + RefSystemConfig, + Simona, + TransformerControlGroup +} import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.io.result.ResultSinkType import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference} @@ -128,6 +133,9 @@ case object ConfigFailFast extends LazyLogging { /* Check power flow resolution configuration */ checkPowerFlowResolutionConfiguration(simonaConfig.simona.powerflow) + + /* Check control scheme definitions */ + simonaConfig.simona.control.foreach(checkControlSchemes) } /** Checks for valid sink configuration @@ -395,15 +403,6 @@ case object ConfigFailFast extends LazyLogging { s"Provided refSystem is: $refSystem." ) - voltLvls.foreach { voltLvl => - { - if (!ConfigConventions.voltLvlRegex.matches(voltLvl)) - throw new InvalidConfigParameterException( - s"The definition string for voltLvl '$voltLvl' does not comply with the definition {, }!" - ) - } - } - gridIds.foreach { case gridIdRange @ ConfigConventions.gridIdDotRange(from, to) => rangeCheck(from.toInt, to.toInt, gridIdRange) @@ -537,6 +536,50 @@ case object ConfigFailFast extends LazyLogging { } } + /** Check the validity of control scheme definitions + * + * @param control + * Control scheme definitions + */ + private def checkControlSchemes(control: Simona.Control): Unit = { + control.transformer.foreach(checkTransformerControl) + } + + /** Check the suitability of transformer control group definition. + * + * One important check cannot be performed at this place, as input data is + * not available, yet: Do the measurements belong to a region, that can be + * influenced by the transformer? + * + * @param transformerControlGroup + * Transformer control group definition + */ + private def checkTransformerControl( + transformerControlGroup: TransformerControlGroup + ): Unit = transformerControlGroup match { + case TransformerControlGroup(measurements, transformers, vMax, vMin) => + if (measurements.isEmpty) + throw new InvalidConfigParameterException( + "A transformer control group cannot have no measurements assigned." + ) + if (transformers.isEmpty) + throw new InvalidConfigParameterException( + "A transformer control group cannot have no transformers assigned." + ) + if (vMin < 0) + throw new InvalidConfigParameterException( + "The minimum permissible voltage magnitude of a transformer control group has to be positive." + ) + if (vMax < 0) + throw new InvalidConfigParameterException( + "The maximum permissible voltage magnitude of a transformer control group has to be positive." + ) + if (vMax < vMin) + throw new InvalidConfigParameterException( + "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." + ) + } + /** Check the default config * * @param config diff --git a/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala b/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala index 9bf9f5e1b2..2b8a8477b0 100644 --- a/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala +++ b/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala @@ -108,11 +108,11 @@ object RefSystemParser { voltLvls.foldLeft(Vector.empty[(VoltageLevel, RefSystem)])( (voltLvlRefSystems, voltLvlDef) => { val voltLvl = voltLvlDef match { - case ConfigConventions.voltLvlRegex(id, vNom) => + case SimonaConfig.VoltLvlConfig(id, vNom) => VoltLvlParser.parse(id, vNom) case invalid => throw new InvalidConfigParameterException( - s"Got invalid voltage level string $invalid. Has to look like this: {MV, 10 kV}" + s"Got invalid voltage level definition $invalid. Double-check your entry!" ) } voltLvlRefSystems :+ (voltLvl, refSystem) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 6283055bbc..f6774a0c81 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,5 +1,5 @@ /* - * © 2021. TU Dortmund University, + * © 2022. TU Dortmund University, * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ @@ -377,7 +377,7 @@ object SimonaConfig { gridIds: scala.Option[scala.List[java.lang.String]], sNom: java.lang.String, vNom: java.lang.String, - voltLvls: scala.Option[scala.List[java.lang.String]] + voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object RefSystemConfig { def apply( @@ -397,11 +397,31 @@ object SimonaConfig { voltLvls = if (c.hasPathOrNull("voltLvls")) scala.Some( - $_L$_str(c.getList("voltLvls"), parentPath, $tsCfgValidator) + $_LSimonaConfig_VoltLvlConfig( + c.getList("voltLvls"), + parentPath, + $tsCfgValidator + ) ) else None ) } + private def $_LSimonaConfig_VoltLvlConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.VoltLvlConfig] = { + import scala.jdk.CollectionConverters._ + cl.asScala + .map(cv => + SimonaConfig.VoltLvlConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList + } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, @@ -420,6 +440,45 @@ object SimonaConfig { } + final case class TransformerControlGroup( + measurements: scala.List[java.lang.String], + transformers: scala.List[java.lang.String], + vMax: scala.Double, + vMin: scala.Double + ) + object TransformerControlGroup { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.TransformerControlGroup = { + SimonaConfig.TransformerControlGroup( + measurements = + $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = + $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + ) + } + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { + if (c == null) 0 + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } + } + + } + final case class VoltLvlConfig( id: java.lang.String, vNom: java.lang.String @@ -514,6 +573,7 @@ object SimonaConfig { } final case class Simona( + control: scala.Option[SimonaConfig.Simona.Control], event: SimonaConfig.Simona.Event, gridConfig: SimonaConfig.Simona.GridConfig, input: SimonaConfig.Simona.Input, @@ -524,6 +584,41 @@ object SimonaConfig { time: SimonaConfig.Simona.Time ) object Simona { + final case class Control( + transformer: scala.List[SimonaConfig.TransformerControlGroup] + ) + object Control { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Control = { + SimonaConfig.Simona.Control( + transformer = $_LSimonaConfig_TransformerControlGroup( + c.getList("transformer"), + parentPath, + $tsCfgValidator + ) + ) + } + private def $_LSimonaConfig_TransformerControlGroup( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.TransformerControlGroup] = { + import scala.jdk.CollectionConverters._ + cl.asScala + .map(cv => + SimonaConfig.TransformerControlGroup( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList + } + } + final case class Event( listener: scala.Option[ scala.List[SimonaConfig.Simona.Event.Listener$Elm] @@ -2133,6 +2228,16 @@ object SimonaConfig { $tsCfgValidator: $TsCfgValidator ): SimonaConfig.Simona = { SimonaConfig.Simona( + control = + if (c.hasPathOrNull("control")) + scala.Some( + SimonaConfig.Simona.Control( + c.getConfig("control"), + parentPath + "control.", + $tsCfgValidator + ) + ) + else None, event = SimonaConfig.Simona.Event( if (c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala new file mode 100644 index 0000000000..652b40b4e1 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -0,0 +1,75 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.control + +import breeze.math.Complex +import edu.ie3.powerflow.model.NodeData.StateData +import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult +import edu.ie3.simona.model.control.TransformerControlGroup.RegulationCriterion +import tech.units.indriya.ComparableQuantity + +import java.util.UUID +import javax.measure.quantity.Dimensionless + +/** Business logic for a transformer control group. It's main purpose is to + * determine, if there is any regulation need and if yes, in what circumference + * (here: voltage raise or reduction to achieve) + * + * @param nodalRegulationCriterion + * Mapping from nodal index to a partial function, that determines the + * regulation need at this node + * @param harmonizeRegulationNeeds + * Partial function to harmonize different, possible contradictory regulation + * needs + */ +final case class TransformerControlGroup( + nodalRegulationCriterion: Map[UUID, RegulationCriterion], + harmonizeRegulationNeeds: Array[ + ComparableQuantity[Dimensionless] + ] => Option[ComparableQuantity[Dimensionless]] +) { + + /** Based on the given successful power flow result, determine the difference + * in voltage magnitude, that needs to be achieved by regulating the + * transformer tap position + * + * @param result + * Power flow result to account for + * @param uuidToIndex + * Mapping from node's uuid to nodal index + * @return + * Optional voltage magnitude, that a transformer tap regulation needs to + * achieve + */ + def determineRegulationNeed( + result: SuccessFullPowerFlowResult, + uuidToIndex: Map[UUID, Int] + ): Option[ComparableQuantity[Dimensionless]] = { + val regulationNeeds = result.nodeData.flatMap { + case StateData(resultNodeIndex, _, voltage, _) => + /* Find possible matching criterion and evaluate it */ + nodalRegulationCriterion + .find { case (uuid, _) => + val index = uuidToIndex(uuid) + index == resultNodeIndex + } + .map { case (_, criterion) => + criterion(voltage) + } + }.flatten + Option + .when(regulationNeeds.nonEmpty)( + harmonizeRegulationNeeds(regulationNeeds) + ) + .flatten + } +} + +object TransformerControlGroup { + type RegulationCriterion = + Complex => Option[ComparableQuantity[Dimensionless]] +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 3331b2280d..8eb4e6b966 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -105,11 +105,7 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( def activeToReactivePowerFunc( nodalVoltage: ComparableQuantity[Dimensionless] ): ComparableQuantity[Power] => ComparableQuantity[Power] = - qControl.activeToReactivePowerFunc( - sRated.multiply(scalingFactor), - cosPhiRated, - nodalVoltage - ) + qControl.activeToReactivePowerFunc(sRated, cosPhiRated, nodalVoltage) /** Calculate the reactive power of the model * diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index decc6d59cd..fd2bcc8026 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -15,6 +15,7 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.{Csv, InfluxDb1x} import edu.ie3.simona.config.SimonaConfig.Simona.Powerflow.Newtonraphson import edu.ie3.simona.config.SimonaConfig.Simona.{Powerflow, Time} +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec} import edu.ie3.simona.util.ConfigUtil.{CsvConfigUtil, NotifierIdentifier} @@ -69,8 +70,8 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List(10, 30), 100 ), - Duration.of(3600, ChronoUnit.SECONDS), - Duration.of(3600, ChronoUnit.SECONDS) + resolution = Duration.of(3600, ChronoUnit.SECONDS), + sweepTimeout = Duration.of(3600, ChronoUnit.SECONDS) ) ) } @@ -112,31 +113,6 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { } - "throw an InvalidConfigParametersException when the voltLevel is malformed (e.g. a number)" in { - val refSystemConfigAllEmpty = - ConfigFactory.parseString("""simona.gridConfig.refSystems = [ - | { - | sNom="100 MVA", - | vNom="0.4 kV", - | voltLvls = ["1"] - | } - |]""".stripMargin) - val faultyConfig = - refSystemConfigAllEmpty.withFallback(typesafeConfig).resolve() - val faultySimonaConfig = SimonaConfig(faultyConfig) - - // get the private method for validation - val checkRefSystem = - PrivateMethod[Unit](Symbol("checkRefSystem")) - - intercept[InvalidConfigParameterException] { - faultySimonaConfig.simona.gridConfig.refSystems.foreach(refSystem => - ConfigFailFast invokePrivate checkRefSystem(refSystem) - ) - }.getMessage shouldBe "The definition string for voltLvl '1' does not comply with the definition {, }!" - - } - "throw an InvalidConfigParametersException when the gridId is malformed" in { val malformedGridIds = List("10--100", "MS", "10..100") @@ -176,7 +152,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { | { | sNom="100", | vNom="0.4 kV", - | voltLvls = ["{MS, 10 kV}","{HS, 110 kV}"] + | voltLvls = [{id = "MS", vNom = "10 kV"},{id = "HS", vNom = "110 kV"}] | } |]""".stripMargin ) @@ -192,7 +168,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { faultySimonaConfig.simona.gridConfig.refSystems.foreach(refSystem => ConfigFailFast invokePrivate checkRefSystem(refSystem) ) - }.getMessage shouldBe "Invalid value for sNom from provided refSystem RefSystemConfig(None,100,0.4 kV,Some(List({MS, 10 kV}, {HS, 110 kV}))). Is a valid unit provided?" + }.getMessage shouldBe "Invalid value for sNom from provided refSystem RefSystemConfig(None,100,0.4 kV,Some(List(VoltLvlConfig(MS,10 kV), VoltLvlConfig(HS,110 kV)))). Is a valid unit provided?" } @@ -204,7 +180,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { | { | sNom="100 MVA", | vNom="0.4", - | voltLvls = ["{MS, 10 kV}","{HS, 110 kV}"] + | voltLvls = [{id = "MS", vNom = "10 kV"},{id = "HS", vNom = "110 kV"}] | } |]""".stripMargin ) @@ -220,7 +196,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { faultySimonaConfig.simona.gridConfig.refSystems.foreach(refSystem => ConfigFailFast invokePrivate checkRefSystem(refSystem) ) - }.getMessage shouldBe "Invalid value for vNom from provided refSystem RefSystemConfig(None,100 MVA,0.4,Some(List({MS, 10 kV}, {HS, 110 kV}))). Is a valid unit provided?" + }.getMessage shouldBe "Invalid value for vNom from provided refSystem RefSystemConfig(None,100 MVA,0.4,Some(List(VoltLvlConfig(MS,10 kV), VoltLvlConfig(HS,110 kV)))). Is a valid unit provided?" } @@ -231,13 +207,13 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { | { | sNom="100 MVA", | vNom="0.4 kV", - | voltLvls = ["{MS, 10 kV}","{HS, 110 kV}"] + | voltLvls = [{id = "MS", vNom = "10 kV"},{id = "HS", vNom = "110 kV"}] | gridIds = ["1","1-10","10...100"] | }, | { | sNom="1000 MVA", | vNom="10kV", - | voltLvls = ["{HS, 110 kV}","{HoeS, 380 kV}"] + | voltLvls = [{id = "HS", vNom = "110 kV"},{id = "HoeS", vNom = "380 kV"}] | gridIds = ["1-3","3...6","10...100"] | } |]""".stripMargin @@ -877,7 +853,76 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ) }.getMessage shouldBe "The weather data scheme 'this won't work' is not supported. Supported schemes:\n\ticon\n\tpsdm" } + } + + "checking the transformer control groups" should { + val checkTransformerControl = + PrivateMethod[Unit](Symbol("checkTransformerControl")) + "throw an exception, if the measurements are empty" in { + val dut = TransformerControlGroup( + List.empty[String], + List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), + 1.02, + 0.98 + ) + + intercept[InvalidConfigParameterException] { + ConfigFailFast invokePrivate checkTransformerControl(dut) + }.getMessage shouldBe "A transformer control group cannot have no measurements assigned." + } + + "throw an exception, if the transformers are empty" in { + val dut = TransformerControlGroup( + List("6888c53a-7629-4563-ac8e-840f80b03106"), + List.empty[String], + 1.02, + 0.98 + ) + + intercept[InvalidConfigParameterException] { + ConfigFailFast invokePrivate checkTransformerControl(dut) + }.getMessage shouldBe "A transformer control group cannot have no transformers assigned." + } + + "throw an exception, if vMax is smaller than vMin" in { + val dut = TransformerControlGroup( + List("6888c53a-7629-4563-ac8e-840f80b03106"), + List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), + 0.98, + 1.02 + ) + + intercept[InvalidConfigParameterException] { + ConfigFailFast invokePrivate checkTransformerControl(dut) + }.getMessage shouldBe "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." + } + + "throw an exception, if vMin is negative" in { + val dut = TransformerControlGroup( + List("6888c53a-7629-4563-ac8e-840f80b03106"), + List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), + 1.02, + -0.98 + ) + + intercept[InvalidConfigParameterException] { + ConfigFailFast invokePrivate checkTransformerControl(dut) + }.getMessage shouldBe "The minimum permissible voltage magnitude of a transformer control group has to be positive." + } + + "throw an exception, if vMax is negative" in { + val dut = TransformerControlGroup( + List("6888c53a-7629-4563-ac8e-840f80b03106"), + List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), + -1.02, + 0.98 + ) + + intercept[InvalidConfigParameterException] { + ConfigFailFast invokePrivate checkTransformerControl(dut) + }.getMessage shouldBe "The maximum permissible voltage magnitude of a transformer control group has to be positive." + } } } diff --git a/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala b/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala index a757cc2e1c..be5d9b95c4 100644 --- a/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala @@ -6,11 +6,8 @@ package edu.ie3.simona.config -import edu.ie3.datamodel.models.voltagelevels.{ - CommonVoltageLevel, - GermanVoltageLevelUtils -} -import edu.ie3.simona.config.SimonaConfig.RefSystemConfig +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.simona.config.SimonaConfig.{RefSystemConfig, VoltLvlConfig} import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.test.common.UnitSpec @@ -25,13 +22,20 @@ class RefSystemParserSpec extends UnitSpec { gridIds = Some(List("1", "2-10", "15...20")), sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ), new RefSystemConfig( gridIds = Some(List("100")), sNom = "5000 MVA", vNom = "110 kV", - voltLvls = Some(List("{HS, 110 kV}", "{HoeS, 380 kV}")) + voltLvls = Some( + List( + VoltLvlConfig("HS", "110 kV"), + VoltLvlConfig("HoeS", "380 kV") + ) + ) ), new RefSystemConfig( gridIds = None, @@ -90,7 +94,9 @@ class RefSystemParserSpec extends UnitSpec { gridIds = Some(List("1", "2", "2-10", "15...20")), sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ) ) intercept[InvalidConfigParameterException] { @@ -107,13 +113,17 @@ class RefSystemParserSpec extends UnitSpec { gridIds = None, sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ), new RefSystemConfig( gridIds = None, sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ) ) intercept[InvalidConfigParameterException] { @@ -130,18 +140,22 @@ class RefSystemParserSpec extends UnitSpec { gridIds = Some(List("asd")), sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ), new RefSystemConfig( gridIds = None, sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ) ) intercept[InvalidConfigParameterException] { RefSystemParser.parse(validRefSystems) - }.getMessage shouldBe "Unknown gridId format asd provided for refSystem RefSystemConfig(Some(List(asd)),100 MVA,10 kV,Some(List({MS, 10 kV}, {MS, 20 kV})))" + }.getMessage shouldBe "Unknown gridId format asd provided for refSystem RefSystemConfig(Some(List(asd)),100 MVA,10 kV,Some(List(VoltLvlConfig(MS,10 kV), VoltLvlConfig(MS,20 kV))))" } @@ -155,13 +169,17 @@ class RefSystemParserSpec extends UnitSpec { gridIds = Some(List("1", "2-10", "15...20")), sNom = "100 MVA", vNom = "10 kV", - voltLvls = Some(List("{MS, 10 kV}", "{MS, 20 kV}")) + voltLvls = Some( + List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) + ) ), new RefSystemConfig( gridIds = Some(List("100")), sNom = "5000 MVA", vNom = "110 kV", - voltLvls = Some(List("{HS, 110 kV}", "{HoeS, 380 kV}")) + voltLvls = Some( + List(VoltLvlConfig("HS", "110 kV"), VoltLvlConfig("HoeS", "380 kV")) + ) ) ) diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala new file mode 100644 index 0000000000..8def596ce6 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala @@ -0,0 +1,132 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.control + +import breeze.linalg.DenseMatrix +import breeze.math.Complex +import edu.ie3.powerflow.model.NodeData.StateData +import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult +import edu.ie3.powerflow.model.enums.NodeType +import edu.ie3.simona.model.grid.GridModel +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.matchers.QuantityMatchers +import edu.ie3.util.quantities.PowerSystemUnits +import tech.units.indriya.quantity.Quantities + +import java.util.UUID + +class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { + "Checking the function of transformer control groups" should { + val buildTransformerControlModels = PrivateMethod[TransformerControlGroup]( + Symbol("buildTransformerControlModels") + ) + + val dut = GridModel invokePrivate buildTransformerControlModels( + Set( + UUID.fromString( + "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + ), + UUID.fromString( + "08b8d2ca-993d-45cd-9456-f009ecb47bc0" + ), + UUID.fromString( + "324f49e5-1c35-4c49-afb1-3cf41696bf93" + ) + ), + 1.1, + 0.9 + ) + + val uuidToIndex = Map( + UUID.fromString( + "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + ) -> 0, + UUID.fromString( + "08b8d2ca-993d-45cd-9456-f009ecb47bc0" + ) -> 1, + UUID.fromString( + "324f49e5-1c35-4c49-afb1-3cf41696bf93" + ) -> 2 + ) + + "return no regulation need, if everything is fine" in { + val result = ValidNewtonRaphsonPFResult( + 0, + Array( + StateData(0, NodeType.SL, Complex.one, Complex.zero), + StateData(1, NodeType.PQ, Complex.one, Complex.zero), + StateData(2, NodeType.PQ, Complex.one, Complex.zero) + ), + DenseMatrix.zeros(1, 1) + ) + + val actual = dut.determineRegulationNeed(result, uuidToIndex) + + actual shouldBe None + } + + "return no regulation need, if requests are contradictory" in { + val result = ValidNewtonRaphsonPFResult( + 0, + Array( + StateData(0, NodeType.SL, Complex.one, Complex.zero), + StateData(1, NodeType.PQ, Complex.one * 0.88, Complex.zero), + StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero) + ), + DenseMatrix.zeros(1, 1) + ) + + val actual = dut.determineRegulationNeed(result, uuidToIndex) + + actual shouldBe None + } + + "return the biggest positive regulation need" in { + val result = ValidNewtonRaphsonPFResult( + 0, + Array( + StateData(0, NodeType.SL, Complex.one, Complex.zero), + StateData(1, NodeType.PQ, Complex.one * 0.85, Complex.zero), + StateData(2, NodeType.PQ, Complex.one * 0.88, Complex.zero) + ), + DenseMatrix.zeros(1, 1) + ) + + val actual = dut.determineRegulationNeed(result, uuidToIndex) + + actual match { + case Some(regulationNeed) => + regulationNeed should equalWithTolerance( + Quantities.getQuantity(0.05, PowerSystemUnits.PU) + ) + case None => fail("Did expect to receive a regulation need.") + } + } + + "return the biggest negative regulation need" in { + val result = ValidNewtonRaphsonPFResult( + 0, + Array( + StateData(0, NodeType.SL, Complex.one, Complex.zero), + StateData(1, NodeType.PQ, Complex.one * 1.15, Complex.zero), + StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero) + ), + DenseMatrix.zeros(1, 1) + ) + + val actual = dut.determineRegulationNeed(result, uuidToIndex) + + actual match { + case Some(regulationNeed) => + regulationNeed should equalWithTolerance( + Quantities.getQuantity(-0.05, PowerSystemUnits.PU) + ) + case None => fail("Did expect to receive a regulation need.") + } + } + } +} From 9fd51abf215de68284193e825e00a9087f18e9fb Mon Sep 17 00:00:00 2001 From: "Kittl, Chris" Date: Wed, 12 Jan 2022 10:53:17 +0100 Subject: [PATCH 003/305] Build measurement and control models --- CHANGELOG.md | 1 + .../edu/ie3/simona/agent/grid/GridAgent.scala | 3 +- .../edu/ie3/simona/model/grid/GridModel.scala | 189 +++++++++++++++++- .../java/testutils/TestObjectFactory.java | 4 +- .../edu/ie3/simona/model/grid/GridSpec.scala | 116 +++++++++-- .../model/grid/TransformerModelSpec.scala | 3 +- 6 files changed, 289 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06328de446..b997d3fdf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Config possibility for transformer control groups +- Models for measurements within the grid structure ### Changed - Improving code readability in EvcsAgent by moving FreeLotsRequest to separate methods diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 0ed6a265f0..6d3e125a72 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -165,7 +165,8 @@ class GridAgent( .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime - ) + ), + simonaConfig.simona.control ) // we have to wait until the assets are ready diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 865f123c55..f6364a03e2 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -8,26 +8,34 @@ package edu.ie3.simona.model.grid import java.time.ZonedDateTime import java.util.UUID - import breeze.linalg.DenseMatrix import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.NodeInput +import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, PowerFlowCaseC } +import edu.ie3.simona.model.control.{ + TransformerControlGroup => ControlGroupModel +} import edu.ie3.simona.util.CollectionUtils +import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} +import tech.units.indriya.ComparableQuantity +import tech.units.indriya.quantity.Quantities +import javax.measure.quantity.Dimensionless import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ @@ -38,7 +46,8 @@ import scala.jdk.CollectionConverters._ final case class GridModel( subnetNo: Int, mainRefSystem: RefSystem, - gridComponents: GridComponents + gridComponents: GridComponents, + gridControls: GridControls ) { // init nodeUuidToIndexMap @@ -66,10 +75,15 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime - ): GridModel = { - buildAndValidate(subGridContainer, refSystem, startDate, endDate) - } + endDate: ZonedDateTime, + controlConfig: Option[SimonaConfig.Simona.Control] + ): GridModel = buildAndValidate( + subGridContainer, + refSystem, + startDate, + endDate, + controlConfig + ) /** structure that represents all grid components that are needed by a grid * model @@ -82,6 +96,15 @@ case object GridModel { switches: Set[SwitchModel] ) + /** Collection of grid-related control strategies + * + * @param transformerControlGroups + * Transformer control groups + */ + final case class GridControls( + transformerControlGroups: Set[ControlGroupModel] + ) + /** Checks the availability of node calculation models, that are connected by * the given [[ConnectorInput]]. If not both models can be found, * [[InvalidGridException]] s are thrown @@ -491,7 +514,8 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, + maybeControlConfig: Option[SimonaConfig.Simona.Control] ): GridModel = { // build @@ -581,8 +605,26 @@ case object GridModel { switches ) + /* Build transformer control groups */ + val transformerControlGroups = maybeControlConfig + .map { controlConfig => + buildTransformerControlGroups( + controlConfig.transformer, + subGridContainer.getRawGrid.getMeasurementUnits + ) + } + .getOrElse(Set.empty[ControlGroupModel]) + + /* Build grid related control strategies */ + val gridControls = GridControls(transformerControlGroups) + val gridModel = - GridModel(subGridContainer.getSubnet, refSystem, gridComponents) + GridModel( + subGridContainer.getSubnet, + refSystem, + gridComponents, + gridControls + ) // validate validateConsistency(gridModel) @@ -592,6 +634,133 @@ case object GridModel { gridModel } + /** Build business models for transformer control groups + * + * @param config + * List of configs for control groups + * @param measurementUnitInput + * Set of [[MeasurementUnitInput]] s + * @return + * A set of control group business models + */ + private def buildTransformerControlGroups( + config: List[SimonaConfig.TransformerControlGroup], + measurementUnitInput: java.util.Set[MeasurementUnitInput] + ): Set[ControlGroupModel] = config.map { + case TransformerControlGroup(measurements, _, vMax, vMin) => + buildTransformerControlGroupModel( + measurementUnitInput, + measurements, + vMax, + vMin + ) + }.toSet + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[ControlGroupModel]] + */ + private def buildTransformerControlGroupModel( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: List[String], + vMax: Double, + vMin: Double + ): ControlGroupModel = { + val nodeUuids = + determineNodeUuids(measurementUnitInput, measurementConfigs) + buildTransformerControlModels(nodeUuids, vMax, vMin) + } + + /** Determine the uuids of the nodes to control + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @return + * A set of relevant nodal uuids + */ + private def determineNodeUuids( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: List[String] + ): Set[UUID] = Set.from( + measurementUnitInput.asScala + .filter(input => + measurementConfigs.contains(input.getUuid.toString) && input.getVMag + ) + .map(_.getNode.getUuid) + ) + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param nodeUuids + * Collection of all relevant node uuids + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[ControlGroupModel]] + */ + private def buildTransformerControlModels( + nodeUuids: Set[UUID], + vMax: Double, + vMin: Double + ): ControlGroupModel = { + /* Determine the voltage regulation criterion for each of the available nodes */ + val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => + uuid -> { (complexVoltage: Complex) => + { + val vMag = complexVoltage.abs + if (vMag > vMax) + Some(vMax - vMag) + else if (vMag < vMin) + Some(vMin - vMag) + else + None + }.map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + } + }.toMap + + val harmonizationFunction = + (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { + val negativeRequests = regulationRequests.filter( + _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + val positiveRequests = regulationRequests.filter( + _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + + if (negativeRequests.nonEmpty && positiveRequests.nonEmpty) { + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + } else if (negativeRequests.nonEmpty) { + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + } else { + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + } + } + + ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) + } + /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to * account for changes on switches (open / close) It is highly recommended (= * mandatory) to call this method every time a node admittance matrix is diff --git a/src/test/java/testutils/TestObjectFactory.java b/src/test/java/testutils/TestObjectFactory.java index 5c33b6dd9e..2a1b3579bc 100644 --- a/src/test/java/testutils/TestObjectFactory.java +++ b/src/test/java/testutils/TestObjectFactory.java @@ -38,7 +38,7 @@ public static NodeInput buildNodeInput( boolean isSlack, CommonVoltageLevel voltageLvl, int subnet) { return new NodeInput( UUID.randomUUID(), - "TEST_NODE_" + TEST_OBJECT_COUNTER, + "TEST_NODE_" + TEST_OBJECT_COUNTER++, OperatorInput.NO_OPERATOR_ASSIGNED, OperationTime.notLimited(), Quantities.getQuantity(1d, PU), @@ -104,7 +104,7 @@ public static LineTypeInput buildLineTypeInput(VoltageLevel voltageLvl) { public static SwitchInput buildSwitchInput(NodeInput nodeA, NodeInput nodeB) { return new SwitchInput( UUID.randomUUID(), - "TEST_SWITCH" + TEST_OBJECT_COUNTER, + "TEST_SWITCH" + TEST_OBJECT_COUNTER++, OperatorInput.NO_OPERATOR_ASSIGNED, OperationTime.notLimited(), nodeA, diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 5ede9135a8..ca6aa14129 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -7,13 +7,15 @@ package edu.ie3.simona.model.grid import java.util.UUID - import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException +import edu.ie3.datamodel.models.input.MeasurementUnitInput +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.control.TransformerControlGroup +import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, @@ -21,6 +23,9 @@ import edu.ie3.simona.test.common.model.grid.{ FiveLinesWithNodes } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} +import testutils.TestObjectFactory + +import scala.jdk.CollectionConverters.SetHasAsJava class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { @@ -117,7 +122,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation val validateConnectivity: PrivateMethod[Unit] = @@ -145,7 +151,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], Set.empty[SwitchModel] - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation @@ -190,7 +197,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation @@ -229,7 +237,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -272,7 +281,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -357,7 +367,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -425,7 +436,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], Set.empty[SwitchModel] - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -446,9 +458,88 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { gridModel.nodeUuidToIndexMap.keySet.toVector.sorted should be( nodes.map(node => node.uuid).toVector.sorted ) - } + } + + "build correct transformer control models" should { + /* Testing of distinct transformer control group building can be found in the spec for transformer control groups */ + + "determine node uuids correctly" in { + val determineNodeUuids = + PrivateMethod[Set[UUID]](Symbol("determineNodeUuids")) + val node0 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1 + ) + val node1 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1 + ) + val node2 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1 + ) + val node3 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1 + ) + + val measurementUnits = Set( + new MeasurementUnitInput( + UUID.fromString("3ad9e076-c02b-4cf9-8720-18e2bb541ede"), + "measurement_unit_0", + node0, + true, + false, + false, + false + ), + new MeasurementUnitInput( + UUID.fromString("ab66fbb0-ece1-44b9-9341-86a884233ec4"), + "measurement_unit_1", + node1, + true, + false, + false, + false + ), + new MeasurementUnitInput( + UUID.fromString("93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d"), + "measurement_unit_2", + node2, + true, + false, + false, + false + ), + new MeasurementUnitInput( + UUID.fromString("8e84eb8a-2940-4900-b0ce-0eeb6bca8bae"), + "measurement_unit_3", + node3, + false, + false, + false, + false + ) + ).asJava + val selectedMeasurements = List( + "ab66fbb0-ece1-44b9-9341-86a884233ec4", + "93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d", + "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae" + ) + val expectedUuids = Set(node1, node2).map(_.getUuid) + + val actual = GridModel invokePrivate determineNodeUuids( + measurementUnits, + selectedMeasurements + ) + actual should contain theSameElementsAs expectedUuids + } } "process a valid GridInputModel without an Exception" in new GridInputTestData { @@ -456,10 +547,9 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { validTestGridInputModel, gridInputModelTestDataRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, + controlConfig = None ) - } } - } diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index 2911e6c244..a4795f3834 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -403,7 +403,8 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { grid, refSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, + controlConfig = None ) gridModel.gridComponents.transformers From c739e3b7c76c48741da4f4af399c2c8094eb1b2d Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 20 May 2022 11:49:43 +0200 Subject: [PATCH 004/305] CherryPick from #92 --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 3 +- .../edu/ie3/simona/model/grid/GridModel.scala | 189 +++++++++++++++++- .../simona/scheduler/SchedulerHelper.scala | 45 ++--- .../edu/ie3/simona/model/grid/GridSpec.scala | 33 ++- .../model/grid/TransformerModelSpec.scala | 3 +- 5 files changed, 224 insertions(+), 49 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 38026c8e53..948bf6a81b 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -137,7 +137,8 @@ class GridAgent( .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime - ) + ), + simonaConfig.simona.control ) /* Reassure, that there are also calculation models for the given uuids */ diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 865f123c55..f6364a03e2 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -8,26 +8,34 @@ package edu.ie3.simona.model.grid import java.time.ZonedDateTime import java.util.UUID - import breeze.linalg.DenseMatrix import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.NodeInput +import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, PowerFlowCaseC } +import edu.ie3.simona.model.control.{ + TransformerControlGroup => ControlGroupModel +} import edu.ie3.simona.util.CollectionUtils +import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} +import tech.units.indriya.ComparableQuantity +import tech.units.indriya.quantity.Quantities +import javax.measure.quantity.Dimensionless import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ @@ -38,7 +46,8 @@ import scala.jdk.CollectionConverters._ final case class GridModel( subnetNo: Int, mainRefSystem: RefSystem, - gridComponents: GridComponents + gridComponents: GridComponents, + gridControls: GridControls ) { // init nodeUuidToIndexMap @@ -66,10 +75,15 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime - ): GridModel = { - buildAndValidate(subGridContainer, refSystem, startDate, endDate) - } + endDate: ZonedDateTime, + controlConfig: Option[SimonaConfig.Simona.Control] + ): GridModel = buildAndValidate( + subGridContainer, + refSystem, + startDate, + endDate, + controlConfig + ) /** structure that represents all grid components that are needed by a grid * model @@ -82,6 +96,15 @@ case object GridModel { switches: Set[SwitchModel] ) + /** Collection of grid-related control strategies + * + * @param transformerControlGroups + * Transformer control groups + */ + final case class GridControls( + transformerControlGroups: Set[ControlGroupModel] + ) + /** Checks the availability of node calculation models, that are connected by * the given [[ConnectorInput]]. If not both models can be found, * [[InvalidGridException]] s are thrown @@ -491,7 +514,8 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, + maybeControlConfig: Option[SimonaConfig.Simona.Control] ): GridModel = { // build @@ -581,8 +605,26 @@ case object GridModel { switches ) + /* Build transformer control groups */ + val transformerControlGroups = maybeControlConfig + .map { controlConfig => + buildTransformerControlGroups( + controlConfig.transformer, + subGridContainer.getRawGrid.getMeasurementUnits + ) + } + .getOrElse(Set.empty[ControlGroupModel]) + + /* Build grid related control strategies */ + val gridControls = GridControls(transformerControlGroups) + val gridModel = - GridModel(subGridContainer.getSubnet, refSystem, gridComponents) + GridModel( + subGridContainer.getSubnet, + refSystem, + gridComponents, + gridControls + ) // validate validateConsistency(gridModel) @@ -592,6 +634,133 @@ case object GridModel { gridModel } + /** Build business models for transformer control groups + * + * @param config + * List of configs for control groups + * @param measurementUnitInput + * Set of [[MeasurementUnitInput]] s + * @return + * A set of control group business models + */ + private def buildTransformerControlGroups( + config: List[SimonaConfig.TransformerControlGroup], + measurementUnitInput: java.util.Set[MeasurementUnitInput] + ): Set[ControlGroupModel] = config.map { + case TransformerControlGroup(measurements, _, vMax, vMin) => + buildTransformerControlGroupModel( + measurementUnitInput, + measurements, + vMax, + vMin + ) + }.toSet + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[ControlGroupModel]] + */ + private def buildTransformerControlGroupModel( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: List[String], + vMax: Double, + vMin: Double + ): ControlGroupModel = { + val nodeUuids = + determineNodeUuids(measurementUnitInput, measurementConfigs) + buildTransformerControlModels(nodeUuids, vMax, vMin) + } + + /** Determine the uuids of the nodes to control + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @return + * A set of relevant nodal uuids + */ + private def determineNodeUuids( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: List[String] + ): Set[UUID] = Set.from( + measurementUnitInput.asScala + .filter(input => + measurementConfigs.contains(input.getUuid.toString) && input.getVMag + ) + .map(_.getNode.getUuid) + ) + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param nodeUuids + * Collection of all relevant node uuids + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[ControlGroupModel]] + */ + private def buildTransformerControlModels( + nodeUuids: Set[UUID], + vMax: Double, + vMin: Double + ): ControlGroupModel = { + /* Determine the voltage regulation criterion for each of the available nodes */ + val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => + uuid -> { (complexVoltage: Complex) => + { + val vMag = complexVoltage.abs + if (vMag > vMax) + Some(vMax - vMag) + else if (vMag < vMin) + Some(vMin - vMag) + else + None + }.map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + } + }.toMap + + val harmonizationFunction = + (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { + val negativeRequests = regulationRequests.filter( + _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + val positiveRequests = regulationRequests.filter( + _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + + if (negativeRequests.nonEmpty && positiveRequests.nonEmpty) { + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + } else if (negativeRequests.nonEmpty) { + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + } else { + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + } + } + + ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) + } + /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to * account for changes on switches (open / close) It is highly recommended (= * mandatory) to call this method every time a node admittance matrix is diff --git a/src/main/scala/edu/ie3/simona/scheduler/SchedulerHelper.scala b/src/main/scala/edu/ie3/simona/scheduler/SchedulerHelper.scala index a684fd2def..86c3338622 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/SchedulerHelper.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/SchedulerHelper.scala @@ -20,9 +20,7 @@ import edu.ie3.simona.logging.SimonaActorLogging import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage._ import edu.ie3.simona.ontology.trigger.{ScheduledTrigger, Trigger} -import edu.ie3.simona.ontology.trigger.Trigger.InitializeTrigger import edu.ie3.simona.scheduler.SimSchedulerStateData.SchedulerStateData -import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.util.SimonaConstants import edu.ie3.util.TimeUtil @@ -57,17 +55,18 @@ trait SchedulerHelper extends SimonaActorLogging { private val schedulerReadyCheckWindow = simonaTimeConfig.schedulerReadyCheckWindow - /** Sends out all triggers of type [[InitializeTrigger]] inside the trigger - * queue in the provided state data. This method modifies the mutual trigger - * data inside of the provided [[SimSchedulerStateData]]. To indicate this - * behavior, the provided state data is returned again, because the return - * value is a modified, but not a copied version of the provided state data! + /** Sends out all triggers with tick [[SimonaConstants.INIT_SIM_TICK]] inside + * the trigger queue in the provided state data. This method modifies the + * mutual trigger data inside of the provided [[SimSchedulerStateData]]. To + * indicate this behavior, the provided state data is returned again, because + * the return value is a modified, but not a copied version of the provided + * state data! * * @param stateData * the state data that should be processed * @return - * a modified version of the provided state data with all - * [[InitializeTrigger]] send out and updated + * a modified version of the provided state data with all triggers with + * tick [[SimonaConstants.INIT_SIM_TICK]] sent out and updated * [[SimSchedulerStateData.SchedulerStateData.trigger.awaitingResponseMap]] * and * [[SimSchedulerStateData.SchedulerStateData.trigger.triggerIdToScheduledTriggerMap accordingly]] @@ -87,10 +86,7 @@ trait SchedulerHelper extends SimonaActorLogging { val initTriggers = triggerQueue.stream .toScala(Accumulator) .filter(schedTrigger => - schedTrigger.triggerWithIdMessage.trigger match { - case _: InitializeTrigger => true - case _ => false - } + schedTrigger.triggerWithIdMessage.trigger.tick == SimonaConstants.INIT_SIM_TICK ) .map(schedTrigger => { /* actual init process */ @@ -809,9 +805,10 @@ trait SchedulerHelper extends SimonaActorLogging { } /** Checks if initialization of the simulation is complete. It is complete, if - * two conditions are fulfilled:
  1. there is no [[InitializeTrigger]] - * inside the provided trigger queue left
  2. there is no sent out - * [[InitializeTrigger]], which is not completed, yet
+ * two conditions are fulfilled:
  1. there is no trigger with tick + * [[SimonaConstants.INIT_SIM_TICK]] inside the provided trigger queue + * left
  2. there is no sent out trigger with tick + * [[SimonaConstants.INIT_SIM_TICK]], which is not completed, yet
* * @param awaitingResponseMap * a map containing a tick to scheduled trigger mapping @@ -824,22 +821,16 @@ trait SchedulerHelper extends SimonaActorLogging { awaitingResponseMap: TreeMultimap[java.lang.Long, ScheduledTrigger], triggerQueue: java.util.PriorityQueue[ScheduledTrigger] ): Boolean = { - val initAwait = awaitingResponseMap + val initAwait = !awaitingResponseMap .get(SimonaConstants.INIT_SIM_TICK) - .asScala - .iterator - .exists(_.triggerWithIdMessage.trigger match { - case _: InitializeTrigger => true - case _ => false - }) + .isEmpty val initTriggerInQueue = triggerQueue .iterator() .asScala - .exists(_.triggerWithIdMessage.trigger match { - case _: InitializeTrigger => true - case _ => false - }) + .exists( + _.triggerWithIdMessage.trigger.tick == SimonaConstants.INIT_SIM_TICK + ) !initAwait && !initTriggerInQueue } diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 5ede9135a8..26e198f0d7 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -7,13 +7,15 @@ package edu.ie3.simona.model.grid import java.util.UUID - import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException +import edu.ie3.datamodel.models.input.MeasurementUnitInput +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.control.TransformerControlGroup +import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, @@ -21,6 +23,9 @@ import edu.ie3.simona.test.common.model.grid.{ FiveLinesWithNodes } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} +import testutils.TestObjectFactory + +import scala.jdk.CollectionConverters.SetHasAsJava class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { @@ -117,7 +122,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation val validateConnectivity: PrivateMethod[Unit] = @@ -145,7 +151,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], Set.empty[SwitchModel] - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation @@ -190,7 +197,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // get the private method for validation @@ -229,7 +237,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -272,7 +281,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -357,7 +367,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], switches - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -425,7 +436,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set(transformer2wModel), Set.empty[Transformer3wModel], Set.empty[SwitchModel] - ) + ), + GridControls(Set.empty[TransformerControlGroup]) ) // update the uuidToIndexMap @@ -456,7 +468,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { validTestGridInputModel, gridInputModelTestDataRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, + controlConfig = None ) } diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index 2911e6c244..a4795f3834 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -403,7 +403,8 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { grid, refSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, + controlConfig = None ) gridModel.gridComponents.transformers From 103c788189baa31759dc88e857b7965b628a2b2b Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 2 Jun 2022 11:00:36 +0200 Subject: [PATCH 005/305] Review feedback class description --- .../edu/ie3/simona/model/control/TransformerControlGroup.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala index 652b40b4e1..dad17e5f7e 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -16,7 +16,7 @@ import java.util.UUID import javax.measure.quantity.Dimensionless /** Business logic for a transformer control group. It's main purpose is to - * determine, if there is any regulation need and if yes, in what circumference + * determine, if there is any regulation need and if yes, to what extent * (here: voltage raise or reduction to achieve) * * @param nodalRegulationCriterion From b9de2434fc65dc7495f32924ad56f889edf3ee08 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 3 Jun 2022 11:11:32 +0200 Subject: [PATCH 006/305] check Boundaries of Control Group --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 67 ++++++++++++++----- .../control/TransformerControlGroup.scala | 4 +- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 948bf6a81b..d300e5b6dc 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,35 +7,23 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{ - GridAgentBaseData, - GridAgentInitData, - GridAgentUninitializedData -} +import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{ - CompletionMessage, - ScheduleTriggerMessage, - TriggerWithIdMessage -} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ - ActivityStartTrigger, - InitializeGridAgentTrigger, - StartGridSimulationTrigger -} +import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import scala.concurrent.ExecutionContext import scala.concurrent.duration._ import scala.language.postfixOps @@ -223,8 +211,10 @@ class GridAgent( // everything else whenUnhandled(myUnhandled()) - private def failFast(gridAgentInitData: GridAgentInitData): Unit = { + + /** Check if there is InitData for superior or inferior GridGates + */ if ( gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty ) @@ -232,5 +222,48 @@ class GridAgent( s"$actorName has neither superior nor inferior grids! This can either " + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" ) + + /** Check of Control Boundaries + */ + if (simonaConfig.simona.control.isDefined) { + val transformerControlGroup = simonaConfig.simona.control match { + case Some(control) => control.transformer + } + checkBoundariesofControlGroup(transformerControlGroup, gridAgentInitData) + } + } + + private def checkBoundariesofControlGroup( + transformerControlGroup: List[TransformerControlGroup], + gridAgentInitData: GridAgentInitData + ): Unit = { + val vNom = gridAgentInitData.refSystem.nominalVoltage + val lowerBoundary = vNom.multiply(0.8).getValue.doubleValue() + val upperBoundary = vNom.multiply(1.2).getValue.doubleValue() + + for (controlGroup <- transformerControlGroup) + controlGroup match { + case TransformerControlGroup(measurements, transformers, vMax, vMin) => + if (lowerBoundary > vMin) + throw new GridAgentInitializationException( + s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where the lower Boundary is higher than vMin!" + ) + if (lowerBoundary > vMax) + throw new GridAgentInitializationException( + s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where the lower Boundary is higher than vMax!" + ) + if (upperBoundary < vMin) + throw new GridAgentInitializationException( + s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where the upper Boundary is lower than vMin!" + ) + if (upperBoundary < vMax) + throw new GridAgentInitializationException( + s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where the upper Boundary is lower than vMax!" + ) + } } } diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala index dad17e5f7e..bf9bc582b8 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -16,8 +16,8 @@ import java.util.UUID import javax.measure.quantity.Dimensionless /** Business logic for a transformer control group. It's main purpose is to - * determine, if there is any regulation need and if yes, to what extent - * (here: voltage raise or reduction to achieve) + * determine, if there is any regulation need and if yes, to what extent (here: + * voltage raise or reduction to achieve) * * @param nodalRegulationCriterion * Mapping from nodal index to a partial function, that determines the From b55ea2d9e5b71ee5d3b8814deca0ba40d5e2e6cc Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:54:23 +0200 Subject: [PATCH 007/305] methods moved into object --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 124 +++++++++--------- 1 file changed, 65 insertions(+), 59 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index d300e5b6dc..39dc1bb4be 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,7 +7,11 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} +import edu.ie3.simona.agent.grid.GridAgentData.{ + GridAgentBaseData, + GridAgentInitData, + GridAgentUninitializedData +} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} @@ -16,15 +20,22 @@ import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{ + CompletionMessage, + ScheduleTriggerMessage, + TriggerWithIdMessage +} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} +import edu.ie3.simona.ontology.trigger.Trigger.{ + ActivityStartTrigger, + InitializeGridAgentTrigger, + StartGridSimulationTrigger +} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import scala.concurrent.duration._ import scala.language.postfixOps object GridAgent { @@ -40,6 +51,55 @@ object GridAgent { listener ) ) + + private def failFast( + simonaConfig: SimonaConfig, + gridAgentInitData: GridAgentInitData + ): Unit = { + + /** Check if there is InitData for superior or inferior GridGates + */ + if ( + gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty + ) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" + ) + + /** Check of Control Boundaries + */ + simonaConfig.simona.control.foreach(control => + checkBoundariesOfControlGroup(control.transformer, gridAgentInitData) + ) + } + + private def checkBoundariesOfControlGroup( + transformerControlGroup: Seq[TransformerControlGroup], + gridAgentInitData: GridAgentInitData + ): Unit = { + val vNom = gridAgentInitData.refSystem.nominalVoltage + // TODO transfer lowerBoundary Voltage from RefSystem to per Unit + // val lowerBoundary = vNom.multiply(0.8).getValue.doubleValue() + val lowerBoundary = 0.8 + // TODO transfer lowerBoundary Voltage from RefSystem to per Unit + // val upperBoundary = vNom.multiply(1.2).getValue.doubleValue() + val upperBoundary = 1.2 + + transformerControlGroup.foreach { + case TransformerControlGroup(_, _, vMax, vMin) => + if (vMin < lowerBoundary) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" + ) + if (vMax > upperBoundary) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" + ) + } + } } class GridAgent( @@ -97,7 +157,7 @@ class GridAgent( _ ) => // fail fast sanity checks - failFast(gridAgentInitData) + GridAgent.failFast(simonaConfig, gridAgentInitData) log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", @@ -211,59 +271,5 @@ class GridAgent( // everything else whenUnhandled(myUnhandled()) - private def failFast(gridAgentInitData: GridAgentInitData): Unit = { - - /** Check if there is InitData for superior or inferior GridGates - */ - if ( - gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty - ) - throw new GridAgentInitializationException( - s"$actorName has neither superior nor inferior grids! This can either " + - s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" - ) - - /** Check of Control Boundaries - */ - if (simonaConfig.simona.control.isDefined) { - val transformerControlGroup = simonaConfig.simona.control match { - case Some(control) => control.transformer - } - checkBoundariesofControlGroup(transformerControlGroup, gridAgentInitData) - } - } - private def checkBoundariesofControlGroup( - transformerControlGroup: List[TransformerControlGroup], - gridAgentInitData: GridAgentInitData - ): Unit = { - val vNom = gridAgentInitData.refSystem.nominalVoltage - val lowerBoundary = vNom.multiply(0.8).getValue.doubleValue() - val upperBoundary = vNom.multiply(1.2).getValue.doubleValue() - - for (controlGroup <- transformerControlGroup) - controlGroup match { - case TransformerControlGroup(measurements, transformers, vMax, vMin) => - if (lowerBoundary > vMin) - throw new GridAgentInitializationException( - s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where the lower Boundary is higher than vMin!" - ) - if (lowerBoundary > vMax) - throw new GridAgentInitializationException( - s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where the lower Boundary is higher than vMax!" - ) - if (upperBoundary < vMin) - throw new GridAgentInitializationException( - s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where the upper Boundary is lower than vMin!" - ) - if (upperBoundary < vMax) - throw new GridAgentInitializationException( - s"$actorName has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where the upper Boundary is lower than vMax!" - ) - } - } } From 185ce9985cdfc8b1f29ecefea86c737d3dafcbe0 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:54:53 +0200 Subject: [PATCH 008/305] test for check of boundaries of control group --- .../agent/grid/GridAgentControlSpec.scala | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala new file mode 100644 index 0000000000..310a19f73b --- /dev/null +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala @@ -0,0 +1,87 @@ +/* + * © 2020. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.agent.grid + +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup +import edu.ie3.simona.exceptions.agent.GridAgentInitializationException +import edu.ie3.simona.model.grid.RefSystem +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.input.GridInputTestData + +class GridAgentControlSpec extends UnitSpec with GridInputTestData { + + "GridAgentControl" should { + val checkBoundariesOfControlGroup = PrivateMethod[Unit]( + Symbol("checkBoundariesOfControlGroup") + ) + + + val gridAgentInitData = GridAgentInitData( + validTestGridInputModel, + Map.empty, + RefSystem("400 kVA", "400 V") + ) + + "throw Exception when vMin is lower then -21% of nominal Voltage" in { + val transformerControlGroup = Seq( + TransformerControlGroup( + List.empty[String], + List.empty[String], + 1.1, + 0.79 + ) + ) + + intercept[GridAgentInitializationException] { + GridAgent invokePrivate checkBoundariesOfControlGroup( + transformerControlGroup, + gridAgentInitData + ) + }.getMessage shouldBe "TestGrid has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + "by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" + + } + + "throw Exception when vMax is higher then +21% of nominal Voltage" in { + val transformerControlGroup = Seq( + TransformerControlGroup( + List.empty[String], + List.empty[String], + 1.21, + 0.9 + ) + ) + + intercept[GridAgentInitializationException] { + GridAgent invokePrivate checkBoundariesOfControlGroup( + transformerControlGroup, + gridAgentInitData + ) + }.getMessage shouldBe "TestGrid has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + "by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" + + } + + "should run through when vMin and vMax are within the boundaries of +-20% of nominal Voltage" in { + val transformerControlGroup = Seq( + TransformerControlGroup( + List.empty[String], + List.empty[String], + 1.1, + 0.9 + ) + ) + + GridAgent invokePrivate checkBoundariesOfControlGroup( + transformerControlGroup, + gridAgentInitData + ) + } + + } +} From 0dd1acb9af8e80cb3ba94c3606248544520e0d13 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 10:52:16 +0200 Subject: [PATCH 009/305] removed boundary checks of control group back to ConfigFailFast --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 57 ++----------------- .../ie3/simona/config/ConfigFailFast.scala | 17 +++++- 2 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 39dc1bb4be..403ceb4dd6 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,30 +7,17 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{ - GridAgentBaseData, - GridAgentInitData, - GridAgentUninitializedData -} +import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{ - CompletionMessage, - ScheduleTriggerMessage, - TriggerWithIdMessage -} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ - ActivityStartTrigger, - InitializeGridAgentTrigger, - StartGridSimulationTrigger -} +import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime @@ -53,8 +40,7 @@ object GridAgent { ) private def failFast( - simonaConfig: SimonaConfig, - gridAgentInitData: GridAgentInitData + gridAgentInitData: GridAgentInitData ): Unit = { /** Check if there is InitData for superior or inferior GridGates @@ -66,39 +52,6 @@ object GridAgent { s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" ) - - /** Check of Control Boundaries - */ - simonaConfig.simona.control.foreach(control => - checkBoundariesOfControlGroup(control.transformer, gridAgentInitData) - ) - } - - private def checkBoundariesOfControlGroup( - transformerControlGroup: Seq[TransformerControlGroup], - gridAgentInitData: GridAgentInitData - ): Unit = { - val vNom = gridAgentInitData.refSystem.nominalVoltage - // TODO transfer lowerBoundary Voltage from RefSystem to per Unit - // val lowerBoundary = vNom.multiply(0.8).getValue.doubleValue() - val lowerBoundary = 0.8 - // TODO transfer lowerBoundary Voltage from RefSystem to per Unit - // val upperBoundary = vNom.multiply(1.2).getValue.doubleValue() - val upperBoundary = 1.2 - - transformerControlGroup.foreach { - case TransformerControlGroup(_, _, vMax, vMin) => - if (vMin < lowerBoundary) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" - ) - if (vMax > upperBoundary) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" - ) - } } } @@ -157,7 +110,7 @@ class GridAgent( _ ) => // fail fast sanity checks - GridAgent.failFast(simonaConfig, gridAgentInitData) + GridAgent.failFast(gridAgentInitData) log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index 3863ae92c2..5b6b24195c 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -569,7 +569,10 @@ case object ConfigFailFast extends LazyLogging { */ private def checkTransformerControl( transformerControlGroup: TransformerControlGroup - ): Unit = transformerControlGroup match { + ): Unit = { + val lowerBoundary = 0.8 + val upperBoundary = 1.2 + transformerControlGroup match { case TransformerControlGroup(measurements, transformers, vMax, vMin) => if (measurements.isEmpty) throw new InvalidConfigParameterException( @@ -591,8 +594,20 @@ case object ConfigFailFast extends LazyLogging { throw new InvalidConfigParameterException( "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." ) + if (vMin < lowerBoundary) + throw new InvalidConfigParameterException( + s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" + ) + if (vMax > upperBoundary) + throw new InvalidConfigParameterException( + s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" + ) + } } + /** Check the default config * * @param config From 39a42daa2cc8de5b155fbab924b38261422a94be Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 10:53:31 +0200 Subject: [PATCH 010/305] removed unnecessary checks --- .../ie3/simona/config/ConfigFailFast.scala | 57 ++++++++----------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index 5b6b24195c..e3eea5f1e3 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -573,41 +573,32 @@ case object ConfigFailFast extends LazyLogging { val lowerBoundary = 0.8 val upperBoundary = 1.2 transformerControlGroup match { - case TransformerControlGroup(measurements, transformers, vMax, vMin) => - if (measurements.isEmpty) - throw new InvalidConfigParameterException( - "A transformer control group cannot have no measurements assigned." - ) - if (transformers.isEmpty) - throw new InvalidConfigParameterException( - "A transformer control group cannot have no transformers assigned." - ) - if (vMin < 0) - throw new InvalidConfigParameterException( - "The minimum permissible voltage magnitude of a transformer control group has to be positive." - ) - if (vMax < 0) - throw new InvalidConfigParameterException( - "The maximum permissible voltage magnitude of a transformer control group has to be positive." - ) - if (vMax < vMin) - throw new InvalidConfigParameterException( - "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." - ) - if (vMin < lowerBoundary) - throw new InvalidConfigParameterException( - s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" - ) - if (vMax > upperBoundary) - throw new InvalidConfigParameterException( - s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" - ) - } + case TransformerControlGroup(measurements, transformers, vMax, vMin) => + if (measurements.isEmpty) + throw new InvalidConfigParameterException( + "A transformer control group cannot have no measurements assigned." + ) + if (transformers.isEmpty) + throw new InvalidConfigParameterException( + "A transformer control group cannot have no transformers assigned." + ) + if (vMax < vMin) + throw new InvalidConfigParameterException( + "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." + ) + if (vMin < lowerBoundary) + throw new InvalidConfigParameterException( + s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" + ) + if (vMax > upperBoundary) + throw new InvalidConfigParameterException( + s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" + ) + } } - /** Check the default config * * @param config From 8a1027d0debdb09a6bf40c0befc6a927cefaa7a0 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 10:53:43 +0200 Subject: [PATCH 011/305] spotless --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 20 +++++++++++++++---- .../agent/grid/GridAgentControlSpec.scala | 13 ++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 403ceb4dd6..387b96f373 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,7 +7,11 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} +import edu.ie3.simona.agent.grid.GridAgentData.{ + GridAgentBaseData, + GridAgentInitData, + GridAgentUninitializedData +} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} @@ -15,9 +19,17 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{ + CompletionMessage, + ScheduleTriggerMessage, + TriggerWithIdMessage +} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} +import edu.ie3.simona.ontology.trigger.Trigger.{ + ActivityStartTrigger, + InitializeGridAgentTrigger, + StartGridSimulationTrigger +} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime @@ -40,7 +52,7 @@ object GridAgent { ) private def failFast( - gridAgentInitData: GridAgentInitData + gridAgentInitData: GridAgentInitData ): Unit = { /** Check if there is InitData for superior or inferior GridGates diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala index 310a19f73b..54159667d1 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala @@ -20,7 +20,6 @@ class GridAgentControlSpec extends UnitSpec with GridInputTestData { Symbol("checkBoundariesOfControlGroup") ) - val gridAgentInitData = GridAgentInitData( validTestGridInputModel, Map.empty, @@ -69,13 +68,13 @@ class GridAgentControlSpec extends UnitSpec with GridInputTestData { "should run through when vMin and vMax are within the boundaries of +-20% of nominal Voltage" in { val transformerControlGroup = Seq( - TransformerControlGroup( - List.empty[String], - List.empty[String], - 1.1, - 0.9 + TransformerControlGroup( + List.empty[String], + List.empty[String], + 1.1, + 0.9 + ) ) - ) GridAgent invokePrivate checkBoundariesOfControlGroup( transformerControlGroup, From 3939ffcb3bb8a6324bda18c5e4ed1a6e0e5a270f Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 11:28:53 +0200 Subject: [PATCH 012/305] moved test from GridAgentControlSpec to ConfigFailFastSpec --- .../agent/grid/GridAgentControlSpec.scala | 86 ------------------- .../simona/config/ConfigFailFastSpec.scala | 14 +-- 2 files changed, 8 insertions(+), 92 deletions(-) delete mode 100644 src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala deleted file mode 100644 index 54159667d1..0000000000 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentControlSpec.scala +++ /dev/null @@ -1,86 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.agent.grid - -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup -import edu.ie3.simona.exceptions.agent.GridAgentInitializationException -import edu.ie3.simona.model.grid.RefSystem -import edu.ie3.simona.test.common.UnitSpec -import edu.ie3.simona.test.common.input.GridInputTestData - -class GridAgentControlSpec extends UnitSpec with GridInputTestData { - - "GridAgentControl" should { - val checkBoundariesOfControlGroup = PrivateMethod[Unit]( - Symbol("checkBoundariesOfControlGroup") - ) - - val gridAgentInitData = GridAgentInitData( - validTestGridInputModel, - Map.empty, - RefSystem("400 kVA", "400 V") - ) - - "throw Exception when vMin is lower then -21% of nominal Voltage" in { - val transformerControlGroup = Seq( - TransformerControlGroup( - List.empty[String], - List.empty[String], - 1.1, - 0.79 - ) - ) - - intercept[GridAgentInitializationException] { - GridAgent invokePrivate checkBoundariesOfControlGroup( - transformerControlGroup, - gridAgentInitData - ) - }.getMessage shouldBe "TestGrid has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - "by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" - - } - - "throw Exception when vMax is higher then +21% of nominal Voltage" in { - val transformerControlGroup = Seq( - TransformerControlGroup( - List.empty[String], - List.empty[String], - 1.21, - 0.9 - ) - ) - - intercept[GridAgentInitializationException] { - GridAgent invokePrivate checkBoundariesOfControlGroup( - transformerControlGroup, - gridAgentInitData - ) - }.getMessage shouldBe "TestGrid has a control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + - "by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" - - } - - "should run through when vMin and vMax are within the boundaries of +-20% of nominal Voltage" in { - val transformerControlGroup = Seq( - TransformerControlGroup( - List.empty[String], - List.empty[String], - 1.1, - 0.9 - ) - ) - - GridAgent invokePrivate checkBoundariesOfControlGroup( - transformerControlGroup, - gridAgentInitData - ) - } - - } -} diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 4323c80ba1..cf0143040e 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -916,30 +916,32 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { }.getMessage shouldBe "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." } - "throw an exception, if vMin is negative" in { + "throw Exception when vMin is lower then -21% of nominal Voltage" in { val dut = TransformerControlGroup( List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 1.02, - -0.98 + 0.79 ) intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "The minimum permissible voltage magnitude of a transformer control group has to be positive." + }.getMessage shouldBe "A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + "by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" } - "throw an exception, if vMax is negative" in { + "throw Exception when vMax is higher then +21% of nominal Voltage" in { val dut = TransformerControlGroup( List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), - -1.02, + 1.21, 0.98 ) intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "The maximum permissible voltage magnitude of a transformer control group has to be positive." + }.getMessage shouldBe "A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + "by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" } } } From c2c456eff79670c681b1d7decd027a54210dbb26 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 13:56:00 +0200 Subject: [PATCH 013/305] change order of attributes in config-template --- .../config/simona-config-template.conf | 4 +- .../edu/ie3/simona/config/SimonaConfig.scala | 2625 +++++------------ 2 files changed, 757 insertions(+), 1872 deletions(-) diff --git a/src/main/resources/config/simona-config-template.conf b/src/main/resources/config/simona-config-template.conf index 107816194e..0fd4082ea0 100644 --- a/src/main/resources/config/simona-config-template.conf +++ b/src/main/resources/config/simona-config-template.conf @@ -89,11 +89,11 @@ GridOutputConfig { #@define TransformerControlGroup { - transformers: [string] measurements: [string] + transformers: [string] # TODO: Currently, only limit prevention is configurable. Should be an interface, when it is allowed by tscfg - vMin: Double vMax: Double + vMin: Double } ################################################################## diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index dada716baf..b519da4699 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,2356 +1,1241 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ +// generated by tscfg 0.9.998 on Tue Jun 07 13:54:10 CEST 2022 +// source: src/main/resources/config/simona-config-template.conf package edu.ie3.simona.config final case class SimonaConfig( - simona: SimonaConfig.Simona + simona : SimonaConfig.Simona ) object SimonaConfig { final case class BaseCsvParams( - override val csvSep: java.lang.String, - override val directoryPath: java.lang.String, - override val isHierarchic: scala.Boolean - ) extends CsvParams(csvSep, directoryPath, isHierarchic) + override val csvSep : java.lang.String, + override val directoryPath : java.lang.String, + override val isHierarchic : scala.Boolean + ) extends CsvParams(csvSep,directoryPath,isHierarchic) object BaseCsvParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.BaseCsvParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseCsvParams = { SimonaConfig.BaseCsvParams( csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = - $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class BaseOutputConfig( - notifier: java.lang.String, - powerRequestReply: scala.Boolean, - simulationResult: scala.Boolean + notifier : java.lang.String, + powerRequestReply : scala.Boolean, + simulationResult : scala.Boolean ) object BaseOutputConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.BaseOutputConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseOutputConfig = { SimonaConfig.BaseOutputConfig( - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - powerRequestReply = - $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), - simulationResult = - $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + powerRequestReply = $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), + simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - sealed abstract class BaseRuntimeConfig( - val calculateMissingReactivePowerWithModel: scala.Boolean, - val scaling: scala.Double, - val uuids: scala.List[java.lang.String] + + sealed abstract class BaseRuntimeConfig ( + val calculateMissingReactivePowerWithModel : scala.Boolean, + val scaling : scala.Double, + val uuids : scala.List[java.lang.String] ) extends java.io.Serializable - - sealed abstract class CsvParams( - val csvSep: java.lang.String, - val directoryPath: java.lang.String, - val isHierarchic: scala.Boolean + + sealed abstract class CsvParams ( + val csvSep : java.lang.String, + val directoryPath : java.lang.String, + val isHierarchic : scala.Boolean ) - + final case class EvcsRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object EvcsRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.EvcsRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.EvcsRuntimeConfig = { SimonaConfig.EvcsRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class FixedFeedInRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object FixedFeedInRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.FixedFeedInRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.FixedFeedInRuntimeConfig = { SimonaConfig.FixedFeedInRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class GridOutputConfig( - lines: scala.Boolean, - nodes: scala.Boolean, - notifier: java.lang.String, - switches: scala.Boolean, - transformers2w: scala.Boolean, - transformers3w: scala.Boolean + lines : scala.Boolean, + nodes : scala.Boolean, + notifier : java.lang.String, + switches : scala.Boolean, + transformers2w : scala.Boolean, + transformers3w : scala.Boolean ) object GridOutputConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.GridOutputConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.GridOutputConfig = { SimonaConfig.GridOutputConfig( - lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), - nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), - transformers2w = - c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), - transformers3w = - c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") + lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), + nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), + transformers2w = c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), + transformers3w = c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class LoadRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String], - modelBehaviour: java.lang.String, - reference: java.lang.String - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String], + modelBehaviour : java.lang.String, + reference : java.lang.String + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object LoadRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.LoadRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.LoadRuntimeConfig = { SimonaConfig.LoadRuntimeConfig( - modelBehaviour = - $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), - reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + modelBehaviour = $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), + reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PrimaryDataCsvParams( - override val csvSep: java.lang.String, - override val directoryPath: java.lang.String, - override val isHierarchic: scala.Boolean, - timePattern: java.lang.String - ) extends CsvParams(csvSep, directoryPath, isHierarchic) + override val csvSep : java.lang.String, + override val directoryPath : java.lang.String, + override val isHierarchic : scala.Boolean, + timePattern : java.lang.String + ) extends CsvParams(csvSep,directoryPath,isHierarchic) object PrimaryDataCsvParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.PrimaryDataCsvParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PrimaryDataCsvParams = { SimonaConfig.PrimaryDataCsvParams( - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = - $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), + directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PvRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object PvRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.PvRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PvRuntimeConfig = { SimonaConfig.PvRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class RefSystemConfig( - gridIds: scala.Option[scala.List[java.lang.String]], - sNom: java.lang.String, - vNom: java.lang.String, - voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + gridIds : scala.Option[scala.List[java.lang.String]], + sNom : java.lang.String, + vNom : java.lang.String, + voltLvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object RefSystemConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.RefSystemConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RefSystemConfig = { SimonaConfig.RefSystemConfig( - gridIds = - if (c.hasPathOrNull("gridIds")) - scala.Some( - $_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator) - ) - else None, - sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), - vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), - voltLvls = - if (c.hasPathOrNull("voltLvls")) - scala.Some( - $_LSimonaConfig_VoltLvlConfig( - c.getList("voltLvls"), - parentPath, - $tsCfgValidator - ) - ) - else None + gridIds = if(c.hasPathOrNull("gridIds")) scala.Some($_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator)) else None, + sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), + vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), + voltLvls = if(c.hasPathOrNull("voltLvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("voltLvls"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_VoltLvlConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.VoltLvlConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class TransformerControlGroup( - measurements: scala.List[java.lang.String], - transformers: scala.List[java.lang.String], - vMax: scala.Double, - vMin: scala.Double + measurements : scala.List[java.lang.String], + transformers : scala.List[java.lang.String], + vMax : scala.Double, + vMin : scala.Double ) object TransformerControlGroup { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.TransformerControlGroup = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.TransformerControlGroup = { SimonaConfig.TransformerControlGroup( - measurements = - $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), - transformers = - $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), - vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), - vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + measurements = $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) ) } - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class VoltLvlConfig( - id: java.lang.String, - vNom: java.lang.String + id : java.lang.String, + vNom : java.lang.String ) object VoltLvlConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.VoltLvlConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.VoltLvlConfig = { SimonaConfig.VoltLvlConfig( - id = $_reqStr(parentPath, c, "id", $tsCfgValidator), + id = $_reqStr(parentPath, c, "id", $tsCfgValidator), vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class WecRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object WecRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.WecRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.WecRuntimeConfig = { SimonaConfig.WecRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Simona( - control: scala.Option[SimonaConfig.Simona.Control], - event: SimonaConfig.Simona.Event, - gridConfig: SimonaConfig.Simona.GridConfig, - input: SimonaConfig.Simona.Input, - output: SimonaConfig.Simona.Output, - powerflow: SimonaConfig.Simona.Powerflow, - runtime: SimonaConfig.Simona.Runtime, - simulationName: java.lang.String, - time: SimonaConfig.Simona.Time + control : scala.Option[SimonaConfig.Simona.Control], + event : SimonaConfig.Simona.Event, + gridConfig : SimonaConfig.Simona.GridConfig, + input : SimonaConfig.Simona.Input, + output : SimonaConfig.Simona.Output, + powerflow : SimonaConfig.Simona.Powerflow, + runtime : SimonaConfig.Simona.Runtime, + simulationName : java.lang.String, + time : SimonaConfig.Simona.Time ) object Simona { final case class Control( - transformer: scala.List[SimonaConfig.TransformerControlGroup] + transformer : scala.List[SimonaConfig.TransformerControlGroup] ) object Control { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Control = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Control = { SimonaConfig.Simona.Control( - transformer = $_LSimonaConfig_TransformerControlGroup( - c.getList("transformer"), - parentPath, - $tsCfgValidator - ) + transformer = $_LSimonaConfig_TransformerControlGroup(c.getList("transformer"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_TransformerControlGroup( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.TransformerControlGroup] = { + private def $_LSimonaConfig_TransformerControlGroup(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.TransformerControlGroup] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.TransformerControlGroup( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.TransformerControlGroup(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Event( - listener: scala.Option[ - scala.List[SimonaConfig.Simona.Event.Listener$Elm] - ] + listener : scala.Option[scala.List[SimonaConfig.Simona.Event.Listener$Elm]] ) object Event { final case class Listener$Elm( - eventsToProcess: scala.Option[scala.List[java.lang.String]], - fullClassPath: java.lang.String + eventsToProcess : scala.Option[scala.List[java.lang.String]], + fullClassPath : java.lang.String ) object Listener$Elm { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Event.Listener$Elm = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event.Listener$Elm = { SimonaConfig.Simona.Event.Listener$Elm( - eventsToProcess = - if (c.hasPathOrNull("eventsToProcess")) - scala.Some( - $_L$_str( - c.getList("eventsToProcess"), - parentPath, - $tsCfgValidator - ) - ) - else None, - fullClassPath = - $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) + eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, + fullClassPath = $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Event = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event = { SimonaConfig.Simona.Event( - listener = - if (c.hasPathOrNull("listener")) - scala.Some( - $_LSimonaConfig_Simona_Event_Listener$Elm( - c.getList("listener"), - parentPath, - $tsCfgValidator - ) - ) - else None + listener = if(c.hasPathOrNull("listener")) scala.Some($_LSimonaConfig_Simona_Event_Listener$Elm(c.getList("listener"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_Simona_Event_Listener$Elm( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { + private def $_LSimonaConfig_Simona_Event_Listener$Elm(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.Simona.Event.Listener$Elm( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.Simona.Event.Listener$Elm(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class GridConfig( - refSystems: scala.List[SimonaConfig.RefSystemConfig] + refSystems : scala.List[SimonaConfig.RefSystemConfig] ) object GridConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.GridConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.GridConfig = { SimonaConfig.Simona.GridConfig( - refSystems = $_LSimonaConfig_RefSystemConfig( - c.getList("refSystems"), - parentPath, - $tsCfgValidator - ) + refSystems = $_LSimonaConfig_RefSystemConfig(c.getList("refSystems"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_RefSystemConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.RefSystemConfig] = { + private def $_LSimonaConfig_RefSystemConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.RefSystemConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.RefSystemConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.RefSystemConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Input( - grid: SimonaConfig.Simona.Input.Grid, - primary: SimonaConfig.Simona.Input.Primary, - weather: SimonaConfig.Simona.Input.Weather + grid : SimonaConfig.Simona.Input.Grid, + primary : SimonaConfig.Simona.Input.Primary, + weather : SimonaConfig.Simona.Input.Weather ) object Input { final case class Grid( - datasource: SimonaConfig.Simona.Input.Grid.Datasource + datasource : SimonaConfig.Simona.Input.Grid.Datasource ) object Grid { final case class Datasource( - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - id: java.lang.String + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + id : java.lang.String ) object Datasource { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Grid.Datasource = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid.Datasource = { SimonaConfig.Simona.Input.Grid.Datasource( - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - id = $_reqStr(parentPath, c, "id", $tsCfgValidator) + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + id = $_reqStr(parentPath, c, "id", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Grid = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid = { SimonaConfig.Simona.Input.Grid( - datasource = SimonaConfig.Simona.Input.Grid.Datasource( - if (c.hasPathOrNull("datasource")) c.getConfig("datasource") - else - com.typesafe.config.ConfigFactory.parseString("datasource{}"), - parentPath + "datasource.", - $tsCfgValidator - ) + datasource = SimonaConfig.Simona.Input.Grid.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) ) } } - + final case class Primary( - couchbaseParams: scala.Option[ - SimonaConfig.Simona.Input.Primary.CouchbaseParams - ], - csvParams: scala.Option[SimonaConfig.PrimaryDataCsvParams], - influxDb1xParams: scala.Option[ - SimonaConfig.Simona.Input.Primary.InfluxDb1xParams - ], - sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] + couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Primary.CouchbaseParams], + csvParams : scala.Option[SimonaConfig.PrimaryDataCsvParams], + influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Primary.InfluxDb1xParams], + sqlParams : scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] ) object Primary { final case class CouchbaseParams( - bucketName: java.lang.String, - coordinateColumnName: java.lang.String, - keyPrefix: java.lang.String, - password: java.lang.String, - timePattern: java.lang.String, - url: java.lang.String, - userName: java.lang.String + bucketName : java.lang.String, + coordinateColumnName : java.lang.String, + keyPrefix : java.lang.String, + password : java.lang.String, + timePattern : java.lang.String, + url : java.lang.String, + userName : java.lang.String ) object CouchbaseParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { SimonaConfig.Simona.Input.Primary.CouchbaseParams( - bucketName = - $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr( - parentPath, - c, - "coordinateColumnName", - $tsCfgValidator - ), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database: java.lang.String, - port: scala.Int, - timePattern: java.lang.String, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + timePattern : java.lang.String, + url : java.lang.String ) object InfluxDb1xParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + database = $_reqStr(parentPath, c, "database", $tsCfgValidator), + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SqlParams( - jdbcUrl: java.lang.String, - password: java.lang.String, - schemaName: java.lang.String, - timePattern: java.lang.String, - userName: java.lang.String + jdbcUrl : java.lang.String, + password : java.lang.String, + schemaName : java.lang.String, + timePattern : java.lang.String, + userName : java.lang.String ) object SqlParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.SqlParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.SqlParams = { SimonaConfig.Simona.Input.Primary.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = - if (c.hasPathOrNull("schemaName")) c.getString("schemaName") - else "public", - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary = { SimonaConfig.Simona.Input.Primary( - couchbaseParams = - if (c.hasPathOrNull("couchbaseParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.CouchbaseParams( - c.getConfig("couchbaseParams"), - parentPath + "couchbaseParams.", - $tsCfgValidator - ) - ) - else None, - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.PrimaryDataCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - influxDb1xParams = - if (c.hasPathOrNull("influxDb1xParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - c.getConfig("influxDb1xParams"), - parentPath + "influxDb1xParams.", - $tsCfgValidator - ) - ) - else None, - sqlParams = - if (c.hasPathOrNull("sqlParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.SqlParams( - c.getConfig("sqlParams"), - parentPath + "sqlParams.", - $tsCfgValidator - ) - ) - else None + couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Primary.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.PrimaryDataCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Primary.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, + sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Primary.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None ) } } - + final case class Weather( - datasource: SimonaConfig.Simona.Input.Weather.Datasource + datasource : SimonaConfig.Simona.Input.Weather.Datasource ) object Weather { final case class Datasource( - coordinateSource: SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, - couchbaseParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams - ], - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - influxDb1xParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams - ], - resolution: scala.Option[scala.Long], - sampleParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.SampleParams - ], - scheme: java.lang.String, - sqlParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.SqlParams - ], - timestampPattern: scala.Option[java.lang.String] + coordinateSource : SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, + couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams], + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams], + resolution : scala.Option[scala.Long], + sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SampleParams], + scheme : java.lang.String, + sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SqlParams], + timestampPattern : scala.Option[java.lang.String] ) object Datasource { final case class CoordinateSource( - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - gridModel: java.lang.String, - sampleParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams - ] + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + gridModel : java.lang.String, + sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams] ) object CoordinateSource { final case class SampleParams( - use: scala.Boolean + use : scala.Boolean ) object SampleParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SampleParams( - use = !c.hasPathOrNull("use") || c.getBoolean("use") - ) + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams( + use = !c.hasPathOrNull("use") || c.getBoolean("use") + ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - gridModel = - if (c.hasPathOrNull("gridModel")) c.getString("gridModel") - else "icon", - sampleParams = - if (c.hasPathOrNull("sampleParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SampleParams( - c.getConfig("sampleParams"), - parentPath + "sampleParams.", - $tsCfgValidator - ) - ) - else None + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + gridModel = if(c.hasPathOrNull("gridModel")) c.getString("gridModel") else "icon", + sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None ) } } - + final case class CouchbaseParams( - bucketName: java.lang.String, - coordinateColumnName: java.lang.String, - keyPrefix: java.lang.String, - password: java.lang.String, - url: java.lang.String, - userName: java.lang.String + bucketName : java.lang.String, + coordinateColumnName : java.lang.String, + keyPrefix : java.lang.String, + password : java.lang.String, + url : java.lang.String, + userName : java.lang.String ) object CouchbaseParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams( - bucketName = - $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr( - parentPath, - c, - "coordinateColumnName", - $tsCfgValidator - ), - keyPrefix = - $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database: java.lang.String, - port: scala.Int, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + url : java.lang.String ) object InfluxDb1xParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SampleParams( - use: scala.Boolean + use : scala.Boolean ) object SampleParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( use = !c.hasPathOrNull("use") || c.getBoolean("use") ) } } - + final case class SqlParams( - jdbcUrl: java.lang.String, - password: java.lang.String, - schemaName: java.lang.String, - tableName: java.lang.String, - userName: java.lang.String + jdbcUrl : java.lang.String, + password : java.lang.String, + schemaName : java.lang.String, + tableName : java.lang.String, + userName : java.lang.String ) object SqlParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = - if (c.hasPathOrNull("schemaName")) c.getString("schemaName") - else "public", - tableName = - $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", + tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource = { SimonaConfig.Simona.Input.Weather.Datasource( - coordinateSource = - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - if (c.hasPathOrNull("coordinateSource")) - c.getConfig("coordinateSource") - else - com.typesafe.config.ConfigFactory - .parseString("coordinateSource{}"), - parentPath + "coordinateSource.", - $tsCfgValidator - ), - couchbaseParams = - if (c.hasPathOrNull("couchbaseParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource - .CouchbaseParams( - c.getConfig("couchbaseParams"), - parentPath + "couchbaseParams.", - $tsCfgValidator - ) - ) - else None, - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - influxDb1xParams = - if (c.hasPathOrNull("influxDb1xParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource - .InfluxDb1xParams( - c.getConfig("influxDb1xParams"), - parentPath + "influxDb1xParams.", - $tsCfgValidator - ) - ) - else None, - resolution = - if (c.hasPathOrNull("resolution")) - Some(c.getLong("resolution").longValue()) - else None, - sampleParams = - if (c.hasPathOrNull("sampleParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( - c.getConfig("sampleParams"), - parentPath + "sampleParams.", - $tsCfgValidator - ) - ) - else None, - scheme = - if (c.hasPathOrNull("scheme")) c.getString("scheme") - else "icon", - sqlParams = - if (c.hasPathOrNull("sqlParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - c.getConfig("sqlParams"), - parentPath + "sqlParams.", - $tsCfgValidator - ) - ) - else None, - timestampPattern = - if (c.hasPathOrNull("timestampPattern")) - Some(c.getString("timestampPattern")) - else None + coordinateSource = SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource(if(c.hasPathOrNull("coordinateSource")) c.getConfig("coordinateSource") else com.typesafe.config.ConfigFactory.parseString("coordinateSource{}"), parentPath + "coordinateSource.", $tsCfgValidator), + couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, + resolution = if(c.hasPathOrNull("resolution")) Some(c.getLong("resolution").longValue()) else None, + sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, + scheme = if(c.hasPathOrNull("scheme")) c.getString("scheme") else "icon", + sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None, + timestampPattern = if(c.hasPathOrNull("timestampPattern")) Some(c.getString("timestampPattern")) else None ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather = { SimonaConfig.Simona.Input.Weather( - datasource = SimonaConfig.Simona.Input.Weather.Datasource( - if (c.hasPathOrNull("datasource")) c.getConfig("datasource") - else - com.typesafe.config.ConfigFactory.parseString("datasource{}"), - parentPath + "datasource.", - $tsCfgValidator - ) + datasource = SimonaConfig.Simona.Input.Weather.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input = { SimonaConfig.Simona.Input( - grid = SimonaConfig.Simona.Input.Grid( - if (c.hasPathOrNull("grid")) c.getConfig("grid") - else com.typesafe.config.ConfigFactory.parseString("grid{}"), - parentPath + "grid.", - $tsCfgValidator - ), - primary = SimonaConfig.Simona.Input.Primary( - if (c.hasPathOrNull("primary")) c.getConfig("primary") - else com.typesafe.config.ConfigFactory.parseString("primary{}"), - parentPath + "primary.", - $tsCfgValidator - ), - weather = SimonaConfig.Simona.Input.Weather( - if (c.hasPathOrNull("weather")) c.getConfig("weather") - else com.typesafe.config.ConfigFactory.parseString("weather{}"), - parentPath + "weather.", - $tsCfgValidator - ) + grid = SimonaConfig.Simona.Input.Grid(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), + primary = SimonaConfig.Simona.Input.Primary(if(c.hasPathOrNull("primary")) c.getConfig("primary") else com.typesafe.config.ConfigFactory.parseString("primary{}"), parentPath + "primary.", $tsCfgValidator), + weather = SimonaConfig.Simona.Input.Weather(if(c.hasPathOrNull("weather")) c.getConfig("weather") else com.typesafe.config.ConfigFactory.parseString("weather{}"), parentPath + "weather.", $tsCfgValidator) ) } } - + final case class Output( - base: SimonaConfig.Simona.Output.Base, - grid: SimonaConfig.GridOutputConfig, - participant: SimonaConfig.Simona.Output.Participant, - sink: SimonaConfig.Simona.Output.Sink + base : SimonaConfig.Simona.Output.Base, + grid : SimonaConfig.GridOutputConfig, + participant : SimonaConfig.Simona.Output.Participant, + sink : SimonaConfig.Simona.Output.Sink ) object Output { final case class Base( - addTimestampToOutputDir: scala.Boolean, - dir: java.lang.String + addTimestampToOutputDir : scala.Boolean, + dir : java.lang.String ) object Base { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Base = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Base = { SimonaConfig.Simona.Output.Base( - addTimestampToOutputDir = !c.hasPathOrNull( - "addTimestampToOutputDir" - ) || c.getBoolean("addTimestampToOutputDir"), - dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) + addTimestampToOutputDir = !c.hasPathOrNull("addTimestampToOutputDir") || c.getBoolean("addTimestampToOutputDir"), + dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class Participant( - defaultConfig: SimonaConfig.BaseOutputConfig, - individualConfigs: scala.List[SimonaConfig.BaseOutputConfig] + defaultConfig : SimonaConfig.BaseOutputConfig, + individualConfigs : scala.List[SimonaConfig.BaseOutputConfig] ) object Participant { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Participant = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Participant = { SimonaConfig.Simona.Output.Participant( - defaultConfig = SimonaConfig.BaseOutputConfig( - if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_BaseOutputConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.BaseOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_BaseOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_BaseOutputConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.BaseOutputConfig] = { + private def $_LSimonaConfig_BaseOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.BaseOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.BaseOutputConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.BaseOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Sink( - csv: scala.Option[SimonaConfig.Simona.Output.Sink.Csv], - influxDb1x: scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x] + csv : scala.Option[SimonaConfig.Simona.Output.Sink.Csv], + influxDb1x : scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x] ) object Sink { final case class Csv( - fileFormat: java.lang.String, - filePrefix: java.lang.String, - fileSuffix: java.lang.String, - isHierarchic: scala.Boolean + fileFormat : java.lang.String, + filePrefix : java.lang.String, + fileSuffix : java.lang.String, + isHierarchic : scala.Boolean ) object Csv { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink.Csv = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.Csv = { SimonaConfig.Simona.Output.Sink.Csv( - fileFormat = - if (c.hasPathOrNull("fileFormat")) c.getString("fileFormat") - else ".csv", - filePrefix = - if (c.hasPathOrNull("filePrefix")) c.getString("filePrefix") - else "", - fileSuffix = - if (c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") - else "", - isHierarchic = - c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") + fileFormat = if(c.hasPathOrNull("fileFormat")) c.getString("fileFormat") else ".csv", + filePrefix = if(c.hasPathOrNull("filePrefix")) c.getString("filePrefix") else "", + fileSuffix = if(c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") else "", + isHierarchic = c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") ) } } - + final case class InfluxDb1x( - database: java.lang.String, - port: scala.Int, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + url : java.lang.String ) object InfluxDb1x { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink = { SimonaConfig.Simona.Output.Sink( - csv = - if (c.hasPathOrNull("csv")) - scala.Some( - SimonaConfig.Simona.Output.Sink.Csv( - c.getConfig("csv"), - parentPath + "csv.", - $tsCfgValidator - ) - ) - else None, - influxDb1x = - if (c.hasPathOrNull("influxDb1x")) - scala.Some( - SimonaConfig.Simona.Output.Sink.InfluxDb1x( - c.getConfig("influxDb1x"), - parentPath + "influxDb1x.", - $tsCfgValidator - ) - ) - else None + csv = if(c.hasPathOrNull("csv")) scala.Some(SimonaConfig.Simona.Output.Sink.Csv(c.getConfig("csv"), parentPath + "csv.", $tsCfgValidator)) else None, + influxDb1x = if(c.hasPathOrNull("influxDb1x")) scala.Some(SimonaConfig.Simona.Output.Sink.InfluxDb1x(c.getConfig("influxDb1x"), parentPath + "influxDb1x.", $tsCfgValidator)) else None ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output = { SimonaConfig.Simona.Output( - base = SimonaConfig.Simona.Output.Base( - if (c.hasPathOrNull("base")) c.getConfig("base") - else com.typesafe.config.ConfigFactory.parseString("base{}"), - parentPath + "base.", - $tsCfgValidator - ), - grid = SimonaConfig.GridOutputConfig( - if (c.hasPathOrNull("grid")) c.getConfig("grid") - else com.typesafe.config.ConfigFactory.parseString("grid{}"), - parentPath + "grid.", - $tsCfgValidator - ), - participant = SimonaConfig.Simona.Output.Participant( - if (c.hasPathOrNull("participant")) c.getConfig("participant") - else com.typesafe.config.ConfigFactory.parseString("participant{}"), - parentPath + "participant.", - $tsCfgValidator - ), - sink = SimonaConfig.Simona.Output.Sink( - if (c.hasPathOrNull("sink")) c.getConfig("sink") - else com.typesafe.config.ConfigFactory.parseString("sink{}"), - parentPath + "sink.", - $tsCfgValidator - ) + base = SimonaConfig.Simona.Output.Base(if(c.hasPathOrNull("base")) c.getConfig("base") else com.typesafe.config.ConfigFactory.parseString("base{}"), parentPath + "base.", $tsCfgValidator), + grid = SimonaConfig.GridOutputConfig(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), + participant = SimonaConfig.Simona.Output.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), + sink = SimonaConfig.Simona.Output.Sink(if(c.hasPathOrNull("sink")) c.getConfig("sink") else com.typesafe.config.ConfigFactory.parseString("sink{}"), parentPath + "sink.", $tsCfgValidator) ) } } - + final case class Powerflow( - maxSweepPowerDeviation: scala.Double, - newtonraphson: SimonaConfig.Simona.Powerflow.Newtonraphson, - resolution: java.time.Duration, - sweepTimeout: java.time.Duration + maxSweepPowerDeviation : scala.Double, + newtonraphson : SimonaConfig.Simona.Powerflow.Newtonraphson, + resolution : java.time.Duration, + sweepTimeout : java.time.Duration ) object Powerflow { final case class Newtonraphson( - epsilon: scala.List[scala.Double], - iterations: scala.Int + epsilon : scala.List[scala.Double], + iterations : scala.Int ) object Newtonraphson { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Powerflow.Newtonraphson = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow.Newtonraphson = { SimonaConfig.Simona.Powerflow.Newtonraphson( - epsilon = - $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), + epsilon = $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Powerflow = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow = { SimonaConfig.Simona.Powerflow( - maxSweepPowerDeviation = - $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), - newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson( - if (c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") - else - com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), - parentPath + "newtonraphson.", - $tsCfgValidator - ), - resolution = - if (c.hasPathOrNull("resolution")) c.getDuration("resolution") - else java.time.Duration.parse("PT1H"), - sweepTimeout = - if (c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") - else java.time.Duration.parse("PT30S") + maxSweepPowerDeviation = $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), + newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson(if(c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") else com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), parentPath + "newtonraphson.", $tsCfgValidator), + resolution = if(c.hasPathOrNull("resolution")) c.getDuration("resolution") else java.time.Duration.parse("PT1H"), + sweepTimeout = if(c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") else java.time.Duration.parse("PT30S") ) } - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Runtime( - participant: SimonaConfig.Simona.Runtime.Participant, - selected_subgrids: scala.Option[scala.List[scala.Int]], - selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + participant : SimonaConfig.Simona.Runtime.Participant, + selected_subgrids : scala.Option[scala.List[scala.Int]], + selected_volt_lvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object Runtime { final case class Participant( - evcs: SimonaConfig.Simona.Runtime.Participant.Evcs, - fixedFeedIn: SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, - load: SimonaConfig.Simona.Runtime.Participant.Load, - pv: SimonaConfig.Simona.Runtime.Participant.Pv, - requestVoltageDeviationThreshold: scala.Double, - wec: SimonaConfig.Simona.Runtime.Participant.Wec + evcs : SimonaConfig.Simona.Runtime.Participant.Evcs, + fixedFeedIn : SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, + load : SimonaConfig.Simona.Runtime.Participant.Load, + pv : SimonaConfig.Simona.Runtime.Participant.Pv, + requestVoltageDeviationThreshold : scala.Double, + wec : SimonaConfig.Simona.Runtime.Participant.Wec ) object Participant { final case class Evcs( - defaultConfig: SimonaConfig.EvcsRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig] + defaultConfig : SimonaConfig.EvcsRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.EvcsRuntimeConfig] ) object Evcs { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Evcs = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Evcs = { SimonaConfig.Simona.Runtime.Participant.Evcs( - defaultConfig = SimonaConfig.EvcsRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.EvcsRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_EvcsRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.EvcsRuntimeConfig] = { + private def $_LSimonaConfig_EvcsRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.EvcsRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.EvcsRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.EvcsRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class FixedFeedIn( - defaultConfig: SimonaConfig.FixedFeedInRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig] + defaultConfig : SimonaConfig.FixedFeedInRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.FixedFeedInRuntimeConfig] ) object FixedFeedIn { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_FixedFeedInRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { + private def $_LSimonaConfig_FixedFeedInRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.FixedFeedInRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.FixedFeedInRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Load( - defaultConfig: SimonaConfig.LoadRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig] + defaultConfig : SimonaConfig.LoadRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.LoadRuntimeConfig] ) object Load { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Load = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Load = { SimonaConfig.Simona.Runtime.Participant.Load( - defaultConfig = SimonaConfig.LoadRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_LoadRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.LoadRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_LoadRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_LoadRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.LoadRuntimeConfig] = { + private def $_LSimonaConfig_LoadRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.LoadRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.LoadRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.LoadRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Pv( - defaultConfig: SimonaConfig.PvRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig] + defaultConfig : SimonaConfig.PvRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.PvRuntimeConfig] ) object Pv { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Pv = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Pv = { SimonaConfig.Simona.Runtime.Participant.Pv( - defaultConfig = SimonaConfig.PvRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_PvRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.PvRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_PvRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_PvRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.PvRuntimeConfig] = { + private def $_LSimonaConfig_PvRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.PvRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.PvRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.PvRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Wec( - defaultConfig: SimonaConfig.WecRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig] + defaultConfig : SimonaConfig.WecRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.WecRuntimeConfig] ) object Wec { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Wec = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Wec = { SimonaConfig.Simona.Runtime.Participant.Wec( - defaultConfig = SimonaConfig.WecRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_WecRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.WecRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_WecRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_WecRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.WecRuntimeConfig] = { + private def $_LSimonaConfig_WecRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.WecRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.WecRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.WecRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant = { SimonaConfig.Simona.Runtime.Participant( - evcs = SimonaConfig.Simona.Runtime.Participant.Evcs( - if (c.hasPathOrNull("evcs")) c.getConfig("evcs") - else com.typesafe.config.ConfigFactory.parseString("evcs{}"), - parentPath + "evcs.", - $tsCfgValidator - ), - fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - if (c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") - else - com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), - parentPath + "fixedFeedIn.", - $tsCfgValidator - ), - load = SimonaConfig.Simona.Runtime.Participant.Load( - if (c.hasPathOrNull("load")) c.getConfig("load") - else com.typesafe.config.ConfigFactory.parseString("load{}"), - parentPath + "load.", - $tsCfgValidator - ), - pv = SimonaConfig.Simona.Runtime.Participant.Pv( - if (c.hasPathOrNull("pv")) c.getConfig("pv") - else com.typesafe.config.ConfigFactory.parseString("pv{}"), - parentPath + "pv.", - $tsCfgValidator - ), - requestVoltageDeviationThreshold = - if (c.hasPathOrNull("requestVoltageDeviationThreshold")) - c.getDouble("requestVoltageDeviationThreshold") - else 1e-14, - wec = SimonaConfig.Simona.Runtime.Participant.Wec( - if (c.hasPathOrNull("wec")) c.getConfig("wec") - else com.typesafe.config.ConfigFactory.parseString("wec{}"), - parentPath + "wec.", - $tsCfgValidator - ) + evcs = SimonaConfig.Simona.Runtime.Participant.Evcs(if(c.hasPathOrNull("evcs")) c.getConfig("evcs") else com.typesafe.config.ConfigFactory.parseString("evcs{}"), parentPath + "evcs.", $tsCfgValidator), + fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn(if(c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") else com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), parentPath + "fixedFeedIn.", $tsCfgValidator), + load = SimonaConfig.Simona.Runtime.Participant.Load(if(c.hasPathOrNull("load")) c.getConfig("load") else com.typesafe.config.ConfigFactory.parseString("load{}"), parentPath + "load.", $tsCfgValidator), + pv = SimonaConfig.Simona.Runtime.Participant.Pv(if(c.hasPathOrNull("pv")) c.getConfig("pv") else com.typesafe.config.ConfigFactory.parseString("pv{}"), parentPath + "pv.", $tsCfgValidator), + requestVoltageDeviationThreshold = if(c.hasPathOrNull("requestVoltageDeviationThreshold")) c.getDouble("requestVoltageDeviationThreshold") else 1E-14, + wec = SimonaConfig.Simona.Runtime.Participant.Wec(if(c.hasPathOrNull("wec")) c.getConfig("wec") else com.typesafe.config.ConfigFactory.parseString("wec{}"), parentPath + "wec.", $tsCfgValidator) ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime = { SimonaConfig.Simona.Runtime( - participant = SimonaConfig.Simona.Runtime.Participant( - if (c.hasPathOrNull("participant")) c.getConfig("participant") - else com.typesafe.config.ConfigFactory.parseString("participant{}"), - parentPath + "participant.", - $tsCfgValidator - ), - selected_subgrids = - if (c.hasPathOrNull("selected_subgrids")) - scala.Some( - $_L$_int( - c.getList("selected_subgrids"), - parentPath, - $tsCfgValidator - ) - ) - else None, - selected_volt_lvls = - if (c.hasPathOrNull("selected_volt_lvls")) - scala.Some( - $_LSimonaConfig_VoltLvlConfig( - c.getList("selected_volt_lvls"), - parentPath, - $tsCfgValidator - ) - ) - else None + participant = SimonaConfig.Simona.Runtime.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), + selected_subgrids = if(c.hasPathOrNull("selected_subgrids")) scala.Some($_L$_int(c.getList("selected_subgrids"), parentPath, $tsCfgValidator)) else None, + selected_volt_lvls = if(c.hasPathOrNull("selected_volt_lvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("selected_volt_lvls"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_VoltLvlConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.VoltLvlConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Time( - endDateTime: java.lang.String, - schedulerReadyCheckWindow: scala.Option[scala.Int], - startDateTime: java.lang.String, - stopOnFailedPowerFlow: scala.Boolean + endDateTime : java.lang.String, + schedulerReadyCheckWindow : scala.Option[scala.Int], + startDateTime : java.lang.String, + stopOnFailedPowerFlow : scala.Boolean ) object Time { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Time = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Time = { SimonaConfig.Simona.Time( - endDateTime = - if (c.hasPathOrNull("endDateTime")) c.getString("endDateTime") - else "2011-05-01 01:00:00", - schedulerReadyCheckWindow = - if (c.hasPathOrNull("schedulerReadyCheckWindow")) - Some(c.getInt("schedulerReadyCheckWindow")) - else None, - startDateTime = - if (c.hasPathOrNull("startDateTime")) c.getString("startDateTime") - else "2011-05-01 00:00:00", - stopOnFailedPowerFlow = - c.hasPathOrNull("stopOnFailedPowerFlow") && c.getBoolean( - "stopOnFailedPowerFlow" - ) + endDateTime = if(c.hasPathOrNull("endDateTime")) c.getString("endDateTime") else "2011-05-01 01:00:00", + schedulerReadyCheckWindow = if(c.hasPathOrNull("schedulerReadyCheckWindow")) Some(c.getInt("schedulerReadyCheckWindow")) else None, + startDateTime = if(c.hasPathOrNull("startDateTime")) c.getString("startDateTime") else "2011-05-01 00:00:00", + stopOnFailedPowerFlow = c.hasPathOrNull("stopOnFailedPowerFlow") && c.getBoolean("stopOnFailedPowerFlow") ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona = { SimonaConfig.Simona( - control = - if (c.hasPathOrNull("control")) - scala.Some( - SimonaConfig.Simona.Control( - c.getConfig("control"), - parentPath + "control.", - $tsCfgValidator - ) - ) - else None, - event = SimonaConfig.Simona.Event( - if (c.hasPathOrNull("event")) c.getConfig("event") - else com.typesafe.config.ConfigFactory.parseString("event{}"), - parentPath + "event.", - $tsCfgValidator - ), - gridConfig = SimonaConfig.Simona.GridConfig( - if (c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") - else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), - parentPath + "gridConfig.", - $tsCfgValidator - ), - input = SimonaConfig.Simona.Input( - if (c.hasPathOrNull("input")) c.getConfig("input") - else com.typesafe.config.ConfigFactory.parseString("input{}"), - parentPath + "input.", - $tsCfgValidator - ), - output = SimonaConfig.Simona.Output( - if (c.hasPathOrNull("output")) c.getConfig("output") - else com.typesafe.config.ConfigFactory.parseString("output{}"), - parentPath + "output.", - $tsCfgValidator - ), - powerflow = SimonaConfig.Simona.Powerflow( - if (c.hasPathOrNull("powerflow")) c.getConfig("powerflow") - else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), - parentPath + "powerflow.", - $tsCfgValidator - ), - runtime = SimonaConfig.Simona.Runtime( - if (c.hasPathOrNull("runtime")) c.getConfig("runtime") - else com.typesafe.config.ConfigFactory.parseString("runtime{}"), - parentPath + "runtime.", - $tsCfgValidator - ), - simulationName = - $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), - time = SimonaConfig.Simona.Time( - if (c.hasPathOrNull("time")) c.getConfig("time") - else com.typesafe.config.ConfigFactory.parseString("time{}"), - parentPath + "time.", - $tsCfgValidator - ) + control = if(c.hasPathOrNull("control")) scala.Some(SimonaConfig.Simona.Control(c.getConfig("control"), parentPath + "control.", $tsCfgValidator)) else None, + event = SimonaConfig.Simona.Event(if(c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), parentPath + "event.", $tsCfgValidator), + gridConfig = SimonaConfig.Simona.GridConfig(if(c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), parentPath + "gridConfig.", $tsCfgValidator), + input = SimonaConfig.Simona.Input(if(c.hasPathOrNull("input")) c.getConfig("input") else com.typesafe.config.ConfigFactory.parseString("input{}"), parentPath + "input.", $tsCfgValidator), + output = SimonaConfig.Simona.Output(if(c.hasPathOrNull("output")) c.getConfig("output") else com.typesafe.config.ConfigFactory.parseString("output{}"), parentPath + "output.", $tsCfgValidator), + powerflow = SimonaConfig.Simona.Powerflow(if(c.hasPathOrNull("powerflow")) c.getConfig("powerflow") else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), parentPath + "powerflow.", $tsCfgValidator), + runtime = SimonaConfig.Simona.Runtime(if(c.hasPathOrNull("runtime")) c.getConfig("runtime") else com.typesafe.config.ConfigFactory.parseString("runtime{}"), parentPath + "runtime.", $tsCfgValidator), + simulationName = $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), + time = SimonaConfig.Simona.Time(if(c.hasPathOrNull("time")) c.getConfig("time") else com.typesafe.config.ConfigFactory.parseString("time{}"), parentPath + "time.", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + def apply(c: com.typesafe.config.Config): SimonaConfig = { val $tsCfgValidator: $TsCfgValidator = new $TsCfgValidator() val parentPath: java.lang.String = "" val $result = SimonaConfig( - simona = SimonaConfig.Simona( - if (c.hasPathOrNull("simona")) c.getConfig("simona") - else com.typesafe.config.ConfigFactory.parseString("simona{}"), - parentPath + "simona.", - $tsCfgValidator - ) + simona = SimonaConfig.Simona(if(c.hasPathOrNull("simona")) c.getConfig("simona") else com.typesafe.config.ConfigFactory.parseString("simona{}"), parentPath + "simona.", $tsCfgValidator) ) $tsCfgValidator.validate() $result } - private def $_L$_dbl( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[scala.Double] = { + private def $_L$_dbl(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Double] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_dbl(cv)).toList } - private def $_L$_int( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[scala.Int] = { + private def $_L$_int(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Int] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_int(cv)).toList } - private def $_L$_str( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[java.lang.String] = { + private def $_L$_str(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[java.lang.String] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_str(cv)).toList } - private def $_dbl(cv: com.typesafe.config.ConfigValue): scala.Double = { + private def $_dbl(cv:com.typesafe.config.ConfigValue): scala.Double = { val u: Any = cv.unwrapped - if ( - (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[java.lang.Number] - ) throw $_expE(cv, "double") + if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[java.lang.Number]) throw $_expE(cv, "double") u.asInstanceOf[java.lang.Number].doubleValue() } - private def $_expE( - cv: com.typesafe.config.ConfigValue, - exp: java.lang.String - ) = { + private def $_expE(cv:com.typesafe.config.ConfigValue, exp:java.lang.String) = { val u: Any = cv.unwrapped - new java.lang.RuntimeException( - s"${cv.origin.lineNumber}: " + - "expecting: " + exp + " got: " + - (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u) - ) + new java.lang.RuntimeException(s"${cv.origin.lineNumber}: " + + "expecting: " + exp + " got: " + + (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u)) } - private def $_int(cv: com.typesafe.config.ConfigValue): scala.Int = { + private def $_int(cv:com.typesafe.config.ConfigValue): scala.Int = { val u: Any = cv.unwrapped - if ( - (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[Integer] - ) throw $_expE(cv, "integer") + if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[Integer]) throw $_expE(cv, "integer") u.asInstanceOf[Integer] } - private def $_str(cv: com.typesafe.config.ConfigValue): java.lang.String = { + private def $_str(cv:com.typesafe.config.ConfigValue): java.lang.String = { java.lang.String.valueOf(cv.unwrapped()) } final class $TsCfgValidator { - private val badPaths = - scala.collection.mutable.ArrayBuffer[java.lang.String]() + private val badPaths = scala.collection.mutable.ArrayBuffer[java.lang.String]() - def addBadPath( - path: java.lang.String, - e: com.typesafe.config.ConfigException - ): Unit = { + def addBadPath(path: java.lang.String, e: com.typesafe.config.ConfigException): Unit = { badPaths += s"'$path': ${e.getClass.getName}(${e.getMessage})" } - def addInvalidEnumValue( - path: java.lang.String, - value: java.lang.String, - enumName: java.lang.String - ): Unit = { + def addInvalidEnumValue(path: java.lang.String, value: java.lang.String, enumName: java.lang.String): Unit = { badPaths += s"'$path': invalid value $value for enumeration $enumName" } @@ -2358,7 +1243,7 @@ object SimonaConfig { if (badPaths.nonEmpty) { throw new com.typesafe.config.ConfigException( badPaths.mkString("Invalid configuration:\n ", "\n ", "") - ) {} + ){} } } } From 47054b8175a7023bc33e3039be56a26c6102b792 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 7 Jun 2022 13:56:43 +0200 Subject: [PATCH 014/305] fix file name of config template --- gradle/scripts/tscfg.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/scripts/tscfg.gradle b/gradle/scripts/tscfg.gradle index e81ad99320..1c8db401ac 100644 --- a/gradle/scripts/tscfg.gradle +++ b/gradle/scripts/tscfg.gradle @@ -15,7 +15,7 @@ task genConfigClass { args = [ "build/tscfg-${tscfgVersion}.jar", "--spec", - "src/main/resources/config/config-template.conf", + "src/main/resources/config/simona-config-template.conf", "--scala", "--durations", "--pn", From 0fef590e81aad7dede2ecbd018c01e72aa3a4572 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Wed, 8 Jun 2022 13:21:55 +0200 Subject: [PATCH 015/305] adapt changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f023e434..85da45cd96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Implement SQL source for primary data [#34](https://github.com/ie3-institute/simona/issues/34), [#101](https://github.com/ie3-institute/simona/issues/101) - Relevant scientific papers have been added to the documentation [#139](https://github.com/ie3-institute/simona/issues/139) - Add troubleshooting section to Users guide [#160](https://github.com/ie3-institute/simona/issues/160) -- Config possibility for transformer control groups -- Models for measurements within the grid structure +- Models for measurements within the grid structure [#89](https://github.com/ie3-institute/simona/issues/89) +- Config possibility for transformer control groups [#90](https://github.com/ie3-institute/simona/issues/90) + ### Changed - Re-organizing test resources into their respective packages [#105](https://github.com/ie3-institute/simona/issues/105) From 203d70a7730f2d4497da9387944721b51da83f48 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Wed, 8 Jun 2022 13:25:31 +0200 Subject: [PATCH 016/305] spotless --- .../edu/ie3/simona/config/SimonaConfig.scala | 2625 ++++++++++++----- 1 file changed, 1870 insertions(+), 755 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index b519da4699..dada716baf 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,1241 +1,2356 @@ -// generated by tscfg 0.9.998 on Tue Jun 07 13:54:10 CEST 2022 -// source: src/main/resources/config/simona-config-template.conf +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ package edu.ie3.simona.config final case class SimonaConfig( - simona : SimonaConfig.Simona + simona: SimonaConfig.Simona ) object SimonaConfig { final case class BaseCsvParams( - override val csvSep : java.lang.String, - override val directoryPath : java.lang.String, - override val isHierarchic : scala.Boolean - ) extends CsvParams(csvSep,directoryPath,isHierarchic) + override val csvSep: java.lang.String, + override val directoryPath: java.lang.String, + override val isHierarchic: scala.Boolean + ) extends CsvParams(csvSep, directoryPath, isHierarchic) object BaseCsvParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseCsvParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.BaseCsvParams = { SimonaConfig.BaseCsvParams( csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + directoryPath = + $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class BaseOutputConfig( - notifier : java.lang.String, - powerRequestReply : scala.Boolean, - simulationResult : scala.Boolean + notifier: java.lang.String, + powerRequestReply: scala.Boolean, + simulationResult: scala.Boolean ) object BaseOutputConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseOutputConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.BaseOutputConfig = { SimonaConfig.BaseOutputConfig( - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - powerRequestReply = $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), - simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + powerRequestReply = + $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), + simulationResult = + $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - sealed abstract class BaseRuntimeConfig ( - val calculateMissingReactivePowerWithModel : scala.Boolean, - val scaling : scala.Double, - val uuids : scala.List[java.lang.String] + + sealed abstract class BaseRuntimeConfig( + val calculateMissingReactivePowerWithModel: scala.Boolean, + val scaling: scala.Double, + val uuids: scala.List[java.lang.String] ) extends java.io.Serializable - - sealed abstract class CsvParams ( - val csvSep : java.lang.String, - val directoryPath : java.lang.String, - val isHierarchic : scala.Boolean + + sealed abstract class CsvParams( + val csvSep: java.lang.String, + val directoryPath: java.lang.String, + val isHierarchic: scala.Boolean ) - + final case class EvcsRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object EvcsRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.EvcsRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.EvcsRuntimeConfig = { SimonaConfig.EvcsRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class FixedFeedInRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object FixedFeedInRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.FixedFeedInRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.FixedFeedInRuntimeConfig = { SimonaConfig.FixedFeedInRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class GridOutputConfig( - lines : scala.Boolean, - nodes : scala.Boolean, - notifier : java.lang.String, - switches : scala.Boolean, - transformers2w : scala.Boolean, - transformers3w : scala.Boolean + lines: scala.Boolean, + nodes: scala.Boolean, + notifier: java.lang.String, + switches: scala.Boolean, + transformers2w: scala.Boolean, + transformers3w: scala.Boolean ) object GridOutputConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.GridOutputConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.GridOutputConfig = { SimonaConfig.GridOutputConfig( - lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), - nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), - transformers2w = c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), - transformers3w = c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") + lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), + nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), + transformers2w = + c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), + transformers3w = + c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class LoadRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String], - modelBehaviour : java.lang.String, - reference : java.lang.String - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String], + modelBehaviour: java.lang.String, + reference: java.lang.String + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object LoadRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.LoadRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.LoadRuntimeConfig = { SimonaConfig.LoadRuntimeConfig( - modelBehaviour = $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), - reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + modelBehaviour = + $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), + reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PrimaryDataCsvParams( - override val csvSep : java.lang.String, - override val directoryPath : java.lang.String, - override val isHierarchic : scala.Boolean, - timePattern : java.lang.String - ) extends CsvParams(csvSep,directoryPath,isHierarchic) + override val csvSep: java.lang.String, + override val directoryPath: java.lang.String, + override val isHierarchic: scala.Boolean, + timePattern: java.lang.String + ) extends CsvParams(csvSep, directoryPath, isHierarchic) object PrimaryDataCsvParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PrimaryDataCsvParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.PrimaryDataCsvParams = { SimonaConfig.PrimaryDataCsvParams( - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), + directoryPath = + $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PvRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object PvRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PvRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.PvRuntimeConfig = { SimonaConfig.PvRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class RefSystemConfig( - gridIds : scala.Option[scala.List[java.lang.String]], - sNom : java.lang.String, - vNom : java.lang.String, - voltLvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + gridIds: scala.Option[scala.List[java.lang.String]], + sNom: java.lang.String, + vNom: java.lang.String, + voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object RefSystemConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RefSystemConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.RefSystemConfig = { SimonaConfig.RefSystemConfig( - gridIds = if(c.hasPathOrNull("gridIds")) scala.Some($_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator)) else None, - sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), - vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), - voltLvls = if(c.hasPathOrNull("voltLvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("voltLvls"), parentPath, $tsCfgValidator)) else None + gridIds = + if (c.hasPathOrNull("gridIds")) + scala.Some( + $_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator) + ) + else None, + sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), + vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), + voltLvls = + if (c.hasPathOrNull("voltLvls")) + scala.Some( + $_LSimonaConfig_VoltLvlConfig( + c.getList("voltLvls"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.VoltLvlConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class TransformerControlGroup( - measurements : scala.List[java.lang.String], - transformers : scala.List[java.lang.String], - vMax : scala.Double, - vMin : scala.Double + measurements: scala.List[java.lang.String], + transformers: scala.List[java.lang.String], + vMax: scala.Double, + vMin: scala.Double ) object TransformerControlGroup { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.TransformerControlGroup = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.TransformerControlGroup = { SimonaConfig.TransformerControlGroup( - measurements = $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), - transformers = $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), - vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), - vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + measurements = + $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = + $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) ) } - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class VoltLvlConfig( - id : java.lang.String, - vNom : java.lang.String + id: java.lang.String, + vNom: java.lang.String ) object VoltLvlConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.VoltLvlConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.VoltLvlConfig = { SimonaConfig.VoltLvlConfig( - id = $_reqStr(parentPath, c, "id", $tsCfgValidator), + id = $_reqStr(parentPath, c, "id", $tsCfgValidator), vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class WecRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object WecRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.WecRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.WecRuntimeConfig = { SimonaConfig.WecRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Simona( - control : scala.Option[SimonaConfig.Simona.Control], - event : SimonaConfig.Simona.Event, - gridConfig : SimonaConfig.Simona.GridConfig, - input : SimonaConfig.Simona.Input, - output : SimonaConfig.Simona.Output, - powerflow : SimonaConfig.Simona.Powerflow, - runtime : SimonaConfig.Simona.Runtime, - simulationName : java.lang.String, - time : SimonaConfig.Simona.Time + control: scala.Option[SimonaConfig.Simona.Control], + event: SimonaConfig.Simona.Event, + gridConfig: SimonaConfig.Simona.GridConfig, + input: SimonaConfig.Simona.Input, + output: SimonaConfig.Simona.Output, + powerflow: SimonaConfig.Simona.Powerflow, + runtime: SimonaConfig.Simona.Runtime, + simulationName: java.lang.String, + time: SimonaConfig.Simona.Time ) object Simona { final case class Control( - transformer : scala.List[SimonaConfig.TransformerControlGroup] + transformer: scala.List[SimonaConfig.TransformerControlGroup] ) object Control { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Control = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Control = { SimonaConfig.Simona.Control( - transformer = $_LSimonaConfig_TransformerControlGroup(c.getList("transformer"), parentPath, $tsCfgValidator) + transformer = $_LSimonaConfig_TransformerControlGroup( + c.getList("transformer"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_TransformerControlGroup(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.TransformerControlGroup] = { + private def $_LSimonaConfig_TransformerControlGroup( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.TransformerControlGroup] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.TransformerControlGroup(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.TransformerControlGroup( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Event( - listener : scala.Option[scala.List[SimonaConfig.Simona.Event.Listener$Elm]] + listener: scala.Option[ + scala.List[SimonaConfig.Simona.Event.Listener$Elm] + ] ) object Event { final case class Listener$Elm( - eventsToProcess : scala.Option[scala.List[java.lang.String]], - fullClassPath : java.lang.String + eventsToProcess: scala.Option[scala.List[java.lang.String]], + fullClassPath: java.lang.String ) object Listener$Elm { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event.Listener$Elm = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Event.Listener$Elm = { SimonaConfig.Simona.Event.Listener$Elm( - eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, - fullClassPath = $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) + eventsToProcess = + if (c.hasPathOrNull("eventsToProcess")) + scala.Some( + $_L$_str( + c.getList("eventsToProcess"), + parentPath, + $tsCfgValidator + ) + ) + else None, + fullClassPath = + $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Event = { SimonaConfig.Simona.Event( - listener = if(c.hasPathOrNull("listener")) scala.Some($_LSimonaConfig_Simona_Event_Listener$Elm(c.getList("listener"), parentPath, $tsCfgValidator)) else None + listener = + if (c.hasPathOrNull("listener")) + scala.Some( + $_LSimonaConfig_Simona_Event_Listener$Elm( + c.getList("listener"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_Simona_Event_Listener$Elm(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { + private def $_LSimonaConfig_Simona_Event_Listener$Elm( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.Simona.Event.Listener$Elm(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.Simona.Event.Listener$Elm( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class GridConfig( - refSystems : scala.List[SimonaConfig.RefSystemConfig] + refSystems: scala.List[SimonaConfig.RefSystemConfig] ) object GridConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.GridConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.GridConfig = { SimonaConfig.Simona.GridConfig( - refSystems = $_LSimonaConfig_RefSystemConfig(c.getList("refSystems"), parentPath, $tsCfgValidator) + refSystems = $_LSimonaConfig_RefSystemConfig( + c.getList("refSystems"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_RefSystemConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.RefSystemConfig] = { + private def $_LSimonaConfig_RefSystemConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.RefSystemConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.RefSystemConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.RefSystemConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Input( - grid : SimonaConfig.Simona.Input.Grid, - primary : SimonaConfig.Simona.Input.Primary, - weather : SimonaConfig.Simona.Input.Weather + grid: SimonaConfig.Simona.Input.Grid, + primary: SimonaConfig.Simona.Input.Primary, + weather: SimonaConfig.Simona.Input.Weather ) object Input { final case class Grid( - datasource : SimonaConfig.Simona.Input.Grid.Datasource + datasource: SimonaConfig.Simona.Input.Grid.Datasource ) object Grid { final case class Datasource( - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - id : java.lang.String + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + id: java.lang.String ) object Datasource { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid.Datasource = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Grid.Datasource = { SimonaConfig.Simona.Input.Grid.Datasource( - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - id = $_reqStr(parentPath, c, "id", $tsCfgValidator) + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + id = $_reqStr(parentPath, c, "id", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Grid = { SimonaConfig.Simona.Input.Grid( - datasource = SimonaConfig.Simona.Input.Grid.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) + datasource = SimonaConfig.Simona.Input.Grid.Datasource( + if (c.hasPathOrNull("datasource")) c.getConfig("datasource") + else + com.typesafe.config.ConfigFactory.parseString("datasource{}"), + parentPath + "datasource.", + $tsCfgValidator + ) ) } } - + final case class Primary( - couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Primary.CouchbaseParams], - csvParams : scala.Option[SimonaConfig.PrimaryDataCsvParams], - influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Primary.InfluxDb1xParams], - sqlParams : scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] + couchbaseParams: scala.Option[ + SimonaConfig.Simona.Input.Primary.CouchbaseParams + ], + csvParams: scala.Option[SimonaConfig.PrimaryDataCsvParams], + influxDb1xParams: scala.Option[ + SimonaConfig.Simona.Input.Primary.InfluxDb1xParams + ], + sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] ) object Primary { final case class CouchbaseParams( - bucketName : java.lang.String, - coordinateColumnName : java.lang.String, - keyPrefix : java.lang.String, - password : java.lang.String, - timePattern : java.lang.String, - url : java.lang.String, - userName : java.lang.String + bucketName: java.lang.String, + coordinateColumnName: java.lang.String, + keyPrefix: java.lang.String, + password: java.lang.String, + timePattern: java.lang.String, + url: java.lang.String, + userName: java.lang.String ) object CouchbaseParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { SimonaConfig.Simona.Input.Primary.CouchbaseParams( - bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = + $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr( + parentPath, + c, + "coordinateColumnName", + $tsCfgValidator + ), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database : java.lang.String, - port : scala.Int, - timePattern : java.lang.String, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + timePattern: java.lang.String, + url: java.lang.String ) object InfluxDb1xParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + database = $_reqStr(parentPath, c, "database", $tsCfgValidator), + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SqlParams( - jdbcUrl : java.lang.String, - password : java.lang.String, - schemaName : java.lang.String, - timePattern : java.lang.String, - userName : java.lang.String + jdbcUrl: java.lang.String, + password: java.lang.String, + schemaName: java.lang.String, + timePattern: java.lang.String, + userName: java.lang.String ) object SqlParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.SqlParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.SqlParams = { SimonaConfig.Simona.Input.Primary.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = + if (c.hasPathOrNull("schemaName")) c.getString("schemaName") + else "public", + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary = { SimonaConfig.Simona.Input.Primary( - couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Primary.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.PrimaryDataCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Primary.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, - sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Primary.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None + couchbaseParams = + if (c.hasPathOrNull("couchbaseParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.CouchbaseParams( + c.getConfig("couchbaseParams"), + parentPath + "couchbaseParams.", + $tsCfgValidator + ) + ) + else None, + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.PrimaryDataCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + influxDb1xParams = + if (c.hasPathOrNull("influxDb1xParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( + c.getConfig("influxDb1xParams"), + parentPath + "influxDb1xParams.", + $tsCfgValidator + ) + ) + else None, + sqlParams = + if (c.hasPathOrNull("sqlParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.SqlParams( + c.getConfig("sqlParams"), + parentPath + "sqlParams.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class Weather( - datasource : SimonaConfig.Simona.Input.Weather.Datasource + datasource: SimonaConfig.Simona.Input.Weather.Datasource ) object Weather { final case class Datasource( - coordinateSource : SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, - couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams], - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams], - resolution : scala.Option[scala.Long], - sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SampleParams], - scheme : java.lang.String, - sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SqlParams], - timestampPattern : scala.Option[java.lang.String] + coordinateSource: SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, + couchbaseParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams + ], + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + influxDb1xParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams + ], + resolution: scala.Option[scala.Long], + sampleParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.SampleParams + ], + scheme: java.lang.String, + sqlParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.SqlParams + ], + timestampPattern: scala.Option[java.lang.String] ) object Datasource { final case class CoordinateSource( - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - gridModel : java.lang.String, - sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams] + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + gridModel: java.lang.String, + sampleParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams + ] ) object CoordinateSource { final case class SampleParams( - use : scala.Boolean + use: scala.Boolean ) object SampleParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams( - use = !c.hasPathOrNull("use") || c.getBoolean("use") - ) + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SampleParams( + use = !c.hasPathOrNull("use") || c.getBoolean("use") + ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - gridModel = if(c.hasPathOrNull("gridModel")) c.getString("gridModel") else "icon", - sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + gridModel = + if (c.hasPathOrNull("gridModel")) c.getString("gridModel") + else "icon", + sampleParams = + if (c.hasPathOrNull("sampleParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SampleParams( + c.getConfig("sampleParams"), + parentPath + "sampleParams.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class CouchbaseParams( - bucketName : java.lang.String, - coordinateColumnName : java.lang.String, - keyPrefix : java.lang.String, - password : java.lang.String, - url : java.lang.String, - userName : java.lang.String + bucketName: java.lang.String, + coordinateColumnName: java.lang.String, + keyPrefix: java.lang.String, + password: java.lang.String, + url: java.lang.String, + userName: java.lang.String ) object CouchbaseParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams( - bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = + $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr( + parentPath, + c, + "coordinateColumnName", + $tsCfgValidator + ), + keyPrefix = + $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database : java.lang.String, - port : scala.Int, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + url: java.lang.String ) object InfluxDb1xParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SampleParams( - use : scala.Boolean + use: scala.Boolean ) object SampleParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( use = !c.hasPathOrNull("use") || c.getBoolean("use") ) } } - + final case class SqlParams( - jdbcUrl : java.lang.String, - password : java.lang.String, - schemaName : java.lang.String, - tableName : java.lang.String, - userName : java.lang.String + jdbcUrl: java.lang.String, + password: java.lang.String, + schemaName: java.lang.String, + tableName: java.lang.String, + userName: java.lang.String ) object SqlParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", - tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = + if (c.hasPathOrNull("schemaName")) c.getString("schemaName") + else "public", + tableName = + $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource = { SimonaConfig.Simona.Input.Weather.Datasource( - coordinateSource = SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource(if(c.hasPathOrNull("coordinateSource")) c.getConfig("coordinateSource") else com.typesafe.config.ConfigFactory.parseString("coordinateSource{}"), parentPath + "coordinateSource.", $tsCfgValidator), - couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, - resolution = if(c.hasPathOrNull("resolution")) Some(c.getLong("resolution").longValue()) else None, - sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, - scheme = if(c.hasPathOrNull("scheme")) c.getString("scheme") else "icon", - sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None, - timestampPattern = if(c.hasPathOrNull("timestampPattern")) Some(c.getString("timestampPattern")) else None + coordinateSource = + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( + if (c.hasPathOrNull("coordinateSource")) + c.getConfig("coordinateSource") + else + com.typesafe.config.ConfigFactory + .parseString("coordinateSource{}"), + parentPath + "coordinateSource.", + $tsCfgValidator + ), + couchbaseParams = + if (c.hasPathOrNull("couchbaseParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource + .CouchbaseParams( + c.getConfig("couchbaseParams"), + parentPath + "couchbaseParams.", + $tsCfgValidator + ) + ) + else None, + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + influxDb1xParams = + if (c.hasPathOrNull("influxDb1xParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource + .InfluxDb1xParams( + c.getConfig("influxDb1xParams"), + parentPath + "influxDb1xParams.", + $tsCfgValidator + ) + ) + else None, + resolution = + if (c.hasPathOrNull("resolution")) + Some(c.getLong("resolution").longValue()) + else None, + sampleParams = + if (c.hasPathOrNull("sampleParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( + c.getConfig("sampleParams"), + parentPath + "sampleParams.", + $tsCfgValidator + ) + ) + else None, + scheme = + if (c.hasPathOrNull("scheme")) c.getString("scheme") + else "icon", + sqlParams = + if (c.hasPathOrNull("sqlParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( + c.getConfig("sqlParams"), + parentPath + "sqlParams.", + $tsCfgValidator + ) + ) + else None, + timestampPattern = + if (c.hasPathOrNull("timestampPattern")) + Some(c.getString("timestampPattern")) + else None ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather = { SimonaConfig.Simona.Input.Weather( - datasource = SimonaConfig.Simona.Input.Weather.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) + datasource = SimonaConfig.Simona.Input.Weather.Datasource( + if (c.hasPathOrNull("datasource")) c.getConfig("datasource") + else + com.typesafe.config.ConfigFactory.parseString("datasource{}"), + parentPath + "datasource.", + $tsCfgValidator + ) ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input = { SimonaConfig.Simona.Input( - grid = SimonaConfig.Simona.Input.Grid(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), - primary = SimonaConfig.Simona.Input.Primary(if(c.hasPathOrNull("primary")) c.getConfig("primary") else com.typesafe.config.ConfigFactory.parseString("primary{}"), parentPath + "primary.", $tsCfgValidator), - weather = SimonaConfig.Simona.Input.Weather(if(c.hasPathOrNull("weather")) c.getConfig("weather") else com.typesafe.config.ConfigFactory.parseString("weather{}"), parentPath + "weather.", $tsCfgValidator) + grid = SimonaConfig.Simona.Input.Grid( + if (c.hasPathOrNull("grid")) c.getConfig("grid") + else com.typesafe.config.ConfigFactory.parseString("grid{}"), + parentPath + "grid.", + $tsCfgValidator + ), + primary = SimonaConfig.Simona.Input.Primary( + if (c.hasPathOrNull("primary")) c.getConfig("primary") + else com.typesafe.config.ConfigFactory.parseString("primary{}"), + parentPath + "primary.", + $tsCfgValidator + ), + weather = SimonaConfig.Simona.Input.Weather( + if (c.hasPathOrNull("weather")) c.getConfig("weather") + else com.typesafe.config.ConfigFactory.parseString("weather{}"), + parentPath + "weather.", + $tsCfgValidator + ) ) } } - + final case class Output( - base : SimonaConfig.Simona.Output.Base, - grid : SimonaConfig.GridOutputConfig, - participant : SimonaConfig.Simona.Output.Participant, - sink : SimonaConfig.Simona.Output.Sink + base: SimonaConfig.Simona.Output.Base, + grid: SimonaConfig.GridOutputConfig, + participant: SimonaConfig.Simona.Output.Participant, + sink: SimonaConfig.Simona.Output.Sink ) object Output { final case class Base( - addTimestampToOutputDir : scala.Boolean, - dir : java.lang.String + addTimestampToOutputDir: scala.Boolean, + dir: java.lang.String ) object Base { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Base = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Base = { SimonaConfig.Simona.Output.Base( - addTimestampToOutputDir = !c.hasPathOrNull("addTimestampToOutputDir") || c.getBoolean("addTimestampToOutputDir"), - dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) + addTimestampToOutputDir = !c.hasPathOrNull( + "addTimestampToOutputDir" + ) || c.getBoolean("addTimestampToOutputDir"), + dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class Participant( - defaultConfig : SimonaConfig.BaseOutputConfig, - individualConfigs : scala.List[SimonaConfig.BaseOutputConfig] + defaultConfig: SimonaConfig.BaseOutputConfig, + individualConfigs: scala.List[SimonaConfig.BaseOutputConfig] ) object Participant { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Participant = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Participant = { SimonaConfig.Simona.Output.Participant( - defaultConfig = SimonaConfig.BaseOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_BaseOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.BaseOutputConfig( + if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_BaseOutputConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_BaseOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.BaseOutputConfig] = { + private def $_LSimonaConfig_BaseOutputConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.BaseOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.BaseOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.BaseOutputConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Sink( - csv : scala.Option[SimonaConfig.Simona.Output.Sink.Csv], - influxDb1x : scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x] + csv: scala.Option[SimonaConfig.Simona.Output.Sink.Csv], + influxDb1x: scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x] ) object Sink { final case class Csv( - fileFormat : java.lang.String, - filePrefix : java.lang.String, - fileSuffix : java.lang.String, - isHierarchic : scala.Boolean + fileFormat: java.lang.String, + filePrefix: java.lang.String, + fileSuffix: java.lang.String, + isHierarchic: scala.Boolean ) object Csv { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.Csv = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink.Csv = { SimonaConfig.Simona.Output.Sink.Csv( - fileFormat = if(c.hasPathOrNull("fileFormat")) c.getString("fileFormat") else ".csv", - filePrefix = if(c.hasPathOrNull("filePrefix")) c.getString("filePrefix") else "", - fileSuffix = if(c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") else "", - isHierarchic = c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") + fileFormat = + if (c.hasPathOrNull("fileFormat")) c.getString("fileFormat") + else ".csv", + filePrefix = + if (c.hasPathOrNull("filePrefix")) c.getString("filePrefix") + else "", + fileSuffix = + if (c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") + else "", + isHierarchic = + c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") ) } } - + final case class InfluxDb1x( - database : java.lang.String, - port : scala.Int, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + url: java.lang.String ) object InfluxDb1x { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink = { SimonaConfig.Simona.Output.Sink( - csv = if(c.hasPathOrNull("csv")) scala.Some(SimonaConfig.Simona.Output.Sink.Csv(c.getConfig("csv"), parentPath + "csv.", $tsCfgValidator)) else None, - influxDb1x = if(c.hasPathOrNull("influxDb1x")) scala.Some(SimonaConfig.Simona.Output.Sink.InfluxDb1x(c.getConfig("influxDb1x"), parentPath + "influxDb1x.", $tsCfgValidator)) else None + csv = + if (c.hasPathOrNull("csv")) + scala.Some( + SimonaConfig.Simona.Output.Sink.Csv( + c.getConfig("csv"), + parentPath + "csv.", + $tsCfgValidator + ) + ) + else None, + influxDb1x = + if (c.hasPathOrNull("influxDb1x")) + scala.Some( + SimonaConfig.Simona.Output.Sink.InfluxDb1x( + c.getConfig("influxDb1x"), + parentPath + "influxDb1x.", + $tsCfgValidator + ) + ) + else None ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output = { SimonaConfig.Simona.Output( - base = SimonaConfig.Simona.Output.Base(if(c.hasPathOrNull("base")) c.getConfig("base") else com.typesafe.config.ConfigFactory.parseString("base{}"), parentPath + "base.", $tsCfgValidator), - grid = SimonaConfig.GridOutputConfig(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), - participant = SimonaConfig.Simona.Output.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), - sink = SimonaConfig.Simona.Output.Sink(if(c.hasPathOrNull("sink")) c.getConfig("sink") else com.typesafe.config.ConfigFactory.parseString("sink{}"), parentPath + "sink.", $tsCfgValidator) + base = SimonaConfig.Simona.Output.Base( + if (c.hasPathOrNull("base")) c.getConfig("base") + else com.typesafe.config.ConfigFactory.parseString("base{}"), + parentPath + "base.", + $tsCfgValidator + ), + grid = SimonaConfig.GridOutputConfig( + if (c.hasPathOrNull("grid")) c.getConfig("grid") + else com.typesafe.config.ConfigFactory.parseString("grid{}"), + parentPath + "grid.", + $tsCfgValidator + ), + participant = SimonaConfig.Simona.Output.Participant( + if (c.hasPathOrNull("participant")) c.getConfig("participant") + else com.typesafe.config.ConfigFactory.parseString("participant{}"), + parentPath + "participant.", + $tsCfgValidator + ), + sink = SimonaConfig.Simona.Output.Sink( + if (c.hasPathOrNull("sink")) c.getConfig("sink") + else com.typesafe.config.ConfigFactory.parseString("sink{}"), + parentPath + "sink.", + $tsCfgValidator + ) ) } } - + final case class Powerflow( - maxSweepPowerDeviation : scala.Double, - newtonraphson : SimonaConfig.Simona.Powerflow.Newtonraphson, - resolution : java.time.Duration, - sweepTimeout : java.time.Duration + maxSweepPowerDeviation: scala.Double, + newtonraphson: SimonaConfig.Simona.Powerflow.Newtonraphson, + resolution: java.time.Duration, + sweepTimeout: java.time.Duration ) object Powerflow { final case class Newtonraphson( - epsilon : scala.List[scala.Double], - iterations : scala.Int + epsilon: scala.List[scala.Double], + iterations: scala.Int ) object Newtonraphson { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow.Newtonraphson = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Powerflow.Newtonraphson = { SimonaConfig.Simona.Powerflow.Newtonraphson( - epsilon = $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), + epsilon = + $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Powerflow = { SimonaConfig.Simona.Powerflow( - maxSweepPowerDeviation = $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), - newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson(if(c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") else com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), parentPath + "newtonraphson.", $tsCfgValidator), - resolution = if(c.hasPathOrNull("resolution")) c.getDuration("resolution") else java.time.Duration.parse("PT1H"), - sweepTimeout = if(c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") else java.time.Duration.parse("PT30S") + maxSweepPowerDeviation = + $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), + newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson( + if (c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") + else + com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), + parentPath + "newtonraphson.", + $tsCfgValidator + ), + resolution = + if (c.hasPathOrNull("resolution")) c.getDuration("resolution") + else java.time.Duration.parse("PT1H"), + sweepTimeout = + if (c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") + else java.time.Duration.parse("PT30S") ) } - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Runtime( - participant : SimonaConfig.Simona.Runtime.Participant, - selected_subgrids : scala.Option[scala.List[scala.Int]], - selected_volt_lvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + participant: SimonaConfig.Simona.Runtime.Participant, + selected_subgrids: scala.Option[scala.List[scala.Int]], + selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object Runtime { final case class Participant( - evcs : SimonaConfig.Simona.Runtime.Participant.Evcs, - fixedFeedIn : SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, - load : SimonaConfig.Simona.Runtime.Participant.Load, - pv : SimonaConfig.Simona.Runtime.Participant.Pv, - requestVoltageDeviationThreshold : scala.Double, - wec : SimonaConfig.Simona.Runtime.Participant.Wec + evcs: SimonaConfig.Simona.Runtime.Participant.Evcs, + fixedFeedIn: SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, + load: SimonaConfig.Simona.Runtime.Participant.Load, + pv: SimonaConfig.Simona.Runtime.Participant.Pv, + requestVoltageDeviationThreshold: scala.Double, + wec: SimonaConfig.Simona.Runtime.Participant.Wec ) object Participant { final case class Evcs( - defaultConfig : SimonaConfig.EvcsRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.EvcsRuntimeConfig] + defaultConfig: SimonaConfig.EvcsRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig] ) object Evcs { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Evcs = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Evcs = { SimonaConfig.Simona.Runtime.Participant.Evcs( - defaultConfig = SimonaConfig.EvcsRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.EvcsRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_EvcsRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.EvcsRuntimeConfig] = { + private def $_LSimonaConfig_EvcsRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.EvcsRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.EvcsRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.EvcsRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class FixedFeedIn( - defaultConfig : SimonaConfig.FixedFeedInRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.FixedFeedInRuntimeConfig] + defaultConfig: SimonaConfig.FixedFeedInRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig] ) object FixedFeedIn { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_FixedFeedInRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { + private def $_LSimonaConfig_FixedFeedInRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.FixedFeedInRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.FixedFeedInRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Load( - defaultConfig : SimonaConfig.LoadRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.LoadRuntimeConfig] + defaultConfig: SimonaConfig.LoadRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig] ) object Load { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Load = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Load = { SimonaConfig.Simona.Runtime.Participant.Load( - defaultConfig = SimonaConfig.LoadRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_LoadRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.LoadRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_LoadRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_LoadRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.LoadRuntimeConfig] = { + private def $_LSimonaConfig_LoadRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.LoadRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.LoadRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.LoadRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Pv( - defaultConfig : SimonaConfig.PvRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.PvRuntimeConfig] + defaultConfig: SimonaConfig.PvRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig] ) object Pv { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Pv = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Pv = { SimonaConfig.Simona.Runtime.Participant.Pv( - defaultConfig = SimonaConfig.PvRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_PvRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.PvRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_PvRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_PvRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.PvRuntimeConfig] = { + private def $_LSimonaConfig_PvRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.PvRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.PvRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.PvRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Wec( - defaultConfig : SimonaConfig.WecRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.WecRuntimeConfig] + defaultConfig: SimonaConfig.WecRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig] ) object Wec { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Wec = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Wec = { SimonaConfig.Simona.Runtime.Participant.Wec( - defaultConfig = SimonaConfig.WecRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_WecRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.WecRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_WecRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_WecRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.WecRuntimeConfig] = { + private def $_LSimonaConfig_WecRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.WecRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.WecRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.WecRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant = { SimonaConfig.Simona.Runtime.Participant( - evcs = SimonaConfig.Simona.Runtime.Participant.Evcs(if(c.hasPathOrNull("evcs")) c.getConfig("evcs") else com.typesafe.config.ConfigFactory.parseString("evcs{}"), parentPath + "evcs.", $tsCfgValidator), - fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn(if(c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") else com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), parentPath + "fixedFeedIn.", $tsCfgValidator), - load = SimonaConfig.Simona.Runtime.Participant.Load(if(c.hasPathOrNull("load")) c.getConfig("load") else com.typesafe.config.ConfigFactory.parseString("load{}"), parentPath + "load.", $tsCfgValidator), - pv = SimonaConfig.Simona.Runtime.Participant.Pv(if(c.hasPathOrNull("pv")) c.getConfig("pv") else com.typesafe.config.ConfigFactory.parseString("pv{}"), parentPath + "pv.", $tsCfgValidator), - requestVoltageDeviationThreshold = if(c.hasPathOrNull("requestVoltageDeviationThreshold")) c.getDouble("requestVoltageDeviationThreshold") else 1E-14, - wec = SimonaConfig.Simona.Runtime.Participant.Wec(if(c.hasPathOrNull("wec")) c.getConfig("wec") else com.typesafe.config.ConfigFactory.parseString("wec{}"), parentPath + "wec.", $tsCfgValidator) + evcs = SimonaConfig.Simona.Runtime.Participant.Evcs( + if (c.hasPathOrNull("evcs")) c.getConfig("evcs") + else com.typesafe.config.ConfigFactory.parseString("evcs{}"), + parentPath + "evcs.", + $tsCfgValidator + ), + fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( + if (c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") + else + com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), + parentPath + "fixedFeedIn.", + $tsCfgValidator + ), + load = SimonaConfig.Simona.Runtime.Participant.Load( + if (c.hasPathOrNull("load")) c.getConfig("load") + else com.typesafe.config.ConfigFactory.parseString("load{}"), + parentPath + "load.", + $tsCfgValidator + ), + pv = SimonaConfig.Simona.Runtime.Participant.Pv( + if (c.hasPathOrNull("pv")) c.getConfig("pv") + else com.typesafe.config.ConfigFactory.parseString("pv{}"), + parentPath + "pv.", + $tsCfgValidator + ), + requestVoltageDeviationThreshold = + if (c.hasPathOrNull("requestVoltageDeviationThreshold")) + c.getDouble("requestVoltageDeviationThreshold") + else 1e-14, + wec = SimonaConfig.Simona.Runtime.Participant.Wec( + if (c.hasPathOrNull("wec")) c.getConfig("wec") + else com.typesafe.config.ConfigFactory.parseString("wec{}"), + parentPath + "wec.", + $tsCfgValidator + ) ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime = { SimonaConfig.Simona.Runtime( - participant = SimonaConfig.Simona.Runtime.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), - selected_subgrids = if(c.hasPathOrNull("selected_subgrids")) scala.Some($_L$_int(c.getList("selected_subgrids"), parentPath, $tsCfgValidator)) else None, - selected_volt_lvls = if(c.hasPathOrNull("selected_volt_lvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("selected_volt_lvls"), parentPath, $tsCfgValidator)) else None + participant = SimonaConfig.Simona.Runtime.Participant( + if (c.hasPathOrNull("participant")) c.getConfig("participant") + else com.typesafe.config.ConfigFactory.parseString("participant{}"), + parentPath + "participant.", + $tsCfgValidator + ), + selected_subgrids = + if (c.hasPathOrNull("selected_subgrids")) + scala.Some( + $_L$_int( + c.getList("selected_subgrids"), + parentPath, + $tsCfgValidator + ) + ) + else None, + selected_volt_lvls = + if (c.hasPathOrNull("selected_volt_lvls")) + scala.Some( + $_LSimonaConfig_VoltLvlConfig( + c.getList("selected_volt_lvls"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.VoltLvlConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Time( - endDateTime : java.lang.String, - schedulerReadyCheckWindow : scala.Option[scala.Int], - startDateTime : java.lang.String, - stopOnFailedPowerFlow : scala.Boolean + endDateTime: java.lang.String, + schedulerReadyCheckWindow: scala.Option[scala.Int], + startDateTime: java.lang.String, + stopOnFailedPowerFlow: scala.Boolean ) object Time { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Time = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Time = { SimonaConfig.Simona.Time( - endDateTime = if(c.hasPathOrNull("endDateTime")) c.getString("endDateTime") else "2011-05-01 01:00:00", - schedulerReadyCheckWindow = if(c.hasPathOrNull("schedulerReadyCheckWindow")) Some(c.getInt("schedulerReadyCheckWindow")) else None, - startDateTime = if(c.hasPathOrNull("startDateTime")) c.getString("startDateTime") else "2011-05-01 00:00:00", - stopOnFailedPowerFlow = c.hasPathOrNull("stopOnFailedPowerFlow") && c.getBoolean("stopOnFailedPowerFlow") + endDateTime = + if (c.hasPathOrNull("endDateTime")) c.getString("endDateTime") + else "2011-05-01 01:00:00", + schedulerReadyCheckWindow = + if (c.hasPathOrNull("schedulerReadyCheckWindow")) + Some(c.getInt("schedulerReadyCheckWindow")) + else None, + startDateTime = + if (c.hasPathOrNull("startDateTime")) c.getString("startDateTime") + else "2011-05-01 00:00:00", + stopOnFailedPowerFlow = + c.hasPathOrNull("stopOnFailedPowerFlow") && c.getBoolean( + "stopOnFailedPowerFlow" + ) ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona = { SimonaConfig.Simona( - control = if(c.hasPathOrNull("control")) scala.Some(SimonaConfig.Simona.Control(c.getConfig("control"), parentPath + "control.", $tsCfgValidator)) else None, - event = SimonaConfig.Simona.Event(if(c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), parentPath + "event.", $tsCfgValidator), - gridConfig = SimonaConfig.Simona.GridConfig(if(c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), parentPath + "gridConfig.", $tsCfgValidator), - input = SimonaConfig.Simona.Input(if(c.hasPathOrNull("input")) c.getConfig("input") else com.typesafe.config.ConfigFactory.parseString("input{}"), parentPath + "input.", $tsCfgValidator), - output = SimonaConfig.Simona.Output(if(c.hasPathOrNull("output")) c.getConfig("output") else com.typesafe.config.ConfigFactory.parseString("output{}"), parentPath + "output.", $tsCfgValidator), - powerflow = SimonaConfig.Simona.Powerflow(if(c.hasPathOrNull("powerflow")) c.getConfig("powerflow") else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), parentPath + "powerflow.", $tsCfgValidator), - runtime = SimonaConfig.Simona.Runtime(if(c.hasPathOrNull("runtime")) c.getConfig("runtime") else com.typesafe.config.ConfigFactory.parseString("runtime{}"), parentPath + "runtime.", $tsCfgValidator), - simulationName = $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), - time = SimonaConfig.Simona.Time(if(c.hasPathOrNull("time")) c.getConfig("time") else com.typesafe.config.ConfigFactory.parseString("time{}"), parentPath + "time.", $tsCfgValidator) + control = + if (c.hasPathOrNull("control")) + scala.Some( + SimonaConfig.Simona.Control( + c.getConfig("control"), + parentPath + "control.", + $tsCfgValidator + ) + ) + else None, + event = SimonaConfig.Simona.Event( + if (c.hasPathOrNull("event")) c.getConfig("event") + else com.typesafe.config.ConfigFactory.parseString("event{}"), + parentPath + "event.", + $tsCfgValidator + ), + gridConfig = SimonaConfig.Simona.GridConfig( + if (c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") + else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), + parentPath + "gridConfig.", + $tsCfgValidator + ), + input = SimonaConfig.Simona.Input( + if (c.hasPathOrNull("input")) c.getConfig("input") + else com.typesafe.config.ConfigFactory.parseString("input{}"), + parentPath + "input.", + $tsCfgValidator + ), + output = SimonaConfig.Simona.Output( + if (c.hasPathOrNull("output")) c.getConfig("output") + else com.typesafe.config.ConfigFactory.parseString("output{}"), + parentPath + "output.", + $tsCfgValidator + ), + powerflow = SimonaConfig.Simona.Powerflow( + if (c.hasPathOrNull("powerflow")) c.getConfig("powerflow") + else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), + parentPath + "powerflow.", + $tsCfgValidator + ), + runtime = SimonaConfig.Simona.Runtime( + if (c.hasPathOrNull("runtime")) c.getConfig("runtime") + else com.typesafe.config.ConfigFactory.parseString("runtime{}"), + parentPath + "runtime.", + $tsCfgValidator + ), + simulationName = + $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), + time = SimonaConfig.Simona.Time( + if (c.hasPathOrNull("time")) c.getConfig("time") + else com.typesafe.config.ConfigFactory.parseString("time{}"), + parentPath + "time.", + $tsCfgValidator + ) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + def apply(c: com.typesafe.config.Config): SimonaConfig = { val $tsCfgValidator: $TsCfgValidator = new $TsCfgValidator() val parentPath: java.lang.String = "" val $result = SimonaConfig( - simona = SimonaConfig.Simona(if(c.hasPathOrNull("simona")) c.getConfig("simona") else com.typesafe.config.ConfigFactory.parseString("simona{}"), parentPath + "simona.", $tsCfgValidator) + simona = SimonaConfig.Simona( + if (c.hasPathOrNull("simona")) c.getConfig("simona") + else com.typesafe.config.ConfigFactory.parseString("simona{}"), + parentPath + "simona.", + $tsCfgValidator + ) ) $tsCfgValidator.validate() $result } - private def $_L$_dbl(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Double] = { + private def $_L$_dbl( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[scala.Double] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_dbl(cv)).toList } - private def $_L$_int(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Int] = { + private def $_L$_int( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[scala.Int] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_int(cv)).toList } - private def $_L$_str(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[java.lang.String] = { + private def $_L$_str( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[java.lang.String] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_str(cv)).toList } - private def $_dbl(cv:com.typesafe.config.ConfigValue): scala.Double = { + private def $_dbl(cv: com.typesafe.config.ConfigValue): scala.Double = { val u: Any = cv.unwrapped - if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[java.lang.Number]) throw $_expE(cv, "double") + if ( + (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[java.lang.Number] + ) throw $_expE(cv, "double") u.asInstanceOf[java.lang.Number].doubleValue() } - private def $_expE(cv:com.typesafe.config.ConfigValue, exp:java.lang.String) = { + private def $_expE( + cv: com.typesafe.config.ConfigValue, + exp: java.lang.String + ) = { val u: Any = cv.unwrapped - new java.lang.RuntimeException(s"${cv.origin.lineNumber}: " + - "expecting: " + exp + " got: " + - (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u)) + new java.lang.RuntimeException( + s"${cv.origin.lineNumber}: " + + "expecting: " + exp + " got: " + + (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u) + ) } - private def $_int(cv:com.typesafe.config.ConfigValue): scala.Int = { + private def $_int(cv: com.typesafe.config.ConfigValue): scala.Int = { val u: Any = cv.unwrapped - if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[Integer]) throw $_expE(cv, "integer") + if ( + (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[Integer] + ) throw $_expE(cv, "integer") u.asInstanceOf[Integer] } - private def $_str(cv:com.typesafe.config.ConfigValue): java.lang.String = { + private def $_str(cv: com.typesafe.config.ConfigValue): java.lang.String = { java.lang.String.valueOf(cv.unwrapped()) } final class $TsCfgValidator { - private val badPaths = scala.collection.mutable.ArrayBuffer[java.lang.String]() + private val badPaths = + scala.collection.mutable.ArrayBuffer[java.lang.String]() - def addBadPath(path: java.lang.String, e: com.typesafe.config.ConfigException): Unit = { + def addBadPath( + path: java.lang.String, + e: com.typesafe.config.ConfigException + ): Unit = { badPaths += s"'$path': ${e.getClass.getName}(${e.getMessage})" } - def addInvalidEnumValue(path: java.lang.String, value: java.lang.String, enumName: java.lang.String): Unit = { + def addInvalidEnumValue( + path: java.lang.String, + value: java.lang.String, + enumName: java.lang.String + ): Unit = { badPaths += s"'$path': invalid value $value for enumeration $enumName" } @@ -1243,7 +2358,7 @@ object SimonaConfig { if (badPaths.nonEmpty) { throw new com.typesafe.config.ConfigException( badPaths.mkString("Invalid configuration:\n ", "\n ", "") - ){} + ) {} } } } From b33946a11a481f258ab0c495d3fa0ec2851bfea6 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Mon, 13 Jun 2022 12:40:20 +0200 Subject: [PATCH 017/305] changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0ece9beb7..23d4ff4089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Made SimonaConfig.BaseRuntimeConfig serializable [#36](https://github.com/ie3-institute/simona/issues/36) - Adapt to new simonaAPI snapshot [#95](https://github.com/ie3-institute/simona/issues/95) - Update Sphinx to 4.5.0 as well as extensions [#214](https://github.com/ie3-institute/simona/issues/214) +- Respect for scaling factor when simulating the system participants [#81](https://github.com/ie3-institute/simona/issues/81) +- Harmonize participant model instantiation [#81](https://github.com/ie3-institute/simona/issues/81) + ### Fixed - Location of `vn_simona` test grid (was partially in Berlin and Dortmund) [#72](https://github.com/ie3-institute/simona/issues/72) @@ -48,9 +51,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed some unreachable code [#167](https://github.com/ie3-institute/simona/issues/167) - Fix treatment of non-InitializeTrigger triggers in initialization within SimScheduler [#237](https://github.com/ie3-institute/simona/issues/237) - Fix breaking SIMONA caused by introducing temperature dependant load profiles in PSDM [#255](https://github.com/ie3-institute/simona/issues/255) -- Improving code readability in `EvcsAgent` by moving FreeLotsRequest to separate methods -- Respect for scaling factor when simulating the system participants -- Harmonize participant model instantiation ### Removed - Remove workaround for tscfg tmp directory [#178](https://github.com/ie3-institute/simona/issues/178) From f0eb5642a4aaa89df48ef4426102593ad45e51f7 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Mon, 13 Jun 2022 15:00:51 +0200 Subject: [PATCH 018/305] BdewStandardLoadProfile and spotless --- .../load/RandomLoadModelTest.groovy | 64 ++++++++++--------- .../load/LoadModelScalingSpec.scala | 23 +++---- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index e891a87a5a..b425aab973 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -34,38 +34,38 @@ import static tech.units.indriya.unit.Units.WATT class RandomLoadModelTest extends Specification { def loadInput = - new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + H0, + false, + Quantities.getQuantity(3000d, KILOWATTHOUR), + Quantities.getQuantity(282.74d, VOLTAMPERE), + 0.95 + ) def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + loadInput.operationTime + ) def testingTolerance = 1e-6 // Equals to 1 W power def "A random load model should be instantiated from valid input correctly"() { @@ -75,7 +75,7 @@ class RandomLoadModelTest extends Specification { foreSeenOperationInterval, 1.0, reference - ) + ) then: abs(actual.sRated().subtract(expSRated).getValue().doubleValue()) < testingTolerance @@ -97,7 +97,7 @@ class RandomLoadModelTest extends Specification { loadInput.sRated, loadInput.cosPhiRated, new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) + ) /* Working day, 61th quarter hour */ def queryDate = TimeUtil.withDefaults.toZonedDateTime('2019-07-19 15:21:00') def expectedParams = new RandomLoadParameters(0.405802458524704, 0.0671483352780342, 0.0417016632854939) @@ -133,7 +133,7 @@ class RandomLoadModelTest extends Specification { loadInput.sRated, loadInput.cosPhiRated, new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) + ) def relevantDatas = (0..35040).stream().map({ cnt -> new RandomLoadModel.RandomRelevantData( startDate.plus(cnt * 15, ChronoUnit.MINUTES)) @@ -147,3 +147,5 @@ class RandomLoadModelTest extends Specification { (dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)).asType(Energy).to(KILOWATTHOUR).value.doubleValue() }).sum() }).average().orElse(0d) + } +} diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 6f31894485..45c1f35484 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -7,10 +7,11 @@ package edu.ie3.simona.model.participant.load import breeze.numerics.abs +import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} -import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl @@ -60,7 +61,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { -1 ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), @@ -84,9 +85,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { forAll( Table( "profile", - BdewLoadProfile.H0, - BdewLoadProfile.L0, - BdewLoadProfile.G0 + BdewStandardLoadProfile.H0, + BdewStandardLoadProfile.L0, + BdewStandardLoadProfile.G0 ) ) { profile => val dut = ProfileLoadModel( @@ -164,7 +165,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { QControl.apply(profileLoadInput.getqCharacteristics()), profileLoadInput.getsRated(), profileLoadInput.getCosPhiRated, - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) ) dut.enable() @@ -224,9 +225,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { forAll( Table( "profile", - BdewLoadProfile.H0, - BdewLoadProfile.L0, - BdewLoadProfile.G0 + BdewStandardLoadProfile.H0, + BdewStandardLoadProfile.L0, + BdewStandardLoadProfile.G0 ) ) { profile => val dut = ProfileLoadModel( @@ -285,7 +286,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { QControl.apply(profileLoadInput.getqCharacteristics()), profileLoadInput.getsRated(), profileLoadInput.getCosPhiRated, - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) ) dut.enable() @@ -339,7 +340,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { -1 ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), From 355bd233945582ca770bcedf5a54dbd55265711f Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 14 Jun 2022 09:52:56 +0200 Subject: [PATCH 019/305] more BdewStandardLoadProfile --- .../model/participant/load/profile/ProfileLoadModel.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index bb7a07088f..a952fb34dc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -6,9 +6,8 @@ package edu.ie3.simona.model.participant.load.profile -import edu.ie3.datamodel.models.profile.StandardLoadProfile import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig +import edu.ie3.datamodel.models.profile.StandardLoadProfile import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ @@ -145,8 +144,8 @@ case object ProfileLoadModel { case LoadReference.EnergyConsumption(energyConsumption) => val loadProfileMax = LoadProfileStore().maxPower( - input.getLoadProfile.asInstanceOf[StandardLoadProfile] - ) + input.getLoadProfile.asInstanceOf[StandardLoadProfile] + ) val sRatedEnergy = LoadModel.scaleSRatedEnergy( input, energyConsumption, From f004d6aabf86d037858c5fe9eb10293cb293be9f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 20 Jun 2022 18:38:28 +0200 Subject: [PATCH 020/305] Adding link to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ab37feb55..18c65fd408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- Config possibility for transformer control groups - Implement SQL source for primary data [#34](https://github.com/ie3-institute/simona/issues/34), [#101](https://github.com/ie3-institute/simona/issues/101) - Relevant scientific papers have been added to the documentation [#139](https://github.com/ie3-institute/simona/issues/139) - Add troubleshooting section to Users guide [#160](https://github.com/ie3-institute/simona/issues/160) - Added Kafka sink for results [#24](https://github.com/ie3-institute/simona/issues/24) +- Config possibility for transformer control groups [#90](https://github.com/ie3-institute/simona/issues/90) ### Changed - Re-organizing test resources into their respective packages [#105](https://github.com/ie3-institute/simona/issues/105) From b0ee37d36cfc06d9a5a3c6fce973a71818af362e Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 21 Jun 2022 17:00:26 +0200 Subject: [PATCH 021/305] include transformerControlGroup to Exception message --- .../scala/edu/ie3/simona/config/ConfigFailFast.scala | 10 +++++----- .../edu/ie3/simona/config/ConfigFailFastSpec.scala | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index 661337bd2b..b068411a6d 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -581,24 +581,24 @@ case object ConfigFailFast extends LazyLogging { case TransformerControlGroup(measurements, transformers, vMax, vMin) => if (measurements.isEmpty) throw new InvalidConfigParameterException( - "A transformer control group cannot have no measurements assigned." + s"A transformer control group (${transformerControlGroup.toString}) cannot have no measurements assigned." ) if (transformers.isEmpty) throw new InvalidConfigParameterException( - "A transformer control group cannot have no transformers assigned." + s"A transformer control group (${transformerControlGroup.toString}) cannot have no transformers assigned." ) if (vMax < vMin) throw new InvalidConfigParameterException( - "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." + s"The minimum permissible voltage magnitude of a transformer control group (${transformerControlGroup.toString}) must be smaller than the maximum permissible voltage magnitude." ) if (vMin < lowerBoundary) throw new InvalidConfigParameterException( - s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" ) if (vMax > upperBoundary) throw new InvalidConfigParameterException( - s"A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" ) } diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 1917d316b1..64cd61890f 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -947,7 +947,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "A transformer control group cannot have no measurements assigned." + }.getMessage shouldBe s"A transformer control group (${dut.toString}) cannot have no measurements assigned." } "throw an exception, if the transformers are empty" in { @@ -960,7 +960,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "A transformer control group cannot have no transformers assigned." + }.getMessage shouldBe s"A transformer control group (${dut.toString}) cannot have no transformers assigned." } "throw an exception, if vMax is smaller than vMin" in { @@ -973,7 +973,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." + }.getMessage shouldBe s"The minimum permissible voltage magnitude of a transformer control group (${dut.toString}) must be smaller than the maximum permissible voltage magnitude." } "throw Exception when vMin is lower then -21% of nominal Voltage" in { @@ -986,7 +986,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + }.getMessage shouldBe s"A control group (${dut.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + "by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" } @@ -1000,7 +1000,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkTransformerControl(dut) - }.getMessage shouldBe "A control group which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + }.getMessage shouldBe s"A control group (${dut.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + "by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" } } From 1b0169145535603ec9835c3e9fd97bd6e6660d9c Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Sat, 25 Jun 2022 10:16:58 +0200 Subject: [PATCH 022/305] check voltage measurement at gridagent failfast --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 387b96f373..558f90e564 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,11 +7,7 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{ - GridAgentBaseData, - GridAgentInitData, - GridAgentUninitializedData -} +import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} @@ -19,22 +15,15 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{ - CompletionMessage, - ScheduleTriggerMessage, - TriggerWithIdMessage -} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ - ActivityStartTrigger, - InitializeGridAgentTrigger, - StartGridSimulationTrigger -} +import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID +import scala.jdk.CollectionConverters.CollectionHasAsScala import scala.language.postfixOps object GridAgent { @@ -52,7 +41,8 @@ object GridAgent { ) private def failFast( - gridAgentInitData: GridAgentInitData + gridAgentInitData: GridAgentInitData, + simonaConfig: SimonaConfig, ): Unit = { /** Check if there is InitData for superior or inferior GridGates @@ -64,6 +54,15 @@ object GridAgent { s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" ) + + /** Check if there exits voltage measurements for transformerControlGroups + */ + val measurementUnitInput = gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits + val maybeControlConfig: Option[SimonaConfig.Simona.Control] = simonaConfig.simona.control + if (maybeControlConfig.isDefined && !measurementUnitInput.asScala.exists(input => input.getVMag)) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a control group with measurement that don't deliver voltage magnitude." + ) } } @@ -122,7 +121,7 @@ class GridAgent( _ ) => // fail fast sanity checks - GridAgent.failFast(gridAgentInitData) + GridAgent.failFast(gridAgentInitData, simonaConfig) log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", From 58a2f34ff3650b4b37986520c13eff1aac0d7c0c Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Sat, 25 Jun 2022 10:27:13 +0200 Subject: [PATCH 023/305] move GridAgentFailFast to own class --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 48 +++++++------------ .../simona/agent/grid/GridAgentFailFast.scala | 46 ++++++++++++++++++ 2 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 558f90e564..94a607f6fa 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -7,23 +7,33 @@ package edu.ie3.simona.agent.grid import akka.actor.{ActorRef, Props, Stash} -import edu.ie3.simona.agent.grid.GridAgentData.{GridAgentBaseData, GridAgentInitData, GridAgentUninitializedData} +import edu.ie3.simona.agent.grid.GridAgentData.{ + GridAgentBaseData, + GridAgentInitData, + GridAgentUninitializedData +} import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.{CompletionMessage, ScheduleTriggerMessage, TriggerWithIdMessage} +import edu.ie3.simona.ontology.messages.SchedulerMessage.{ + CompletionMessage, + ScheduleTriggerMessage, + TriggerWithIdMessage +} import edu.ie3.simona.ontology.messages.StopMessage -import edu.ie3.simona.ontology.trigger.Trigger.{ActivityStartTrigger, InitializeGridAgentTrigger, StartGridSimulationTrigger} +import edu.ie3.simona.ontology.trigger.Trigger.{ + ActivityStartTrigger, + InitializeGridAgentTrigger, + StartGridSimulationTrigger +} import edu.ie3.util.TimeUtil import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import scala.jdk.CollectionConverters.CollectionHasAsScala import scala.language.postfixOps object GridAgent { @@ -39,33 +49,7 @@ object GridAgent { listener ) ) - - private def failFast( - gridAgentInitData: GridAgentInitData, - simonaConfig: SimonaConfig, - ): Unit = { - - /** Check if there is InitData for superior or inferior GridGates - */ - if ( - gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty - ) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + - s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" - ) - - /** Check if there exits voltage measurements for transformerControlGroups - */ - val measurementUnitInput = gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits - val maybeControlConfig: Option[SimonaConfig.Simona.Control] = simonaConfig.simona.control - if (maybeControlConfig.isDefined && !measurementUnitInput.asScala.exists(input => input.getVMag)) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a control group with measurement that don't deliver voltage magnitude." - ) - } } - class GridAgent( val environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, @@ -121,7 +105,7 @@ class GridAgent( _ ) => // fail fast sanity checks - GridAgent.failFast(gridAgentInitData, simonaConfig) + GridAgentFailFast.failFast(gridAgentInitData, simonaConfig) log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala new file mode 100644 index 0000000000..9d1d411abc --- /dev/null +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -0,0 +1,46 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.agent.grid + +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.exceptions.agent.GridAgentInitializationException +import scala.jdk.CollectionConverters.CollectionHasAsScala + +case object GridAgentFailFast { + + def failFast( + gridAgentInitData: GridAgentInitData, + simonaConfig: SimonaConfig + ): Unit = { + + /** Check if there is InitData for superior or inferior GridGates + */ + if ( + gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty + ) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" + ) + + /** Check if there exits voltage measurements for transformerControlGroups + */ + val measurementUnitInput = + gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits + val maybeControlConfig: Option[SimonaConfig.Simona.Control] = + simonaConfig.simona.control + if ( + maybeControlConfig.isDefined && !measurementUnitInput.asScala.exists( + input => input.getVMag + ) + ) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a control group with measurement that don't deliver voltage magnitude." + ) + } +} From 4d0e826d57cfe21a36e2b38ef8737598736d3f33 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 5 Jul 2022 14:58:42 +0200 Subject: [PATCH 024/305] fastfail check voltage measurement of transformerControlGroups --- .../simona/agent/grid/GridAgentFailFast.scala | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 9d1d411abc..fafe56a1e3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -9,7 +9,9 @@ package edu.ie3.simona.agent.grid import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException -import scala.jdk.CollectionConverters.CollectionHasAsScala + +import java.util.UUID +import scala.jdk.CollectionConverters._ case object GridAgentFailFast { @@ -30,17 +32,29 @@ case object GridAgentFailFast { /** Check if there exits voltage measurements for transformerControlGroups */ - val measurementUnitInput = - gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits + val maybeControlConfig: Option[SimonaConfig.Simona.Control] = simonaConfig.simona.control - if ( - maybeControlConfig.isDefined && !measurementUnitInput.asScala.exists( - input => input.getVMag + + val measurementUnits = + gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits.asScala + + maybeControlConfig.foreach(control => + control.transformer.foreach(transformer => + transformer.measurements.map(UUID.fromString).foreach { measurements => + val measurementUnit = measurementUnits + .find(element => element.getUuid == measurements) + .getOrElse( + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." + ) + ) + if (!measurementUnit.getVMag) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + ) + } ) ) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a control group with measurement that don't deliver voltage magnitude." - ) } } From 9be075db378dcce949b19db7be6895df5a282256 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 5 Jul 2022 18:06:36 +0200 Subject: [PATCH 025/305] update fastfail check voltage measurement of transformerControlGroups --- .../simona/agent/grid/GridAgentFailFast.scala | 60 ++++++++++++++----- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index fafe56a1e3..4905bb141f 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -39,22 +39,50 @@ case object GridAgentFailFast { val measurementUnits = gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits.asScala - maybeControlConfig.foreach(control => - control.transformer.foreach(transformer => - transformer.measurements.map(UUID.fromString).foreach { measurements => - val measurementUnit = measurementUnits - .find(element => element.getUuid == measurements) - .getOrElse( - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." - ) - ) - if (!measurementUnit.getVMag) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." - ) - } + val transformerUnits2W = + gridAgentInitData.subGridContainer.getRawGrid.getTransformer2Ws.asScala + + if (maybeControlConfig.isDefined) { + /* + maybeControlConfig.foreach(control => + control.transformer.foreach(transformer => + transformer.transformers.map(UUID.fromString).foreach { + transformers => + val transformerUnit = transformerUnits2W + .find(element => element.getUuid == transformers) + + + if(transformerUnit.isDefined) + + */ + maybeControlConfig.foreach(control => + control.transformer.foreach(transformer => + transformer.transformers.map(UUID.fromString).foreach { + transformers => + // Check if transformer is part of subgrid of this GridAgent + val transformerUnit = transformerUnits2W + .find(element => element.getUuid == transformers) + if (transformerUnit.isDefined) { + + transformer.measurements + .map(UUID.fromString) + .foreach { measurements => + val measurementUnit = measurementUnits + .find(element => element.getUuid == measurements) + .getOrElse( + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." + ) + ) + if (!measurementUnit.getVMag) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + ) + } + } + } + ) ) - ) + } } } From 92a00be2ece4391633e0c9be9810f784ac20fd74 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Tue, 5 Jul 2022 18:11:13 +0200 Subject: [PATCH 026/305] update also for 3Wtransformers --- .../simona/agent/grid/GridAgentFailFast.scala | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 4905bb141f..09217d5c6e 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -42,27 +42,20 @@ case object GridAgentFailFast { val transformerUnits2W = gridAgentInitData.subGridContainer.getRawGrid.getTransformer2Ws.asScala - if (maybeControlConfig.isDefined) { - /* - maybeControlConfig.foreach(control => - control.transformer.foreach(transformer => - transformer.transformers.map(UUID.fromString).foreach { - transformers => - val transformerUnit = transformerUnits2W - .find(element => element.getUuid == transformers) + val transformerUnits3W = + gridAgentInitData.subGridContainer.getRawGrid.getTransformer3Ws.asScala - - if(transformerUnit.isDefined) - - */ + if (maybeControlConfig.isDefined) { maybeControlConfig.foreach(control => control.transformer.foreach(transformer => transformer.transformers.map(UUID.fromString).foreach { transformers => // Check if transformer is part of subgrid of this GridAgent - val transformerUnit = transformerUnits2W + val transformerUnit2W = transformerUnits2W + .find(element => element.getUuid == transformers) + val transformerUnit3W = transformerUnits3W .find(element => element.getUuid == transformers) - if (transformerUnit.isDefined) { + if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { transformer.measurements .map(UUID.fromString) From b58d2295f2e2963fe7efd23925756e6d058727f3 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:59:07 +0200 Subject: [PATCH 027/305] rollback remove of scalingfactor --- .../edu/ie3/simona/model/participant/SystemParticipant.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 8eb4e6b966..77c2e11eff 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -105,7 +105,7 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( def activeToReactivePowerFunc( nodalVoltage: ComparableQuantity[Dimensionless] ): ComparableQuantity[Power] => ComparableQuantity[Power] = - qControl.activeToReactivePowerFunc(sRated, cosPhiRated, nodalVoltage) + qControl.activeToReactivePowerFunc(sRated.multiply(scalingFactor), cosPhiRated, nodalVoltage) /** Calculate the reactive power of the model * From cd7d7b6faeaf226c9821677c4ac784bf14013ba7 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 8 Jul 2022 13:19:53 +0200 Subject: [PATCH 028/305] spotless --- .../ie3/simona/model/participant/SystemParticipant.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 77c2e11eff..3331b2280d 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -105,7 +105,11 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( def activeToReactivePowerFunc( nodalVoltage: ComparableQuantity[Dimensionless] ): ComparableQuantity[Power] => ComparableQuantity[Power] = - qControl.activeToReactivePowerFunc(sRated.multiply(scalingFactor), cosPhiRated, nodalVoltage) + qControl.activeToReactivePowerFunc( + sRated.multiply(scalingFactor), + cosPhiRated, + nodalVoltage + ) /** Calculate the reactive power of the model * From 17d4273ba3b97b931dec869aac240c0d8d6fa45a Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 8 Jul 2022 18:22:30 +0200 Subject: [PATCH 029/305] adapt to name change of BdewLoadModel --- .../load/ProfileLoadModelSpec.scala | 25 ++++++++----------- .../load/RandomLoadModelSpec.scala | 19 ++++---------- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index a4140fab4b..9588dc2695 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -6,17 +6,14 @@ package edu.ie3.simona.model.participant.load +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.{NodeInput, OperatorInput} +import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} -import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -47,7 +44,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { -1 ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), @@ -72,36 +69,36 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { Table( ("profile", "reference", "expectedsRated"), ( - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, ActivePower(Quantities.getQuantity(268.6, Units.WATT)), Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) ), ( - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, EnergyConsumption( Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) ), Quantities.getQuantity(848.22, PowerSystemUnits.VOLTAMPERE) ), ( - BdewLoadProfile.L0, + BdewStandardLoadProfile.L0, ActivePower(Quantities.getQuantity(268.6, Units.WATT)), Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) ), ( - BdewLoadProfile.L0, + BdewStandardLoadProfile.L0, EnergyConsumption( Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) ), Quantities.getQuantity(759.158, PowerSystemUnits.VOLTAMPERE) ), ( - BdewLoadProfile.G0, + BdewStandardLoadProfile.G0, ActivePower(Quantities.getQuantity(268.6, Units.WATT)), Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) ), ( - BdewLoadProfile.G0, + BdewStandardLoadProfile.G0, EnergyConsumption( Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) ), @@ -110,7 +107,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { ) ) { (profile, reference, expectedSRated) => val actual = ProfileLoadModel( - loadInput.copy().standardLoadProfile(profile).build(), + loadInput.copy().loadprofile(profile).build(), foreSeenOperationInterval, 1.0, reference diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index a32cc4e5a9..f1878da3d5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -7,34 +7,25 @@ package edu.ie3.simona.model.participant.load import de.lmu.ifi.dbs.elki.math.statistics.distribution.GeneralizedExtremeValueDistribution +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.{NodeInput, OperatorInput} +import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.datamodel.models.{BdewLoadProfile, OperationTime} -import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} -import edu.ie3.simona.model.participant.load.random.{ - RandomLoadModel, - RandomLoadParameters -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParameters} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks -import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities import tech.units.indriya.unit.Units -import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Dimensionless, Energy, Power} class RandomLoadModelSpec extends UnitSpec @@ -59,7 +50,7 @@ class RandomLoadModelSpec -1 ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - BdewLoadProfile.H0, + BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), From 0fe62ce825bf75cc2a9340bb2ae7136551411c06 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:14:52 +0200 Subject: [PATCH 030/305] change case object to object class --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 09217d5c6e..43dbfc48df 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -13,7 +13,7 @@ import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import java.util.UUID import scala.jdk.CollectionConverters._ -case object GridAgentFailFast { +object GridAgentFailFast { def failFast( gridAgentInitData: GridAgentInitData, From e941d9bdbc20ffbd0d989583bb1ef204ad1be1da Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:16:58 +0200 Subject: [PATCH 031/305] remove unnecessarfy if statement --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 43dbfc48df..14336608b6 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -45,8 +45,7 @@ object GridAgentFailFast { val transformerUnits3W = gridAgentInitData.subGridContainer.getRawGrid.getTransformer3Ws.asScala - if (maybeControlConfig.isDefined) { - maybeControlConfig.foreach(control => + maybeControlConfig.foreach(control => control.transformer.foreach(transformer => transformer.transformers.map(UUID.fromString).foreach { transformers => @@ -76,6 +75,6 @@ object GridAgentFailFast { } ) ) - } + } } From 9305f5c5df5fd7bdb1001316a298e8960b6e190f Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:19:01 +0200 Subject: [PATCH 032/305] renaming subjects in foreach loops --- .../ie3/simona/agent/grid/GridAgentFailFast.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 14336608b6..3cfee1e1f8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -46,17 +46,17 @@ object GridAgentFailFast { gridAgentInitData.subGridContainer.getRawGrid.getTransformer3Ws.asScala maybeControlConfig.foreach(control => - control.transformer.foreach(transformer => - transformer.transformers.map(UUID.fromString).foreach { - transformers => + control.transformer.foreach(controlGroup => + controlGroup.transformers.map(UUID.fromString).foreach { + transformer => // Check if transformer is part of subgrid of this GridAgent val transformerUnit2W = transformerUnits2W - .find(element => element.getUuid == transformers) + .find(element => element.getUuid == transformer) val transformerUnit3W = transformerUnits3W - .find(element => element.getUuid == transformers) + .find(element => element.getUuid == transformer) if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { - transformer.measurements + controlGroup.measurements .map(UUID.fromString) .foreach { measurements => val measurementUnit = measurementUnits @@ -75,6 +75,6 @@ object GridAgentFailFast { } ) ) - + } } From 581d5802b32b8cf9e91b21945fe0ca765ed19023 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:20:14 +0200 Subject: [PATCH 033/305] Update src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala commit from review, direct apply of variable Co-authored-by: Sebastian Peter --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 09217d5c6e..6e0036b254 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -52,7 +52,7 @@ case object GridAgentFailFast { transformers => // Check if transformer is part of subgrid of this GridAgent val transformerUnit2W = transformerUnits2W - .find(element => element.getUuid == transformers) + .find(_.getUuid == transformer) val transformerUnit3W = transformerUnits3W .find(element => element.getUuid == transformers) if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { From 8b7b93da1bdcdb482a71888d51928033d849bf0e Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:22:52 +0200 Subject: [PATCH 034/305] change to direct apply of variable --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index fe34f56e05..0136772cda 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -53,14 +53,14 @@ object GridAgentFailFast { val transformerUnit2W = transformerUnits2W .find(_.getUuid == transformer) val transformerUnit3W = transformerUnits3W - .find(element => element.getUuid == transformer) + .find(_.getUuid == transformer) if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { controlGroup.measurements .map(UUID.fromString) .foreach { measurements => val measurementUnit = measurementUnits - .find(element => element.getUuid == measurements) + .find(_.getUuid == measurements) .getOrElse( throw new GridAgentInitializationException( s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." From 24793fd4db07050b30a677fad69323524c629a6f Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:23:51 +0200 Subject: [PATCH 035/305] singular measurment --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 0136772cda..a24e509e0e 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -58,9 +58,9 @@ object GridAgentFailFast { controlGroup.measurements .map(UUID.fromString) - .foreach { measurements => + .foreach { measurement => val measurementUnit = measurementUnits - .find(_.getUuid == measurements) + .find(_.getUuid == measurement) .getOrElse( throw new GridAgentInitializationException( s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." From dae0ea4e83f42fd7b025a3a0aadc09232824fca7 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:25:29 +0200 Subject: [PATCH 036/305] Update src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala more explicid test description 1 Co-authored-by: Sebastian Peter --- src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 64cd61890f..761f69f613 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -976,7 +976,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { }.getMessage shouldBe s"The minimum permissible voltage magnitude of a transformer control group (${dut.toString}) must be smaller than the maximum permissible voltage magnitude." } - "throw Exception when vMin is lower then -21% of nominal Voltage" in { + "throw Exception if vMin is lower than -20% of nominal Voltage" in { val dut = TransformerControlGroup( List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), From 027d6d3c443b04e8660739dd400c2f20107ebdb1 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:25:43 +0200 Subject: [PATCH 037/305] Update src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala more explicid test description 2 Co-authored-by: Sebastian Peter --- src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 761f69f613..67b6bb055f 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -990,7 +990,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" } - "throw Exception when vMax is higher then +21% of nominal Voltage" in { + "throw Exception if vMax is higher than +20% of nominal Voltage" in { val dut = TransformerControlGroup( List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), From 05c5e36073bd098c52e165931c4a0f32ea084f7e Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:27:17 +0200 Subject: [PATCH 038/305] remove unnecessary imports --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 26e198f0d7..42199475d7 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -11,8 +11,6 @@ import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.MeasurementUnitInput -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} @@ -23,9 +21,6 @@ import edu.ie3.simona.test.common.model.grid.{ FiveLinesWithNodes } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} -import testutils.TestObjectFactory - -import scala.jdk.CollectionConverters.SetHasAsJava class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { From 14b046957ae6996d44022e51d2fca217cbaca667 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Thu, 14 Jul 2022 20:29:18 +0200 Subject: [PATCH 039/305] spotless --- .../simona/agent/grid/GridAgentFailFast.scala | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index a24e509e0e..1e82c39e81 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -46,35 +46,34 @@ object GridAgentFailFast { gridAgentInitData.subGridContainer.getRawGrid.getTransformer3Ws.asScala maybeControlConfig.foreach(control => - control.transformer.foreach(controlGroup => - controlGroup.transformers.map(UUID.fromString).foreach { - transformer => - // Check if transformer is part of subgrid of this GridAgent - val transformerUnit2W = transformerUnits2W - .find(_.getUuid == transformer) - val transformerUnit3W = transformerUnits3W - .find(_.getUuid == transformer) - if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { + control.transformer.foreach(controlGroup => + controlGroup.transformers.map(UUID.fromString).foreach { transformer => + // Check if transformer is part of subgrid of this GridAgent + val transformerUnit2W = transformerUnits2W + .find(_.getUuid == transformer) + val transformerUnit3W = transformerUnits3W + .find(_.getUuid == transformer) + if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { - controlGroup.measurements - .map(UUID.fromString) - .foreach { measurement => - val measurementUnit = measurementUnits - .find(_.getUuid == measurement) - .getOrElse( - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." - ) - ) - if (!measurementUnit.getVMag) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." - ) - } + controlGroup.measurements + .map(UUID.fromString) + .foreach { measurement => + val measurementUnit = measurementUnits + .find(_.getUuid == measurement) + .getOrElse( + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." + ) + ) + if (!measurementUnit.getVMag) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + ) } } - ) + } ) + ) } } From bf36273e687fb6323ed3dc66e0ea71a1f90a0059 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 15 Jul 2022 08:04:53 +0200 Subject: [PATCH 040/305] Scala Doc --- .../simona/agent/grid/GridAgentFailFast.scala | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 1e82c39e81..ffd588ad6d 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -6,6 +6,7 @@ package edu.ie3.simona.agent.grid +import edu.ie3.datamodel.models.input.container.SubGridContainer import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException @@ -15,6 +16,13 @@ import scala.jdk.CollectionConverters._ object GridAgentFailFast { + /** FailFast Check of GridAgent at Initialisation + * @param gridAgentInitData + * Data that is send to the [[GridAgent]] directly after startup. It + * contains the main information for initialization. + * @param simonaConfig + * the config that should be checked + */ def failFast( gridAgentInitData: GridAgentInitData, simonaConfig: SimonaConfig @@ -33,17 +41,34 @@ object GridAgentFailFast { /** Check if there exits voltage measurements for transformerControlGroups */ - val maybeControlConfig: Option[SimonaConfig.Simona.Control] = + checkControlGroupsForMeasurement( + gridAgentInitData.subGridContainer, simonaConfig.simona.control + ) + } + + /** Checks all ControlGroups if a) Transformer of ControlGroup and Measurement + * belongs to the same sub grid. b) Measurements are measure voltage + * magnitude. + * + * @param subGridContainer + * Container of all models for this sub grid + * @param maybeControlConfig + * Config of ControlGroup + */ + def checkControlGroupsForMeasurement( + subGridContainer: SubGridContainer, + maybeControlConfig: Option[SimonaConfig.Simona.Control] + ): Unit = { val measurementUnits = - gridAgentInitData.subGridContainer.getRawGrid.getMeasurementUnits.asScala + subGridContainer.getRawGrid.getMeasurementUnits.asScala val transformerUnits2W = - gridAgentInitData.subGridContainer.getRawGrid.getTransformer2Ws.asScala + subGridContainer.getRawGrid.getTransformer2Ws.asScala val transformerUnits3W = - gridAgentInitData.subGridContainer.getRawGrid.getTransformer3Ws.asScala + subGridContainer.getRawGrid.getTransformer3Ws.asScala maybeControlConfig.foreach(control => control.transformer.foreach(controlGroup => @@ -62,18 +87,17 @@ object GridAgentFailFast { .find(_.getUuid == measurement) .getOrElse( throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." ) ) if (!measurementUnit.getVMag) throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." ) } } } ) ) - } } From 2cc9e4083df1b08b62cf03b806c4331555fd3327 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 15 Jul 2022 08:16:31 +0200 Subject: [PATCH 041/305] More Scala Doc --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index ffd588ad6d..665430856b 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -73,13 +73,15 @@ object GridAgentFailFast { maybeControlConfig.foreach(control => control.transformer.foreach(controlGroup => controlGroup.transformers.map(UUID.fromString).foreach { transformer => - // Check if transformer is part of subgrid of this GridAgent val transformerUnit2W = transformerUnits2W .find(_.getUuid == transformer) val transformerUnit3W = transformerUnits3W .find(_.getUuid == transformer) + /** In order to check that the measurements are located in the subgrid + * of this GridAgent, it is first checked if the transformer belongs + * to this GridAgent and is therefore part of this subgrid. + */ if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { - controlGroup.measurements .map(UUID.fromString) .foreach { measurement => From 4abfe3898ff49ceaecefe3818b23b7f13dd44b15 Mon Sep 17 00:00:00 2001 From: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> Date: Fri, 15 Jul 2022 08:22:52 +0200 Subject: [PATCH 042/305] even more Scala Doc --- .../scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala | 1 + src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 665430856b..27d8d216c8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -77,6 +77,7 @@ object GridAgentFailFast { .find(_.getUuid == transformer) val transformerUnit3W = transformerUnits3W .find(_.getUuid == transformer) + /** In order to check that the measurements are located in the subgrid * of this GridAgent, it is first checked if the transformer belongs * to this GridAgent and is therefore part of this subgrid. diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index b068411a6d..dd3cf4cf84 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -567,7 +567,8 @@ case object ConfigFailFast extends LazyLogging { * * One important check cannot be performed at this place, as input data is * not available, yet: Do the measurements belong to a region, that can be - * influenced by the transformer? + * influenced by the transformer? This is partly addressed in + * [[edu.ie3.simona.agent.grid.GridAgentFailFast]] * * @param transformerControlGroup * Transformer control group definition From 10e066e544da5c1fa34016176fe729bd346336c7 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 3 Aug 2022 13:48:46 +0200 Subject: [PATCH 043/305] generate SimonaConfig and spotless --- .../edu/ie3/simona/config/SimonaConfig.scala | 39 +++++++++++++++++++ .../simona/config/ConfigFailFastSpec.scala | 6 ++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 3133b193c7..ca4f958fb3 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -675,6 +675,45 @@ object SimonaConfig { } + final case class TransformerControlGroup( + measurements: scala.List[java.lang.String], + transformers: scala.List[java.lang.String], + vMax: scala.Double, + vMin: scala.Double + ) + object TransformerControlGroup { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.TransformerControlGroup = { + SimonaConfig.TransformerControlGroup( + measurements = + $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = + $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + ) + } + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { + if (c == null) 0 + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } + } + + } + final case class VoltLvlConfig( id: java.lang.String, vNom: java.lang.String diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 13f7a7103b..b1db4feeb4 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -12,7 +12,11 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.{Csv, InfluxDb1x} import edu.ie3.simona.config.SimonaConfig.Simona.Powerflow.Newtonraphson import edu.ie3.simona.config.SimonaConfig.Simona.{Powerflow, Time} -import edu.ie3.simona.config.SimonaConfig.{BaseCsvParams, ResultKafkaParams, TransformerControlGroup} +import edu.ie3.simona.config.SimonaConfig.{ + BaseCsvParams, + ResultKafkaParams, + TransformerControlGroup +} import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec} import edu.ie3.simona.util.ConfigUtil.{CsvConfigUtil, NotifierIdentifier} From c446b9b9b19e1e93d37a32fca4c308620c80443d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 3 Aug 2022 14:00:10 +0200 Subject: [PATCH 044/305] change gradletasks to name change of simona-config-template --- gradle/scripts/tscfg.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/scripts/tscfg.gradle b/gradle/scripts/tscfg.gradle index e81ad99320..d9ee8bca7b 100644 --- a/gradle/scripts/tscfg.gradle +++ b/gradle/scripts/tscfg.gradle @@ -15,7 +15,7 @@ task genConfigClass { args = [ "build/tscfg-${tscfgVersion}.jar", "--spec", - "src/main/resources/config/config-template.conf", + "src/main/resources/config/simona-config-template.conf", "--scala", "--durations", "--pn", @@ -47,7 +47,7 @@ task genConfigSample { args = [ "build/tscfg-${tscfgVersion}.jar", "--spec", - "src/main/resources/config/config-template.conf", + "src/main/resources/config/simona-config-template.conf", "--tpl", "input/samples/configSample.conf" ] From 26a4b8317d01545788b804d34c9de2fe46d9f3ca Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 3 Aug 2022 14:03:06 +0200 Subject: [PATCH 045/305] generate SimonaConfig and spotless --- .../edu/ie3/simona/config/SimonaConfig.scala | 75 +++++++++++++++++++ .../simona/config/ConfigFailFastSpec.scala | 6 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 1ace3e57f9..ca4f958fb3 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -675,6 +675,45 @@ object SimonaConfig { } + final case class TransformerControlGroup( + measurements: scala.List[java.lang.String], + transformers: scala.List[java.lang.String], + vMax: scala.Double, + vMin: scala.Double + ) + object TransformerControlGroup { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.TransformerControlGroup = { + SimonaConfig.TransformerControlGroup( + measurements = + $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = + $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + ) + } + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { + if (c == null) 0 + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } + } + + } + final case class VoltLvlConfig( id: java.lang.String, vNom: java.lang.String @@ -769,6 +808,7 @@ object SimonaConfig { } final case class Simona( + control: scala.Option[SimonaConfig.Simona.Control], event: SimonaConfig.Simona.Event, gridConfig: SimonaConfig.Simona.GridConfig, input: SimonaConfig.Simona.Input, @@ -779,6 +819,41 @@ object SimonaConfig { time: SimonaConfig.Simona.Time ) object Simona { + final case class Control( + transformer: scala.List[SimonaConfig.TransformerControlGroup] + ) + object Control { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Control = { + SimonaConfig.Simona.Control( + transformer = $_LSimonaConfig_TransformerControlGroup( + c.getList("transformer"), + parentPath, + $tsCfgValidator + ) + ) + } + private def $_LSimonaConfig_TransformerControlGroup( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.TransformerControlGroup] = { + import scala.jdk.CollectionConverters._ + cl.asScala + .map(cv => + SimonaConfig.TransformerControlGroup( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList + } + } + final case class Event( listener: scala.Option[ scala.List[SimonaConfig.Simona.Event.Listener$Elm] diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 42de85365e..d83aa551e0 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -12,7 +12,11 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.{Csv, InfluxDb1x} import edu.ie3.simona.config.SimonaConfig.Simona.Powerflow.Newtonraphson import edu.ie3.simona.config.SimonaConfig.Simona.{Powerflow, Time} -import edu.ie3.simona.config.SimonaConfig.{BaseCsvParams, ResultKafkaParams, TransformerControlGroup} +import edu.ie3.simona.config.SimonaConfig.{ + BaseCsvParams, + ResultKafkaParams, + TransformerControlGroup +} import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec} import edu.ie3.simona.util.ConfigUtil.{CsvConfigUtil, NotifierIdentifier} From f36c5b290497717fa66149d110eddcbaaf061468 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 6 Sep 2022 12:40:39 +0200 Subject: [PATCH 046/305] merge --- .../edu/ie3/simona/model/grid/GridModel.scala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 9f5e0ac83e..5e49eba51e 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -9,11 +9,15 @@ package edu.ie3.simona.model.grid import breeze.linalg.DenseMatrix import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} -import edu.ie3.datamodel.models.input.connector._ +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup +import edu.ie3.datamodel.models.input.MeasurementUnitInput +import edu.ie3.datamodel.models.input.connector.{ + ConnectorInput, + ConnectorPort, + Transformer3WInput +} import edu.ie3.datamodel.models.input.container.SubGridContainer import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} @@ -22,9 +26,6 @@ import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseB, PowerFlowCaseC } -import edu.ie3.simona.model.control.{ - TransformerControlGroup => ControlGroupModel -} import edu.ie3.simona.util.CollectionUtils import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph @@ -32,6 +33,9 @@ import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities +import edu.ie3.simona.model.control.{ + TransformerControlGroup => ControlGroupModel +} import java.time.ZonedDateTime import java.util.UUID From 4a61fa451b44527d3e7aff529e71f2220578d511 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 8 Feb 2023 14:37:51 +0100 Subject: [PATCH 047/305] rtd for transformer control groups --- docs/readthedocs/measurement_control.md | 9 +++++++++ docs/readthedocs/models.md | 6 ++++++ 2 files changed, 15 insertions(+) create mode 100644 docs/readthedocs/measurement_control.md diff --git a/docs/readthedocs/measurement_control.md b/docs/readthedocs/measurement_control.md new file mode 100644 index 0000000000..11b2a4ba07 --- /dev/null +++ b/docs/readthedocs/measurement_control.md @@ -0,0 +1,9 @@ +(measurement_control)= + +# Measurement and Control + +This page gives an overview of available Measurement and Control functions in *SIMONA*. + +## Transformer Control groups + +Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index 482d2abd15..ec65d0cbc4 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -31,3 +31,9 @@ models/load_model models/pv_model models/wec_model ``` + +## Measurement and Control +```{toctree} +--- +maxdepth: 1 +--- \ No newline at end of file From 6eaf9fdb09788b061147b8ccdaf3b3fb25a2f53b Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 8 Feb 2023 14:44:18 +0100 Subject: [PATCH 048/305] rtd for transformer control groups --- docs/readthedocs/models.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index ec65d0cbc4..fd1fb07e84 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -36,4 +36,5 @@ models/wec_model ```{toctree} --- maxdepth: 1 ---- \ No newline at end of file +--- +measurement_control From 5107c506af952855dd5d7db4d96706709d2c729e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 8 Feb 2023 14:50:11 +0100 Subject: [PATCH 049/305] rtd for transformer control groups --- docs/readthedocs/measurement_control.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/readthedocs/measurement_control.md b/docs/readthedocs/measurement_control.md index 11b2a4ba07..8913f2a753 100644 --- a/docs/readthedocs/measurement_control.md +++ b/docs/readthedocs/measurement_control.md @@ -1,9 +1,5 @@ -(measurement_control)= +(transformer_control_groups)= -# Measurement and Control - -This page gives an overview of available Measurement and Control functions in *SIMONA*. - -## Transformer Control groups +# Transformer Control groups Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer From 0bf2e69ea046f6ff4232428e68014ab1bb4f6f42 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 8 Feb 2023 14:52:29 +0100 Subject: [PATCH 050/305] typo --- docs/readthedocs/measurement_control.md | 2 +- docs/readthedocs/models.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/readthedocs/measurement_control.md b/docs/readthedocs/measurement_control.md index 8913f2a753..243ed82975 100644 --- a/docs/readthedocs/measurement_control.md +++ b/docs/readthedocs/measurement_control.md @@ -1,5 +1,5 @@ (transformer_control_groups)= -# Transformer Control groups +# Transformer Control Groups Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index fd1fb07e84..6981a8e308 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -37,4 +37,4 @@ models/wec_model --- maxdepth: 1 --- -measurement_control +transformer_control_groups From be6f3a9cfe161d686db9d93036eb2bf0a6650b0c Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 11:10:37 +0100 Subject: [PATCH 051/305] typo --- docs/readthedocs/models.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index 6981a8e308..402b66908b 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -38,3 +38,4 @@ models/wec_model maxdepth: 1 --- transformer_control_groups +``` \ No newline at end of file From 106ef522e4686230dc2451aa751363e0d0e92aab Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 11:25:35 +0100 Subject: [PATCH 052/305] rtd --- docs/readthedocs/measurement_control.md | 4 ++-- docs/readthedocs/models.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/readthedocs/measurement_control.md b/docs/readthedocs/measurement_control.md index 243ed82975..e57238d6a6 100644 --- a/docs/readthedocs/measurement_control.md +++ b/docs/readthedocs/measurement_control.md @@ -1,5 +1,5 @@ -(transformer_control_groups)= +(measurement_control)= # Transformer Control Groups -Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer +Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer. diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index 402b66908b..0dcd569d64 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -37,5 +37,5 @@ models/wec_model --- maxdepth: 1 --- -transformer_control_groups -``` \ No newline at end of file +measurement_control +``` From d89b3a2ee6e6ce908323ba11f7dd39924a74d0a5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 14:01:44 +0100 Subject: [PATCH 053/305] fix test --- .../model/participant/load/RandomLoadModelTest.groovy | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index d22625f364..851ca94f52 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -139,7 +139,7 @@ class RandomLoadModelTest extends Specification { startDate.plus(cnt * 15, ChronoUnit.MINUTES)) }).collect(Collectors.toSet()) - when: + and: def avgEnergy = (0..10).parallelStream().mapToDouble( { runCnt -> relevantDatas.parallelStream().mapToDouble( @@ -147,11 +147,6 @@ class RandomLoadModelTest extends Specification { (dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)).asType(Energy).to(KILOWATTHOUR).value.doubleValue() }).sum() }).average().orElse(0d) + avgEnergy } } - - def get95Quantile(Double[] sortedArray) { - def quantIdx = sortedArray.length * 0.95 as int - sortedArray[quantIdx] - } -} \ No newline at end of file From 5d9797bff42a33cf436eeabe779291e2f286b6f4 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 14:29:08 +0100 Subject: [PATCH 054/305] spotless --- .../model/participant/ChpModelTest.groovy | 14 +- .../model/participant/HpModelTest.groovy | 14 +- .../load/RandomLoadModelTest.groovy | 170 +++++++++--------- 3 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy index e878e7a9a1..d2888fe40e 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy @@ -214,13 +214,13 @@ class ChpModelTest extends Specification { def thermalStorage = buildThermalStorage(storageInput, 90) def chpModelCaseClass = buildChpModel(thermalStorage) def startDate = TimeUtil.withDefaults.toZonedDateTime("2021-01-01 00:00:00") - def endDate = startDate.plusSeconds(86400L) - def chpModelCaseObject = ChpModel.apply( - chpInput, - startDate, - endDate, - null, - 1.0, + def endDate = startDate.plusSeconds(86400L) + def chpModelCaseObject = ChpModel.apply( + chpInput, + startDate, + endDate, + null, + 1.0, thermalStorage) then: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy index b0a9fecc04..29f4d03450 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy @@ -152,13 +152,13 @@ class HpModelTest extends Specification { def thermalHouse = buildThermalHouse(18, 22) def hpModelCaseClass = buildStandardModel(thermalHouse) def startDate = TimeUtil.withDefaults.toZonedDateTime("2021-01-01 00:00:00") - def endDate = startDate.plusSeconds(86400L) - def hpModelCaseObject = HpModel.apply( - hpInput, - startDate, - endDate, - null, - 1.0, + def endDate = startDate.plusSeconds(86400L) + def hpModelCaseObject = HpModel.apply( + hpInput, + startDate, + endDate, + null, + 1.0, thermalHouse) then: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index 851ca94f52..d96248a928 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -33,49 +33,49 @@ import static tech.units.indriya.unit.Units.MINUTE import static tech.units.indriya.unit.Units.WATT class RandomLoadModelTest extends Specification { - def loadInput = - new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) - - def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) - def testingTolerance = 1e-6 // Equals to 1 W power - - def "A random load model should be instantiated from valid input correctly"() { - when: - def actual = RandomLoadModel.apply( - loadInput, - foreSeenOperationInterval, - 1.0, - reference - ) + def loadInput = + new LoadInput( + UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), + "testLoad", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + new NodeInput( + UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), + "TestNodeInputModel", + OperatorInput.NO_OPERATOR_ASSIGNED, + OperationTime.notLimited(), + Quantities.getQuantity(1d, PU), + false, + NodeInput.DEFAULT_GEO_POSITION, + GermanVoltageLevelUtils.LV, + -1 + ), + new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), + H0, + false, + Quantities.getQuantity(3000d, KILOWATTHOUR), + Quantities.getQuantity(282.74d, VOLTAMPERE), + 0.95 + ) + + def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") + def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") + def foreSeenOperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + loadInput.operationTime + ) + def testingTolerance = 1e-6 // Equals to 1 W power + + def "A random load model should be instantiated from valid input correctly"() { + when: + def actual = RandomLoadModel.apply( + loadInput, + foreSeenOperationInterval, + 1.0, + reference + ) then: abs(actual.sRated().subtract(expSRated).getValue().doubleValue()) < testingTolerance @@ -86,21 +86,21 @@ class RandomLoadModelTest extends Specification { new EnergyConsumption(Quantities.getQuantity(2000d, KILOWATTHOUR)) || Quantities.getQuantity(467.156124576697, VOLTAMPERE) } - def "A random load model is able to deliver the correct distribution on request"() { - given: - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - /* Working day, 61th quarter hour */ - def queryDate = TimeUtil.withDefaults.toZonedDateTime('2019-07-19 15:21:00') - def expectedParams = new RandomLoadParameters(0.405802458524704, 0.0671483352780342, 0.0417016632854939) + def "A random load model is able to deliver the correct distribution on request"() { + given: + def dut = new RandomLoadModel( + loadInput.uuid, + loadInput.id, + foreSeenOperationInterval, + 1.0, + QControl.apply(loadInput.qCharacteristics), + loadInput.sRated, + loadInput.cosPhiRated, + new ActivePower(Quantities.getQuantity(268.6, WATT)) + ) + /* Working day, 61th quarter hour */ + def queryDate = TimeUtil.withDefaults.toZonedDateTime('2019-07-19 15:21:00') + def expectedParams = new RandomLoadParameters(0.405802458524704, 0.0671483352780342, 0.0417016632854939) when: /* First query leeds to generation of distribution */ @@ -121,32 +121,30 @@ class RandomLoadModelTest extends Specification { secondHit == firstHit } - def "A random load model should approx. reach the targeted annual energy consumption"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new RandomLoadModel.RandomRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - and: - def avgEnergy = (0..10).parallelStream().mapToDouble( - { runCnt -> - relevantDatas.parallelStream().mapToDouble( - { relevantData -> - (dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)).asType(Energy).to(KILOWATTHOUR).value.doubleValue() - }).sum() - }).average().orElse(0d) - avgEnergy - } + def "A random load model should approx. reach the targeted annual energy consumption"() { + given: + def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") + def dut = new RandomLoadModel( + loadInput.uuid, + loadInput.id, + foreSeenOperationInterval, + 1.0, + QControl.apply(loadInput.qCharacteristics), + loadInput.sRated, + loadInput.cosPhiRated, + new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) + ) + def relevantDatas = (0..35040).stream().map({ cnt -> + new RandomLoadModel.RandomRelevantData( + startDate.plus(cnt * 15, ChronoUnit.MINUTES)) + }).collect(Collectors.toSet()) + + and: + def avgEnergy = (0..10).parallelStream().mapToDouble( { runCnt -> + relevantDatas.parallelStream().mapToDouble( { relevantData -> + (dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)).asType(Energy).to(KILOWATTHOUR).value.doubleValue() + }).sum() + }).average().orElse(0d) + avgEnergy + } } From 72183edcfd18245a140be9deac1a8f88664561c2 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 14:33:29 +0100 Subject: [PATCH 055/305] spotless --- .../model/participant/load/ProfileLoadModelSpec.scala | 5 ++++- .../model/participant/load/RandomLoadModelSpec.scala | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index 9588dc2695..cf8d3da8b5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -13,7 +13,10 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index f1878da3d5..97d818357e 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -15,8 +15,14 @@ import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} -import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParameters} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} +import edu.ie3.simona.model.participant.load.random.{ + RandomLoadModel, + RandomLoadParameters +} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers import edu.ie3.util.TimeUtil From f7243164ab9758c40c2b46f387efa396fb01aa9f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 15 Mar 2023 15:39:15 +0100 Subject: [PATCH 056/305] fix scapegoat issue in LoadModelScalingSpec --- .../load/LoadModelScalingSpec.scala | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 45c1f35484..8e67458885 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -9,8 +9,8 @@ package edu.ie3.simona.model.participant.load import breeze.numerics.abs import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent @@ -126,9 +126,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .asType(classOf[Energy]) .to(PowerSystemUnits.KILOWATTHOUR) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) .divide(totalRuns) Quantities @@ -193,9 +197,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .asType(classOf[Energy]) .to(PowerSystemUnits.KILOWATTHOUR) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) .divide(totalRuns) Quantities @@ -391,9 +399,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .asType(classOf[Energy]) .to(PowerSystemUnits.KILOWATTHOUR) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) .divide(totalRuns) Quantities @@ -456,9 +468,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .asType(classOf[Energy]) .to(PowerSystemUnits.KILOWATTHOUR) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) } - .reduce((l, r) => l.add(r)) + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) .divide(totalRuns) Quantities From b4cba70a263fbcae5c6ef165c1e11e32398a9855 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 16 Mar 2023 09:23:07 +0100 Subject: [PATCH 057/305] double entry in changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8870fafdc9..2523c4c868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,7 +62,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updating `CONTRIBUTING.md` [#201](https://github.com/ie3-institute/simona/issues/201) - Speeding up additionalActivationTicks in participant's BaseStateData [#421](https://github.com/ie3-institute/simona/pull/421) - Changed format of example grid `vn_simona` [#216](https://github.com/ie3-institute/simona/issues/216) -- Updated authors in [#301](https://github.com/ie3-institute/simona/issues/301) - Respect for scaling factor when simulating the system participants [#81](https://github.com/ie3-institute/simona/issues/81) - Harmonize participant model instantiation [#81](https://github.com/ie3-institute/simona/issues/81) From b35e0f7bdda1f3f9dfe8a62988821c813b504b54 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 16 Mar 2023 09:24:56 +0100 Subject: [PATCH 058/305] scaling of ProfileLoadModel --- .../model/participant/load/profile/ProfileLoadModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index a952fb34dc..b271599a72 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -111,7 +111,7 @@ final case class ProfileLoadModel( .multiply(energyReferenceScalingFactor) .asType(classOf[Power]) } - activePower + activePower.multiply(scalingFactor) } } From e9a162113ff16dc6f0092af70d322710b59d8387 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:02:33 +0200 Subject: [PATCH 059/305] Test: Correctly account for the scaling factor, when targeting a given annual energy consumption --- .../load/LoadModelScalingSpec.scala | 142 ++++++++++++------ 1 file changed, 95 insertions(+), 47 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 8e67458885..7d6a6761fa 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -14,6 +14,7 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, @@ -27,9 +28,11 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks +import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities import tech.units.indriya.unit.Units +import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID import javax.measure.quantity.{Dimensionless, Energy} @@ -102,6 +105,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { EnergyConsumption(targetEnergyConsumption) ) dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> ProfileRelevantData( @@ -173,54 +177,12 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { EnergyConsumption(targetEnergyConsumption) ) dut.enable() - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(expectedEnergy) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) should beLessThanWithTolerance( + calculateAverageEnergy( + dut.asInstanceOf[LoadModel[LoadRelevantData]], + simulationStartDate, + expectedEnergy + ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 ) @@ -375,6 +337,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { EnergyConsumption(targetEnergyConsumption) ) dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> RandomLoadModel.RandomRelevantData( @@ -510,6 +473,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> RandomLoadModel.RandomRelevantData( @@ -602,4 +566,88 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } } + + def getRelevantDatas[T <: LoadModel[LoadRelevantData]]( + dut: LoadModel[LoadRelevantData], + simulationStartDate: ZonedDateTime + ): Map[Int, LoadRelevantData] = { + + if (dut.isInstanceOf[ProfileLoadModel]) { + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileLoadModel.ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + return relevantDatas + } + + if (dut.isInstanceOf[RandomLoadModel]) { + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + relevantDatas + } + else { + throw new IllegalArgumentException("Unknown load model type") + } + } + + def calculateAverageEnergy[T <: LoadModel[ProfileRelevantData]]( + dut: LoadModel[LoadRelevantData], + simulationStartDate: ZonedDateTime, + expectedEnergy: ComparableQuantity[Energy] + )= { + + val relevantDatas = getRelevantDatas(dut, simulationStartDate) + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) + } + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) + .divide(totalRuns) + + val result = Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(expectedEnergy) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) + result + } + + } From f4aeefc97539e97099cb03c39fa01763a67c2ba6 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:06:21 +0200 Subject: [PATCH 060/305] fmt --- .../load/LoadModelScalingSpec.scala | 102 +++++++++--------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 7d6a6761fa..70e3e59505 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -591,63 +591,61 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) ) .toMap - relevantDatas - } - else { + relevantDatas + } else { throw new IllegalArgumentException("Unknown load model type") } } - def calculateAverageEnergy[T <: LoadModel[ProfileRelevantData]]( - dut: LoadModel[LoadRelevantData], - simulationStartDate: ZonedDateTime, - expectedEnergy: ComparableQuantity[Energy] - )= { - - val relevantDatas = getRelevantDatas(dut, simulationStartDate) - - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - val result = Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(expectedEnergy) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT + def calculateAverageEnergy[T <: LoadModel[ProfileRelevantData]]( + dut: LoadModel[LoadRelevantData], + simulationStartDate: ZonedDateTime, + expectedEnergy: ComparableQuantity[Energy] + ): ComparableQuantity[Dimensionless] = { + + val relevantDatas = getRelevantDatas(dut, simulationStartDate) + + val totalRuns = 10 + val avgEnergy = (0 until totalRuns) + .map { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) + } + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) ) + } + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) + .divide(totalRuns) + + val result = Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgEnergy + .divide(expectedEnergy) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT ) - result - } - + ) + result + } } From de294d3678684cc81de338394e28ac01e8a01ee2 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:08:35 +0200 Subject: [PATCH 061/305] remove enableing dut --- .../ie3/simona/model/participant/load/LoadModelScalingSpec.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 70e3e59505..232c51c20a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -104,7 +104,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profile, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() val relevantDatas = (0 until 35040) .map(tick => From d658c4c4d891dcac7214a288511531e40b394ac3 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:13:10 +0200 Subject: [PATCH 062/305] remove enabling dut --- .../model/participant/load/LoadModelScalingSpec.scala | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 232c51c20a..cfb3c668c7 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -175,7 +175,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() calculateAverageEnergy( dut.asInstanceOf[LoadModel[LoadRelevantData]], @@ -210,7 +209,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profile, ActivePower(targetMaximumPower) ) - dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> ProfileRelevantData( @@ -258,7 +257,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) ) - dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> ProfileRelevantData( @@ -335,7 +334,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() val relevantDatas = (0 until 35040) .map(tick => @@ -405,7 +403,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> RandomLoadModel.RandomRelevantData( @@ -471,7 +469,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) - dut.enable() val relevantDatas = (0 until 35040) .map(tick => @@ -531,7 +528,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) - dut.enable() + val relevantDatas = (0 until 35040) .map(tick => tick -> RandomLoadModel.RandomRelevantData( From 5b280c3ac40839de4b6a7bc451b9d2317f9d5b8e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:29:43 +0200 Subject: [PATCH 063/305] further transfer of tests into methods --- .../load/LoadModelScalingSpec.scala | 189 +++--------------- 1 file changed, 24 insertions(+), 165 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index cfb3c668c7..5d7b9d8197 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -103,56 +103,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, profile, EnergyConsumption(targetEnergyConsumption) - ) - - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + ).asInstanceOf[LoadModel[LoadRelevantData]] - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(targetEnergyConsumption) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) should beLessThanWithTolerance( + calculateAverageEnergy( + dut, + simulationStartDate, + targetEnergyConsumption + ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 ) @@ -174,10 +131,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) - ) + ).asInstanceOf[LoadModel[LoadRelevantData]] calculateAverageEnergy( - dut.asInstanceOf[LoadModel[LoadRelevantData]], + dut, simulationStartDate, expectedEnergy ) should beLessThanWithTolerance( @@ -208,15 +165,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, profile, ActivePower(targetMaximumPower) - ) + ).asInstanceOf[LoadModel[LoadRelevantData]] - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + val relevantDatas = getRelevantDatas(dut, simulationStartDate) val totalRuns = 10 (0 until totalRuns).flatMap { _ => @@ -256,15 +207,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) - ) + ).asInstanceOf[LoadModel[LoadRelevantData]] - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + val relevantDatas = getRelevantDatas(dut, simulationStartDate) val totalRuns = 10 (0 until totalRuns).flatMap { _ => @@ -333,56 +278,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) - ) - - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + ).asInstanceOf[LoadModel[LoadRelevantData]] - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(targetEnergyConsumption) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) should beLessThanWithTolerance( + calculateAverageEnergy( + dut, + simulationStartDate, + targetEnergyConsumption + ) should beLessThanWithTolerance( Quantities.getQuantity(1d, Units.PERCENT), 1e-1 ) @@ -402,56 +304,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) - ) + ).asInstanceOf[LoadModel[LoadRelevantData]] - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(expectedEnergy) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) should beLessThanWithTolerance( + calculateAverageEnergy( + dut, + simulationStartDate, + expectedEnergy + ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 ) From 2146ea8e02cd5380f567d658199788a29a4c73e7 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:37:12 +0200 Subject: [PATCH 064/305] codacy avoid return --- .../ie3/simona/model/participant/load/LoadModelScalingSpec.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 5d7b9d8197..0a68e2590d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -435,7 +435,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) ) .toMap - return relevantDatas } if (dut.isInstanceOf[RandomLoadModel]) { From fbc0def8777f03aeeda5f18dab07a2bfb0481942 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 24 Apr 2023 14:56:35 +0200 Subject: [PATCH 065/305] method for avgPower --- .../load/LoadModelScalingSpec.scala | 145 ++++++++---------- 1 file changed, 66 insertions(+), 79 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 0a68e2590d..60ab62d91d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -35,7 +35,7 @@ import tech.units.indriya.unit.Units import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Dimensionless, Energy} +import javax.measure.quantity.{Dimensionless, Energy, Power} class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "Testing correct scaling of load models" when { @@ -327,46 +327,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) - ) - - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } - .sorted - .toArray + ).asInstanceOf[LoadModel[LoadRelevantData]] + val powers = + calculateAveragePower(dut, simulationStartDate, targetMaximumPower) val quantile95 = RandomLoadModelSpec.get95Quantile(powers) - Quantities.getQuantity( - abs( - 100 - - quantile95 - .divide(targetMaximumPower) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT + getRelativeResult( + quantile95.asInstanceOf[ComparableQuantity[Dimensionless]], + targetMaximumPower.asInstanceOf[ComparableQuantity[Dimensionless]] ) should beLessThanWithTolerance( Quantities.getQuantity(1d, Units.PERCENT), 1e-1 @@ -386,32 +355,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) - ) - - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + ).asInstanceOf[LoadModel[LoadRelevantData]] - val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(1d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } - .sorted - .toArray + val powers = + calculateAveragePower(dut, simulationStartDate, expectedMaximum) /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ RandomLoadModelSpec.get95Quantile(powers) should equalWithTolerance( @@ -451,6 +398,28 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } + def getRelativeResult( + avgResult: ComparableQuantity[Dimensionless], + expectedResult: ComparableQuantity[Dimensionless] + ): ComparableQuantity[Dimensionless] = { + val result = Quantities + .getQuantity(100, Units.PERCENT) + .subtract( + Quantities.getQuantity( + abs( + avgResult + .divide(expectedResult) + .asType(classOf[Dimensionless]) + .to(Units.PERCENT) + .getValue + .doubleValue() + ), + Units.PERCENT + ) + ) + result + } + def calculateAverageEnergy[T <: LoadModel[ProfileRelevantData]]( dut: LoadModel[LoadRelevantData], simulationStartDate: ZonedDateTime, @@ -484,22 +453,40 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) .divide(totalRuns) - val result = Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgEnergy - .divide(expectedEnergy) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) - result + getRelativeResult( + avgEnergy.asInstanceOf[ComparableQuantity[Dimensionless]], + expectedEnergy.asInstanceOf[ComparableQuantity[Dimensionless]] + ) + + } + + def calculateAveragePower[T <: LoadModel[ProfileRelevantData]]( + dut: LoadModel[LoadRelevantData], + simulationStartDate: ZonedDateTime, + targetPower: ComparableQuantity[Power] + ): Array[ComparableQuantity[Power]] = { + + val relevantDatas = getRelevantDatas(dut, simulationStartDate) + + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + .sorted + .toArray + + powers + } } From d2b7e14bf9146fbd7b3a07b92642855949c2e642 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 16:11:07 +0200 Subject: [PATCH 066/305] LoadModelScalingSpec --- .../load/LoadModelScalingSpec.scala | 203 +++++++++++------- 1 file changed, 124 insertions(+), 79 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 60ab62d91d..46df2a2508 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -14,15 +14,12 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel +import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData import edu.ie3.simona.test.common.TestTags.SnailTest import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -35,7 +32,7 @@ import tech.units.indriya.unit.Units import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Dimensionless, Energy, Power} +import javax.measure.quantity.{Dimensionless, Energy} class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "Testing correct scaling of load models" when { @@ -103,9 +100,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, profile, EnergyConsumption(targetEnergyConsumption) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() - calculateAverageEnergy( + calculateAverageEnergyFromProfile( dut, simulationStartDate, targetEnergyConsumption @@ -131,12 +129,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() - calculateAverageEnergy( + calculateAverageEnergyFromProfile( dut, simulationStartDate, - expectedEnergy + targetEnergyConsumption ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 @@ -165,9 +164,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, profile, ActivePower(targetMaximumPower) - ).asInstanceOf[LoadModel[LoadRelevantData]] - - val relevantDatas = getRelevantDatas(dut, simulationStartDate) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap val totalRuns = 10 (0 until totalRuns).flatMap { _ => @@ -207,9 +212,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) - ).asInstanceOf[LoadModel[LoadRelevantData]] - - val relevantDatas = getRelevantDatas(dut, simulationStartDate) + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap val totalRuns = 10 (0 until totalRuns).flatMap { _ => @@ -278,13 +289,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() - calculateAverageEnergy( - dut, - simulationStartDate, - targetEnergyConsumption - ) should beLessThanWithTolerance( + + calculateAverageEnergyFromRandom(dut, simulationStartDate, targetEnergyConsumption) should beLessThanWithTolerance( Quantities.getQuantity(1d, Units.PERCENT), 1e-1 ) @@ -304,13 +313,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() - calculateAverageEnergy( - dut, - simulationStartDate, - expectedEnergy - ) should beLessThanWithTolerance( + calculateAverageEnergyFromRandom(dut, simulationStartDate, targetEnergyConsumption) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 ) @@ -327,10 +333,34 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() + + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + .sorted + .toArray - val powers = - calculateAveragePower(dut, simulationStartDate, targetMaximumPower) val quantile95 = RandomLoadModelSpec.get95Quantile(powers) getRelativeResult( @@ -355,10 +385,32 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getsRated(), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) - ).asInstanceOf[LoadModel[LoadRelevantData]] + ) + dut.enable() + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap - val powers = - calculateAveragePower(dut, simulationStartDate, expectedMaximum) + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(1d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + .sorted + .toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ RandomLoadModelSpec.get95Quantile(powers) should equalWithTolerance( @@ -369,35 +421,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } - def getRelevantDatas[T <: LoadModel[LoadRelevantData]]( - dut: LoadModel[LoadRelevantData], - simulationStartDate: ZonedDateTime - ): Map[Int, LoadRelevantData] = { - - if (dut.isInstanceOf[ProfileLoadModel]) { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileLoadModel.ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - } - - if (dut.isInstanceOf[RandomLoadModel]) { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - relevantDatas - } else { - throw new IllegalArgumentException("Unknown load model type") - } - } - def getRelativeResult( avgResult: ComparableQuantity[Dimensionless], expectedResult: ComparableQuantity[Dimensionless] @@ -420,13 +443,19 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { result } - def calculateAverageEnergy[T <: LoadModel[ProfileRelevantData]]( - dut: LoadModel[LoadRelevantData], + def calculateAverageEnergyFromProfile[T <: LoadModel[ProfileRelevantData]]( + dut: T, simulationStartDate: ZonedDateTime, expectedEnergy: ComparableQuantity[Energy] ): ComparableQuantity[Dimensionless] = { - val relevantDatas = getRelevantDatas(dut, simulationStartDate) + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap val totalRuns = 10 val avgEnergy = (0 until totalRuns) @@ -460,17 +489,23 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } - def calculateAveragePower[T <: LoadModel[ProfileRelevantData]]( - dut: LoadModel[LoadRelevantData], - simulationStartDate: ZonedDateTime, - targetPower: ComparableQuantity[Power] - ): Array[ComparableQuantity[Power]] = { + def calculateAverageEnergyFromRandom[T <: LoadModel[RandomRelevantData]]( + dut: T, + simulationStartDate: ZonedDateTime, + expectedEnergy: ComparableQuantity[Energy] + ): ComparableQuantity[Dimensionless] = { - val relevantDatas = getRelevantDatas(dut, simulationStartDate) + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => + val avgEnergy = (0 until totalRuns) + .map { _ => relevantDatas .map { case (tick, relevantData) => dut @@ -480,13 +515,23 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { relevantData ) .p + .multiply(Quantities.getQuantity(15d, Units.MINUTE)) + .asType(classOf[Energy]) + .to(PowerSystemUnits.KILOWATTHOUR) } + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) } - .sorted - .toArray + .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( + _.add(_) + ) + .divide(totalRuns) - powers + getRelativeResult( + avgEnergy.asInstanceOf[ComparableQuantity[Dimensionless]], + expectedEnergy.asInstanceOf[ComparableQuantity[Dimensionless]] + ) } - } From 76a0bece39bbc39285261cefdb07c2c0b836691a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 16:19:47 +0200 Subject: [PATCH 067/305] fmt --- .../load/LoadModelScalingSpec.scala | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 46df2a2508..ddc4a60d82 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -15,7 +15,10 @@ import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel @@ -292,8 +295,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - - calculateAverageEnergyFromRandom(dut, simulationStartDate, targetEnergyConsumption) should beLessThanWithTolerance( + calculateAverageEnergyFromRandom( + dut, + simulationStartDate, + targetEnergyConsumption + ) should beLessThanWithTolerance( Quantities.getQuantity(1d, Units.PERCENT), 1e-1 ) @@ -316,7 +322,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergyFromRandom(dut, simulationStartDate, targetEnergyConsumption) should beLessThanWithTolerance( + calculateAverageEnergyFromRandom( + dut, + simulationStartDate, + targetEnergyConsumption + ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 ) @@ -490,9 +500,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def calculateAverageEnergyFromRandom[T <: LoadModel[RandomRelevantData]]( - dut: T, - simulationStartDate: ZonedDateTime, - expectedEnergy: ComparableQuantity[Energy] + dut: T, + simulationStartDate: ZonedDateTime, + expectedEnergy: ComparableQuantity[Energy] ): ComparableQuantity[Dimensionless] = { val relevantDatas = (0 until 35040) From 236c18cf66bccfcd12a833795c4211b5878ab466 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 16:58:03 +0200 Subject: [PATCH 068/305] fix BasicGridWithSwitches --- .../edu/ie3/simona/model/grid/GridModel.scala | 19 ++++++++++--------- .../edu/ie3/simona/model/grid/GridSpec.scala | 2 +- .../model/grid/BasicGridWithSwitches.scala | 13 ++++--------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 5dfbb048f5..5cd11970d2 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -9,22 +9,16 @@ package edu.ie3.simona.model.grid import breeze.linalg.DenseMatrix import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} +import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.control.{TransformerControlGroup => ControlGroupModel} import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} -import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ - PowerFlowCaseA, - PowerFlowCaseB, - PowerFlowCaseC -} -import edu.ie3.simona.model.control.{ - TransformerControlGroup => ControlGroupModel -} +import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{PowerFlowCaseA, PowerFlowCaseB, PowerFlowCaseC} import edu.ie3.simona.util.CollectionUtils import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph @@ -105,6 +99,13 @@ case object GridModel { transformerControlGroups: Set[ControlGroupModel] ) + /** Represents an empty Transformer control groups + * + */ + val EMPTY_GRID_CONTROLS: GridControls = GridControls( + Set.empty[ControlGroupModel] + ) + /** Checks the availability of node calculation models, that are connected by * the given [[ConnectorInput]]. If not both models can be found, * [[InvalidGridException]] s are thrown diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 439af5a255..560bacf17f 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -287,7 +287,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches ), - GridControls(Set.empty[TransformerControlGroup]) + Set.empty[ControlGroupModel] ) // get the private method for validation diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index c9270e0888..fec4c39d46 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -6,14 +6,8 @@ package edu.ie3.simona.test.common.model.grid -import edu.ie3.simona.model.grid.GridModel.GridComponents -import edu.ie3.simona.model.grid.{ - GridModel, - LineModel, - NodeModel, - SwitchModel, - Transformer3wModel -} +import edu.ie3.simona.model.grid.GridModel.{EMPTY_GRID_CONTROLS, GridComponents, GridControls} +import edu.ie3.simona.model.grid.{GridModel, LineModel, NodeModel, SwitchModel, Transformer3wModel} import edu.ie3.util.quantities.PowerSystemUnits._ import tech.units.indriya.quantity.Quantities @@ -229,7 +223,8 @@ trait BasicGridWithSwitches extends BasicGrid { Set(transformer2wModel), Set.empty[Transformer3wModel], gridSwitches - ) + ), + EMPTY_GRID_CONTROLS, ) } From 758ae20442188ace0caa0f899151c8130e224c3d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 17:02:45 +0200 Subject: [PATCH 069/305] fix GridSpec --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 560bacf17f..19f1f48fee 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -15,7 +15,11 @@ import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup -import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} +import edu.ie3.simona.model.grid.GridModel.{ + EMPTY_GRID_CONTROLS, + GridComponents, + GridControls +} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, @@ -26,7 +30,6 @@ import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import testutils.TestObjectFactory import scala.jdk.CollectionConverters.SetHasAsJava - import java.util.UUID class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { @@ -287,7 +290,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches ), - Set.empty[ControlGroupModel] + EMPTY_GRID_CONTROLS ) // get the private method for validation From 4810475d9d02fe400a1559402ca196111a1ddb7d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 17:03:08 +0200 Subject: [PATCH 070/305] fmt --- .../edu/ie3/simona/model/grid/GridModel.scala | 11 ++++++++--- .../model/grid/BasicGridWithSwitches.scala | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 5cd11970d2..55bb02069d 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -16,9 +16,15 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.control.{TransformerControlGroup => ControlGroupModel} +import edu.ie3.simona.model.control.{ + TransformerControlGroup => ControlGroupModel +} import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} -import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{PowerFlowCaseA, PowerFlowCaseB, PowerFlowCaseC} +import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ + PowerFlowCaseA, + PowerFlowCaseB, + PowerFlowCaseC +} import edu.ie3.simona.util.CollectionUtils import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph @@ -100,7 +106,6 @@ case object GridModel { ) /** Represents an empty Transformer control groups - * */ val EMPTY_GRID_CONTROLS: GridControls = GridControls( Set.empty[ControlGroupModel] diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index fec4c39d46..226e46a82f 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -6,8 +6,18 @@ package edu.ie3.simona.test.common.model.grid -import edu.ie3.simona.model.grid.GridModel.{EMPTY_GRID_CONTROLS, GridComponents, GridControls} -import edu.ie3.simona.model.grid.{GridModel, LineModel, NodeModel, SwitchModel, Transformer3wModel} +import edu.ie3.simona.model.grid.GridModel.{ + EMPTY_GRID_CONTROLS, + GridComponents, + GridControls +} +import edu.ie3.simona.model.grid.{ + GridModel, + LineModel, + NodeModel, + SwitchModel, + Transformer3wModel +} import edu.ie3.util.quantities.PowerSystemUnits._ import tech.units.indriya.quantity.Quantities @@ -224,7 +234,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches ), - EMPTY_GRID_CONTROLS, + EMPTY_GRID_CONTROLS ) } From d11a1982758b7e9118665665d97114f659487e20 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 17:09:04 +0200 Subject: [PATCH 071/305] fix BasicGridWithSwitches and GridSpec --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 6 ++++++ src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 2 +- .../test/common/model/grid/BasicGridWithSwitches.scala | 9 +++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index ace9679725..d49f27bd1f 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -109,6 +109,12 @@ case object GridModel { transformerControlGroups: Set[ControlGroupModel] ) + /** Represents an empty Transformer control groups + */ + val EMPTY_GRID_CONTROLS: GridControls = GridControls( + Set.empty[ControlGroupModel] + ) + /** Checks the availability of node calculation models, that are connected by * the given [[ConnectorInput]]. If not both models can be found, * [[InvalidGridException]] s are thrown diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index cc84552b53..4f2c3f3403 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -282,7 +282,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches ), - GridControls(Set.empty[TransformerControlGroup]) + EMPTY_GRID_CONTROLS ) // get the private method for validation diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index c9270e0888..226e46a82f 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -6,7 +6,11 @@ package edu.ie3.simona.test.common.model.grid -import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.grid.GridModel.{ + EMPTY_GRID_CONTROLS, + GridComponents, + GridControls +} import edu.ie3.simona.model.grid.{ GridModel, LineModel, @@ -229,7 +233,8 @@ trait BasicGridWithSwitches extends BasicGrid { Set(transformer2wModel), Set.empty[Transformer3wModel], gridSwitches - ) + ), + EMPTY_GRID_CONTROLS ) } From 5c7c88569a7903541b629e3650d2625d01d49d66 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 17:13:42 +0200 Subject: [PATCH 072/305] fix BasicGridWithSwitches and GridSpec --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 4f2c3f3403..1ec9814682 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -13,13 +13,9 @@ import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup -import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} +import edu.ie3.simona.model.grid.GridModel.{EMPTY_GRID_CONTROLS, GridComponents, GridControls} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} -import edu.ie3.simona.test.common.model.grid.{ - BasicGrid, - BasicGridWithSwitches, - FiveLinesWithNodes -} +import edu.ie3.simona.test.common.model.grid.{BasicGrid, BasicGridWithSwitches, FiveLinesWithNodes} import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import java.util.UUID From 2ea2e4634ceb5246c197d02f9389e5bca9186e9e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 25 Apr 2023 17:17:56 +0200 Subject: [PATCH 073/305] fmt --- .../scala/edu/ie3/simona/model/grid/GridSpec.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 1ec9814682..8a7f210c2d 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -13,9 +13,17 @@ import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup -import edu.ie3.simona.model.grid.GridModel.{EMPTY_GRID_CONTROLS, GridComponents, GridControls} +import edu.ie3.simona.model.grid.GridModel.{ + EMPTY_GRID_CONTROLS, + GridComponents, + GridControls +} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} -import edu.ie3.simona.test.common.model.grid.{BasicGrid, BasicGridWithSwitches, FiveLinesWithNodes} +import edu.ie3.simona.test.common.model.grid.{ + BasicGrid, + BasicGridWithSwitches, + FiveLinesWithNodes +} import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import java.util.UUID From 79302d434eacdc3428acaff94c5afa84624a0a1a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 09:41:47 +0200 Subject: [PATCH 074/305] Adaptions of LoadModelScalingSpec --- .../load/LoadModelScalingSpec.scala | 87 ++++++++----------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index ddc4a60d82..61d7897452 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -35,7 +35,7 @@ import tech.units.indriya.unit.Units import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Dimensionless, Energy} +import javax.measure.quantity.{Dimensionless, Energy, Power} class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "Testing correct scaling of load models" when { @@ -138,7 +138,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { calculateAverageEnergyFromProfile( dut, simulationStartDate, - targetEnergyConsumption + expectedEnergy ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 @@ -325,7 +325,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { calculateAverageEnergyFromRandom( dut, simulationStartDate, - targetEnergyConsumption + expectedEnergy ) should beLessThanWithTolerance( Quantities.getQuantity(2d, Units.PERCENT), 1e-1 @@ -346,28 +346,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } + val powers = getPowerFromRelevantDataRandom( + simulationStartDate, + dut + ) .sorted .toArray @@ -397,30 +379,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(1d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } - .sorted - .toArray + val powers = getPowerFromRelevantDataRandom( + simulationStartDate, + dut + ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ RandomLoadModelSpec.get95Quantile(powers) should equalWithTolerance( @@ -430,7 +392,34 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } } + def getPowerFromRelevantDataRandom[T <: LoadModel[RandomRelevantData]]( + simulationStartDate: ZonedDateTime, + dut: T + ): IndexedSeq[ComparableQuantity[Power]] = { + val relevantDatas = (0 until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + val totalRuns = 10 + val powers = (0 until totalRuns) + .flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(1d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + powers + } def getRelativeResult( avgResult: ComparableQuantity[Dimensionless], expectedResult: ComparableQuantity[Dimensionless] From 25658082dd1ad93618754a25e991bdafcba508b7 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 09:53:32 +0200 Subject: [PATCH 075/305] fmt --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 61d7897452..1d216584e9 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -349,9 +349,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val powers = getPowerFromRelevantDataRandom( simulationStartDate, dut - ) - .sorted - .toArray + ).sorted.toArray val quantile95 = RandomLoadModelSpec.get95Quantile(powers) From 7fa3c4864528c13abdf39c8bfd41fdbe0e5ca2be Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 09:59:00 +0200 Subject: [PATCH 076/305] method transfer LoadModelScalingSpec --- .../load/LoadModelScalingSpec.scala | 80 +++++++++---------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 1d216584e9..09bac13ec4 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -169,27 +169,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - (0 until totalRuns).flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - } - }.maxOption match { + getPowerFromRelevantDataProfile( + simulationStartDate, + dut + ).maxOption match { case Some(maximumPower) => maximumPower should equalWithTolerance( targetMaximumPower.to(PowerSystemUnits.MEGAWATT), @@ -217,27 +200,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - (0 until totalRuns).flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - } - }.maxOption match { + + getPowerFromRelevantDataProfile( + simulationStartDate, + dut + ).maxOption match { case Some(maximumPower) => maximumPower should equalWithTolerance( expectedMaximum.to(PowerSystemUnits.MEGAWATT), @@ -390,6 +357,35 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } } + + def getPowerFromRelevantDataProfile[T <: LoadModel[ProfileRelevantData]]( + simulationStartDate: ZonedDateTime, + dut: T + ): IndexedSeq[ComparableQuantity[Power]] = { + val relevantDatas = (0 until 35040) + .map(tick => + tick -> ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + + val totalRuns = 10 + val powers = + (0 until totalRuns).flatMap { _ => + relevantDatas + .map { case (tick, relevantData) => + dut + .calculatePower( + tick, + Quantities.getQuantity(0d, PowerSystemUnits.PU), + relevantData + ) + .p + } + } + powers + } def getPowerFromRelevantDataRandom[T <: LoadModel[RandomRelevantData]]( simulationStartDate: ZonedDateTime, dut: T From b2883ef567b62f834e1afc9778cb2f34aad6da36 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 11:27:44 +0200 Subject: [PATCH 077/305] remove scaling in ProfileLoadModel --- .../model/participant/load/profile/ProfileLoadModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index b271599a72..a952fb34dc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -111,7 +111,7 @@ final case class ProfileLoadModel( .multiply(energyReferenceScalingFactor) .asType(classOf[Power]) } - activePower.multiply(scalingFactor) + activePower } } From 0aaa640f2dae841ae305926a541e6f0aed4a9a52 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 12:47:29 +0200 Subject: [PATCH 078/305] remove tests of scaling in ProfileLoadModelTest since scaling transfered to system participant --- .../load/ProfileLoadModelTest.groovy | 83 ------------------- 1 file changed, 83 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy index 05c1d2bc69..cd87791c8b 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy @@ -123,45 +123,6 @@ class ProfileLoadModelTest extends Specification { G0 || 268.0029932985852E-6 } - def "A profile load model should account for the (global) scaling factor correctly when scaling to maximum power within a year"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - globalScaling, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - H0, - new ActivePower(Quantities.getQuantity(268.6, WATT)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def max = relevantDatas.stream().mapToDouble({ relevantData -> - dut.calculateActivePower(relevantData).to(MEGAWATT).value.doubleValue() - }).max().getAsDouble() - - then: - abs(max - expectedMax) < testingTolerance - - where: - globalScaling || expectedMax - 0.25 || 67.00074832464630E-6 - 0.5 || 134.0014966492930E-6 - 0.75 || 201.0022449739390E-6 - 1.0 || 268.0029932985852E-6 - 1.25 || 335.0037416232310E-6 - 1.5 || 402.0044899478780E-6 - 1.75 || 469.0052382725240E-6 - 2.0 || 536.0059865971700E-6 - } - def "A profile load model should reach the targeted annual energy consumption"() { given: /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles @@ -200,48 +161,4 @@ class ProfileLoadModelTest extends Specification { L0 || 3000d G0 || 3000d } - - def "A profile load model should account for the (global) scaling factor correctly when scaling to annual energy consumption"() { - given: - /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles - * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % - * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach - * this accuracy. */ - def testingTolerance = 0.02 - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - globalScaling, - QControl.apply(loadInput.qCharacteristics), - loadInput.sRated, - loadInput.cosPhiRated, - H0, - new EnergyConsumption(Quantities.getQuantity(3000d, KILOWATTHOUR)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData) * Quantities.getQuantity(15d, MINUTE)) as ComparableQuantity).to(KILOWATTHOUR).value.doubleValue() - }).sum() - - then: - abs(annualEnergy - expectedEnergy) / expectedEnergy < testingTolerance - - where: - globalScaling || expectedEnergy - 0.25 || 750d - 0.5 || 1500d - 0.75 || 2250d - 1.0 || 3000d - 1.25 || 3750d - 1.5 || 4500d - 1.75 || 5250d - 2.0 || 6000d - } } From 71f8d11db45a1945cd22d2c2990eae6ddf42cf36 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 28 Apr 2023 14:21:18 +0200 Subject: [PATCH 079/305] get the absolute relative result from test --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 09bac13ec4..5df7303925 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -433,7 +433,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { Units.PERCENT ) ) - result + Quantities.getQuantity(abs(result.getValue.doubleValue()), Units.PERCENT) } def calculateAverageEnergyFromProfile[T <: LoadModel[ProfileRelevantData]]( From 78467cc767113dfb5ef117115b12c0d23a6bef1e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 10:31:04 +0200 Subject: [PATCH 080/305] calculate average energy --- .../load/LoadModelScalingSpec.scala | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 5df7303925..997a0978b2 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -14,6 +14,7 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, @@ -106,7 +107,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergyFromProfile( + calculateAverageEnergy( dut, simulationStartDate, targetEnergyConsumption @@ -135,7 +136,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergyFromProfile( + calculateAverageEnergy( dut, simulationStartDate, expectedEnergy @@ -262,7 +263,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergyFromRandom( + calculateAverageEnergy( dut, simulationStartDate, targetEnergyConsumption @@ -289,7 +290,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergyFromRandom( + calculateAverageEnergy( dut, simulationStartDate, expectedEnergy @@ -436,19 +437,30 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { Quantities.getQuantity(abs(result.getValue.doubleValue()), Units.PERCENT) } - def calculateAverageEnergyFromProfile[T <: LoadModel[ProfileRelevantData]]( + def calculateAverageEnergy[C <: LoadRelevantData, T <: LoadModel[C]]( dut: T, simulationStartDate: ZonedDateTime, expectedEnergy: ComparableQuantity[Energy] ): ComparableQuantity[Dimensionless] = { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + val relevantDatas = dut match { + case _: RandomLoadModel => + (0L until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + case _: ProfileLoadModel => + (0L until 35040) + .map(tick => + tick -> ProfileLoadModel.ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + } val totalRuns = 10 val avgEnergy = (0 until totalRuns) @@ -459,7 +471,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .calculatePower( tick, Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData + relevantData.asInstanceOf[C] ) .p .multiply(Quantities.getQuantity(15d, Units.MINUTE)) From f6823e0a98e9709869ef95b589d8a68b0cad9d0d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 10:33:32 +0200 Subject: [PATCH 081/305] calculate power from relevantData --- .../load/LoadModelScalingSpec.scala | 123 +++++------------- 1 file changed, 31 insertions(+), 92 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 997a0978b2..48c76ed93a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -170,7 +170,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - getPowerFromRelevantDataProfile( + calculatePowerFromRelevantData( simulationStartDate, dut ).maxOption match { @@ -202,7 +202,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - getPowerFromRelevantDataProfile( + calculatePowerFromRelevantData( simulationStartDate, dut ).maxOption match { @@ -314,7 +314,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - val powers = getPowerFromRelevantDataRandom( + val powers = calculatePowerFromRelevantData( simulationStartDate, dut ).sorted.toArray @@ -345,9 +345,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - val powers = getPowerFromRelevantDataRandom( - simulationStartDate, - dut + val powers = calculatePowerFromRelevantData( + dut, + simulationStartDate ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ @@ -359,62 +359,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } - def getPowerFromRelevantDataProfile[T <: LoadModel[ProfileRelevantData]]( - simulationStartDate: ZonedDateTime, - dut: T - ): IndexedSeq[ComparableQuantity[Power]] = { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val powers = - (0 until totalRuns).flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } - powers - } - def getPowerFromRelevantDataRandom[T <: LoadModel[RandomRelevantData]]( - simulationStartDate: ZonedDateTime, - dut: T - ): IndexedSeq[ComparableQuantity[Power]] = { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - - val totalRuns = 10 - val powers = (0 until totalRuns) - .flatMap { _ => - relevantDatas - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Quantities.getQuantity(1d, PowerSystemUnits.PU), - relevantData - ) - .p - } - } - powers - } def getRelativeResult( avgResult: ComparableQuantity[Dimensionless], expectedResult: ComparableQuantity[Dimensionless] @@ -494,49 +438,44 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } - def calculateAverageEnergyFromRandom[T <: LoadModel[RandomRelevantData]]( - dut: T, + def calculatePowerFromRelevantData[C <: LoadRelevantData, T <: LoadModel[C]]( simulationStartDate: ZonedDateTime, - expectedEnergy: ComparableQuantity[Energy] - ): ComparableQuantity[Dimensionless] = { + dut: T + ): IndexedSeq[ComparableQuantity[Power]] = { - val relevantDatas = (0 until 35040) - .map(tick => - tick -> RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap + val relevantDatas = dut match { + case _: RandomLoadModel => + (0L until 35040) + .map(tick => + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + case _: ProfileLoadModel => + (0L until 35040) + .map(tick => + tick -> ProfileLoadModel.ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap + } val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => + val powers = (0 until totalRuns) + .flatMap { _ => relevantDatas .map { case (tick, relevantData) => dut .calculatePower( tick, Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData + relevantData.asInstanceOf[C] ) .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) - ) - .divide(totalRuns) - - getRelativeResult( - avgEnergy.asInstanceOf[ComparableQuantity[Dimensionless]], - expectedEnergy.asInstanceOf[ComparableQuantity[Dimensionless]] - ) - + powers } } From f124c50b7c535203b9a3820e5e74f091dc825b20 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 10:34:57 +0200 Subject: [PATCH 082/305] calculate power from relevantData --- .../model/participant/load/LoadModelScalingSpec.scala | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 48c76ed93a..bfbe427c30 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -16,14 +16,9 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel -import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel -import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData import edu.ie3.simona.test.common.TestTags.SnailTest import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -346,8 +341,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() val powers = calculatePowerFromRelevantData( - dut, - simulationStartDate + simulationStartDate, + dut ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ From 7066eea93c7f4eadd81606452985bd90fd722ade Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 11:56:24 +0200 Subject: [PATCH 083/305] addressing sonar issues --- .../model/participant/load/LoadModelScalingSpec.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index bfbe427c30..21779e5c30 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -317,8 +317,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val quantile95 = RandomLoadModelSpec.get95Quantile(powers) getRelativeResult( - quantile95.asInstanceOf[ComparableQuantity[Dimensionless]], - targetMaximumPower.asInstanceOf[ComparableQuantity[Dimensionless]] + quantile95, + targetMaximumPower ) should beLessThanWithTolerance( Quantities.getQuantity(1d, Units.PERCENT), 1e-1 @@ -458,7 +458,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } val totalRuns = 10 - val powers = (0 until totalRuns) + (0 until totalRuns) .flatMap { _ => relevantDatas .map { case (tick, relevantData) => @@ -471,6 +471,5 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .p } } - powers } } From ca3825a5e511755c57b8ea157e36cd26eef37182 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 12:33:09 +0200 Subject: [PATCH 084/305] move relevantDatas to method --- .../load/LoadModelScalingSpec.scala | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 21779e5c30..1551e899b5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -376,30 +376,39 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { Quantities.getQuantity(abs(result.getValue.doubleValue()), Units.PERCENT) } - def calculateAverageEnergy[C <: LoadRelevantData, T <: LoadModel[C]]( - dut: T, - simulationStartDate: ZonedDateTime, - expectedEnergy: ComparableQuantity[Energy] - ): ComparableQuantity[Dimensionless] = { - - val relevantDatas = dut match { + def getRelevantData[C <: LoadRelevantData forSome {type LoadRelevantData}, + T <: LoadModel[C] forSome {type C}]( + dut: T, + simulationStartDate: ZonedDateTime) = { + dut match { case _: RandomLoadModel => (0L until 35040) .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) + tick -> RandomLoadModel + .RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ).asInstanceOf[C] ) .toMap case _: ProfileLoadModel => (0L until 35040) .map(tick => - tick -> ProfileLoadModel.ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) + tick -> ProfileLoadModel + .ProfileRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ).asInstanceOf[C] ) .toMap } + } + + def calculateAverageEnergy[C <: LoadRelevantData, T <: LoadModel[C]]( + dut: T, + simulationStartDate: ZonedDateTime, + expectedEnergy: ComparableQuantity[Energy] + ): ComparableQuantity[Dimensionless] = { + + val relevantDatas = getRelevantData(dut, simulationStartDate) val totalRuns = 10 val avgEnergy = (0 until totalRuns) @@ -438,24 +447,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut: T ): IndexedSeq[ComparableQuantity[Power]] = { - val relevantDatas = dut match { - case _: RandomLoadModel => - (0L until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - case _: ProfileLoadModel => - (0L until 35040) - .map(tick => - tick -> ProfileLoadModel.ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap - } + val relevantDatas = getRelevantData(dut, simulationStartDate) val totalRuns = 10 (0 until totalRuns) From 0457c860e8921235404467849e7b3eb61934cbcd Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 12:34:30 +0200 Subject: [PATCH 085/305] sonar --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 1551e899b5..2a13f1dc2f 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -355,8 +355,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def getRelativeResult( - avgResult: ComparableQuantity[Dimensionless], - expectedResult: ComparableQuantity[Dimensionless] + avgResult: ComparableQuantity[_], + expectedResult: ComparableQuantity[_] ): ComparableQuantity[Dimensionless] = { val result = Quantities .getQuantity(100, Units.PERCENT) From 516d86274cc72d205eea68c1e8f791880676cdea Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 12:37:01 +0200 Subject: [PATCH 086/305] method boundary --- .../load/LoadModelScalingSpec.scala | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 2a13f1dc2f..2960a52242 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -14,9 +14,11 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel import edu.ie3.simona.test.common.TestTags.SnailTest @@ -376,10 +378,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { Quantities.getQuantity(abs(result.getValue.doubleValue()), Units.PERCENT) } - def getRelevantData[C <: LoadRelevantData forSome {type LoadRelevantData}, - T <: LoadModel[C] forSome {type C}]( - dut: T, - simulationStartDate: ZonedDateTime) = { + def getRelevantData[ + C <: LoadRelevantData forSome { type LoadRelevantData }, + T <: LoadModel[C] forSome { type C } + ](dut: T, simulationStartDate: ZonedDateTime) = { dut match { case _: RandomLoadModel => (0L until 35040) @@ -387,7 +389,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { tick -> RandomLoadModel .RandomRelevantData( simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ).asInstanceOf[C] + ) + .asInstanceOf[C] ) .toMap case _: ProfileLoadModel => @@ -396,13 +399,17 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { tick -> ProfileLoadModel .ProfileRelevantData( simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ).asInstanceOf[C] + ) + .asInstanceOf[C] ) .toMap } } - def calculateAverageEnergy[C <: LoadRelevantData, T <: LoadModel[C]]( + def calculateAverageEnergy[ + C <: LoadRelevantData forSome { type LoadRelevantData }, + T <: LoadModel[C] forSome { type C } + ]( dut: T, simulationStartDate: ZonedDateTime, expectedEnergy: ComparableQuantity[Energy] @@ -419,7 +426,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .calculatePower( tick, Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData.asInstanceOf[C] + relevantData ) .p .multiply(Quantities.getQuantity(15d, Units.MINUTE)) @@ -442,7 +449,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } - def calculatePowerFromRelevantData[C <: LoadRelevantData, T <: LoadModel[C]]( + def calculatePowerFromRelevantData[ + C <: LoadRelevantData forSome { type LoadRelevantData }, + T <: LoadModel[C] forSome { type C } + ]( simulationStartDate: ZonedDateTime, dut: T ): IndexedSeq[ComparableQuantity[Power]] = { @@ -458,7 +468,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .calculatePower( tick, Quantities.getQuantity(0d, PowerSystemUnits.PU), - relevantData.asInstanceOf[C] + relevantData ) .p } From a6b25b8f22cf27fed8742efc7f795b23163c64f9 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 9 May 2023 12:52:13 +0200 Subject: [PATCH 087/305] more sonar issues --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 2960a52242..07eff0c644 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -443,8 +443,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .divide(totalRuns) getRelativeResult( - avgEnergy.asInstanceOf[ComparableQuantity[Dimensionless]], - expectedEnergy.asInstanceOf[ComparableQuantity[Dimensionless]] + avgEnergy, + expectedEnergy ) } From 72407d6cc5b7a6d50b89617243d8a7022e59e255 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 11 May 2023 08:44:23 +0200 Subject: [PATCH 088/305] deprecated QuantityMatchers --- .../scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala index 8cf7edf16e..c415cb7bf1 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala @@ -17,7 +17,7 @@ import javax.measure.Quantity import org.scalatest.matchers.{MatchResult, Matcher} import tech.units.indriya.ComparableQuantity import tech.units.indriya.quantity.Quantities - +@deprecated("Use implementation in power system utils package") /** Trait, to simplify test coding, that is reliant on [[Quantity]] s */ trait QuantityMatchers { From 5697c075e86fc8437095524ccb9c6ffb86fe9f5d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 23 Aug 2023 15:48:38 +0200 Subject: [PATCH 089/305] fix changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38dc42fa01..6e820c9436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,7 +68,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Renamed ChpData to ChpRelevantData [#494](https://github.com/ie3-institute/simona/issues/494) - Updated gradle to 8.2.1, cleaned up `build.gradle` and `Jenkinsfile` [#572](https://github.com/ie3-institute/simona/issues/572) - Respect for scaling factor when simulating the system participants [#81](https://github.com/ie3-institute/simona/issues/81) -- Harmonize participant model instantiation [#81](https://github.com/ie3-institute/simona/issues/81) ### Fixed - Location of `vn_simona` test grid (was partially in Berlin and Dortmund) [#72](https://github.com/ie3-institute/simona/issues/72) From 6b62df4269d0c4d496120fb1b57ad23bff000151 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 15:44:24 +0200 Subject: [PATCH 090/305] spotless --- .../ie3/simona/model/participant/FixedFeedInModel.scala | 3 ++- .../simona/model/participant/load/FixedLoadModel.scala | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index eeb5b14784..279a588970 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -66,7 +66,8 @@ final case class FixedFeedInModel( override protected def calculateActivePower( data: FixedRelevantData.type = FixedRelevantData ): Power = - sRated * (-1) * cosPhiRated} + sRated * (-1) * cosPhiRated +} case object FixedFeedInModel extends LazyLogging { def apply( diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 6e2083592d..3ccce0e6f4 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -97,10 +97,11 @@ object FixedLoadModel { scalingFactor, QControl(input.getqCharacteristics()), Kilowatts( - input.getsRated - .to(PowerSystemUnits.KILOWATT) - .getValue - .doubleValue), + input.getsRated + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue + ), input.getCosPhiRated, reference ) From 6253e5fa613ab37607f929fdb621e97ea5332d76 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 20:34:23 +0200 Subject: [PATCH 091/305] fix squants with regard to scaling --- .../model/participant/SystemParticipant.scala | 4 +- .../load/LoadModelScalingSpec.scala | 190 ++++++++++-------- .../load/ProfileLoadModelSpec.scala | 34 ++-- .../load/RandomLoadModelSpec.scala | 41 ++-- 4 files changed, 138 insertions(+), 131 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index e9e699b486..19cdcb85a4 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -77,8 +77,8 @@ abstract class SystemParticipant[CD <: CalcRelevantData]( val reactivePower = calculateReactivePower(activePower, voltage) ApparentPower( - activePower.multiply(scalingFactor), - reactivePower.multiply(scalingFactor) + activePower * scalingFactor, + reactivePower * scalingFactor ) } else { ApparentPower( diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 07eff0c644..db888e1e73 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -26,16 +26,18 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks -import tech.units.indriya.ComparableQuantity +import squants.energy.{KilowattHours, Kilowatts, Watts} +import squants.time.Minutes +import squants.{Dimensionless, Each, Energy, Percent, Power} import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -import javax.measure.quantity.{Dimensionless, Energy, Power} class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { + implicit val tolerance: Dimensionless = Each(1e-10) + "Testing correct scaling of load models" when { val simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") @@ -76,7 +78,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) val targetEnergyConsumption = - Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(3000d) "reach the targeted annual energy consumption" taggedAs SnailTest in { /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % @@ -95,9 +97,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, - 1.0, + 1.0d, QControl.apply(profileLoadInput.getqCharacteristics()), - profileLoadInput.getsRated(), + Kilowatts( + profileLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), profileLoadInput.getCosPhiRated, profile, EnergyConsumption(targetEnergyConsumption) @@ -108,17 +116,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, targetEnergyConsumption - ) should beLessThanWithTolerance( - Quantities.getQuantity(2d, Units.PERCENT), - 1e-1 - ) + ) =~ Percent(2d) } } "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { val scalingFactor = 1.5 val expectedEnergy = - Quantities.getQuantity(4500d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(4500d) val dut = ProfileLoadModel( profileLoadInput.getUuid, @@ -126,7 +131,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { foreSeenOperationInterval, scalingFactor, QControl.apply(profileLoadInput.getqCharacteristics()), - profileLoadInput.getsRated(), + Kilowatts( + profileLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) @@ -137,16 +148,12 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, expectedEnergy - ) should beLessThanWithTolerance( - Quantities.getQuantity(2d, Units.PERCENT), - 1e-1 - ) + ) =~ Percent(2d) } - val targetMaximumPower = - Quantities.getQuantity(268.6, Units.WATT) + val targetMaximumPower = Watts(268.6) "approximately reach the maximum power" taggedAs SnailTest in { - + implicit val tolerance: Power = Watts(1d) forAll( Table( "profile", @@ -161,21 +168,25 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { foreSeenOperationInterval, 1.0, QControl.apply(profileLoadInput.getqCharacteristics()), - profileLoadInput.getsRated(), + Kilowatts( + profileLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), profileLoadInput.getCosPhiRated, profile, ActivePower(targetMaximumPower) ) dut.enable() + calculatePowerFromRelevantData( simulationStartDate, dut ).maxOption match { case Some(maximumPower) => - maximumPower should equalWithTolerance( - targetMaximumPower.to(PowerSystemUnits.MEGAWATT), - testingTolerance - ) + maximumPower =~ targetMaximumPower case None => fail("Unable to determine maximum power.") } } @@ -184,15 +195,21 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { val scalingFactor = 1.5 val expectedMaximum = - Quantities.getQuantity(402.0044899478780, Units.WATT) - + Watts(402.0044899478780) + implicit val tolerance: Power = Watts(1d) val dut = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, scalingFactor, QControl.apply(profileLoadInput.getqCharacteristics()), - profileLoadInput.getsRated(), + Kilowatts( + profileLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) @@ -204,10 +221,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut ).maxOption match { case Some(maximumPower) => - maximumPower should equalWithTolerance( - expectedMaximum.to(PowerSystemUnits.MEGAWATT), - testingTolerance - ) + maximumPower =~ expectedMaximum + case None => fail("Unable to determine maximum power.") } } @@ -246,7 +261,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) val targetEnergyConsumption = - Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(3000d) "reach the targeted annual energy consumption" taggedAs SnailTest in { val dut = RandomLoadModel( randomLoadInput.getUuid, @@ -254,7 +269,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { foreSeenOperationInterval, 1.0, QControl.apply(randomLoadInput.getqCharacteristics()), - randomLoadInput.getsRated(), + Kilowatts( + randomLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) @@ -264,16 +285,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, targetEnergyConsumption - ) should beLessThanWithTolerance( - Quantities.getQuantity(1d, Units.PERCENT), - 1e-1 - ) + ) =~ Percent(1d) } "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { val scalingFactor = 1.5 val expectedEnergy = - Quantities.getQuantity(4500d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(4500d) val dut = RandomLoadModel( randomLoadInput.getUuid, @@ -281,7 +299,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { foreSeenOperationInterval, scalingFactor, QControl.apply(randomLoadInput.getqCharacteristics()), - randomLoadInput.getsRated(), + Kilowatts( + randomLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) @@ -291,13 +315,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, expectedEnergy - ) should beLessThanWithTolerance( - Quantities.getQuantity(2d, Units.PERCENT), - 1e-1 - ) + ) =~ Percent(2d) } - val targetMaximumPower = Quantities.getQuantity(268.6, Units.WATT) + val targetMaximumPower = Watts(268.6) "approximately reach the maximum power" taggedAs SnailTest in { val dut = RandomLoadModel( randomLoadInput.getUuid, @@ -305,7 +326,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { foreSeenOperationInterval, 1.0, QControl.apply(randomLoadInput.getqCharacteristics()), - randomLoadInput.getsRated(), + Kilowatts( + randomLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) @@ -321,23 +348,27 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { getRelativeResult( quantile95, targetMaximumPower - ) should beLessThanWithTolerance( - Quantities.getQuantity(1d, Units.PERCENT), - 1e-1 - ) + ) =~ Percent(1d) + } "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { val scalingFactor = 1.5 - val expectedMaximum = targetMaximumPower.multiply(scalingFactor) - + val expectedMaximum = targetMaximumPower * scalingFactor + implicit val tolerance: Power = Watts(1d) val dut = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, foreSeenOperationInterval, scalingFactor, QControl.apply(randomLoadInput.getqCharacteristics()), - randomLoadInput.getsRated(), + Kilowatts( + randomLoadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) @@ -348,34 +379,18 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ - RandomLoadModelSpec.get95Quantile(powers) should equalWithTolerance( - expectedMaximum.to(PowerSystemUnits.MEGAWATT), - 1e-5 - ) + RandomLoadModelSpec.get95Quantile(powers) =~ expectedMaximum } } } - def getRelativeResult( - avgResult: ComparableQuantity[_], - expectedResult: ComparableQuantity[_] - ): ComparableQuantity[Dimensionless] = { - val result = Quantities - .getQuantity(100, Units.PERCENT) - .subtract( - Quantities.getQuantity( - abs( - avgResult - .divide(expectedResult) - .asType(classOf[Dimensionless]) - .to(Units.PERCENT) - .getValue - .doubleValue() - ), - Units.PERCENT - ) - ) - Quantities.getQuantity(abs(result.getValue.doubleValue()), Units.PERCENT) + def getRelativeResult[Q <: squants.Quantity[Q]]( + avgResult: Q, + expectedResult: Q + ): Dimensionless = { + val result = Percent(100) - + Percent(abs(avgResult.divide(expectedResult))) + Percent(abs(result.value.doubleValue())) } def getRelevantData[ @@ -412,8 +427,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ]( dut: T, simulationStartDate: ZonedDateTime, - expectedEnergy: ComparableQuantity[Energy] - ): ComparableQuantity[Dimensionless] = { + expectedEnergy: Energy + ): Dimensionless = { val relevantDatas = getRelevantData(dut, simulationStartDate) @@ -425,20 +440,17 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut .calculatePower( tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), + Each(0d), relevantData ) - .p - .multiply(Quantities.getQuantity(15d, Units.MINUTE)) - .asType(classOf[Energy]) - .to(PowerSystemUnits.KILOWATTHOUR) + .p * Minutes(15d) } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) + .fold(KilowattHours(0))( + _ + _ ) } - .fold(Quantities.getQuantity(0, PowerSystemUnits.KILOWATTHOUR))( - _.add(_) + .fold(KilowattHours(0d))( + _ + _ ) .divide(totalRuns) @@ -455,7 +467,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ]( simulationStartDate: ZonedDateTime, dut: T - ): IndexedSeq[ComparableQuantity[Power]] = { + ): IndexedSeq[Power] = { val relevantDatas = getRelevantData(dut, simulationStartDate) @@ -467,7 +479,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut .calculatePower( tick, - Quantities.getQuantity(0d, PowerSystemUnits.PU), + Each(0d), relevantData ) .p diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index cf8d3da8b5..1b7028ac20 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -22,12 +22,14 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks +import squants.Power +import squants.energy.{KilowattHours, Watts} import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units import java.util.UUID class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { + implicit val tolerance: Power = Watts(1d) "Having a profile load model" when { val loadInput = new LoadInput( @@ -64,7 +66,6 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { simulationEndDate, loadInput.getOperationTime ) - val testingTolerance = 1e-6 // Equals to 1 W power "instantiating it" should { "deliver a proper model" in { @@ -73,39 +74,39 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { ("profile", "reference", "expectedsRated"), ( BdewStandardLoadProfile.H0, - ActivePower(Quantities.getQuantity(268.6, Units.WATT)), - Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ActivePower(Watts(268.6)), + Watts(282.74d) ), ( BdewStandardLoadProfile.H0, EnergyConsumption( - Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(3000d) ), - Quantities.getQuantity(848.22, PowerSystemUnits.VOLTAMPERE) + Watts(848.22d) ), ( BdewStandardLoadProfile.L0, - ActivePower(Quantities.getQuantity(268.6, Units.WATT)), - Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ActivePower(Watts(268.6)), + Watts(282.74d) ), ( BdewStandardLoadProfile.L0, EnergyConsumption( - Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(3000d) ), - Quantities.getQuantity(759.158, PowerSystemUnits.VOLTAMPERE) + Watts(759.158d) ), ( BdewStandardLoadProfile.G0, - ActivePower(Quantities.getQuantity(268.6, Units.WATT)), - Quantities.getQuantity(282.74, PowerSystemUnits.VOLTAMPERE) + ActivePower(Watts(268.6)), + Watts(282.74d) ), ( BdewStandardLoadProfile.G0, EnergyConsumption( - Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR) + KilowattHours(3000d) ), - Quantities.getQuantity(759.158, PowerSystemUnits.VOLTAMPERE) + Watts(759.158d) ) ) ) { (profile, reference, expectedSRated) => @@ -116,10 +117,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { reference ) - actual.sRated should equalWithTolerance( - expectedSRated.to(PowerSystemUnits.MEGAVOLTAMPERE), - testingTolerance - ) + actual.sRated =~ expectedSRated } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 97d818357e..0d62aa229a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -28,8 +28,9 @@ import edu.ie3.simona.test.matchers.QuantityMatchers import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks +import squants.Power +import squants.energy.{KilowattHours, Kilowatts, Watts} import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units import java.util.UUID @@ -37,6 +38,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks with QuantityMatchers { + implicit val tolerance: Power = Watts(1d) "Having a random load model" when { val loadInput = new LoadInput( @@ -77,23 +79,15 @@ class RandomLoadModelSpec "instantiating it" should { "deliver a proper model" in { - forAll( + ( Table( ("reference", "expectedSRated"), - ( - ActivePower(Quantities.getQuantity(268.6, Units.WATT)), - Quantities - .getQuantity(311.0105263157895, PowerSystemUnits.VOLTAMPERE) - ), - ( - EnergyConsumption( - Quantities.getQuantity(2000d, PowerSystemUnits.KILOWATTHOUR) - ), - Quantities - .getQuantity(467.156124576697, PowerSystemUnits.VOLTAMPERE) - ) - ) - ) { (reference, expectedSRated) => + (ActivePower(Watts(268.6)), Watts(311.0105263157895d)) + ), + (EnergyConsumption(KilowattHours(2000d)), Watts(467.156124576697d)) + ) + + { (reference: ActivePower, expectedSRated: Power) => val actual = RandomLoadModel( loadInput, foreSeenOperationInterval, @@ -101,10 +95,7 @@ class RandomLoadModelSpec reference ) - actual.sRated should equalWithTolerance( - expectedSRated.to(PowerSystemUnits.MEGAVOLTAMPERE), - testingTolerance - ) + actual.sRated =~ expectedSRated } } } @@ -117,9 +108,15 @@ class RandomLoadModelSpec foreSeenOperationInterval, 1.0, QControl.apply(loadInput.getqCharacteristics()), - loadInput.getsRated(), + Kilowatts( + loadInput + .getsRated() + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue() + ), loadInput.getCosPhiRated, - new ActivePower(Quantities.getQuantity(268.6, Units.WATT)) + new ActivePower(Watts(268.6)) ) /* Working day, 61th quarter hour */ val queryDate = From 60a9cb768945acad600818215dbe8967c217493a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 20:50:39 +0200 Subject: [PATCH 092/305] codacy --- .../edu/ie3/simona/model/grid/GridModel.scala | 45 +++++++++++-------- .../edu/ie3/simona/model/grid/GridSpec.scala | 5 +-- .../model/grid/BasicGridWithSwitches.scala | 4 +- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index dfa6d64fb9..e6a1ab2f02 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -107,7 +107,7 @@ case object GridModel { /** Represents an empty Transformer control groups */ - val EMPTY_GRID_CONTROLS: GridControls = GridControls( + val emptyGridControls: GridControls = GridControls( Set.empty[ControlGroupModel] ) @@ -687,14 +687,19 @@ case object GridModel { val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => uuid -> { (complexVoltage: Complex) => { - val vMag = complexVoltage.abs - if (vMag > vMax) - Some(vMax - vMag) - else if (vMag < vMin) - Some(vMin - vMag) - else - None - }.map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + complexVoltage.abs match { + case vMag if { + vMag > vMax + } => + Some(vMax - vMag) + case vMag if { + vMag < vMax + } => + Some(vMin - vMag) + case _ => None + } + } + .map(Quantities.getQuantity(_, PowerSystemUnits.PU)) } }.toMap @@ -707,16 +712,20 @@ case object GridModel { _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) ) - if (negativeRequests.nonEmpty && positiveRequests.nonEmpty) { - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - } else if (negativeRequests.nonEmpty) { - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - } else { - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None } + } ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 19f1f48fee..6d50e2da8a 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -16,7 +16,7 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup import edu.ie3.simona.model.grid.GridModel.{ - EMPTY_GRID_CONTROLS, + emptyGridControls, GridComponents, GridControls } @@ -30,7 +30,6 @@ import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import testutils.TestObjectFactory import scala.jdk.CollectionConverters.SetHasAsJava -import java.util.UUID class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { @@ -290,7 +289,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches ), - EMPTY_GRID_CONTROLS + emptyGridControls ) // get the private method for validation diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index 226e46a82f..781a9e7620 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -7,7 +7,7 @@ package edu.ie3.simona.test.common.model.grid import edu.ie3.simona.model.grid.GridModel.{ - EMPTY_GRID_CONTROLS, + emptyGridControls, GridComponents, GridControls } @@ -234,7 +234,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches ), - EMPTY_GRID_CONTROLS + emptyGridControls ) } From 4ce037f8b05103e8b699cebc18a368adf48e2f2f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 20:54:37 +0200 Subject: [PATCH 093/305] codacy --- .../edu/ie3/simona/model/grid/GridModel.scala | 45 +++++++++++-------- .../edu/ie3/simona/model/grid/GridSpec.scala | 6 +-- .../model/grid/BasicGridWithSwitches.scala | 4 +- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index cea9720bb0..1c9c01d93c 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -111,7 +111,7 @@ case object GridModel { /** Represents an empty Transformer control groups */ - val EMPTY_GRID_CONTROLS: GridControls = GridControls( + val emptyGridControls: GridControls = GridControls( Set.empty[ControlGroupModel] ) @@ -691,14 +691,19 @@ case object GridModel { val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => uuid -> { (complexVoltage: Complex) => { - val vMag = complexVoltage.abs - if (vMag > vMax) - Some(vMax - vMag) - else if (vMag < vMin) - Some(vMin - vMag) - else - None - }.map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + complexVoltage.abs match { + case vMag if { + vMag > vMax + } => + Some(vMax - vMag) + case vMag if { + vMag < vMax + } => + Some(vMin - vMag) + case _ => None + } + } + .map(Quantities.getQuantity(_, PowerSystemUnits.PU)) } }.toMap @@ -711,16 +716,20 @@ case object GridModel { _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) ) - if (negativeRequests.nonEmpty && positiveRequests.nonEmpty) { - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - } else if (negativeRequests.nonEmpty) { - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - } else { - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None } + } ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 8a7f210c2d..d1f05ff66a 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -14,7 +14,7 @@ import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroup import edu.ie3.simona.model.grid.GridModel.{ - EMPTY_GRID_CONTROLS, + emptyGridControls, GridComponents, GridControls } @@ -26,8 +26,6 @@ import edu.ie3.simona.test.common.model.grid.{ } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} -import java.util.UUID - class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { private val _printAdmittanceMatrixOnMismatch @@ -286,7 +284,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches ), - EMPTY_GRID_CONTROLS + emptyGridControls ) // get the private method for validation diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index 226e46a82f..781a9e7620 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -7,7 +7,7 @@ package edu.ie3.simona.test.common.model.grid import edu.ie3.simona.model.grid.GridModel.{ - EMPTY_GRID_CONTROLS, + emptyGridControls, GridComponents, GridControls } @@ -234,7 +234,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches ), - EMPTY_GRID_CONTROLS + emptyGridControls ) } From dbe8de721682544487f0dc11dc5097202ff820a1 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 21:19:29 +0200 Subject: [PATCH 094/305] fix test --- .../edu/ie3/simona/model/grid/GridModel.scala | 159 +++++++++--------- 1 file changed, 76 insertions(+), 83 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index e6a1ab2f02..780314d4cb 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -685,97 +685,90 @@ case object GridModel { ): ControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { (complexVoltage: Complex) => - { - complexVoltage.abs match { - case vMag if { - vMag > vMax - } => - Some(vMax - vMag) - case vMag if { - vMag < vMax - } => - Some(vMin - vMag) + uuid -> { + (complexVoltage: Complex) => + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case mag if mag < vMin => Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) case _ => None } - } - .map(Quantities.getQuantity(_, PowerSystemUnits.PU)) } }.toMap - val harmonizationFunction = - (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { - val negativeRequests = regulationRequests.filter( - _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - val positiveRequests = regulationRequests.filter( - _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } - - } - - ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) - } + val harmonizationFunction = + (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { + val negativeRequests = regulationRequests.filter( + _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + val positiveRequests = regulationRequests.filter( + _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) - /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to - * account for changes on switches (open / close) It is highly recommended (= - * mandatory) to call this method every time a node admittance matrix is - * needed after a switch status has changed. - * - * @param gridModel - * the grid model we operate on - */ - def updateUuidToIndexMap(gridModel: GridModel): Unit = { + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None + } - val switches = gridModel.gridComponents.switches - val nodes = gridModel.gridComponents.nodes + } - val nodesAndSwitches: ListSet[SystemComponent] = ListSet - .empty[SystemComponent] ++ switches ++ nodes + ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) + } - val updatedNodeToUuidMap = nodesAndSwitches - .filter(_.isInOperation) - .filter { - case switch: SwitchModel => switch.isClosed - case _: NodeModel => true - } - .zipWithIndex - .foldLeft(Map.empty[UUID, Int]) { - case (map, (gridComponent, componentId)) => - gridComponent match { - case switchModel: SwitchModel => - map ++ Map( - switchModel.nodeAUuid -> componentId, - switchModel.nodeBUuid -> componentId - ) - - case nodeModel: NodeModel => - if (!map.contains(nodeModel.uuid)) { - val idx = map.values.toList.sorted.lastOption - .getOrElse( - -1 - ) + 1 // if we didn't found anything in the list, we don't have switches and want to start @ 0 - map + (nodeModel.uuid -> idx) - } else { - map - } - } - } + /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to + * account for changes on switches (open / close) It is highly recommended (= + * mandatory) to call this method every time a node admittance matrix is + * needed after a switch status has changed. + * + * @param gridModel + * the grid model we operate on + */ + def updateUuidToIndexMap(gridModel: GridModel): Unit = { + + val switches = gridModel.gridComponents.switches + val nodes = gridModel.gridComponents.nodes + + val nodesAndSwitches: ListSet[SystemComponent] = ListSet + .empty[SystemComponent] ++ switches ++ nodes + + val updatedNodeToUuidMap = nodesAndSwitches + .filter(_.isInOperation) + .filter { + case switch: SwitchModel => switch.isClosed + case _: NodeModel => true + } + .zipWithIndex + .foldLeft(Map.empty[UUID, Int]) { + case (map, (gridComponent, componentId)) => + gridComponent match { + case switchModel: SwitchModel => + map ++ Map( + switchModel.nodeAUuid -> componentId, + switchModel.nodeBUuid -> componentId + ) + + case nodeModel: NodeModel => + if (!map.contains(nodeModel.uuid)) { + val idx = map.values.toList.sorted.lastOption + .getOrElse( + -1 + ) + 1 // if we didn't found anything in the list, we don't have switches and want to start @ 0 + map + (nodeModel.uuid -> idx) + } else { + map + } + } + } - gridModel._nodeUuidToIndexMap = updatedNodeToUuidMap + gridModel._nodeUuidToIndexMap = updatedNodeToUuidMap + } } -} From 0854e085304fd1353eab4a3e9b66f5c7171895aa Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 21:21:01 +0200 Subject: [PATCH 095/305] fix test --- .../edu/ie3/simona/model/grid/GridModel.scala | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 1c9c01d93c..4bbd017701 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -689,21 +689,14 @@ case object GridModel { ): ControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { (complexVoltage: Complex) => - { - complexVoltage.abs match { - case vMag if { - vMag > vMax - } => - Some(vMax - vMag) - case vMag if { - vMag < vMax - } => - Some(vMin - vMag) + uuid -> { + (complexVoltage: Complex) => + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case mag if mag < vMin => Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) case _ => None } - } - .map(Quantities.getQuantity(_, PowerSystemUnits.PU)) } }.toMap From 051fbedf80494085dddff8d78c04397a2c4d79d5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 21:24:30 +0200 Subject: [PATCH 096/305] spotless --- .../edu/ie3/simona/model/grid/GridModel.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 4bbd017701..8dbb1a4424 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -689,14 +689,15 @@ case object GridModel { ): ControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { - (complexVoltage: Complex) => - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) - case mag if mag < vMin => Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) - case _ => None - } + uuid -> { (complexVoltage: Complex) => + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case mag if mag < vMin => + Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case _ => None + } } }.toMap From b180043fbbe0d4504c3a0ad7e2a79c641ee59fc8 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 27 Sep 2023 21:25:36 +0200 Subject: [PATCH 097/305] spotless --- .../edu/ie3/simona/model/grid/GridModel.scala | 157 +++++++++--------- 1 file changed, 79 insertions(+), 78 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 780314d4cb..c01455d731 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -685,90 +685,91 @@ case object GridModel { ): ControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { - (complexVoltage: Complex) => - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) - case mag if mag < vMin => Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) - case _ => None - } + uuid -> { (complexVoltage: Complex) => + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case mag if mag < vMin => + Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + case _ => None + } } }.toMap - val harmonizationFunction = - (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { - val negativeRequests = regulationRequests.filter( - _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - val positiveRequests = regulationRequests.filter( - _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } + val harmonizationFunction = + (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { + val negativeRequests = regulationRequests.filter( + _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + val positiveRequests = regulationRequests.filter( + _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) + ) + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None } - ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) - } + } - /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to - * account for changes on switches (open / close) It is highly recommended (= - * mandatory) to call this method every time a node admittance matrix is - * needed after a switch status has changed. - * - * @param gridModel - * the grid model we operate on - */ - def updateUuidToIndexMap(gridModel: GridModel): Unit = { - - val switches = gridModel.gridComponents.switches - val nodes = gridModel.gridComponents.nodes - - val nodesAndSwitches: ListSet[SystemComponent] = ListSet - .empty[SystemComponent] ++ switches ++ nodes - - val updatedNodeToUuidMap = nodesAndSwitches - .filter(_.isInOperation) - .filter { - case switch: SwitchModel => switch.isClosed - case _: NodeModel => true - } - .zipWithIndex - .foldLeft(Map.empty[UUID, Int]) { - case (map, (gridComponent, componentId)) => - gridComponent match { - case switchModel: SwitchModel => - map ++ Map( - switchModel.nodeAUuid -> componentId, - switchModel.nodeBUuid -> componentId - ) - - case nodeModel: NodeModel => - if (!map.contains(nodeModel.uuid)) { - val idx = map.values.toList.sorted.lastOption - .getOrElse( - -1 - ) + 1 // if we didn't found anything in the list, we don't have switches and want to start @ 0 - map + (nodeModel.uuid -> idx) - } else { - map - } - } - } + ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) + } - gridModel._nodeUuidToIndexMap = updatedNodeToUuidMap - } + /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to + * account for changes on switches (open / close) It is highly recommended (= + * mandatory) to call this method every time a node admittance matrix is + * needed after a switch status has changed. + * + * @param gridModel + * the grid model we operate on + */ + def updateUuidToIndexMap(gridModel: GridModel): Unit = { + + val switches = gridModel.gridComponents.switches + val nodes = gridModel.gridComponents.nodes + + val nodesAndSwitches: ListSet[SystemComponent] = ListSet + .empty[SystemComponent] ++ switches ++ nodes + + val updatedNodeToUuidMap = nodesAndSwitches + .filter(_.isInOperation) + .filter { + case switch: SwitchModel => switch.isClosed + case _: NodeModel => true + } + .zipWithIndex + .foldLeft(Map.empty[UUID, Int]) { + case (map, (gridComponent, componentId)) => + gridComponent match { + case switchModel: SwitchModel => + map ++ Map( + switchModel.nodeAUuid -> componentId, + switchModel.nodeBUuid -> componentId + ) + + case nodeModel: NodeModel => + if (!map.contains(nodeModel.uuid)) { + val idx = map.values.toList.sorted.lastOption + .getOrElse( + -1 + ) + 1 // if we didn't found anything in the list, we don't have switches and want to start @ 0 + map + (nodeModel.uuid -> idx) + } else { + map + } + } + } + + gridModel._nodeUuidToIndexMap = updatedNodeToUuidMap } +} From 586b75afe86dd7612583aabd26ca0dba63cbacca Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 28 Sep 2023 12:15:35 +0200 Subject: [PATCH 098/305] squants --- .../model/participant/control/QControl.scala | 49 +++++++++---------- .../util/scala/quantities/QuantityUtil.scala | 7 ++- .../agent/grid/GridResultsSupportSpec.scala | 16 +++--- .../ie3/simona/util/CollectionUtilsSpec.scala | 12 ++--- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala b/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala index cb28f8392b..02c42be94f 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala @@ -13,7 +13,7 @@ import edu.ie3.simona.model.system.Characteristic import edu.ie3.simona.model.system.Characteristic.XYPair import edu.ie3.util.quantities.PowerSystemUnits.PU import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} -import squants.Each +import squants.{Dimensionless, Each, Power} import tech.units.indriya.AbstractUnit import scala.collection.SortedSet @@ -22,9 +22,8 @@ import scala.jdk.CollectionConverters._ import scala.math._ sealed trait QControl { - protected val _cosPhiMultiplication - : (Double, squants.Power) => ReactivePower = - (cosPhi: Double, p: squants.Power) => + protected val _cosPhiMultiplication: (Double, Power) => ReactivePower = + (cosPhi: Double, p: Power) => if ((cosPhi - 1).abs < 0.0000001) { Megavars(0d) } else { @@ -44,10 +43,10 @@ sealed trait QControl { * The function */ def activeToReactivePowerFunc( - sRated: squants.Power, + sRated: Power, cosPhiRated: Double, - nodalVoltage: squants.Dimensionless - ): squants.Power => ReactivePower + nodalVoltage: Dimensionless + ): Power => ReactivePower } /** Object to create a [[QControl]]. Currently the following QControls @@ -72,7 +71,7 @@ object QControl { CosPhiP( TreeSet.from( cosPhiP.getPoints.asScala.map(point => - XYPair[squants.Dimensionless, squants.Dimensionless]( + XYPair[Dimensionless, Dimensionless]( Each(point.getX.getValue.doubleValue()), Each(point.getY.getValue.doubleValue()) ) @@ -84,7 +83,7 @@ object QControl { TreeSet.from( qv.getPoints.asScala .map(point => - XYPair[squants.Dimensionless, squants.Dimensionless]( + XYPair[Dimensionless, Dimensionless]( Each(point.getX.getValue.doubleValue()), Each(point.getY.getValue.doubleValue()) ) @@ -117,10 +116,10 @@ object QControl { * The function */ override def activeToReactivePowerFunc( - sRated: squants.Power, + sRated: Power, cosPhiRated: Double, - nodalVoltage: squants.Dimensionless - ): squants.Power => ReactivePower = { activePower: squants.Power => + nodalVoltage: Dimensionless + ): Power => ReactivePower = { activePower: Power => _cosPhiMultiplication(cosPhi, activePower) } } @@ -132,10 +131,10 @@ object QControl { */ final case class QV private ( xyCoordinates: SortedSet[ - XYPair[squants.Dimensionless, squants.Dimensionless] + XYPair[Dimensionless, Dimensionless] ] ) extends QControl - with Characteristic[squants.Dimensionless, squants.Dimensionless] { + with Characteristic[Dimensionless, Dimensionless] { /** Returns the resulting reactive power for the requested voltage level * value. The conversion to abstract unit [[AbstractUnit.ONE]] is necessary @@ -151,7 +150,7 @@ object QControl { * the resulting reactive power q */ def q( - vInPu: squants.Dimensionless, + vInPu: Dimensionless, qMax: ReactivePower ): ReactivePower = { qMax * interpolateXy(vInPu)._2.toEach @@ -169,10 +168,10 @@ object QControl { * The function */ override def activeToReactivePowerFunc( - sRated: squants.Power, + sRated: Power, cosPhiRated: Double, - nodalVoltage: squants.Dimensionless - ): squants.Power => ReactivePower = { activePower: squants.Power => + nodalVoltage: Dimensionless + ): Power => ReactivePower = { activePower: Power => val qMaxFromP = Megavars( sqrt( pow(sRated.toMegawatts, 2) - @@ -213,10 +212,10 @@ object QControl { */ final case class CosPhiP private ( xyCoordinates: SortedSet[ - XYPair[squants.Dimensionless, squants.Dimensionless] + XYPair[Dimensionless, Dimensionless] ] ) extends QControl - with Characteristic[squants.Dimensionless, squants.Dimensionless] { + with Characteristic[Dimensionless, Dimensionless] { /** Returns the requested cosine phi value for a provided power value * (p/sRated) in p.u. If the cosine phi cannot be found for the requested @@ -228,8 +227,8 @@ object QControl { * the cosine phi for the requested p.u. value */ def cosPhi( - pInPu: squants.Dimensionless - ): squants.Dimensionless = + pInPu: Dimensionless + ): Dimensionless = interpolateXy(pInPu)._2 /** Obtain the function, that transfers active into reactive power @@ -244,10 +243,10 @@ object QControl { * The function */ override def activeToReactivePowerFunc( - sRated: squants.Power, + sRated: Power, cosPhiRated: Double, - nodalVoltage: squants.Dimensionless - ): squants.Power => ReactivePower = { activePower: squants.Power => + nodalVoltage: Dimensionless + ): Power => ReactivePower = { activePower: Power => /* cosphi( P / P_N ) = cosphi( P / (S_N * cosphi_rated) ) */ val pInPu = activePower / (sRated * cosPhiRated) diff --git a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala index bc949dae2b..8507633d4c 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala @@ -8,6 +8,7 @@ package edu.ie3.util.scala.quantities import edu.ie3.simona.exceptions.QuantityException import edu.ie3.util.quantities.{QuantityUtil => PSQuantityUtil} +import squants.UnitOfMeasure import tech.units.indriya.ComparableQuantity import tech.units.indriya.function.Calculus import tech.units.indriya.quantity.Quantities @@ -33,10 +34,14 @@ object QuantityUtil { ) ) - def zero[Q <: Quantity[Q]]( + def zeroCompQuantity[Q <: Quantity[Q]]( unit: javax.measure.Unit[Q] ): ComparableQuantity[Q] = Quantities.getQuantity(0, unit) + def zero[Q <: squants.Quantity[Q]]( + unit: UnitOfMeasure[Q] + ): Q = unit(0d) + @deprecated( "Use reduceOption { (power1, power2) => power1.add(power2) } instead" ) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala index 77668a425e..c2f67e8701 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala @@ -199,10 +199,10 @@ class GridResultsSupportSpec disabledLineResult shouldBe new LineResult( defaultSimulationStart, line0To1.uuid, - ScalaQuantityUtil.zero(Units.AMPERE), - ScalaQuantityUtil.zero(DEGREE_GEOM), - ScalaQuantityUtil.zero(Units.AMPERE), - ScalaQuantityUtil.zero(DEGREE_GEOM) + ScalaQuantityUtil.zeroCompQuantity(Units.AMPERE), + ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), + ScalaQuantityUtil.zeroCompQuantity(Units.AMPERE), + ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM) ) } @@ -403,10 +403,10 @@ class GridResultsSupportSpec val expectedResult: Transformer2WResult = new Transformer2WResult( TimeUtil.withDefaults.toZonedDateTime("2020-06-08 09:03:00"), transformerModel.uuid, - ScalaQuantityUtil.zero(AMPERE), - ScalaQuantityUtil.zero(DEGREE_GEOM), - ScalaQuantityUtil.zero(AMPERE), - ScalaQuantityUtil.zero(DEGREE_GEOM), + ScalaQuantityUtil.zeroCompQuantity(AMPERE), + ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), + ScalaQuantityUtil.zeroCompQuantity(AMPERE), + ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), transformerModel.currentTapPos ) diff --git a/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala b/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala index 6b6fdb3243..2553818567 100644 --- a/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala +++ b/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala @@ -8,12 +8,8 @@ package edu.ie3.simona.util import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.util.CollectionUtils._ -import edu.ie3.util.quantities.PowerSystemUnits._ import squants.Each -import tech.units.indriya.ComparableQuantity -import tech.units.indriya.quantity.Quantities.getQuantity - -import javax.measure.quantity.Dimensionless +import squants.Dimensionless class CollectionUtilsSpec extends UnitSpec { @@ -38,13 +34,13 @@ class CollectionUtilsSpec extends UnitSpec { ) def returnedSequence1: Seq[ - (squants.Dimensionless, squants.Dimensionless) + (Dimensionless, Dimensionless) ] = closestKeyValuePairs(map, Each(1.5)) def returnedSequence2: Seq[ - (squants.Dimensionless, squants.Dimensionless) + (Dimensionless, Dimensionless) ] = closestKeyValuePairs(map, Each(2.5)) def returnedSequence3: Seq[ - (squants.Dimensionless, squants.Dimensionless) + (Dimensionless, Dimensionless) ] = closestKeyValuePairs(map, Each(3d)) returnedSequence1 shouldBe Seq( From 7fed7c00211ceb80ed64a8cfb37ce86d8e59d29e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 28 Sep 2023 12:15:55 +0200 Subject: [PATCH 099/305] transfer tests to squants --- .../agent/grid/GridResultsSupport.scala | 16 +++++++-------- .../control/TransformerControlGroup.scala | 11 ++++------ .../edu/ie3/simona/model/grid/GridModel.scala | 20 +++++++------------ .../control/TransformerControlGroupSpec.scala | 12 ++++------- 4 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala index 55d0a5d995..4cf61786db 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala @@ -346,10 +346,10 @@ private[grid] trait GridResultsSupport { new LineResult( timestamp, line.uuid, - QuantityUtil.zero(Units.AMPERE), - QuantityUtil.zero(PowerSystemUnits.DEGREE_GEOM), - QuantityUtil.zero(Units.AMPERE), - QuantityUtil.zero(PowerSystemUnits.DEGREE_GEOM) + QuantityUtil.zeroCompQuantity(Units.AMPERE), + QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), + QuantityUtil.zeroCompQuantity(Units.AMPERE), + QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM) ) } } @@ -415,10 +415,10 @@ private[grid] trait GridResultsSupport { new Transformer2WResult( timestamp, trafo2w.uuid, - QuantityUtil.zero(Units.AMPERE), - QuantityUtil.zero(PowerSystemUnits.DEGREE_GEOM), - QuantityUtil.zero(Units.AMPERE), - QuantityUtil.zero(PowerSystemUnits.DEGREE_GEOM), + QuantityUtil.zeroCompQuantity(Units.AMPERE), + QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), + QuantityUtil.zeroCompQuantity(Units.AMPERE), + QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), trafo2w.currentTapPos ) } diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala index 652b40b4e1..0a8bf08f1e 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -10,10 +10,9 @@ import breeze.math.Complex import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult import edu.ie3.simona.model.control.TransformerControlGroup.RegulationCriterion -import tech.units.indriya.ComparableQuantity import java.util.UUID -import javax.measure.quantity.Dimensionless +import squants.Dimensionless /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, in what circumference @@ -28,9 +27,7 @@ import javax.measure.quantity.Dimensionless */ final case class TransformerControlGroup( nodalRegulationCriterion: Map[UUID, RegulationCriterion], - harmonizeRegulationNeeds: Array[ - ComparableQuantity[Dimensionless] - ] => Option[ComparableQuantity[Dimensionless]] + harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless] ) { /** Based on the given successful power flow result, determine the difference @@ -48,7 +45,7 @@ final case class TransformerControlGroup( def determineRegulationNeed( result: SuccessFullPowerFlowResult, uuidToIndex: Map[UUID, Int] - ): Option[ComparableQuantity[Dimensionless]] = { + ): Option[Dimensionless] = { val regulationNeeds = result.nodeData.flatMap { case StateData(resultNodeIndex, _, voltage, _) => /* Find possible matching criterion and evaluate it */ @@ -71,5 +68,5 @@ final case class TransformerControlGroup( object TransformerControlGroup { type RegulationCriterion = - Complex => Option[ComparableQuantity[Dimensionless]] + Complex => Option[Dimensionless] } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index c01455d731..3342809985 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -26,16 +26,14 @@ import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseC } import edu.ie3.simona.util.CollectionUtils -import edu.ie3.util.quantities.PowerSystemUnits + import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} -import tech.units.indriya.ComparableQuantity -import tech.units.indriya.quantity.Quantities +import squants.{Dimensionless, Each} import java.time.ZonedDateTime import java.util.UUID -import javax.measure.quantity.Dimensionless import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ @@ -689,22 +687,18 @@ case object GridModel { val vMag = complexVoltage.abs vMag match { case mag if mag > vMax => - Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + Some(vMax - mag).map(Each(_)) case mag if mag < vMin => - Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + Some(vMin - mag).map(Each(_)) case _ => None } } }.toMap val harmonizationFunction = - (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { - val negativeRequests = regulationRequests.filter( - _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - val positiveRequests = regulationRequests.filter( - _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { case (true, true) => diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala index 8def596ce6..100f1bb9e5 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala @@ -14,12 +14,12 @@ import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers -import edu.ie3.util.quantities.PowerSystemUnits -import tech.units.indriya.quantity.Quantities +import squants.{Dimensionless, Each} import java.util.UUID class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { + implicit val tolerance: Dimensionless = Each(1e-10) "Checking the function of transformer control groups" should { val buildTransformerControlModels = PrivateMethod[TransformerControlGroup]( Symbol("buildTransformerControlModels") @@ -100,9 +100,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { actual match { case Some(regulationNeed) => - regulationNeed should equalWithTolerance( - Quantities.getQuantity(0.05, PowerSystemUnits.PU) - ) + regulationNeed =~ Each(0.05d) case None => fail("Did expect to receive a regulation need.") } } @@ -122,9 +120,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { actual match { case Some(regulationNeed) => - regulationNeed should equalWithTolerance( - Quantities.getQuantity(-0.05, PowerSystemUnits.PU) - ) + regulationNeed =~ Each(-990.05d) case None => fail("Did expect to receive a regulation need.") } } From 667e8cf63251d403f61467e4cd4d49483a9c7f5c Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 28 Sep 2023 12:53:53 +0200 Subject: [PATCH 100/305] fix test --- .../edu/ie3/simona/model/participant/ChpModelTest.groovy | 2 +- .../groovy/edu/ie3/simona/model/participant/HpModelTest.groovy | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy index 7bcf8524b8..fba865235c 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/ChpModelTest.groovy @@ -21,7 +21,7 @@ import edu.ie3.datamodel.models.input.system.type.ChpTypeInput import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.simona.model.participant.ChpModel.ChpState import edu.ie3.simona.model.thermal.CylindricalThermalStorage -import edu.ie3.util.scala.OperationInterval +import edu.ie3.util.TimeUtil import edu.ie3.util.scala.quantities.Sq import spock.lang.Shared import spock.lang.Specification diff --git a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy index 94f7192b8d..2bb79b647e 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/HpModelTest.groovy @@ -24,9 +24,8 @@ import edu.ie3.simona.model.participant.HpModel.HpData import edu.ie3.simona.model.participant.HpModel.HpState import edu.ie3.simona.model.thermal.ThermalHouse import squants.energy.Kilowatts$ -import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.Sq - +import edu.ie3.util.TimeUtil import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll From 7655154c519505a19ee7ce5ddf113c1fb8ba5c9c Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 22 Nov 2023 17:40:59 +0100 Subject: [PATCH 101/305] fmt --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f41129154..d79171d0d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add safety factor sRated calculation [#629](https://github.com/ie3-institute/simona/issues/629) - Re-implemented ResultEventListener in akka typed [#343](https://github.com/ie3-institute/simona/issues/343) - Add additional test cases from references for PvModelTest [#590](https://github.com/ie3-institute/simona/issues/590) - - Models for measurements within the grid structure [#89](https://github.com/ie3-institute/simona/issues/89) - Config possibility for transformer control groups [#90](https://github.com/ie3-institute/simona/issues/90) From c97c4062ebadcd49c2b47b6f557f6f3932ce5f15 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 23 Nov 2023 13:16:57 +0100 Subject: [PATCH 102/305] merge conflicts --- .../load/LoadAgentFundamentals.scala | 40 +++++++------------ .../simona/model/participant/HpModel.scala | 7 +--- .../load/LoadModelScalingSpec.scala | 5 +-- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index b94eb54aee..965cdba16f 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -8,45 +8,28 @@ package edu.ie3.simona.agent.participant.load import akka.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.result.system.{ - LoadResult, - SystemParticipantResult -} +import edu.ie3.datamodel.models.result.system.{LoadResult, SystemParticipantResult} import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals -import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ - ApparentPower, - ZERO_POWER -} +import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ApparentPower, ZERO_POWER} import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData -import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, - ParticipantStateData -} +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer +import edu.ie3.simona.agent.participant.statedata.{DataCollectionStateData, ParticipantStateData} import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig +import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.InconsistentStateException import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData -import edu.ie3.simona.model.participant.load.profile.{ - LoadProfileStore, - ProfileLoadModel -} +import edu.ie3.simona.model.participant.load.profile.{LoadProfileStore, ProfileLoadModel} import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData -import edu.ie3.simona.model.participant.load.random.{ - RandomLoadModel, - RandomLoadParamStore -} -import edu.ie3.simona.model.participant.load.{ - FixedLoadModel, - LoadModel, - LoadReference -} +import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParamStore} +import edu.ie3.simona.model.participant.load.{FixedLoadModel, LoadModel, LoadReference} import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.quantities.PowerSystemUnits.PU @@ -192,7 +175,12 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ inputModel.electricalInputModel.getOperationTime ) val reference = LoadReference(inputModel.electricalInputModel, modelConfig) - buildModel(inputModel.electricalInputModel, operationInterval, modelConfig, reference) + buildModel( + inputModel.electricalInputModel, + operationInterval, + modelConfig, + reference + ) } protected def buildModel( diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index a3387a1bf8..5735226799 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -6,11 +6,9 @@ package edu.ie3.simona.model.participant -import java.util.UUID import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHeat import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.HpModel._ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.ThermalHouse @@ -18,13 +16,11 @@ import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities - import squants.energy.Kilowatts import squants.{Power, Temperature, Time} import java.time.ZonedDateTime - -import java.time.ZonedDateTime +import java.util.UUID /** Model of a heat pump (HP) with a [[ThermalHouse]] medium and its current * [[HpState]]. @@ -299,7 +295,6 @@ case object HpModel { scalingFactor: Double, thermalHouse: ThermalHouse ): HpModel = { - val model = new HpModel( val operationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index db888e1e73..9dda1705a8 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -15,10 +15,7 @@ import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel import edu.ie3.simona.test.common.TestTags.SnailTest From 59578ac62c8bbb8cf5a6b99b35cfec0acdc5549a Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 29 Nov 2023 12:48:00 +0100 Subject: [PATCH 103/305] Fixing type error --- .../load/LoadAgentFundamentals.scala | 31 ++++++-- .../load/LoadModelScalingSpec.scala | 79 +++++++++---------- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index 638dd62514..e503c5e0c2 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -8,15 +8,24 @@ package edu.ie3.simona.agent.participant.load import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.result.system.{LoadResult, SystemParticipantResult} +import edu.ie3.datamodel.models.result.system.{ + LoadResult, + SystemParticipantResult +} import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals -import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ApparentPower, ZERO_POWER} +import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ + ApparentPower, + ZERO_POWER +} import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer -import edu.ie3.simona.agent.participant.statedata.{DataCollectionStateData, ParticipantStateData} +import edu.ie3.simona.agent.participant.statedata.{ + DataCollectionStateData, + ParticipantStateData +} import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig @@ -26,10 +35,20 @@ import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData -import edu.ie3.simona.model.participant.load.profile.{LoadProfileStore, ProfileLoadModel} +import edu.ie3.simona.model.participant.load.profile.{ + LoadProfileStore, + ProfileLoadModel +} import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData -import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParamStore} -import edu.ie3.simona.model.participant.load.{FixedLoadModel, LoadModel, LoadReference} +import edu.ie3.simona.model.participant.load.random.{ + RandomLoadModel, + RandomLoadParamStore +} +import edu.ie3.simona.model.participant.load.{ + FixedLoadModel, + LoadModel, + LoadReference +} import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.quantities.PowerSystemUnits.PU diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 9dda1705a8..7b01c0b4f0 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -14,10 +14,16 @@ import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel +import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel +import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData import edu.ie3.simona.test.common.TestTags.SnailTest import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -40,7 +46,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") val simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - val testingTolerance = 1e-6 // Equals to 1 W power "having a profile load model" should { val profileLoadInput = @@ -109,7 +114,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy( + calculateAverageEnergy[ProfileRelevantData]( dut, simulationStartDate, targetEnergyConsumption @@ -141,7 +146,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy( + calculateAverageEnergy[ProfileRelevantData]( dut, simulationStartDate, expectedEnergy @@ -178,7 +183,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculatePowerFromRelevantData( + calculatePowerFromRelevantData[ProfileRelevantData]( simulationStartDate, dut ).maxOption match { @@ -213,7 +218,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculatePowerFromRelevantData( + calculatePowerFromRelevantData[ProfileRelevantData]( simulationStartDate, dut ).maxOption match { @@ -278,7 +283,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy( + calculateAverageEnergy[RandomRelevantData]( dut, simulationStartDate, targetEnergyConsumption @@ -308,7 +313,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy( + calculateAverageEnergy[RandomRelevantData]( dut, simulationStartDate, expectedEnergy @@ -335,10 +340,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - val powers = calculatePowerFromRelevantData( - simulationStartDate, - dut - ).sorted.toArray + val powers = + calculatePowerFromRelevantData[RandomRelevantData]( + simulationStartDate, + dut + ).sorted.toArray val quantile95 = RandomLoadModelSpec.get95Quantile(powers) @@ -370,10 +376,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ActivePower(targetMaximumPower) ) dut.enable() - val powers = calculatePowerFromRelevantData( - simulationStartDate, - dut - ).sorted.toArray + val powers = + calculatePowerFromRelevantData[RandomRelevantData]( + simulationStartDate, + dut + ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ RandomLoadModelSpec.get95Quantile(powers) =~ expectedMaximum @@ -391,20 +398,17 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def getRelevantData[ - C <: LoadRelevantData forSome { type LoadRelevantData }, - T <: LoadModel[C] forSome { type C } - ](dut: T, simulationStartDate: ZonedDateTime) = { + C <: LoadRelevantData + ](dut: LoadModel[C], simulationStartDate: ZonedDateTime): Map[Long, C] = { dut match { case _: RandomLoadModel => (0L until 35040) .map(tick => - tick -> RandomLoadModel - .RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - .asInstanceOf[C] + tick -> RandomLoadModel.RandomRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) ) - .toMap + .toMap[Long, C] case _: ProfileLoadModel => (0L until 35040) .map(tick => @@ -412,27 +416,23 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .ProfileRelevantData( simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) ) - .asInstanceOf[C] ) - .toMap + .toMap[Long, C] } } - def calculateAverageEnergy[ - C <: LoadRelevantData forSome { type LoadRelevantData }, - T <: LoadModel[C] forSome { type C } - ]( - dut: T, + def calculateAverageEnergy[C <: LoadRelevantData]( + dut: LoadModel[C], simulationStartDate: ZonedDateTime, expectedEnergy: Energy ): Dimensionless = { - val relevantDatas = getRelevantData(dut, simulationStartDate) + val relevantData = getRelevantData(dut, simulationStartDate) val totalRuns = 10 val avgEnergy = (0 until totalRuns) .map { _ => - relevantDatas + relevantData .map { case (tick, relevantData) => dut .calculatePower( @@ -458,20 +458,17 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } - def calculatePowerFromRelevantData[ - C <: LoadRelevantData forSome { type LoadRelevantData }, - T <: LoadModel[C] forSome { type C } - ]( + def calculatePowerFromRelevantData[C <: LoadRelevantData]( simulationStartDate: ZonedDateTime, - dut: T + dut: LoadModel[C] ): IndexedSeq[Power] = { - val relevantDatas = getRelevantData(dut, simulationStartDate) + val relevantData = getRelevantData(dut, simulationStartDate) val totalRuns = 10 (0 until totalRuns) .flatMap { _ => - relevantDatas + relevantData .map { case (tick, relevantData) => dut .calculatePower( From afa8a8538da6232eda9dcd4ae30ea416954c4517 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 29 Nov 2023 13:02:21 +0100 Subject: [PATCH 104/305] Removed unused trait implementation --- .../model/participant/load/RandomLoadModelSpec.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 0d62aa229a..c598dad526 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -24,7 +24,6 @@ import edu.ie3.simona.model.participant.load.random.{ RandomLoadParameters } import edu.ie3.simona.test.common.UnitSpec -import edu.ie3.simona.test.matchers.QuantityMatchers import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks @@ -34,10 +33,7 @@ import tech.units.indriya.quantity.Quantities import java.util.UUID -class RandomLoadModelSpec - extends UnitSpec - with TableDrivenPropertyChecks - with QuantityMatchers { +class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { implicit val tolerance: Power = Watts(1d) "Having a random load model" when { val loadInput = @@ -75,7 +71,6 @@ class RandomLoadModelSpec simulationEndDate, loadInput.getOperationTime ) - val testingTolerance = 1e-6 // Equals to 1 W power "instantiating it" should { "deliver a proper model" in { From c4f6df93990bd4b19b247c4ad8f6147ae1530c6b Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 16:30:02 +0100 Subject: [PATCH 105/305] remove SnailTest since tests are fast enough with squants now --- gradle/scripts/tests.gradle | 7 ------- .../edu/ie3/simona/test/common/TestTags.scala | 16 ---------------- 2 files changed, 23 deletions(-) delete mode 100644 src/test/scala/edu/ie3/simona/test/common/TestTags.scala diff --git a/gradle/scripts/tests.gradle b/gradle/scripts/tests.gradle index 1b44201880..ccccb3ac33 100644 --- a/gradle/scripts/tests.gradle +++ b/gradle/scripts/tests.gradle @@ -7,13 +7,6 @@ test { /* Register scala test with the overall test task */ test.dependsOn(scalatest) -/* Exclude slow tests */ -scalatest { - tags { - exclude "edu.ie3.simona.test.common.TestTags.SnailTest" - } -} - // test task performance improvements, see -> https://docs.gradle.org/current/userguide/performance.html tasks.withType(Test).configureEach { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 diff --git a/src/test/scala/edu/ie3/simona/test/common/TestTags.scala b/src/test/scala/edu/ie3/simona/test/common/TestTags.scala deleted file mode 100644 index 07ce3a25b8..0000000000 --- a/src/test/scala/edu/ie3/simona/test/common/TestTags.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.test.common - -import org.scalatest.Tag - -sealed trait TestTags -object TestTags { - object SnailTest - extends Tag("edu.ie3.simona.test.common.TestTags.SnailTest") - with TestTags -} From 31755dc75ca9cc9a5057bf30a7ea17595ccf74d5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 16:50:33 +0100 Subject: [PATCH 106/305] remove SnailTest since tests are fast enough with squants now --- .../participant/load/LoadModelScalingSpec.scala | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 7b01c0b4f0..818c48d89f 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -24,7 +24,6 @@ import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData -import edu.ie3.simona.test.common.TestTags.SnailTest import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits @@ -81,7 +80,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val targetEnergyConsumption = KilowattHours(3000d) - "reach the targeted annual energy consumption" taggedAs SnailTest in { + "reach the targeted annual energy consumption" in { /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach @@ -122,7 +121,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } - "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { + "correctly account for the scaling factor, when targeting a given annual energy consumption" in { val scalingFactor = 1.5 val expectedEnergy = KilowattHours(4500d) @@ -154,7 +153,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } val targetMaximumPower = Watts(268.6) - "approximately reach the maximum power" taggedAs SnailTest in { + "approximately reach the maximum power" in { implicit val tolerance: Power = Watts(1d) forAll( Table( @@ -194,7 +193,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } - "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { + "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 val expectedMaximum = Watts(402.0044899478780) @@ -264,7 +263,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val targetEnergyConsumption = KilowattHours(3000d) - "reach the targeted annual energy consumption" taggedAs SnailTest in { + "reach the targeted annual energy consumption" in { val dut = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, @@ -290,7 +289,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) =~ Percent(1d) } - "correctly account for the scaling factor, when targeting a given annual energy consumption" taggedAs SnailTest in { + "correctly account for the scaling factor, when targeting a given annual energy consumption" in { val scalingFactor = 1.5 val expectedEnergy = KilowattHours(4500d) @@ -321,7 +320,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } val targetMaximumPower = Watts(268.6) - "approximately reach the maximum power" taggedAs SnailTest in { + "approximately reach the maximum power" in { val dut = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, @@ -355,7 +354,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } - "correctly account for the scaling factor when targeting at maximum power" taggedAs SnailTest in { + "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 val expectedMaximum = targetMaximumPower * scalingFactor implicit val tolerance: Power = Watts(1d) From 66537663a7654035c55d0762e3d7a87f68933e83 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 17:32:58 +0100 Subject: [PATCH 107/305] fix ProfileLoadModelSpec --- .../simona/model/participant/load/ProfileLoadModelSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index 1b7028ac20..1dc66e57e5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -117,7 +117,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { reference ) - actual.sRated =~ expectedSRated + (actual.sRated =~ expectedSRated) shouldBe true } } } From 878df288ebff5427bf59c515bf048ab5d94c3c78 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 17:33:36 +0100 Subject: [PATCH 108/305] fix RandomLoadModelSpec for Power --- .../load/RandomLoadModelSpec.scala | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index c598dad526..809783c6b6 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -15,14 +15,8 @@ import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ - ActivePower, - EnergyConsumption -} -import edu.ie3.simona.model.participant.load.random.{ - RandomLoadModel, - RandomLoadParameters -} +import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} +import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParameters} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits @@ -74,15 +68,14 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { "instantiating it" should { "deliver a proper model" in { - ( - Table( - ("reference", "expectedSRated"), - (ActivePower(Watts(268.6)), Watts(311.0105263157895d)) - ), + + val testData = Table( + ("reference", "expectedSRated"), + (ActivePower(Watts(268.6)), Watts(311.0105263157895d)), (EnergyConsumption(KilowattHours(2000d)), Watts(467.156124576697d)) ) - { (reference: ActivePower, expectedSRated: Power) => + forAll(testData) {(reference, expectedSRated: Power) => val actual = RandomLoadModel( loadInput, foreSeenOperationInterval, @@ -90,7 +83,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { reference ) - actual.sRated =~ expectedSRated + (actual.sRated =~ expectedSRated) shouldBe true } } } From 4a4a047fcb2f1ce39321104bd5f1e2e4b36c5ea1 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 17:47:00 +0100 Subject: [PATCH 109/305] fmt --- .../model/participant/load/LoadModelSpec.scala | 1 - .../model/participant/load/RandomLoadModelSpec.scala | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala index a70b39f723..b5317a8b71 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.model.participant.load -import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 809783c6b6..424d74e2ad 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -15,8 +15,14 @@ import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.LoadReference.{ActivePower, EnergyConsumption} -import edu.ie3.simona.model.participant.load.random.{RandomLoadModel, RandomLoadParameters} +import edu.ie3.simona.model.participant.load.LoadReference.{ + ActivePower, + EnergyConsumption +} +import edu.ie3.simona.model.participant.load.random.{ + RandomLoadModel, + RandomLoadParameters +} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits @@ -75,7 +81,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { (EnergyConsumption(KilowattHours(2000d)), Watts(467.156124576697d)) ) - forAll(testData) {(reference, expectedSRated: Power) => + forAll(testData) { (reference, expectedSRated: Power) => val actual = RandomLoadModel( loadInput, foreSeenOperationInterval, From d6a61659f9d50d9eae7c7535d6ce92a59f639c72 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 18:04:06 +0100 Subject: [PATCH 110/305] adapts expected sRated at RandomLoadModelSpec when testing with EnergyConsumption caused by higher safetyFactor in RandomLoadModel --- .../ie3/simona/model/participant/load/LoadModel.scala | 11 +++-------- .../participant/load/random/RandomLoadModel.scala | 1 - .../model/participant/load/RandomLoadModelSpec.scala | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala index 6844fef7ff..9e9a57af67 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala @@ -9,18 +9,13 @@ package edu.ie3.simona.model.participant.load import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower -import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData -import edu.ie3.simona.model.participant.{ - ApparentPowerParticipant, - SystemParticipant -} import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.participant.{ApparentPowerParticipant, SystemParticipant} import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval -import squants.{Energy, Power} import squants.energy.Megawatts +import squants.{Energy, Power} import java.util.UUID @@ -89,7 +84,7 @@ case object LoadModel extends LazyLogging { * * When the load is scaled based on the consumed energy per year, the * installed sRated capacity is not usable anymore instead, the load's rated - * apparent power ist scaled on the maximum power occurring in the specified + * apparent power is scaled on the maximum power occurring in the specified * load profile multiplied by the ratio of the annual consumption and the * standard load profile scale * diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 6b67adb4bb..6b5cd6ebff 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -9,7 +9,6 @@ package edu.ie3.simona.model.participant.load.random import de.lmu.ifi.dbs.elki.math.statistics.distribution.GeneralizedExtremeValueDistribution import de.lmu.ifi.dbs.elki.utilities.random.RandomFactory import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 424d74e2ad..641c4658a5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -78,7 +78,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { val testData = Table( ("reference", "expectedSRated"), (ActivePower(Watts(268.6)), Watts(311.0105263157895d)), - (EnergyConsumption(KilowattHours(2000d)), Watts(467.156124576697d)) + (EnergyConsumption(KilowattHours(2000d)), Watts(513.871737d)) ) forAll(testData) { (reference, expectedSRated: Power) => From 11d6966187fc13cc7fd832c64c6e8b924b8e9943 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Dec 2023 18:26:38 +0100 Subject: [PATCH 111/305] fmt --- .../edu/ie3/simona/model/participant/load/LoadModel.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala index 9e9a57af67..4305d4babe 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala @@ -11,7 +11,10 @@ import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.{ApparentPowerParticipant, SystemParticipant} +import edu.ie3.simona.model.participant.{ + ApparentPowerParticipant, + SystemParticipant +} import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import squants.energy.Megawatts From 1fbd64aef21c016e9d579f1080cb20ef91f0bcf0 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 7 Dec 2023 11:33:18 +0100 Subject: [PATCH 112/305] include scaling factor as well for heat --- .../model/participant/ApparentPowerAndHeatParticipant.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/BMModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala | 2 +- .../scala/edu/ie3/simona/model/participant/EvcsModel.scala | 2 +- .../edu/ie3/simona/model/participant/FixedFeedInModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/PvModel.scala | 2 +- .../edu/ie3/simona/model/participant/SystemParticipant.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/WecModel.scala | 2 +- .../edu/ie3/simona/model/participant/load/FixedLoadModel.scala | 3 +-- .../model/participant/load/profile/ProfileLoadModel.scala | 2 +- .../simona/model/participant/load/random/RandomLoadModel.scala | 2 +- 12 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala index 9fe21e87ac..7a022b5182 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala @@ -20,7 +20,7 @@ trait ApparentPowerAndHeatParticipant[CD <: CalcRelevantData] { val apparentPower = calculateApparentPower(tick, voltage, data) val heat = if (isInOperation(tick)) - calculateHeat(tick, data) + calculateHeat(tick, data) * scalingFactor else Megawatts(0d) diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index c8594f3e3c..9b46ac236b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -24,7 +24,7 @@ final case class BMModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhi: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 60b162c327..e40852184a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -49,7 +49,7 @@ final case class ChpModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala index 710e62b02a..ad51c99662 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala @@ -50,7 +50,7 @@ final case class EvcsModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: squants.Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index 52be6e6720..bfaf528903 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -43,7 +43,7 @@ final case class FixedFeedInModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 5735226799..86fd41c689 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -49,7 +49,7 @@ final case class HpModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index 847d45e5a1..789d172ec5 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -29,7 +29,7 @@ final case class PvModel private ( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index fd11c54c37..72d6e9219d 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -51,7 +51,7 @@ abstract class SystemParticipant[ uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double diff --git a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala index ca1719dbb0..4999c57108 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala @@ -57,7 +57,7 @@ final case class WecModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 3ccce0e6f4..0862c93ff0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -7,7 +7,6 @@ package edu.ie3.simona.model.participant.load import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData @@ -46,7 +45,7 @@ final case class FixedLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index bc21ae5301..ce8e8f7574 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -44,7 +44,7 @@ final case class ProfileLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 6b5cd6ebff..91d49aed60 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -50,7 +50,7 @@ final case class RandomLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - scalingFactor: Double, + override protected val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, From 314e4917cf4d0ff7de7c8dc718f1e4f8203c0e73 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 11 Dec 2023 09:38:49 +0100 Subject: [PATCH 113/305] fmt --- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 6ae483f1f7..b1ea5f6daa 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -293,7 +293,7 @@ case object HpModel { simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, qControl: QControl, - scalingFactor: Double, + scalingFactor: Double, thermalGrid: ThermalGrid ): HpModel = { val operationInterval = SystemComponent.determineOperationInterval( From f9525b3cda5fe322e65dc359d9d7bb13b82ab46e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 09:10:33 +0000 Subject: [PATCH 114/305] Bump sphinxcontrib-bibtex from 2.6.1 to 2.6.2 in /docs/readthedocs (#693) --- docs/readthedocs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readthedocs/requirements.txt b/docs/readthedocs/requirements.txt index bd2e90f529..47ba1d25e9 100644 --- a/docs/readthedocs/requirements.txt +++ b/docs/readthedocs/requirements.txt @@ -4,4 +4,4 @@ sphinxcontrib-plantuml==0.27 myst-parser==2.0.0 markdown-it-py==3.0.0 sphinx-hoverxref==1.3.0 -sphinxcontrib-bibtex==2.6.1 +sphinxcontrib-bibtex==2.6.2 From cb918647ca46b23e9502ccd74d3c7ae1b535efb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 11:23:11 +0000 Subject: [PATCH 115/305] Bump org.mockito:mockito-core from 5.8.0 to 5.9.0 (#694) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 016036315b..d48723f1dc 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ dependencies { /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' - testImplementation 'org.mockito:mockito-core:5.8.0' // mocking framework + testImplementation 'org.mockito:mockito-core:5.9.0' // mocking framework testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.17" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0' From ace85450f38345c8b7b5e4f77237f58738ea68e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:19:12 +0000 Subject: [PATCH 116/305] Bump com.diffplug.spotless from 6.23.3 to 6.24.0 (#695) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d48723f1dc..39e47a17a1 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { id 'signing' id 'maven-publish' // publish to a maven repo (local or mvn central, has to be defined) id 'pmd' // code check, working on source code - id 'com.diffplug.spotless' version '6.23.3'// code format + id 'com.diffplug.spotless' version '6.24.0'// code format id "com.github.ben-manes.versions" version '0.50.0' id "de.undercouch.download" version "5.5.0" // downloads plugin id "kr.motd.sphinx" version "2.10.1" // documentation generation From 79765f60ef102f1b8d61edcfc63ae370b6f0c767 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 22 Jan 2024 20:46:12 +0100 Subject: [PATCH 117/305] Even better scheduler structure --- .../exceptions/CriticalFailureException.scala | 19 +++ .../edu/ie3/simona/scheduler/Scheduler.scala | 127 +++++++----------- .../edu/ie3/simona/scheduler/core/Core.scala | 92 +++++-------- .../scheduler/core/PhaseSwitchCore.scala | 65 ++++++--- .../scheduler/core/RegularSchedulerCore.scala | 53 +++++--- src/main/scala/edu/ie3/util/scala/Scope.scala | 43 ++++++ 6 files changed, 231 insertions(+), 168 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala create mode 100644 src/main/scala/edu/ie3/util/scala/Scope.scala diff --git a/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala b/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala new file mode 100644 index 0000000000..6ab75e8af6 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala @@ -0,0 +1,19 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.exceptions + +/** Error that should cause an actor to fail, which might terminate the whole + * simulation + * @param message + * The error message + */ +class CriticalFailureException(message: String) extends Exception(message) { + def this(message: String, cause: Throwable) = { + this(message) + initCause(cause) + } +} diff --git a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala index bac0df01ae..92d225f0cf 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.scheduler -import org.apache.pekko.actor.typed.scaladsl.Behaviors -import org.apache.pekko.actor.typed.{ActorRef, Behavior} import edu.ie3.simona.actor.ActorUtil.stopOnError import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, @@ -20,6 +18,9 @@ import edu.ie3.simona.scheduler.core.Core.{ InactiveCore } import edu.ie3.simona.scheduler.core.RegularSchedulerCore +import edu.ie3.util.scala.Scope +import org.apache.pekko.actor.typed.scaladsl.Behaviors +import org.apache.pekko.actor.typed.{ActorRef, Behavior} /** Scheduler that activates actors at specific ticks and keeps them * synchronized by waiting for the completions of all activations. Can be @@ -45,7 +46,7 @@ object Scheduler { coreFactory: CoreFactory = RegularSchedulerCore ): Behavior[Incoming] = Behaviors.setup { ctx => val adapter = - ctx.messageAdapter[Activation](msg => WrappedActivation(msg)) + ctx.messageAdapter[Activation](WrappedActivation) inactive( SchedulerData(parent, adapter), @@ -58,45 +59,39 @@ object Scheduler { core: InactiveCore ): Behavior[Incoming] = Behaviors.receive { - case (ctx, WrappedActivation(Activation(tick))) => - if (core.checkActivation(tick)) { - val (toActivate, activeCore) = core.activate().takeNewActivations() + case (_, WrappedActivation(Activation(tick))) => + val (toActivate, activeCore) = core + .activate(tick) + .takeNewActivations() - toActivate.foreach { _ ! Activation(tick) } + toActivate.foreach { _ ! Activation(tick) } - active(data, activeCore) - } else { - stopOnError(ctx, s"Cannot activate with new tick $tick") - } + active(data, activeCore) case ( - ctx, + _, ScheduleActivation(actor, newTick, unlockKey) ) => - if (core.checkSchedule(newTick)) { - val (maybeSchedule, newCore) = core.handleSchedule(actor, newTick) - - maybeSchedule match { - case Some(scheduleTick) => - // also potentially schedule with parent if the new earliest tick is - // different from the old earliest tick (including if nothing had - // been scheduled before) - data.parent ! ScheduleActivation( - data.activationAdapter, - scheduleTick, - unlockKey - ) - case None => - // we don't need to escalate to the parent, this means that we can release the lock (if applicable) - unlockKey.foreach { - _.unlock() - } - } - - inactive(data, newCore) - } else { - stopOnError(ctx, s"Cannot schedule an event at tick $newTick") + val (maybeSchedule, newCore) = core.handleSchedule(actor, newTick) + maybeSchedule match { + case Some(scheduleTick) => + // also potentially schedule with parent if the new earliest tick is + // different from the old earliest tick (including if nothing had + // been scheduled before) + data.parent ! ScheduleActivation( + data.activationAdapter, + scheduleTick, + unlockKey + ) + case None => + // we don't need to escalate to the parent, this means that we can release the lock (if applicable) + unlockKey.foreach { + _.unlock() + } } + + inactive(data, newCore) + case (ctx, unexpected) => stopOnError( ctx, @@ -110,48 +105,32 @@ object Scheduler { ): Behavior[Incoming] = Behaviors.receive { case ( - ctx, + _, ScheduleActivation(actor, newTick, unlockKey) ) => - if (core.checkSchedule(actor, newTick)) { - val (toActivate, newCore) = - core.handleSchedule(actor, newTick).takeNewActivations() - - // if there's a lock: - // since we're active and any scheduled activation can still influence our next activation, - // we can directly unlock the lock with the key - unlockKey.foreach { - _.unlock() - } - - toActivate.foreach { - _ ! Activation(newCore.activeTick) - } + val (toActivate, newCore) = core + .handleSchedule(actor, newTick) + .takeNewActivations() + + // if there's a lock: + // since we're active and any scheduled activation can still influence our next activation, + // we can directly unlock the lock with the key + unlockKey.foreach { + _.unlock() + } - active(data, newCore) - } else { - stopOnError(ctx, s"Cannot schedule an event at tick $newTick") + toActivate.foreach { + _ ! Activation(newCore.activeTick) } - case (ctx, Completion(actor, maybeNewTick)) => - Either - .cond( - core.checkCompletion(actor), - core.handleCompletion(actor), - s"Actor $actor is not part of the expected completing actors" - ) - .flatMap { newCore => - // if successful + active(data, newCore) + + case (_, Completion(actor, maybeNewTick)) => + Scope(core.handleCompletion(actor)) + .map { newCore => maybeNewTick - .map { newTick => - Either - .cond( - newCore.checkSchedule(actor, newTick), - newCore.handleSchedule(actor, newTick), - s"Cannot schedule an event at tick $newTick for completing actor $actor" - ) - } - .getOrElse(Right(newCore)) + .map(newCore.handleSchedule(actor, _)) + .getOrElse(newCore) } .map { newCore => val (toActivate, updatedCore) = newCore.takeNewActivations() @@ -175,10 +154,7 @@ object Scheduler { active(data, newCore) } } - .fold( - stopOnError(ctx, _), - identity - ) + .get case (ctx, unexpected) => stopOnError(ctx, s"Received unexpected message $unexpected when active") @@ -196,4 +172,5 @@ object Scheduler { ], activationAdapter: ActorRef[Activation] ) + } diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala b/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala index 7fa9220bb5..1a16456e3f 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala @@ -31,40 +31,28 @@ object Core { */ trait InactiveCore { - /** Checks whether an activation of the scheduler is valid for given tick. - * This method cannot change the state of the inactive scheduler core. + /** Tries to handle an activation of the scheduler for given tick. If the + * activation for the tick is not valid, a + * [[edu.ie3.simona.exceptions.CriticalFailureException]] is thrown. If + * successful, an [[ActiveCore]] is returned with the active tick set to + * the earliest tick scheduled. * * @param newTick * The tick that the scheduler is to be activated with * @return - * true if activation with given tick is allowed, false if not + * The changed [[ActiveCore]] that should be used for the activated + * scheduler + * @throws edu.ie3.simona.exceptions.CriticalFailureException + * on critical error */ - def checkActivation(newTick: Long): Boolean - - /** This method should be called when the scheduler is activated. An - * [[ActiveCore]] is returned with the active tick set to the earliest tick - * scheduled. - * - * @return - * The [[ActiveCore]] that should be used for the activated scheduler - */ - def activate(): ActiveCore - - /** Checks whether scheduling an activation of an actor for given tick is - * valid. This method cannot change the state of the inactive scheduler - * core. - * - * @param newTick - * The tick that the actor wants to be scheduled for - * @return - * true if scheduling the activation is allowed, false if not - */ - def checkSchedule(newTick: Long): Boolean - - /** Handles the scheduling of an activation of given actor for given tick. - * If this activation scheduling makes a separate scheduling of the current - * scheduler with its parent necessary, the tick that the scheduler needs - * to be scheduled for is returned. + def activate(newTick: Long): ActiveCore + + /** Tries to handle the scheduling of an activation of given actor for given + * tick. If scheduling for the tick is not valid, a + * [[edu.ie3.simona.exceptions.CriticalFailureException]] is thrown. If, on + * the other hand, the activation scheduling is successful and makes a + * separate scheduling of the current scheduler with its parent necessary, + * the tick that the scheduler needs to be scheduled for is returned. * * @param actor * The actor to be scheduled @@ -72,12 +60,15 @@ object Core { * The tick that the actor is scheduled for * @return * A tuple of the optional tick that the current scheduler should be - * scheduled for with its parent, and the changed [[InactiveCore]] + * scheduled for with its parent and the changed [[InactiveCore]] + * @throws edu.ie3.simona.exceptions.CriticalFailureException + * on critical error */ def handleSchedule( actor: Actor, newTick: Long ): (Option[Long], InactiveCore) + } /** Data structure holding relevant data and providing methods that handle @@ -92,24 +83,16 @@ object Core { */ def activeTick: Long - /** Checks whether completing an activation of given actor for the currently - * active tick is valid. This method cannot change the state of the active - * scheduler core. - * - * @param actor - * The actor that wants to be complete its activation - * @return - * true if the completion is allowed, false if not - */ - def checkCompletion(actor: Actor): Boolean - - /** Handles the completion of an activation of given actor for the currently - * active tick. + /** Tries to handle the completion of an activation of given actor for the + * currently active tick. If the completion is not valid, a + * [[edu.ie3.simona.exceptions.CriticalFailureException]] is thrown. * * @param actor * The actor whose activation should be completed * @return * The changed [[ActiveCore]] + * @throws edu.ie3.simona.exceptions.CriticalFailureException + * on critical error */ def handleCompletion(actor: Actor): ActiveCore @@ -125,19 +108,9 @@ object Core { */ def maybeComplete(): Option[(Option[Long], InactiveCore)] - /** Checks whether scheduling an activation of an actor for given tick is - * valid. This method cannot change the state of the active scheduler core. - * - * @param actor - * The actor that wants to be scheduled for the given tick - * @param newTick - * The tick that the actor wants to be scheduled for - * @return - * true if scheduling the activation is allowed, false if not - */ - def checkSchedule(actor: Actor, newTick: Long): Boolean - - /** Handles the scheduling of an activation of given actor for given tick. + /** Tries to handle the scheduling of an activation of given actor for given + * tick. If the scheduling is not valid, a + * [[edu.ie3.simona.exceptions.CriticalFailureException]] is thrown. * * @param actor * The actor to be scheduled @@ -145,8 +118,13 @@ object Core { * The tick that the actor is scheduled for * @return * The changed [[ActiveCore]] + * @throws edu.ie3.simona.exceptions.CriticalFailureException + * on critical error */ - def handleSchedule(actor: Actor, newTick: Long): ActiveCore + def handleSchedule( + actor: Actor, + newTick: Long + ): ActiveCore /** Removes and returns activations scheduled for the current tick, which * can be sent out at the current moment. diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala b/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala index c6384db107..27f3dfdb00 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala @@ -6,6 +6,7 @@ package edu.ie3.simona.scheduler.core +import edu.ie3.simona.exceptions.CriticalFailureException import edu.ie3.simona.scheduler.core.Core.{ ActiveCore, Actor, @@ -34,30 +35,40 @@ object PhaseSwitchCore extends CoreFactory { private val activationQueue: PrioritySwitchBiSet[Long, Actor], private val lastActiveTick: Option[Long] ) extends InactiveCore { - override def checkActivation(newTick: Long): Boolean = - activationQueue.headKeyOption.contains(newTick) - - override def activate(): Core.ActiveCore = { - val nextActiveTick = activationQueue.headKeyOption.getOrElse( - throw new RuntimeException("Nothing scheduled, cannot activate.") + override def activate(newTick: Long): ActiveCore = { + val nextScheduledTick = activationQueue.headKeyOption.getOrElse( + throw new CriticalFailureException( + "No activation scheduled, cannot activate." + ) ) - PhaseSwitchActive(activationQueue, activeTick = nextActiveTick) - } - override def checkSchedule(newTick: Long): Boolean = - lastActiveTick.forall(newTick >= _ + 1) + if (nextScheduledTick != newTick) + throw new CriticalFailureException( + s"Cannot activate with new tick $newTick because $nextScheduledTick is the next scheduled tick." + ) + + PhaseSwitchActive(activationQueue, activeTick = newTick) + } override def handleSchedule( actor: Actor, newTick: Long ): (Option[Long], InactiveCore) = { + lastActiveTick.filter(newTick < _).foreach { lastActive => + throw new CriticalFailureException( + s"Cannot schedule an activation for $actor at tick $newTick because the last active tick is $lastActive" + ) + } + val oldEarliestTick = activationQueue.headKeyOption val updatedQueue = activationQueue.set(newTick, actor) val newEarliestTick = updatedQueue.headKeyOption val maybeScheduleTick = - Option.when(newEarliestTick != oldEarliestTick)(newEarliestTick).flatten + Option + .when(newEarliestTick != oldEarliestTick)(newEarliestTick) + .flatten (maybeScheduleTick, copy(activationQueue = updatedQueue)) } @@ -71,11 +82,14 @@ object PhaseSwitchCore extends CoreFactory { private val activeActors: Set[Actor] = Set.empty ) extends ActiveCore { - override def checkCompletion(actor: Actor): Boolean = - activeActors.contains(actor) + override def handleCompletion(actor: Actor): ActiveCore = { + if (!activeActors.contains(actor)) + throw new CriticalFailureException( + s"Actor $actor is not part of the expected completing actors" + ) - override def handleCompletion(actor: Actor): ActiveCore = copy(activeActors = activeActors.excl(actor)) + } override def maybeComplete(): Option[(Option[Long], InactiveCore)] = { Option.when( @@ -90,17 +104,28 @@ object PhaseSwitchCore extends CoreFactory { } } - override def checkSchedule(actor: Actor, newTick: Long): Boolean = { + override def handleSchedule( + actor: Actor, + newTick: Long + ): ActiveCore = { if (newTick == activeTick) { // what's done, is done: old phases are completed, // thus they cannot handle new activation schedulings - activationQueue.indexOf(actor).forall(_ >= phase) - } else - newTick > activeTick - } + if (activationQueue.indexOf(actor).exists(_ < phase)) { + val activeActor = activationQueue.values(phase) + throw new CriticalFailureException( + s"Cannot schedule an activation at tick $newTick for $actor while actor $activeActor is active now" + ) + } + } else { + if (newTick < activeTick) + throw new CriticalFailureException( + s"Cannot schedule an activation at tick $newTick for $actor while tick $activeTick is currently active" + ) + } - override def handleSchedule(actor: Actor, newTick: Long): ActiveCore = copy(activationQueue = activationQueue.set(newTick, actor)) + } override def takeNewActivations(): (Iterable[Actor], ActiveCore) = { Option diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala index cdc81cfdff..dfdb39c02e 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala @@ -6,6 +6,7 @@ package edu.ie3.simona.scheduler.core +import edu.ie3.simona.exceptions.CriticalFailureException import edu.ie3.simona.scheduler.core.Core.{ ActiveCore, Actor, @@ -26,30 +27,41 @@ object RegularSchedulerCore extends CoreFactory { private val activationQueue: PriorityMultiBiSet[Long, Actor], private val lastActiveTick: Option[Long] ) extends InactiveCore { - override def checkActivation(newTick: Long): Boolean = - activationQueue.headKeyOption.contains(newTick) - override def activate(): ActiveCore = { - val newActiveTick = activationQueue.headKeyOption.getOrElse( - throw new RuntimeException("Nothing scheduled, cannot activate.") + override def activate(newTick: Long): ActiveCore = { + val nextScheduledTick = activationQueue.headKeyOption.getOrElse( + throw new CriticalFailureException( + "No activation scheduled, cannot activate." + ) ) - SchedulerActive(activationQueue, activeTick = newActiveTick) - } - override def checkSchedule(newTick: Long): Boolean = - lastActiveTick.forall(newTick >= _ + 1) + if (nextScheduledTick != newTick) + throw new CriticalFailureException( + s"Cannot activate with new tick $newTick because $nextScheduledTick is the next scheduled tick." + ) + + SchedulerActive(activationQueue, activeTick = newTick) + } override def handleSchedule( actor: Actor, newTick: Long ): (Option[Long], InactiveCore) = { + lastActiveTick.filter(newTick < _).foreach { lastActive => + throw new CriticalFailureException( + s"Cannot schedule an activation for $actor at tick $newTick because the last active tick is $lastActive" + ) + } + val oldEarliestTick = activationQueue.headKeyOption activationQueue.set(newTick, actor) val newEarliestTick = activationQueue.headKeyOption val maybeScheduleTick = - Option.when(newEarliestTick != oldEarliestTick)(newEarliestTick).flatten + Option + .when(newEarliestTick != oldEarliestTick)(newEarliestTick) + .flatten (maybeScheduleTick, this) } @@ -61,11 +73,15 @@ object RegularSchedulerCore extends CoreFactory { private val activeActors: Set[Actor] = Set.empty, activeTick: Long ) extends ActiveCore { - override def checkCompletion(actor: Actor): Boolean = - activeActors.contains(actor) - override def handleCompletion(actor: Actor): ActiveCore = + override def handleCompletion(actor: Actor): ActiveCore = { + if (!activeActors.contains(actor)) + throw new CriticalFailureException( + s"Actor $actor is not part of the expected completing actors" + ) + copy(activeActors = activeActors.excl(actor)) + } override def maybeComplete(): Option[(Option[Long], InactiveCore)] = Option.when( @@ -78,10 +94,15 @@ object RegularSchedulerCore extends CoreFactory { ) } - override def checkSchedule(actor: Actor, newTick: Long): Boolean = - newTick >= activeTick + override def handleSchedule( + actor: Actor, + newTick: Long + ): ActiveCore = { + if (newTick < activeTick) + throw new CriticalFailureException( + s"Cannot schedule an activation at tick $newTick" + ) - override def handleSchedule(actor: Actor, newTick: Long): ActiveCore = { activationQueue.set(newTick, actor) this } diff --git a/src/main/scala/edu/ie3/util/scala/Scope.scala b/src/main/scala/edu/ie3/util/scala/Scope.scala new file mode 100644 index 0000000000..093419e449 --- /dev/null +++ b/src/main/scala/edu/ie3/util/scala/Scope.scala @@ -0,0 +1,43 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.util.scala + +/** Class that introduces functional ''mapping'' if there's an object that is + * not wrapped in a monad, such as [[Either]] or [[Option]]. + * + * This class is useful when code should be divided into multiple pieces that + * each have their own scope, so that objects of the same class are not + * confused. For example, in the following code snippet, ''a'', ''b'', ''c'' + * and ''d'' can be easily confused, which can lead to errors that are hard to + * trace. + * + * {{{ + * val a: Foo = create() + * val b: Foo = transform(a) + * val c: Foo = b.doStuff() + * val d: Foo = maybeBar.calculate(c) + * }}} + * + * When using a [[Scope]], the variables cannot be confused anymore: + * + * {{{ + * val d: Foo = Scope(create()) + * .map(transform) + * .map(_.doStuff) + * .map(maybeBar.calculate) + * }}} + * + * @param obj + * The object that is held + * @tparam T + * The type of the object + */ +final case class Scope[T](private val obj: T) { + def map[B](f: T => B): Scope[B] = Scope(f(obj)) + + def get: T = obj +} From 3c4d8e9c1d441c3d5c1887fba1eb5a3e35122310 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 17 Jan 2024 10:30:25 +0100 Subject: [PATCH 118/305] Changelog: Improvements to Scheduler --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65f07e90da..b11275b2a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Adapting to simonaAPI 0.3.0 (adapted message protocol) - Schedule lock [#651](https://github.com/ie3-institute/simona/issues/651) - New scheduling protocol [#650](https://github.com/ie3-institute/simona/issues/650) + - Small improvements to the code [#696](https://github.com/ie3-institute/simona/issues/696) - Replaced akka with pekko [#641](https://github.com/ie3-institute/simona/issues/641) - Use `ThermalGrid` to calculate thermal environment of a heat pump [#315](https://github.com/ie3-institute/simona/issues/315) From c949223474327c7ef67bab188f86c14bf2223049 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 17 Jan 2024 10:49:25 +0100 Subject: [PATCH 119/305] Adding test for a failure that has not been covered so far --- .../scheduler/PhaseSwitchSchedulerSpec.scala | 28 ++++++++++++++++++- .../ie3/simona/scheduler/SchedulerSpec.scala | 26 +++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala index b2c6dae582..4d1bb3119f 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala @@ -315,7 +315,33 @@ class PhaseSwitchSchedulerSpec } - "The Scheduler should fail and stop" when { + "The Scheduler with PhaseSwitchCore should fail and stop" when { + + "activated if no activation is scheduled" in { + val parent = TestProbe[SchedulerMessage]("parent") + val scheduler = spawn( + Scheduler(parent.ref, PhaseSwitchCore) + ) + + val agent1 = TestProbe[Activation]("agent_1") + + scheduler ! ScheduleActivation(agent1.ref, INIT_SIM_TICK) + + val sa1 = parent.expectMessageType[ScheduleActivation] + sa1.tick shouldBe INIT_SIM_TICK + val schedulerActivation = sa1.actor + + // TICK -1 + schedulerActivation ! Activation(INIT_SIM_TICK) + agent1.expectActivationAndComplete(scheduler, INIT_SIM_TICK, None) + parent.expectMessage(Completion(schedulerActivation, None)) + + // No activation scheduled, this should fail now + schedulerActivation ! Activation(0) + + // scheduler stopped + parent.expectTerminated(scheduler) + } "activated with wrong tick" in { val parent = TestProbe[SchedulerMessage]("parent") diff --git a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala index 072fc80f32..00f120509b 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala @@ -387,6 +387,32 @@ class SchedulerSpec "The Scheduler should fail and stop" when { + "activated if no activation is scheduled" in { + val parent = TestProbe[SchedulerMessage]("parent") + val scheduler = spawn( + Scheduler(parent.ref) + ) + + val agent1 = TestProbe[Activation]("agent_1") + + scheduler ! ScheduleActivation(agent1.ref, INIT_SIM_TICK) + + val sa1 = parent.expectMessageType[ScheduleActivation] + sa1.tick shouldBe INIT_SIM_TICK + val schedulerActivation = sa1.actor + + // TICK -1 + schedulerActivation ! Activation(INIT_SIM_TICK) + agent1.expectActivationAndComplete(scheduler, INIT_SIM_TICK, None) + parent.expectMessage(Completion(schedulerActivation, None)) + + // No activation scheduled, this should fail now + schedulerActivation ! Activation(0) + + // scheduler stopped + parent.expectTerminated(scheduler) + } + "activated with wrong tick" in { val parent = TestProbe[SchedulerMessage]("parent") val scheduler = spawn( From 711187086c5fe580b07d0a73459f372158dc8bcf Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 22 Jan 2024 21:11:30 +0100 Subject: [PATCH 120/305] Tighter error checking --- .../ie3/simona/scheduler/core/RegularSchedulerCore.scala | 2 +- .../scala/edu/ie3/simona/scheduler/SchedulerSpec.scala | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala index dfdb39c02e..4428393844 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala @@ -47,7 +47,7 @@ object RegularSchedulerCore extends CoreFactory { actor: Actor, newTick: Long ): (Option[Long], InactiveCore) = { - lastActiveTick.filter(newTick < _).foreach { lastActive => + lastActiveTick.filter(newTick <= _).foreach { lastActive => throw new CriticalFailureException( s"Cannot schedule an activation for $actor at tick $newTick because the last active tick is $lastActive" ) diff --git a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala index 00f120509b..bb92347d26 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala @@ -438,7 +438,7 @@ class SchedulerSpec parent.expectTerminated(scheduler) } - "asked to schedule activation for a past tick while inactive" in { + "asked to schedule activation for the last tick while inactive" in { val parent = TestProbe[SchedulerMessage]("parent") val scheduler = spawn( Scheduler(parent.ref) @@ -464,8 +464,9 @@ class SchedulerSpec parent.expectMessage(Completion(schedulerActivation, Some(1800))) // now inactive again - // can't schedule activation with earlier tick than last tick (900) -> error - scheduler ! ScheduleActivation(agent1.ref, INIT_SIM_TICK) + // can't schedule activation with tick equal to last tick (900) -> error + // same result with any other past tick + scheduler ! ScheduleActivation(agent1.ref, 900) // agent does not receive activation agent1.expectNoMessage() From a9ae9642c8f9882d80c56070ab70b5a67bf08e1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 08:18:44 +0000 Subject: [PATCH 121/305] Bump com.github.ben-manes.versions from 0.50.0 to 0.51.0 (#700) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 39e47a17a1..df74551b94 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id 'maven-publish' // publish to a maven repo (local or mvn central, has to be defined) id 'pmd' // code check, working on source code id 'com.diffplug.spotless' version '6.24.0'// code format - id "com.github.ben-manes.versions" version '0.50.0' + id "com.github.ben-manes.versions" version '0.51.0' id "de.undercouch.download" version "5.5.0" // downloads plugin id "kr.motd.sphinx" version "2.10.1" // documentation generation id "com.github.johnrengelman.shadow" version "8.1.1" // fat jar From 7a68478fe7bdf107c3b1ba5e0f16061f7268bd0f Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Tue, 23 Jan 2024 10:19:52 +0100 Subject: [PATCH 122/305] Enable windows paths for config parameter. --- CHANGELOG.md | 1 + .../scala/edu/ie3/simona/config/ArgsParser.scala | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65f07e90da..4fcbb5e899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New scheduling protocol [#650](https://github.com/ie3-institute/simona/issues/650) - Replaced akka with pekko [#641](https://github.com/ie3-institute/simona/issues/641) - Use `ThermalGrid` to calculate thermal environment of a heat pump [#315](https://github.com/ie3-institute/simona/issues/315) +- Enable windows path as config parameters [#549](https://github.com/ie3-institute/simona/issues/549) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) diff --git a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala index 65c563bd80..dd03a8eadd 100644 --- a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala +++ b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala @@ -10,6 +10,7 @@ import com.typesafe.config.{ConfigFactory, Config => TypesafeConfig} import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.event.listener.SimonaListenerCompanion import edu.ie3.util.scala.ReflectionTools +import org.apache.commons.io.FilenameUtils import scopt.{OptionParser => scoptOptionParser} import java.io.File @@ -40,20 +41,17 @@ object ArgsParser extends LazyLogging { new scoptOptionParser[Arguments]("simona") { opt[String]("config") .action((value, args) => { + val harmonized = FilenameUtils.normalize(value, true) + args.copy( - config = Some(parseTypesafeConfig(value)), - configLocation = Option(value) + config = Some(parseTypesafeConfig(harmonized)), + configLocation = Option(harmonized) ) }) .validate(value => if (value.trim.isEmpty) failure("config location cannot be empty") else success ) - .validate(value => - if (value.contains("\\")) - failure("wrong config path, expected: /, found: \\") - else success - ) .text("Location of the simona config file") .minOccurs(1) opt[Map[String, String]]("tArgs") @@ -232,7 +230,7 @@ object ArgsParser extends LazyLogging { val argsConfig = ConfigFactory.parseString( - s"""config = ${parsedArgs.configLocation.get} + s"""config = "${parsedArgs.configLocation.get}" |simona.runtime_configuration { | selected_subnets = [${parsedArgs.selectedSubnets.getOrElse("")}] | selected_volt_lvls = [${parsedArgs.selectedVoltLvls From 14e880010c674094beb258e9fbae2bca4a5f4491 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Tue, 23 Jan 2024 12:11:05 +0100 Subject: [PATCH 123/305] Remove CsvDataSource workaround --- CHANGELOG.md | 1 + .../service/weather/WeatherSource.scala | 5 ++--- .../util/scala/io/CsvDataSourceAdapter.java | 19 ------------------- .../util/scala/io/GraphicDataCleaner.scala | 2 +- 4 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 src/main/scala/edu/ie3/util/scala/io/CsvDataSourceAdapter.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 65f07e90da..52dd570404 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) - Removed version number "2.0" from the logo printed to console [#642](https://github.com/ie3-institute/simona/issues/642) - Fixed PV Model documentation [#684](https://github.com/ie3-institute/simona/issues/684), [#686](https://github.com/ie3-institute/simona/issues/686) +- Removed `CsvDataSourceAdapter` workaround [#702](https://github.com/ie3-institute/simona/issues/702) ## [3.0.0] - 2023-08-07 diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala index 14838d6afb..eb7262560c 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala @@ -15,7 +15,7 @@ import edu.ie3.datamodel.io.factory.timeseries.{ } import edu.ie3.datamodel.io.naming.FileNamingStrategy import edu.ie3.datamodel.io.source.IdCoordinateSource -import edu.ie3.datamodel.io.source.csv.CsvIdCoordinateSource +import edu.ie3.datamodel.io.source.csv.{CsvDataSource, CsvIdCoordinateSource} import edu.ie3.datamodel.io.source.sql.SqlIdCoordinateSource import edu.ie3.datamodel.models.value.WeatherValue import edu.ie3.simona.config.SimonaConfig @@ -39,7 +39,6 @@ import edu.ie3.simona.util.ConfigUtil.DatabaseConfigUtil.{ import edu.ie3.simona.util.ParsableEnumeration import edu.ie3.util.geo.{CoordinateDistance, GeoUtils} import edu.ie3.util.quantities.PowerSystemUnits -import edu.ie3.util.scala.io.CsvDataSourceAdapter import edu.ie3.util.scala.quantities.WattsPerSquareMeter import org.locationtech.jts.geom.{Coordinate, Point} import squants.motion.MetersPerSecond @@ -470,7 +469,7 @@ object WeatherSource { () => new CsvIdCoordinateSource( idCoordinateFactory, - new CsvDataSourceAdapter( + new CsvDataSource( csvSep, Paths.get(directoryPath), new FileNamingStrategy() diff --git a/src/main/scala/edu/ie3/util/scala/io/CsvDataSourceAdapter.java b/src/main/scala/edu/ie3/util/scala/io/CsvDataSourceAdapter.java deleted file mode 100644 index 16ea4883b6..0000000000 --- a/src/main/scala/edu/ie3/util/scala/io/CsvDataSourceAdapter.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * © 2023. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.util.scala.io; - -import edu.ie3.datamodel.io.naming.FileNamingStrategy; -import edu.ie3.datamodel.io.source.csv.CsvDataSource; -import java.nio.file.Path; - -public class CsvDataSourceAdapter extends CsvDataSource { - - public CsvDataSourceAdapter( - String csvSep, Path folderPath, FileNamingStrategy fileNamingStrategy) { - super(csvSep, folderPath, fileNamingStrategy); - } -} diff --git a/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala b/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala index 7737599d18..e4a66cbf5c 100644 --- a/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala +++ b/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala @@ -31,7 +31,7 @@ object GraphicDataCleaner { /* setup */ val dataSource: CsvDataSource = - new CsvDataSourceAdapter(csvSep, baseFolder, fileNamingStrategy) + new CsvDataSource(csvSep, baseFolder, fileNamingStrategy) val csvTypeSource: TypeSource = new TypeSource(dataSource) From 04ce5ffc3da3211cd606df86027c7b093cae5a6c Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 23 Jan 2024 14:05:46 +0100 Subject: [PATCH 124/305] Fixing duration calculation in result events Testing for the bug as well --- CHANGELOG.md | 1 + .../simona/scheduler/RuntimeNotifier.scala | 13 +- .../simona/scheduler/TimeAdvancerSpec.scala | 304 ++++++++++++++---- 3 files changed, 244 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52dd570404..141a920fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removed version number "2.0" from the logo printed to console [#642](https://github.com/ie3-institute/simona/issues/642) - Fixed PV Model documentation [#684](https://github.com/ie3-institute/simona/issues/684), [#686](https://github.com/ie3-institute/simona/issues/686) - Removed `CsvDataSourceAdapter` workaround [#702](https://github.com/ie3-institute/simona/issues/702) +- Logging wrong duration in the first simulation hour [#705](https://github.com/ie3-institute/simona/issues/705) ## [3.0.0] - 2023-08-07 diff --git a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala index f80011fb2f..0ca024a2ac 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala @@ -28,7 +28,7 @@ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK * Time in milliseconds when the simulation was last started (before * initialization or after a pause) * @param lastCheckWindowTime - * Time when in milliseconds when + * Time in milliseconds when the last check window was passed */ final case class RuntimeNotifier( eventListener: ActorRef[RuntimeEvent], @@ -65,10 +65,15 @@ final case class RuntimeNotifier( Simulating(tick, pauseOrEndTick) }) - if (tick > 0L) - copy(lastStartTime = nowTime) + if (simStartTime > -1) + // Has been started before: resuming simulation + copy(lastStartTime = nowTime, lastCheckWindowTime = nowTime) else - copy(simStartTime = nowTime, lastStartTime = nowTime) + copy( + simStartTime = nowTime, + lastStartTime = nowTime, + lastCheckWindowTime = nowTime + ) } /** Notifier listeners that simulation is pausing at given tick diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index 21edf2210f..63cc83ce42 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -32,6 +32,11 @@ class TimeAdvancerSpec with AnyWordSpecLike with should.Matchers { + /** A high duration in milliseconds for RuntimeEvent duration checking. The + * tests should under no circumstance take longer than ten minutes. + */ + private val maxEventDuration: Long = 10 * 60 * 1000 + "The TimeAdvancer should work correctly" when { "started checkWindow but without pauseTick" in { @@ -62,7 +67,10 @@ class TimeAdvancerSpec // tick -1 is completed timeAdvancer ! Completion(scheduler.ref, Some(0)) - listener.expectMessageType[InitComplete] + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } // tick 0 is activated automatically scheduler.expectMessage(Activation(0)) @@ -70,9 +78,21 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref, Some(3600)) - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 2700 + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 2700 + duration should (be >= 0 and be < maxEventDuration) + } // tick 3600 is activated automatically scheduler.expectMessage(Activation(3600)) @@ -80,10 +100,26 @@ class TimeAdvancerSpec // tick 3600 is completed timeAdvancer ! Completion(scheduler.ref, Some(7200)) - listener.expectMessageType[CheckWindowPassed].tick shouldBe 3600 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 4500 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 5400 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 6300 + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 4500 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 5400 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 6300 + duration should (be >= 0 and be < maxEventDuration) + } // tick 7200 is activated automatically scheduler.expectMessage(Activation(7200)) @@ -91,9 +127,12 @@ class TimeAdvancerSpec // tick 7200 is completed timeAdvancer ! Completion(scheduler.ref) - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 7200 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 7200 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -121,7 +160,10 @@ class TimeAdvancerSpec // tick -1 is completed timeAdvancer ! Completion(scheduler.ref, Some(0)) - listener.expectMessageType[InitComplete] + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } // tick 0 is activated automatically scheduler.expectMessage(Activation(0)) @@ -137,9 +179,12 @@ class TimeAdvancerSpec // tick 3600 is completed timeAdvancer ! Completion(scheduler.ref) - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -172,7 +217,10 @@ class TimeAdvancerSpec // tick -1 is completed timeAdvancer ! Completion(scheduler.ref, Some(3600)) - listener.expectMessageType[InitComplete] + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } listener.expectMessageType[Ready].tick shouldBe INIT_SIM_TICK // simulation should be paused @@ -189,13 +237,28 @@ class TimeAdvancerSpec // tick 3600 is completed timeAdvancer ! Completion(scheduler.ref) // check window events should only come now, since we paused at -1 before - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 2700 - - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 2700 + duration should (be >= 0 and be < maxEventDuration) + } + + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -227,7 +290,10 @@ class TimeAdvancerSpec // tick -1 is completed timeAdvancer ! Completion(scheduler.ref, Some(0)) - listener.expectMessageType[InitComplete] + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } // tick 0 is activated automatically scheduler.expectMessage(Activation(0)) @@ -235,10 +301,26 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref, Some(5400)) - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 2700 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 3600 + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 2700 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + } listener.expectMessageType[Ready].tick shouldBe 3600 // simulation should be paused @@ -254,10 +336,17 @@ class TimeAdvancerSpec // tick 5400 is completed timeAdvancer ! Completion(scheduler.ref) - listener.expectMessageType[CheckWindowPassed].tick shouldBe 4500 - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 5400 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 4500 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 5400 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -289,7 +378,10 @@ class TimeAdvancerSpec // tick -1 is completed timeAdvancer ! Completion(scheduler.ref, Some(0)) - listener.expectMessageType[InitComplete] + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } // tick 0 is activated automatically scheduler.expectMessage(Activation(0)) @@ -297,9 +389,21 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref, Some(3600)) - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 2700 + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 2700 + duration should (be >= 0 and be < maxEventDuration) + } listener.expectMessageType[Ready].tick shouldBe 3599 // simulation should be paused @@ -315,9 +419,12 @@ class TimeAdvancerSpec // tick 3600 is completed timeAdvancer ! Completion(scheduler.ref) - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -349,15 +456,25 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref, Some(3601)) - listener.expectMessageType[InitComplete] - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } // tick 3601 should not be activated! scheduler.expectNoMessage() - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -389,17 +506,35 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref) - listener.expectMessageType[InitComplete] - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 - listener.expectMessageType[CheckWindowPassed].tick shouldBe 2700 + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 2700 + duration should (be >= 0 and be < maxEventDuration) + } // scheduler should not be activated! scheduler.expectNoMessage() - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -431,15 +566,25 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref) - listener.expectMessageType[InitComplete] - listener.expectMessageType[CheckWindowPassed].tick shouldBe 1800 + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + } // scheduler should not be activated! scheduler.expectNoMessage() - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 3600 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 3600 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -471,15 +616,25 @@ class TimeAdvancerSpec // tick 0 is completed timeAdvancer ! Completion(scheduler.ref) - listener.expectMessageType[InitComplete] - listener.expectMessageType[CheckWindowPassed].tick shouldBe 900 + listener.expectMessageType[InitComplete] match { + case InitComplete(duration) => + duration should (be >= 0 and be < maxEventDuration) + } + listener.expectMessageType[CheckWindowPassed] match { + case CheckWindowPassed(tick, duration) => + tick shouldBe 900 + duration should (be >= 0 and be < maxEventDuration) + } // scheduler should not be activated! scheduler.expectNoMessage() - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 1800 - doneMsg.errorInSim shouldBe false + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 1800 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe false + } simulation.expectMessage(SimulationSuccessful) } @@ -515,9 +670,12 @@ class TimeAdvancerSpec listener.expectMessageType[Error].errMsg should include( "tick -1, although current active tick was 0" ) - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 0 - doneMsg.errorInSim shouldBe true + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 0 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe true + } // scheduler should not be activated! scheduler.expectNoMessage() @@ -559,9 +717,12 @@ class TimeAdvancerSpec timeAdvancer ! Stop("Test message") listener.expectMessageType[Error].errMsg should include("Test message") - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 1 - doneMsg.errorInSim shouldBe true + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 1 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe true + } scheduler.expectTerminated(timeAdvancer) @@ -594,9 +755,12 @@ class TimeAdvancerSpec timeAdvancer ! Stop("Test message") listener.expectMessageType[Error].errMsg should include("Test message") - val doneMsg = listener.expectMessageType[Done] - doneMsg.tick shouldBe 0 - doneMsg.errorInSim shouldBe true + listener.expectMessageType[Done] match { + case Done(tick, duration, errorInSim) => + tick shouldBe 0 + duration should (be >= 0 and be < maxEventDuration) + errorInSim shouldBe true + } scheduler.expectTerminated(timeAdvancer) From 183b10eedb8365cb1fd26e17ef5a816b79f80f37 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 23 Jan 2024 15:43:36 +0100 Subject: [PATCH 125/305] Fixing compile error --- .../simona/scheduler/TimeAdvancerSpec.scala | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index 63cc83ce42..d85cf910e5 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -69,7 +69,7 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(0)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 0 is activated automatically @@ -81,17 +81,17 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 2700 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 3600 is activated automatically @@ -103,22 +103,22 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 4500 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 5400 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 6300 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 7200 is activated automatically @@ -130,7 +130,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 7200 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -162,7 +162,7 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(0)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 0 is activated automatically @@ -182,7 +182,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -219,7 +219,7 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(3600)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[Ready].tick shouldBe INIT_SIM_TICK @@ -240,23 +240,23 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 2700 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -292,7 +292,7 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(0)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 0 is activated automatically @@ -304,22 +304,22 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 2700 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[Ready].tick shouldBe 3600 @@ -339,12 +339,12 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 4500 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 5400 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -380,7 +380,7 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(0)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 0 is activated automatically @@ -392,17 +392,17 @@ class TimeAdvancerSpec listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 2700 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[Ready].tick shouldBe 3599 @@ -422,7 +422,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -458,12 +458,12 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref, Some(3601)) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // tick 3601 should not be activated! @@ -472,7 +472,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -508,22 +508,22 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 2700 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // scheduler should not be activated! @@ -532,7 +532,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -568,12 +568,12 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // scheduler should not be activated! @@ -582,7 +582,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 3600 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -618,12 +618,12 @@ class TimeAdvancerSpec timeAdvancer ! Completion(scheduler.ref) listener.expectMessageType[InitComplete] match { case InitComplete(duration) => - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } listener.expectMessageType[CheckWindowPassed] match { case CheckWindowPassed(tick, duration) => tick shouldBe 900 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) } // scheduler should not be activated! @@ -632,7 +632,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 1800 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe false } @@ -673,7 +673,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 0 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe true } @@ -720,7 +720,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 1 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe true } @@ -758,7 +758,7 @@ class TimeAdvancerSpec listener.expectMessageType[Done] match { case Done(tick, duration, errorInSim) => tick shouldBe 0 - duration should (be >= 0 and be < maxEventDuration) + duration should (be >= 0L and be < maxEventDuration) errorInSim shouldBe true } From 664226a63bc5e1d914a93349d7400beb16419998 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 23 Jan 2024 17:07:31 +0100 Subject: [PATCH 126/305] Fixing duration calculation for Done messages --- src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala index 0ca024a2ac..4735ba208c 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala @@ -140,7 +140,7 @@ final case class RuntimeNotifier( notify( Done( endTick, - simStartTime - now(), + now() - simStartTime, errorInSim = false ) ) @@ -161,7 +161,7 @@ final case class RuntimeNotifier( notify( Done( endTick, - simStartTime - now(), + now() - simStartTime, errorInSim = true ) ) From bbe835679de6fd783507e55dcc8eacf193541ac6 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 23 Jan 2024 17:38:41 +0100 Subject: [PATCH 127/305] Fixing duration when early error happens --- .../simona/scheduler/RuntimeNotifier.scala | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala index 4735ba208c..4e11d597e2 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.scheduler import org.apache.pekko.actor.typed.ActorRef import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.RuntimeEvent._ -import edu.ie3.simona.scheduler.RuntimeNotifier.now +import edu.ie3.simona.scheduler.RuntimeNotifier._ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK /** Determines runtime events at different stages of the simulation and notifies @@ -31,12 +31,12 @@ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK * Time in milliseconds when the last check window was passed */ final case class RuntimeNotifier( - eventListener: ActorRef[RuntimeEvent], - readyCheckWindow: Option[Int], - lastCheck: Long = -1, - simStartTime: Long = -1, - lastStartTime: Long = -1, - lastCheckWindowTime: Long = -1 + private val eventListener: ActorRef[RuntimeEvent], + private val readyCheckWindow: Option[Int], + private val lastCheck: Option[Long] = None, + private val simStartTime: Option[Long] = None, + private val lastStartTime: Option[Long] = None, + private val lastCheckWindowTime: Option[Long] = None ) { /** Notifier listeners that simulation has started or continued with given @@ -65,14 +65,14 @@ final case class RuntimeNotifier( Simulating(tick, pauseOrEndTick) }) - if (simStartTime > -1) + if (simStartTime.nonEmpty) // Has been started before: resuming simulation - copy(lastStartTime = nowTime, lastCheckWindowTime = nowTime) + copy(lastStartTime = Some(nowTime), lastCheckWindowTime = Some(nowTime)) else copy( - simStartTime = nowTime, - lastStartTime = nowTime, - lastCheckWindowTime = nowTime + simStartTime = Some(nowTime), + lastStartTime = Some(nowTime), + lastCheckWindowTime = Some(nowTime) ) } @@ -83,7 +83,7 @@ final case class RuntimeNotifier( * Updated notifier */ def pausing(pauseTick: Long): RuntimeNotifier = { - notify(Ready(pauseTick, now() - simStartTime)) + notify(Ready(pauseTick, duration(simStartTime))) this } @@ -99,35 +99,33 @@ final case class RuntimeNotifier( def completing(completedTick: Long): RuntimeNotifier = { val nowTime = now() - // check if InitComplete should be sent, then adjust lastCheck - val adjustedLastCheck = if (lastCheck <= -1) { - if (completedTick >= INIT_SIM_TICK) - notify(InitComplete(nowTime - simStartTime)) - 0 - } else - lastCheck + // first tick (usually INIT_SIM_TICK) has completed + if (lastCheck.isEmpty) + notify(InitComplete(duration(simStartTime))) + + // start with 0 if this is the first completed tick + val adjustedLastCheck = lastCheck.getOrElse(0L) readyCheckWindow .flatMap { checkWindow => val completedWindows = (adjustedLastCheck + checkWindow) to completedTick by checkWindow + completedWindows.foreach { tick => + notify(CheckWindowPassed(tick, duration(lastStartTime, nowTime))) + } + completedWindows.lastOption .map { lastPassedCheck => - // at least one window has been passed - completedWindows.foreach { tick => - notify(CheckWindowPassed(tick, nowTime - lastCheckWindowTime)) - } - copy( - lastCheck = lastPassedCheck, - lastCheckWindowTime = nowTime + lastCheck = Some(lastPassedCheck), + lastCheckWindowTime = Some(nowTime) ) } } .getOrElse { // no check window set or no windows passed - copy(lastCheck = adjustedLastCheck) + copy(lastCheck = Some(adjustedLastCheck)) } } @@ -140,7 +138,7 @@ final case class RuntimeNotifier( notify( Done( endTick, - now() - simStartTime, + duration(simStartTime), errorInSim = false ) ) @@ -161,7 +159,7 @@ final case class RuntimeNotifier( notify( Done( endTick, - now() - simStartTime, + duration(simStartTime), errorInSim = true ) ) @@ -174,6 +172,23 @@ final case class RuntimeNotifier( object RuntimeNotifier { + /** Returns the duration from given interval start to end, with a fallback + * duration of 0 if the start is not (yet) set (which can happen in edge + * cases, e.g. simulation failed and aborts) + * + * @param intervalStart + * Optional start of the interval + * @param intervalEnd + * The end of the interval + * @return + * The duration in milliseconds + */ + private def duration( + intervalStart: Option[Long], + intervalEnd: Long = now() + ): Long = + intervalStart.map(intervalEnd - _).getOrElse(0) + /** @return * Current time in milliseconds */ From 707fc989981b6f9d2bb6d7fc19fcf86710169124 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:38:16 +0000 Subject: [PATCH 128/305] Bump com.diffplug.spotless from 6.24.0 to 6.25.0 (#711) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index df74551b94..1279fd5819 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { id 'signing' id 'maven-publish' // publish to a maven repo (local or mvn central, has to be defined) id 'pmd' // code check, working on source code - id 'com.diffplug.spotless' version '6.24.0'// code format + id 'com.diffplug.spotless' version '6.25.0'// code format id "com.github.ben-manes.versions" version '0.51.0' id "de.undercouch.download" version "5.5.0" // downloads plugin id "kr.motd.sphinx" version "2.10.1" // documentation generation From 88918ac15f83c2fcd2c62a2470a340e8bacc06c6 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 24 Jan 2024 12:51:21 +0100 Subject: [PATCH 129/305] Alternative solution: Allowing Windows paths (backslashes), but escaping them when necessary --- src/main/scala/edu/ie3/simona/config/ArgsParser.scala | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala index dd03a8eadd..502564d5d6 100644 --- a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala +++ b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala @@ -10,7 +10,6 @@ import com.typesafe.config.{ConfigFactory, Config => TypesafeConfig} import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.event.listener.SimonaListenerCompanion import edu.ie3.util.scala.ReflectionTools -import org.apache.commons.io.FilenameUtils import scopt.{OptionParser => scoptOptionParser} import java.io.File @@ -41,11 +40,9 @@ object ArgsParser extends LazyLogging { new scoptOptionParser[Arguments]("simona") { opt[String]("config") .action((value, args) => { - val harmonized = FilenameUtils.normalize(value, true) - args.copy( - config = Some(parseTypesafeConfig(harmonized)), - configLocation = Option(harmonized) + config = Some(parseTypesafeConfig(value)), + configLocation = Option(value) ) }) .validate(value => @@ -230,7 +227,7 @@ object ArgsParser extends LazyLogging { val argsConfig = ConfigFactory.parseString( - s"""config = "${parsedArgs.configLocation.get}" + s"""config = "${parsedArgs.configLocation.get.replace("\\", "\\\\")}" |simona.runtime_configuration { | selected_subnets = [${parsedArgs.selectedSubnets.getOrElse("")}] | selected_volt_lvls = [${parsedArgs.selectedVoltLvls From 00ecca684248a5da857274a93278015d0ac87b76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 09:25:12 +0000 Subject: [PATCH 130/305] Bump org.mockito:mockito-core from 5.9.0 to 5.10.0 (#713) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1279fd5819..157c5d3dd5 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,7 @@ dependencies { /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' - testImplementation 'org.mockito:mockito-core:5.9.0' // mocking framework + testImplementation 'org.mockito:mockito-core:5.10.0' // mocking framework testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.17" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0' From 0f49043bf7aa8c204de891ffa67d8bdd00c7da92 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 11:55:52 +0100 Subject: [PATCH 131/305] Applying changes from all/#tbw-wHp-squants-2023-12 --- CHANGELOG.md | 2 + build.gradle | 2 +- .../resources/config/config-template.conf | 2 + .../edu/ie3/simona/agent/ValueStore.scala | 67 +- .../agent/participant/ParticipantAgent.scala | 261 ++++++-- .../ParticipantAgentFundamentals.scala | 613 ++++++++++++++---- .../participant/ServiceRegistration.scala | 39 +- .../agent/participant/evcs/EvcsAgent.scala | 23 +- .../fixedfeedin/FixedFeedInAgent.scala | 4 +- .../FixedFeedInAgentFundamentals.scala | 149 ++++- .../simona/agent/participant/hp/HpAgent.scala | 5 +- .../agent/participant/load/LoadAgent.scala | 4 +- .../load/LoadAgentFundamentals.scala | 194 +++++- .../simona/agent/participant/pv/PvAgent.scala | 4 +- .../participant/pv/PvAgentFundamentals.scala | 284 +++++--- .../participant/statedata/BaseStateData.scala | 69 +- .../statedata/InitializeStateData.scala | 5 +- .../statedata/ParticipantStateData.scala | 95 ++- .../agent/participant/wec/WecAgent.scala | 6 +- .../wec/WecAgentFundamentals.scala | 246 +++++-- .../edu/ie3/simona/config/SimonaConfig.scala | 7 +- .../edu/ie3/simona/event/ResultEvent.scala | 15 +- .../event/listener/ResultEventListener.scala | 5 + .../event/notifier/NotifierConfig.scala | 3 +- .../edu/ie3/simona/model/em/EmTools.scala | 78 +++ .../ApparentPowerAndHeatParticipant.scala | 21 +- .../ApparentPowerParticipant.scala | 8 +- .../simona/model/participant/BMModel.scala | 31 +- .../simona/model/participant/ChpModel.scala | 25 +- .../model/participant/FixedFeedInModel.scala | 31 +- .../participant/FlexChangeIndicator.scala | 12 + .../simona/model/participant/ModelState.scala | 14 + .../simona/model/participant/PvModel.scala | 24 +- .../model/participant/SystemParticipant.scala | 43 +- .../simona/model/participant/WecModel.scala | 30 +- .../participant/load/FixedLoadModel.scala | 2 + .../model/participant/load/LoadModel.scala | 26 +- .../participant/load/LoadReference.scala | 2 +- .../load/profile/LoadProfileStore.scala | 7 +- .../load/profile/ProfileLoadModel.scala | 6 +- .../load/random/RandomLoadModel.scala | 6 +- .../messages/flex/FlexibilityMessage.scala | 141 ++++ .../flex/MinMaxFlexibilityMessage.scala | 108 +++ .../messages/services/EvMessage.scala | 8 +- .../services/PrimaryDataMessage.scala | 4 +- .../messages/services/ServiceMessage.scala | 17 +- .../messages/services/WeatherMessage.scala | 2 + .../simona/service/ev/ExtEvDataService.scala | 2 +- .../service/primary/PrimaryServiceProxy.scala | 6 +- .../primary/PrimaryServiceWorker.scala | 4 +- .../service/weather/WeatherService.scala | 13 +- .../ie3/simona/sim/setup/SetupHelper.scala | 4 +- .../edu/ie3/simona/util/ConfigUtil.scala | 26 +- .../scala/edu/ie3/simona/util/TickUtil.scala | 5 +- .../util/scala/quantities/ReactivePower.scala | 2 +- .../model/participant/BMModelTest.groovy | 2 +- .../participant/FixedFeedModelTest.groovy | 2 +- .../simona/model/participant/PvModelIT.groovy | 2 +- .../model/participant/WecModelTest.groovy | 35 +- .../load/FixedLoadModelTest.groovy | 5 +- .../load/ProfileLoadModelTest.groovy | 9 +- .../load/RandomLoadModelTest.groovy | 7 +- .../test/common/model/MockParticipant.groovy | 21 +- .../edu/ie3/simona/agent/ValueStoreSpec.scala | 4 +- .../grid/DBFSAlgorithmParticipantSpec.scala | 5 +- .../agent/grid/DBFSMockGridAgents.scala | 2 +- ...FixedFeedInAgentModelCalculationSpec.scala | 56 +- .../LoadAgentFixedModelCalculationSpec.scala | 56 +- ...LoadAgentProfileModelCalculationSpec.scala | 51 +- .../ParticipantAgent2ListenerSpec.scala | 32 +- .../ParticipantAgentExternalSourceSpec.scala | 65 +- .../ParticipantAgentFundamentalsSpec.scala | 60 +- .../participant/ParticipantAgentMock.scala | 184 +++++- .../PvAgentModelCalculationSpec.scala | 150 +++-- .../WecAgentModelCalculationSpec.scala | 136 ++-- .../simona/config/ConfigFailFastSpec.scala | 18 +- .../edu/ie3/simona/event/NotifierSpec.scala | 1 - .../ApparentPowerAndHeatSpec.scala | 59 +- .../primary/PrimaryServiceProxySpec.scala | 6 +- .../primary/PrimaryServiceProxySqlIT.scala | 6 +- .../primary/PrimaryServiceWorkerSpec.scala | 33 +- .../primary/PrimaryServiceWorkerSqlIT.scala | 4 +- .../service/weather/WeatherServiceSpec.scala | 22 +- .../simona/test/ParticipantAgentSpec.scala | 5 +- .../simona/test/common/DefaultTestData.scala | 1 + .../test/common/input/EvcsInputTestData.scala | 3 +- .../edu/ie3/simona/util/ConfigUtilSpec.scala | 66 +- 87 files changed, 3062 insertions(+), 858 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/model/em/EmTools.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/ModelState.scala create mode 100644 src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala create mode 100644 src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index 52dd570404..608cc1582a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Instantiation of Heat Pump Agents [#253](https://github.com/ie3-institute/simona/issues/253) - Output of accompanying thermal result models - Added JDK installation, Scala Plugin + SDK in usersguide [#324](https://github.com/ie3-institute/simona/issues/324) +- Energy Management capabilities: + - Added capability of SystemParticipants to handle flexibility [#308](https://github.com/ie3-institute/simona/issues/308) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) diff --git a/build.gradle b/build.gradle index 157c5d3dd5..39a800ea26 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ ext { pekkoVersion = '1.0.1' jtsVersion = '1.19.0' confluentKafkaVersion = '7.4.0' - tscfgVersion = '1.0.2' + tscfgVersion = '1.0.0' scapegoatVersion = '2.1.3' testContainerVersion = '0.41.0' diff --git a/src/main/resources/config/config-template.conf b/src/main/resources/config/config-template.conf index e5448bcb6a..8e0a5f4882 100644 --- a/src/main/resources/config/config-template.conf +++ b/src/main/resources/config/config-template.conf @@ -111,6 +111,7 @@ SimpleOutputConfig { ParticipantBaseOutputConfig { base: BaseOutputConfig powerRequestReply: boolean # Inform listeners about power request replies + flexResult: boolean | false } #@define @@ -257,6 +258,7 @@ simona.output.thermal = { defaultConfig = SimpleOutputConfig individualConfigs = [SimpleOutputConfig] } +simona.output.flex = Boolean | false ################################################################## # Runtime Configuration // todo refactor as this naming is misleading diff --git a/src/main/scala/edu/ie3/simona/agent/ValueStore.scala b/src/main/scala/edu/ie3/simona/agent/ValueStore.scala index eea250e176..38fea13e80 100644 --- a/src/main/scala/edu/ie3/simona/agent/ValueStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/ValueStore.scala @@ -9,6 +9,8 @@ package edu.ie3.simona.agent import edu.ie3.simona.util.SimonaConstants import squants.Dimensionless +import scala.collection.SortedMap + /** Represents a value store to hold data of former ticks * * @param maxTickSpan @@ -20,7 +22,7 @@ import squants.Dimensionless */ final case class ValueStore[+D]( maxTickSpan: Long, - private val store: Map[Long, D] = Map.empty[Long, D] + private val store: SortedMap[Long, D] = SortedMap.empty[Long, D] ) { /** Determine the lastly known data tick, if available. Includes the given @@ -42,9 +44,7 @@ final case class ValueStore[+D]( * An Option to the last entry */ def last(requestedTick: Long): Option[(Long, D)] = - store - .filter(_._1 <= requestedTick) - .maxByOption(_._1) + store.rangeTo(requestedTick).lastOption /** Get the last known entry (with the highest tick) * @@ -52,7 +52,27 @@ final case class ValueStore[+D]( * An Option to the last entry */ def last(): Option[(Long, D)] = - store.maxByOption(_._1) + store.lastOption + + /** Optionally returns the entry for given tick + * @param tick + * The tick + * @return + * The data for the tick if it exists, otherwise [[None]] + */ + def get(tick: Long): Option[D] = + store.get(tick) + + /** Returns the data associated with a tick, or a default value if no data + * exists for the tick. + * @param tick + * The tick + * @return + * the data associated with `tick` if it exists, otherwise the result of + * the `default` function. + */ + def getOrElse[D2 >: D](tick: Long, default: => D2): D2 = + store.getOrElse(tick, default) /** Acquires the stored information within the specified tick window * @@ -65,20 +85,13 @@ final case class ValueStore[+D]( * in the value store */ def get(requestStart: Long, requestEnd: Long): Map[Long, D] = - store.filter(entry => entry._1 >= requestStart && entry._1 <= requestEnd) + store.rangeFrom(requestStart).rangeTo(requestEnd).toMap - /** Checks, if all needed ticks are available in the given value store - * - * @param neededTicks - * An Array of needed ticks - * @return - * true, if everything is there - */ - def allTicksAvailable(neededTicks: Array[Long]): Boolean = - store.keySet.toSeq.sorted.containsSlice(neededTicks.toSeq.sorted) + def asMap: Map[Long, D] = + store.toMap } -case object ValueStore { +object ValueStore { /** Create a default "empty" voltage value store which requires an initial * voltage value to be set for tick 0 @@ -96,7 +109,7 @@ case object ValueStore { ): ValueStore[Dimensionless] = new ValueStore( maxTickSpan, - Map(SimonaConstants.FIRST_TICK_IN_SIMULATION -> initialPerUnit) + SortedMap(SimonaConstants.FIRST_TICK_IN_SIMULATION -> initialPerUnit) ) /** Create a value store for result values. A result value store requires a @@ -132,8 +145,20 @@ case object ValueStore { valueStore: ValueStore[D], tick: Long, newEntry: D - ): ValueStore[D] = valueStore.copy( - store = (valueStore.store + (tick -> newEntry)) - .filter(pair => pair._1 > tick - valueStore.maxTickSpan) - ) + ): ValueStore[D] = { + val updatedStore = valueStore.store ++ SortedMap(tick -> newEntry) + + // always keep at least 3 entries + val minKeep = 3 + + valueStore.copy( + store = if (updatedStore.size > minKeep) { + val (rest, keep) = updatedStore.splitAt(updatedStore.size - minKeep) + val restPruned = rest.rangeFrom(tick - valueStore.maxTickSpan + 1L) + + restPruned ++ keep + } else + updatedStore + ) + } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala index 063ff508f5..176a67fecc 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala @@ -6,10 +6,8 @@ package edu.ie3.simona.agent.participant -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.SystemParticipantInput -import edu.ie3.simona.agent.SimonaAgent +import edu.ie3.simona.agent.{SimonaAgent, ValueStore} import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.participant.ParticipantAgent.{ StartCalculationTrigger, @@ -38,8 +36,19 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.{ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.InconsistentStateException -import edu.ie3.simona.model.participant.{CalcRelevantData, SystemParticipant} +import edu.ie3.simona.model.participant.ModelState.ConstantState +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + FlexChangeIndicator, + ModelState, + SystemParticipant +} import edu.ie3.simona.ontology.messages.Activation +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexResponse, + IssueFlexControl, + RequestFlexOptions +} import edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage @@ -50,9 +59,13 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Power} import java.time.ZonedDateTime +import scala.reflect.ClassTag /** Common properties to participant agents * @@ -60,6 +73,8 @@ import java.time.ZonedDateTime * Type of primary data, the calculation model will produce * @tparam CD * Type of compilation of [[SecondaryData]], that are needed for calculation + * @tparam MS + * Type of model state data * @tparam D * Type of participant state data to use * @tparam I @@ -77,15 +92,30 @@ import java.time.ZonedDateTime abstract class ParticipantAgent[ PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, + MS <: ModelState, D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD] -](scheduler: ActorRef, initStateData: ParticipantInitializeStateData[I, MC, PD]) + M <: SystemParticipant[CD, PD, MS] +]( + scheduler: ActorRef, + initStateData: ParticipantInitializeStateData[I, MC, PD] +)(implicit val tag: ClassTag[MS]) extends SimonaAgent[ParticipantStateData[PD]] { val alternativeResult: PD + /** Partial function, that is able to transfer + * [[ParticipantModelBaseStateData]] (holding the actual calculation model) + * into a pair of active and reactive power + */ + protected val calculateModelPowerFunc: ( + Long, + ParticipantModelBaseStateData[PD, CD, MS, M], + MS, + squants.Dimensionless + ) => PD + // general agent states // first fsm state of the agent startWith(Uninitialized, ParticipantUninitializedStateData[PD]()) @@ -110,26 +140,27 @@ abstract class ParticipantAgent[ initStateData.simulationEndDate, initStateData.resolution, initStateData.requestVoltageDeviationThreshold, - initStateData.outputConfig + initStateData.outputConfig, + initStateData.maybeEmAgent ) } when(Idle) { case Event( - Activation(currentTick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] + Activation(tick), + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] ) if modelBaseStateData.services.isEmpty => /* An activity start trigger is sent and no data is awaited (neither secondary nor primary). Therefore go straight * ahead to calculations */ /* Hold tick, as state transition is needed */ - holdTick(currentTick) + holdTick(tick) - self ! StartCalculationTrigger(currentTick) + self ! StartCalculationTrigger(tick) /* Remove this tick from the array of foreseen activation ticks */ val additionalActivationTicks = - modelBaseStateData.additionalActivationTicks.rangeFrom(currentTick + 1) + modelBaseStateData.additionalActivationTicks.rangeFrom(tick + 1) goto(Calculate) using BaseStateData.updateBaseStateData( modelBaseStateData, modelBaseStateData.resultValueStore, @@ -141,7 +172,7 @@ abstract class ParticipantAgent[ case Event( Activation(currentTick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] ) => /* An activation is sent, but I'm not sure yet, if secondary data will arrive. Figure out, if someone * is about to deliver new data and either go to HandleInformation, check and possibly wait for data provision @@ -189,12 +220,47 @@ abstract class ParticipantAgent[ ) => // clean up agent result value store finalizeTickAfterPF(baseStateData, tick) + + case Event( + RequestFlexOptions(tick), + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + ) => + val expectedSenders = baseStateData.foreseenDataTicks + .collect { + case (actorRef, Some(expectedTick)) if expectedTick == tick => + actorRef -> None + } + + // Unexpected data provisions (e.g. by ExtEvDataService) are not possible when EM-managed. + // These data have to be always provided _before_ flex request is received here. + + if (expectedSenders.nonEmpty) { + val nextStateData = DataCollectionStateData( + baseStateData, + expectedSenders, + yetTriggered = true + ) + + /* Do await provision messages in HandleInformation */ + goto(HandleInformation) using nextStateData + } else { + /* I don't expect any data. Calculate right away */ + val updatedStateData = handleFlexRequest(baseStateData, tick) + + stay() using updatedStateData + } + + case Event( + flexCtrl: IssueFlexControl, + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + ) => + handleFlexCtrl(baseStateData, flexCtrl, scheduler) } when(HandleInformation) { /* Receive registration confirm from primary data service -> Set up actor for replay of data */ case Event( - RegistrationSuccessfulMessage(maybeNextDataTick), + RegistrationSuccessfulMessage(serviceRef, maybeNextDataTick), ParticipantInitializingStateData( inputModel: InputModelContainer[I], modelConfig: MC, @@ -203,7 +269,8 @@ abstract class ParticipantAgent[ simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + _ ) ) => log.debug("Will replay primary data") @@ -216,13 +283,13 @@ abstract class ParticipantAgent[ resolution, requestVoltageDeviationThreshold, outputConfig, - sender() -> maybeNextDataTick, + serviceRef -> maybeNextDataTick, scheduler ) /* Receive registration refuse from primary data service -> Set up actor for model calculation */ case Event( - RegistrationResponseMessage.RegistrationFailedMessage, + RegistrationResponseMessage.RegistrationFailedMessage(_), ParticipantInitializingStateData( inputModel: InputModelContainer[I], modelConfig: MC, @@ -231,7 +298,8 @@ abstract class ParticipantAgent[ simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) ) => log.debug("Will perform model calculations") @@ -244,7 +312,8 @@ abstract class ParticipantAgent[ resolution, requestVoltageDeviationThreshold, outputConfig, - scheduler + scheduler, + maybeEmAgent ) /* Receiving the registration replies from services and collect their next data ticks */ @@ -268,6 +337,17 @@ abstract class ParticipantAgent[ scheduler )(stateData.baseStateData.outputConfig) + case Event( + RequestFlexOptions(tick), + stateData: DataCollectionStateData[PD] + ) => + checkForExpectedDataAndChangeState( + stateData, + isYetTriggered = true, + tick, + scheduler + )(stateData.baseStateData.outputConfig) + case Event( msg: ProvisionMessage[_], stateData @ DataCollectionStateData( @@ -279,13 +359,13 @@ abstract class ParticipantAgent[ /* We yet have received at least one data provision message. Handle all messages, that follow up for this tick, by * adding the received data to the collection state data and checking, if everything is at its place */ val unexpectedSender = baseStateData.foreseenDataTicks.exists { - case (ref, None) => sender() == ref + case (ref, None) => msg.serviceRef == ref case _ => false } - if (data.contains(sender()) || unexpectedSender) { + if (data.contains(msg.serviceRef) || unexpectedSender) { /* Update the yet received information */ - val updatedData = data + (sender() -> Some(msg.data)) + val updatedData = data + (msg.serviceRef -> Some(msg.data)) /* If we have received unexpected data, we also have not been scheduled before */ if (unexpectedSender) @@ -298,7 +378,7 @@ abstract class ParticipantAgent[ /* Depending on if a next data tick can be foreseen, either update the entry in the base state data or remove * it */ val foreSeenDataTicks = - baseStateData.foreseenDataTicks + (sender() -> msg.nextDataTick) + baseStateData.foreseenDataTicks + (msg.serviceRef -> msg.nextDataTick) val updatedBaseStateData = BaseStateData.updateBaseStateData( baseStateData, baseStateData.resultValueStore, @@ -315,12 +395,12 @@ abstract class ParticipantAgent[ checkForExpectedDataAndChangeState( updatedStateData, isYetTriggered, - currentTick, + msg.tick, scheduler )(updatedBaseStateData.outputConfig) } else throw new IllegalStateException( - s"Did not expect message from ${sender()} at tick $currentTick" + s"Did not expect message from ${msg.serviceRef} at tick ${msg.tick}" ) case Event( @@ -349,27 +429,47 @@ abstract class ParticipantAgent[ when(Calculate) { case Event( StartCalculationTrigger(currentTick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] ) => /* Model calculation without any secondary data needed */ val voltage = getAndCheckNodalVoltage(modelBaseStateData, currentTick) + val lastModelState = + getLastOrInitialStateData(modelBaseStateData, currentTick) + calculatePowerWithoutSecondaryDataAndGoToIdle( modelBaseStateData, + lastModelState, currentTick, scheduler, - voltage, - calculateModelPowerFunc + voltage ) case Event( StartCalculationTrigger(currentTick), - serviceCollectionStateData: DataCollectionStateData[PD] + DataCollectionStateData( + participantStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + data, + _ + ) ) => + val updatedReceivedSecondaryData = ValueStore.updateValueStore( + participantStateData.receivedSecondaryDataStore, + currentTick, + data.map { case (actorRef, Some(data: SecondaryData)) => + actorRef -> data + } + ) + /* At least parts of the needed data has been received or it is an additional activation, that has been triggered. * Anyways, the calculation routine has also to take care of filling up missing data. */ + val lastModelState = + getLastOrInitialStateData(participantStateData, currentTick) calculatePowerWithSecondaryDataAndGoToIdle( - serviceCollectionStateData, + participantStateData.copy( + receivedSecondaryDataStore = updatedReceivedSecondaryData + ), + lastModelState, currentTick, scheduler ) @@ -469,7 +569,8 @@ abstract class ParticipantAgent[ resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - scheduler: ActorRef + scheduler: ActorRef, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): FSM.State[AgentState, ParticipantStateData[PD]] /** Handles the responses from service providers, this actor has registered @@ -533,6 +634,22 @@ abstract class ParticipantAgent[ } } + protected def getLastOrInitialStateData( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): MS = + ConstantState match { + case constantState: MS => + constantState + case _ => + baseStateData.stateDataStore + .last(tick) + .map { case (_, lastState) => + lastState + } + .getOrElse(createInitialState(baseStateData)) + } + /** Handle an incoming data provision message in Idle, try to figure out who's * about to send information in this tick as well. Map together all senders * with their yet apparent information. @@ -584,16 +701,6 @@ abstract class ParticipantAgent[ outputConfig: NotifierConfig ): FSM.State[AgentState, ParticipantStateData[PD]] - /** Partial function, that is able to transfer - * [[ParticipantModelBaseStateData]] (holding the actual calculation model) - * into a pair of active and reactive power - */ - val calculateModelPowerFunc: ( - Long, - ParticipantModelBaseStateData[PD, CD, M], - Dimensionless - ) => PD - /** Abstractly calculate the power output of the participant without needing * any secondary data. The next state is [[Idle]], sending a * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to @@ -602,28 +709,23 @@ abstract class ParticipantAgent[ * * @param baseStateData * Base state data to update + * @param lastModelState + * The current model state, before updating it * @param currentTick * Tick, the trigger belongs to * @param scheduler * [[ActorRef]] to the scheduler in the simulation * @param nodalVoltage * Current nodal voltage - * @param calculateModelPowerFunc - * Function, that transfer the current tick, the state data and the nodal - * voltage to participants power exchange with the grid * @return * [[Idle]] with updated result values */ def calculatePowerWithoutSecondaryDataAndGoToIdle( - baseStateData: ParticipantModelBaseStateData[PD, CD, M], + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + lastModelState: MS, currentTick: Long, scheduler: ActorRef, - nodalVoltage: Dimensionless, - calculateModelPowerFunc: ( - Long, - ParticipantModelBaseStateData[PD, CD, M], - Dimensionless - ) => PD + nodalVoltage: Dimensionless ): FSM.State[AgentState, ParticipantStateData[PD]] /** Abstractly calculate the power output of the participant utilising @@ -637,8 +739,11 @@ abstract class ParticipantAgent[ * scheduler and using update result values.

Actual implementation * can be found in each participant's fundamentals.

* - * @param collectionStateData - * State data with collected secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param lastModelState + * The current model state, before applying changes by externally received + * data * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -647,11 +752,59 @@ abstract class ParticipantAgent[ * [[Idle]] with updated result values */ def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[PD], + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + lastModelState: MS, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[PD]] + protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + ): MS + + protected def handleFlexRequest( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): ParticipantModelBaseStateData[PD, CD, MS, M] + + protected def calculateFlexOptions( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): ParticipantModelBaseStateData[PD, CD, MS, M] + + protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): CD + + protected def handleFlexCtrl( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + flexCtrl: IssueFlexControl, + scheduler: ActorRef + ): State + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + data: CD, + lastState: MS, + setPower: squants.Power + ): (MS, PD, FlexChangeIndicator) + /** Determining the reply to an * [[edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage]], * send this answer and stay in the current state. If no reply can be diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala index 98230dbd5a..5627047aea 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala @@ -6,15 +6,13 @@ package edu.ie3.simona.agent.participant -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorRef, FSM, PoisonPill} -import org.apache.pekko.event.LoggingAdapter -import org.apache.pekko.util -import org.apache.pekko.util.Timeout import breeze.numerics.{ceil, floor, pow, sqrt} import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.datamodel.models.result.ResultEntity -import edu.ie3.datamodel.models.result.system.SystemParticipantResult +import edu.ie3.datamodel.models.result.system.{ + FlexOptionsResult, + SystemParticipantResult +} import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.StartCalculationTrigger @@ -26,7 +24,6 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ EnrichableData, PrimaryDataWithApparentPower } -import edu.ie3.simona.agent.participant.data.Data.SecondaryData.DateTime import edu.ie3.simona.agent.participant.data.Data.{PrimaryData, SecondaryData} import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ @@ -51,6 +48,7 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.{ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.event.ResultEvent.{ + FlexOptionsResultEvent, ParticipantResultEvent, ThermalResultEvent } @@ -62,7 +60,12 @@ import edu.ie3.simona.exceptions.agent.{ InvalidRequestException } import edu.ie3.simona.io.result.AccompaniedSimulationResult -import edu.ie3.simona.model.participant.{CalcRelevantData, SystemParticipant} +import edu.ie3.simona.model.em.EmTools +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + ModelState, + SystemParticipant +} import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, @@ -72,13 +75,22 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation } +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ProvisionMessage, RegistrationResponseMessage } import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.quantities.PowerSystemUnits._ +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.{Megavars, QuantityUtil, ReactivePower} +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM, PoisonPill} +import org.apache.pekko.event.LoggingAdapter +import org.apache.pekko.util +import org.apache.pekko.util.Timeout import squants.energy.Megawatts import squants.{Dimensionless, Each, Energy, Power} @@ -94,35 +106,16 @@ import scala.util.{Failure, Success, Try} protected trait ParticipantAgentFundamentals[ PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, + MS <: ModelState, D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD] -] extends ServiceRegistration[PD, CD, D, I, MC, M] { - this: ParticipantAgent[PD, CD, D, I, MC, M] => + M <: SystemParticipant[CD, PD, MS] +] extends ServiceRegistration[PD, CD, MS, D, I, MC, M] { + this: ParticipantAgent[PD, CD, MS, D, I, MC, M] => protected val pdClassTag: ClassTag[PD] protected implicit val timeout: util.Timeout = Timeout(10, TimeUnit.SECONDS) - /** Tries to extract the DateTime value from the base state data and verifies, - * that it is there - * - * @param baseStateData - * base state data to derive information from - * @return - * valid DateTime value - */ - def getAndCheckDateTime( - baseStateData: DataCollectionStateData[_] - ): ZonedDateTime = { - baseStateData.extract[DateTime]() match { - case Some(dateTime) => dateTime.dateTime - case None => - throw new RuntimeException( - "Did not receive expected information about the date time!" - ) - } - } - override def initializeParticipantForPrimaryDataReplay( inputModel: InputModelContainer[I], modelConfig: MC, @@ -177,7 +170,7 @@ protected trait ParticipantAgentFundamentals[ * @return * [[FromOutsideBaseStateData]] with required information */ - def determineFromOutsideBaseStateData( + private def determineFromOutsideBaseStateData( inputModel: InputModelContainer[I], modelConfig: MC, simulationStartDate: ZonedDateTime, @@ -273,13 +266,23 @@ protected trait ParticipantAgentFundamentals[ resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - scheduler: ActorRef + scheduler: ActorRef, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): FSM.State[AgentState, ParticipantStateData[PD]] = try { /* Register for services */ val awaitRegistrationResponsesFrom = registerForServices(inputModel.electricalInputModel, services) + // register with EM if applicable + maybeEmAgent.foreach { emAgent => + emAgent ! RegisterParticipant( + inputModel.electricalInputModel.getUuid, + self.toTyped[FlexRequest], + inputModel.electricalInputModel + ) + } + val baseStateData = determineModelBaseStateData( inputModel, modelConfig, @@ -288,7 +291,8 @@ protected trait ParticipantAgentFundamentals[ simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) /* If we do have registered with secondary data providers, wait for their responses. If not, the agent does not @@ -305,8 +309,22 @@ protected trait ParticipantAgentFundamentals[ ) releaseTick() - log.debug(s"Going to {}, using {}", Idle, baseStateData) - scheduler ! Completion(self.toTyped, newTick) + maybeEmAgent.foreach { emAgent => + // flex is scheduled for tick 0, if no first tick available + emAgent ! ScheduleFlexRequest( + inputModel.electricalInputModel.getUuid, + newTick.getOrElse(0) + ) + } + + // important: if we are EM-managed, there is no new tick for the + // scheduler, since we are activated by the EmAgent from now on + scheduler ! Completion( + self.toTyped, + newTick.filterNot(_ => baseStateData.isEmManaged) + ) + + log.debug(s"Going to {}, using {}", Idle, nextBaseStateData) goto(Idle) using nextBaseStateData } } catch { @@ -327,8 +345,9 @@ protected trait ParticipantAgentFundamentals[ simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig - ): ParticipantModelBaseStateData[PD, CD, M] + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] + ): ParticipantModelBaseStateData[PD, CD, MS, M] /** Determine all ticks between the operation start and end of the * participant, that are at a full hour or integer multiples of the data's @@ -415,14 +434,15 @@ protected trait ParticipantAgentFundamentals[ ): FSM.State[AgentState, ParticipantStateData[PD]] = registrationResponse match { case RegistrationResponseMessage.RegistrationSuccessfulMessage( + serviceRef, maybeNextTick ) => val remainingResponses = - stateData.pendingResponses.filter(_ != sender()) + stateData.pendingResponses.filter(_ != serviceRef) /* If the sender announces a new next tick, add it to the list of expected ticks, else remove the current entry */ val foreseenDataTicks = - stateData.baseStateData.foreseenDataTicks + (sender() -> maybeNextTick) + stateData.baseStateData.foreseenDataTicks + (serviceRef -> maybeNextTick) if (remainingResponses.isEmpty) { /* All agent have responded. Determine the next to be used state data and reply completion to scheduler. */ @@ -450,10 +470,10 @@ protected trait ParticipantAgentFundamentals[ foreseenNextDataTicks = foreseenDataTicksFlattened ) } - case RegistrationResponseMessage.RegistrationFailedMessage => + case RegistrationResponseMessage.RegistrationFailedMessage(serviceRef) => self ! PoisonPill throw new ActorNotRegisteredException( - s"Registration of actor $actorName for ${sender()} failed." + s"Registration of actor $actorName for $serviceRef failed." ) } @@ -481,11 +501,11 @@ protected trait ParticipantAgentFundamentals[ optTick match { case Some(tick) if msg.tick == tick => // expected data - if (actorRef == sender()) + if (actorRef == msg.serviceRef) Some(actorRef -> Some(msg.data)) else Some(actorRef -> None) - case None if actorRef == sender() => + case None if actorRef == msg.serviceRef => // unexpected data Some(actorRef -> Some(msg.data)) case _ => @@ -494,21 +514,38 @@ protected trait ParticipantAgentFundamentals[ } val unexpectedSender = baseStateData.foreseenDataTicks.exists { - case (ref, None) => sender() == ref + case (ref, None) => msg.serviceRef == ref case _ => false } /* If we have received unexpected data, we also have not been scheduled before */ - if (unexpectedSender) - scheduler ! ScheduleActivation( - self.toTyped, - msg.tick, - msg.unlockKey - ) + if (unexpectedSender) { + baseStateData match { + case modelStateData: ParticipantModelBaseStateData[_, _, _, _] => + val maybeEmAgent = modelStateData.flexStateData.map(_.emAgent) + + maybeEmAgent match { + case Some(emAgent) => + emAgent ! ScheduleFlexRequest( + modelStateData.model.getUuid, + msg.tick, + msg.unlockKey + ) + case None => + scheduler ! ScheduleActivation( + self.toTyped, + msg.tick, + msg.unlockKey + ) + } + case _ => + false + } + } /* If the sender announces a new next tick, add it to the list of expected ticks, else remove the current entry */ val foreseenDataTicks = - baseStateData.foreseenDataTicks + (sender() -> msg.nextDataTick) + baseStateData.foreseenDataTicks + (msg.serviceRef -> msg.nextDataTick) /* Go over to handling these information */ val nextStateData = DataCollectionStateData( @@ -582,7 +619,7 @@ protected trait ParticipantAgentFundamentals[ val resultValueStore = fromOutsideBaseStateData.resultValueStore val updatedResultValueStore = ValueStore.updateValueStore( resultValueStore, - currentTick, + tick, mostRecentData ) val baseStateDataWithUpdatedResults = @@ -607,9 +644,32 @@ protected trait ParticipantAgentFundamentals[ throw exception } - case _: BaseStateData.ModelBaseStateData[_, _, _] => + case modelStateData: BaseStateData.ParticipantModelBaseStateData[ + PD, + CD, + MS, + M + ] if modelStateData.isEmManaged => + val updatedReceivedSecondaryData = ValueStore.updateValueStore( + modelStateData.receivedSecondaryDataStore, + tick, + stateData.data.map { case (actorRef, Some(data: SecondaryData)) => + actorRef -> data + } + ) + + // we don't go to calculate state, but return to idle directly + val updatedStateData = handleFlexRequest( + modelStateData.copy( + receivedSecondaryDataStore = updatedReceivedSecondaryData + ), + tick + ) + goto(Idle) using updatedStateData + + case _: BaseStateData.ModelBaseStateData[_, _, _, _] => /* Go to calculation state and send a trigger for this to myself as well */ - self ! StartCalculationTrigger(currentTick) + self ! StartCalculationTrigger(tick) goto(Calculate) using stateData case x => throw new IllegalStateException( @@ -622,6 +682,296 @@ protected trait ParticipantAgentFundamentals[ } } + override protected def handleFlexRequest( + participantStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): ParticipantModelBaseStateData[PD, CD, MS, M] = { + val updatedBaseStateData = calculateFlexOptions( + participantStateData, + tick + ) + + val updatedFlexData = updatedBaseStateData.flexStateData.getOrElse( + throw new InconsistentStateException("Flex state data is missing!") + ) + + val newestFlexOptions = updatedFlexData.lastFlexOptions + .getOrElse( + throw new RuntimeException( + s"Flex options have not been calculated by agent ${participantStateData.modelUuid}" + ) + ) + + updatedFlexData.emAgent ! newestFlexOptions + + updatedBaseStateData + } + + override protected def calculateFlexOptions( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + tick: Long + ): ParticipantModelBaseStateData[PD, CD, MS, M] = { + + implicit val startDateTime: ZonedDateTime = baseStateData.startDate + + val relevantData = + createCalcRelevantData( + baseStateData, + tick + ) + + val lastState = getLastOrInitialStateData(baseStateData, tick) + + val flexOptions = + baseStateData.model.determineFlexOptions(relevantData, lastState) + + // announce flex options (we can do this right away, since this + // does not include reactive power which could change later) + if (baseStateData.outputConfig.flexResult) { + val flexResult = flexOptions match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + new FlexOptionsResult( + tick.toDateTime, + modelUuid, + referencePower.toMegawatts.asMegaWatt, + minPower.toMegawatts.asMegaWatt, + maxPower.toMegawatts.asMegaWatt + ) + } + + notifyListener(FlexOptionsResultEvent(flexResult)) + } + + baseStateData.copy( + flexStateData = baseStateData.flexStateData.map(data => + data.copy(lastFlexOptions = Some(flexOptions)) + ) + ) + } + + override protected def handleFlexCtrl( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + flexCtrl: IssueFlexControl, + scheduler: ActorRef + ): State = { + /* Collect all needed information */ + val flexStateData = baseStateData.flexStateData.getOrElse( + throw new IllegalStateException( + s"Received $flexCtrl, but participant agent is not in EM mode" + ) + ) + val relevantData = createCalcRelevantData( + baseStateData, + flexCtrl.tick + ) + val lastState = getLastOrInitialStateData(baseStateData, flexCtrl.tick) + + val flexOptions = flexStateData.lastFlexOptions + .getOrElse( + throw new IllegalStateException( + "Flex options have not been calculated before." + ) + ) + + val setPointActivePower = + EmTools.determineFlexPower(flexOptions, flexCtrl) + + /* Handle the flex signal */ + val (updatedState, result, flexChangeIndicator) = + handleControlledPowerChange( + flexCtrl.tick, + baseStateData, + relevantData, + lastState, + setPointActivePower + ) + + // sanity check, simulation will hang if this matches + flexChangeIndicator.changesAtTick match { + case Some(changeAtTick) if changeAtTick <= flexCtrl.tick => + log.error( + s"Scheduling agent ${self.path} (${baseStateData.modelUuid}) for activation at tick $changeAtTick, although current tick is ${flexCtrl.tick}" + ) + case _ => + } + + // store new state data + val updatedStateData: ParticipantModelBaseStateData[PD, CD, MS, M] = + baseStateData + .copy( + stateDataStore = ValueStore.updateValueStore( + baseStateData.stateDataStore, + flexCtrl.tick, + updatedState + ) + ) + + // Send out results etc. + val stateDataWithResults = handleCalculatedResult( + updatedStateData, + result, + flexCtrl.tick + ) + + // determine next tick + val expectedDataComesNext = + pollNextActivationTrigger(stateDataWithResults).exists { dataTick => + flexChangeIndicator.changesAtTick.forall(_ >= dataTick) + } + val (nextActivation, stateDataFinal) = Option + .when(expectedDataComesNext)( + popNextActivationTrigger(stateDataWithResults) + ) + .getOrElse((flexChangeIndicator.changesAtTick, stateDataWithResults)) + + flexStateData.emAgent ! FlexCtrlCompletion( + baseStateData.modelUuid, + result.toApparentPower, + flexChangeIndicator.changesAtNextActivation, + nextActivation + ) + + stay() using stateDataFinal + } + + /** Additional actions on a new calculated simulation result. Typically: Send + * out result to listeners and save result in corresponding ValueStore + * + * @param baseStateData + * The base state data + * @param result + * that has been calculated for the current tick + * @param currentTick + * the current tick + * @return + * updated base state data + */ + protected def handleCalculatedResult( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + result: PD, + currentTick: Long + ): ParticipantModelBaseStateData[PD, CD, MS, M] = { + + // announce last result to listeners + announceSimulationResult( + baseStateData, + currentTick, + AccompaniedSimulationResult(result) + )(baseStateData.outputConfig) + + baseStateData.copy( + resultValueStore = ValueStore.updateValueStore( + baseStateData.resultValueStore, + currentTick, + result + ) + ) + } + + /** Calculate the power output of the participant without needing any + * secondary data. The next state is [[Idle]], sending a [[Completion]] to + * scheduler and using update result values. + * + * @param baseStateData + * Base state data to update + * @param lastModelState + * The current model state, before updating it + * @param currentTick + * Tick, the trigger belongs to + * @param scheduler + * [[ActorRef]] to the scheduler in the simulation + * @return + * [[Idle]] with updated result values + */ + override def calculatePowerWithoutSecondaryDataAndGoToIdle( + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], + lastModelState: MS, + currentTick: Long, + scheduler: ActorRef, + nodalVoltage: squants.Dimensionless + ): FSM.State[AgentState, ParticipantStateData[PD]] = { + val calcRelevantData = + createCalcRelevantData(baseStateData, currentTick) + + val updatedState = + updateState( + currentTick, + lastModelState, + calcRelevantData, + nodalVoltage, + baseStateData.model + ) + + val result = calculateModelPowerFunc( + currentTick, + baseStateData, + updatedState, + nodalVoltage + ) + + val updatedResultValueStore = + ValueStore.updateValueStore( + baseStateData.resultValueStore, + currentTick, + result + ) + + /* Inform the listeners about new result */ + announceSimulationResult( + baseStateData, + currentTick, + AccompaniedSimulationResult(result) + )(baseStateData.outputConfig) + + val updatedStateDataStore = ValueStore.updateValueStore( + baseStateData.stateDataStore, + currentTick, + updatedState + ) + + /* In this case, without secondary data, the agent has been triggered by an ActivityStartTrigger by itself, + * therefore pop the next one */ + val baseStateDataWithUpdatedResultStore = + baseStateData.copy( + resultValueStore = updatedResultValueStore, + stateDataStore = updatedStateDataStore + ) + + goToIdleReplyCompletionAndScheduleTriggerForNextAction( + baseStateDataWithUpdatedResultStore, + scheduler + ) + } + + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + protected def updateState( + tick: Long, + modelState: MS, + calcRelevantData: CD, + nodalVoltage: squants.Dimensionless, + model: M + ): MS + /** Determining the active to reactive power function to apply * * @param tick @@ -730,11 +1080,56 @@ protected trait ParticipantAgentFundamentals[ popNextActivationTrigger(baseStateData) releaseTick() - scheduler ! Completion(self.toTyped, maybeNextTick) + + val emManaged = baseStateData match { + case modelStateData: ParticipantModelBaseStateData[_, _, _, _] => + val maybeEmAgent = modelStateData.flexStateData.map(_.emAgent) + + maybeEmAgent.foreach { + _ ! ScheduleFlexRequest( + modelStateData.model.getUuid, + maybeNextTick.getOrElse(0) + ) + } + + maybeEmAgent.isDefined + case _ => + false + } + + // Only after init: + // if we are EM-managed, there is no new tick for the + // scheduler, since we are activated by the EmAgent from now on + scheduler ! Completion( + self.toTyped, + maybeNextTick.filterNot(_ => emManaged) + ) unstashAll() goto(Idle) using updatedBaseStateData } + def pollNextActivationTrigger( + baseStateData: BaseStateData[PD] + ): Option[Long] = { + /* Determine what comes next: An additional activation or new data - or both at once */ + val nextAdditionalActivation = + baseStateData.additionalActivationTicks.headOption + val nextDataTick = + baseStateData.foreseenDataTicks.values.toSeq.sorted.headOption.flatten + + (nextAdditionalActivation, nextDataTick) match { + case (None, Some(dataTick)) => + Some(dataTick) + case (Some(additionalTick), Some(dataTick)) + if dataTick < additionalTick => + Some(dataTick) + case (Some(additionalTick), _) => + Some(additionalTick) + case (None, None) => + None + } + } + /** Pop the next tick, in which the agent wishes to get triggered, build a * regarding message and update the base state data. This might be either a * tick, where new data is foreseen to be sent by a @@ -830,8 +1225,6 @@ protected trait ParticipantAgentFundamentals[ fInPu: Dimensionless, alternativeResult: PD ): FSM.State[AgentState, ParticipantStateData[PD]] = { - log.debug(s"Received asset power request for tick {}", requestTick) - /* Check, if there is any calculation foreseen for this tick. If so, wait with the response. */ val activationExpected = baseStateData.additionalActivationTicks.headOption.exists(_ < requestTick) @@ -839,8 +1232,8 @@ protected trait ParticipantAgentFundamentals[ baseStateData.foreseenDataTicks.values.flatten.exists(_ < requestTick) if (activationExpected || dataExpected) { log.debug( - s"I got a request for power from '{}' for tick '{}', but I'm still waiting for new" + - s" results before this tick. Waiting with the response.", + s"Received power request from '{}' for tick '{}', but I'm still waiting for new results before " + + s"this tick. Waiting with the response.", sender(), requestTick ) @@ -940,7 +1333,12 @@ protected trait ParticipantAgentFundamentals[ latestProvidedValues.q ) ) - case modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] => + case modelBaseStateData: ParticipantModelBaseStateData[ + PD, + CD, + MS, + M + ] => /* Check, if the last request has been made with the same nodal voltage. If not, recalculate the reactive * power. */ implicit val puTolerance: Dimensionless = @@ -1012,7 +1410,12 @@ protected trait ParticipantAgentFundamentals[ if lastRequestTick == requestTick => /* Repetitive request for the same tick, but with different voltage */ baseStateData match { - case modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] => + case modelBaseStateData: ParticipantModelBaseStateData[ + PD, + CD, + MS, + M + ] => /* Active power is yet calculated, but reactive power needs update */ val nextReactivePower = modelBaseStateData.model .calculateReactivePower(lastResult.p, nodalVoltage) @@ -1289,7 +1692,7 @@ protected trait ParticipantAgentFundamentals[ /* Determine, how the single model would transfer the active into reactive power */ val activeToReactivePowerFunction = baseStateData match { case _: FromOutsideBaseStateData[M, PD] => None - case modelBaseStateData: ParticipantModelBaseStateData[PD, CD, M] => + case modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] => Some( modelBaseStateData.model.activeToReactivePowerFunc(nodalVoltage) ) @@ -1369,63 +1772,6 @@ protected trait ParticipantAgentFundamentals[ } } - /** Calculate the power output of the participant without needing any - * secondary data. The next state is [[Idle]], sending a [[Completion]] to - * scheduler and using update result values. - * - * @param baseStateData - * Base state data to update - * @param currentTick - * Tick, the trigger belongs to - * @param scheduler - * [[ActorRef]] to the scheduler in the simulation - * @return - * [[Idle]] with updated result values - */ - override def calculatePowerWithoutSecondaryDataAndGoToIdle( - baseStateData: ParticipantModelBaseStateData[PD, CD, M], - currentTick: Long, - scheduler: ActorRef, - nodalVoltage: Dimensionless, - calculateModelPowerFunc: ( - Long, - ParticipantModelBaseStateData[PD, CD, M], - Dimensionless - ) => PD - ): FSM.State[AgentState, ParticipantStateData[PD]] = { - val result = - calculateModelPowerFunc(currentTick, baseStateData, nodalVoltage) - - val updatedResultValueStore = - ValueStore.updateValueStore( - baseStateData.resultValueStore, - currentTick, - result - ) - - /* Inform the listeners about new result */ - announceSimulationResult( - baseStateData, - currentTick, - AccompaniedSimulationResult(result) - )(baseStateData.outputConfig) - - /* In this case, without secondary data, the agent has been triggered by an ActivityStartTrigger by itself, - * therefore pop the next one */ - val baseStateDataWithUpdatedResultStore = BaseStateData.updateBaseStateData( - baseStateData, - updatedResultValueStore, - baseStateData.requestValueStore, - baseStateData.voltageValueStore, - baseStateData.additionalActivationTicks, - baseStateData.foreseenDataTicks - ) - goToIdleReplyCompletionAndScheduleTriggerForNextAction( - baseStateDataWithUpdatedResultStore, - scheduler - ) - } - /** Notify listeners about a new simulation result of the participant agent, * if the config says so. * @@ -1438,7 +1784,7 @@ protected trait ParticipantAgentFundamentals[ * @param outputConfig * Configuration of the output behaviour */ - def announceSimulationResult( + protected def announceSimulationResult( baseStateData: BaseStateData[PD], tick: Long, result: AccompaniedSimulationResult[PD] @@ -1452,8 +1798,8 @@ protected trait ParticipantAgentFundamentals[ .foreach(notifyListener(_)) } - /** Update the result and calc relevant data value stores, inform all - * registered listeners and go to Idle using the updated base state data + /** Update the result value store, inform all registered listeners and go to + * Idle using the updated base state data * * @param scheduler * Actor reference of the scheduler @@ -1479,20 +1825,6 @@ protected trait ParticipantAgentFundamentals[ currentTick, result.primaryData ) - val updatedRelevantDataStore = - baseStateData match { - case data: BaseStateData.ModelBaseStateData[_, _, _] => - ValueStore.updateValueStore( - data.calcRelevantDateStore, - currentTick, - relevantData - ) - case _ => - throw new InconsistentStateException( - "Cannot find calculation relevant data to update." - ) - } - /* Inform the listeners about new result */ announceSimulationResult( baseStateData, @@ -1503,10 +1835,9 @@ protected trait ParticipantAgentFundamentals[ /* Update the base state data */ val baseStateDateWithUpdatedResults = baseStateData match { - case data: ParticipantModelBaseStateData[PD, CD, M] => + case data: ParticipantModelBaseStateData[PD, CD, MS, M] => data.copy( - resultValueStore = updatedValueStore, - calcRelevantDateStore = updatedRelevantDataStore + resultValueStore = updatedValueStore ) case _ => throw new InconsistentStateException( @@ -1666,7 +1997,7 @@ protected trait ParticipantAgentFundamentals[ .actorRef } -case object ParticipantAgentFundamentals { +object ParticipantAgentFundamentals { /** Hold all necessary information for later averaging of participant * simulations' results. diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala index d600049a27..7b3662bfef 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala @@ -18,20 +18,25 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.{ } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.model.participant.{CalcRelevantData, SystemParticipant} import edu.ie3.simona.exceptions.agent.ServiceRegistrationException +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + ModelState, + SystemParticipant +} import edu.ie3.simona.ontology.messages.services.EvMessage.RegisterForEvDataMessage import edu.ie3.simona.ontology.messages.services.WeatherMessage.RegisterForWeatherMessage trait ServiceRegistration[ PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, + MS <: ModelState, D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD] + M <: SystemParticipant[CD, PD, MS] ] { - this: ParticipantAgent[PD, CD, D, I, MC, M] => + this: ParticipantAgent[PD, CD, MS, D, I, MC, M] => /** Registers the agent for the needed services and collects all actor * references, with which the actor has been registered @@ -40,20 +45,24 @@ trait ServiceRegistration[ * Input model definition * @param services * Definition of where to get what + * @param scheduleTriggerFunc + * function providing the proper ScheduleTriggerMessage for a given trigger + * @param emControlled + * whether the agent is em-controlled or not * @return * a vector of actor references to wait for responses */ def registerForServices( inputModel: I, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]] - ): Vector[ActorRef] = + services: Option[Seq[SecondaryDataService[_ <: SecondaryData]]] + ): Seq[ActorRef] = services .map(sources => sources.flatMap(service => registerForSecondaryService(service, inputModel) ) ) - .getOrElse(Vector.empty[ActorRef]) + .getOrElse(Seq.empty[ActorRef]) /** Register for the distinct secondary service * @@ -79,12 +88,12 @@ trait ServiceRegistration[ ActorPriceService ) None - case ActorWeatherService(actorRef) => - registerForWeather(actorRef, inputModel) - Some(actorRef) - case ActorEvMovementsService(actorRef) => - registerForEvMovements(actorRef, inputModel) - Some(actorRef) + case ActorWeatherService(serviceRef) => + registerForWeather(serviceRef, inputModel) + Some(serviceRef) + case ActorEvMovementsService(serviceRef) => + registerForEvMovements(serviceRef, inputModel) + Some(serviceRef) } /** Register for the weather service @@ -117,19 +126,19 @@ trait ServiceRegistration[ /** Register for the EV movement service * - * @param actorRef + * @param serviceRef * Actor reference of the EV movements service * @param inputModel * Input model of the simulation mode * @return */ private def registerForEvMovements( - actorRef: ActorRef, + serviceRef: ActorRef, inputModel: I ): Unit = { inputModel match { case evcsInput: EvcsInput => - actorRef ! RegisterForEvDataMessage(evcsInput.getUuid) + serviceRef ! RegisterForEvDataMessage(evcsInput.getUuid) case _ => throw new ServiceRegistrationException( s"Cannot register for EV movements information at node ${inputModel.getNode.getId} " + diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala index 3814da101c..59516ff5ab 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala @@ -6,12 +6,7 @@ package edu.ie3.simona.agent.participant.evcs -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.EvcsInput -import edu.ie3.simona.agent.participant.{ - ParticipantAgent, - ParticipantAgentFundamentals -} import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, ZERO_POWER @@ -21,15 +16,23 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.Acto import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData +import edu.ie3.simona.agent.participant.{ + ParticipantAgent, + ParticipantAgentFundamentals +} import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig -import edu.ie3.simona.model.participant.EvcsModel -import edu.ie3.simona.model.participant.EvcsModel.EvcsRelevantData +import edu.ie3.simona.model.participant.evcs.EvcsModel +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsRelevantData, + EvcsState +} import edu.ie3.simona.ontology.messages.services.EvMessage.{ DepartingEvsRequest, EvFreeLotsRequest } import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.{ActorRef, Props} import squants.Power object EvcsAgent { @@ -66,6 +69,7 @@ class EvcsAgent( ) extends ParticipantAgent[ ApparentPower, EvcsRelevantData, + EvcsState, ParticipantStateData[ApparentPower], EvcsInput, EvcsRuntimeConfig, @@ -80,21 +84,24 @@ class EvcsAgent( modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ] ) => handleFreeLotsRequest(tick, modelBaseStateData) stay() + case Event( DepartingEvsRequest(tick, departingEvs), modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ] ) => val updatedStateData = - handleDepartingEvsRequest(tick, modelBaseStateData, departingEvs) + handleDepartingEvsRequest(tick, departingEvs, modelBaseStateData) stay() using updatedStateData } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala index a5c90fe112..3d38db1105 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.fixedfeedin -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.simona.agent.participant.ParticipantAgent import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower @@ -15,6 +14,8 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.Participa import edu.ie3.simona.config.SimonaConfig.FixedFeedInRuntimeConfig import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData import edu.ie3.simona.model.participant.FixedFeedInModel +import edu.ie3.simona.model.participant.ModelState.ConstantState +import org.apache.pekko.actor.{ActorRef, Props} object FixedFeedInAgent { def props( @@ -47,6 +48,7 @@ class FixedFeedInAgent( ) extends ParticipantAgent[ ApparentPower, FixedRelevantData.type, + ConstantState.type, ParticipantStateData[ApparentPower], FixedFeedInInput, FixedFeedInRuntimeConfig, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala index 3f5717d8c6..5f4b34dd3a 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala @@ -6,13 +6,13 @@ package edu.ie3.simona.agent.participant.fixedfeedin -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.datamodel.models.result.system.{ FixedFeedInResult, SystemParticipantResult } import edu.ie3.simona.agent.ValueStore +import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, @@ -20,12 +20,12 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService -import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData -import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer -import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, - ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ + FlexControlledData, + ParticipantModelBaseStateData } +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.FixedFeedInRuntimeConfig @@ -35,12 +35,25 @@ import edu.ie3.simona.exceptions.agent.{ InvalidRequestException } import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData -import edu.ie3.simona.model.participant.FixedFeedInModel +import edu.ie3.simona.model.participant.ModelState.ConstantState +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + FixedFeedInModel, + FlexChangeIndicator, + ModelState +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil.RichZonedDateTime import edu.ie3.util.quantities.PowerSystemUnits.PU import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Each, Power} import java.time.ZonedDateTime @@ -52,6 +65,7 @@ protected trait FixedFeedInAgentFundamentals extends ParticipantAgentFundamentals[ ApparentPower, FixedRelevantData.type, + ConstantState.type, ParticipantStateData[ApparentPower], FixedFeedInInput, FixedFeedInRuntimeConfig, @@ -94,10 +108,12 @@ protected trait FixedFeedInAgentFundamentals simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, + ConstantState.type, FixedFeedInModel ] = { /* Build the calculation model */ @@ -129,6 +145,7 @@ protected trait FixedFeedInAgentFundamentals ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, + ConstantState.type, FixedFeedInModel ]( simulationStartDate, @@ -149,9 +166,11 @@ protected trait FixedFeedInAgentFundamentals .doubleValue ) ), - ValueStore.forResult(resolution, 2), ValueStore(resolution), - ValueStore(resolution) + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) } @@ -167,26 +186,96 @@ protected trait FixedFeedInAgentFundamentals simulationEndDate ) + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + FixedFeedInModel + ] + ): ModelState.ConstantState.type = ConstantState + + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + FixedFeedInModel + ], + tick: Long + ): FixedRelevantData.type = + FixedRelevantData + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + FixedFeedInModel + ], + data: FixedRelevantData.type, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { + /* Calculate result */ + val voltage = getAndCheckNodalVoltage(baseStateData, tick) + + val reactivePower = baseStateData.model.calculateReactivePower( + setPower, + voltage + ) + val result = ApparentPower(setPower, reactivePower) + + /* Handle the request within the model */ + val (updatedState, flexChangeIndicator) = + baseStateData.model.handleControlledPowerChange(data, lastState, setPower) + (updatedState, result, flexChangeIndicator) + } + override val calculateModelPowerFunc: ( Long, ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, + ConstantState.type, FixedFeedInModel ], + ConstantState.type, Dimensionless ) => ApparentPower = ( currentTick: Long, baseStateData: ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, + ConstantState.type, FixedFeedInModel ], + ConstantState, voltage: Dimensionless ) => baseStateData.model match { case fixedModel: FixedFeedInModel => - fixedModel.calculatePower(currentTick, voltage, FixedRelevantData) + fixedModel.calculatePower( + currentTick, + voltage, + ConstantState, + FixedRelevantData + ) case unsupportedModel => throw new InconsistentStateException( s"The model $unsupportedModel is not supported!" @@ -203,8 +292,10 @@ protected trait FixedFeedInAgentFundamentals * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to * scheduler and using update result values.

* - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param lastModelState + * Optional last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -213,7 +304,13 @@ protected trait FixedFeedInAgentFundamentals * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + FixedFeedInModel + ], + lastModelState: ConstantState.type, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = @@ -272,4 +369,28 @@ protected trait FixedFeedInAgentFundamentals result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar ) + + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + override protected def updateState( + tick: Long, + modelState: ModelState.ConstantState.type, + calcRelevantData: CalcRelevantData.FixedRelevantData.type, + nodalVoltage: squants.Dimensionless, + model: FixedFeedInModel + ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala index 758711c3bd..2f587e710a 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.hp -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.simona.agent.participant.ParticipantAgent import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHeat @@ -16,7 +15,8 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig.HpRuntimeConfig import edu.ie3.simona.model.participant.HpModel -import edu.ie3.simona.model.participant.HpModel.HpRelevantData +import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} +import org.apache.pekko.actor.{ActorRef, Props} object HpAgent { def props( @@ -52,6 +52,7 @@ class HpAgent( ) extends ParticipantAgent[ ApparentPowerAndHeat, HpRelevantData, + HpState, ParticipantStateData[ ApparentPowerAndHeat ], diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala index 19fb399742..ed432fb4be 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.load -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.agent.participant.ParticipantAgent import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower @@ -19,6 +18,7 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel @@ -28,6 +28,7 @@ import edu.ie3.simona.model.participant.load.{ LoadModel, LoadModelBehaviour } +import org.apache.pekko.actor.{ActorRef, Props} object LoadAgent { def props( @@ -113,6 +114,7 @@ abstract class LoadAgent[LD <: LoadRelevantData, LM <: LoadModel[LD]]( ) extends ParticipantAgent[ ApparentPower, LD, + ConstantState.type, ParticipantStateData[ApparentPower], LoadInput, LoadRuntimeConfig, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index 64b37b56ae..6dc3d70211 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -6,13 +6,13 @@ package edu.ie3.simona.agent.participant.load -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.result.system.{ LoadResult, SystemParticipantResult } import edu.ie3.simona.agent.ValueStore +import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, @@ -20,12 +20,12 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService -import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData -import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer -import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, - ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ + FlexControlledData, + ParticipantModelBaseStateData } +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.LoadRuntimeConfig @@ -33,6 +33,7 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.InconsistentStateException import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.profile.{ @@ -49,12 +50,20 @@ import edu.ie3.simona.model.participant.load.{ LoadModel, LoadReference } +import edu.ie3.simona.model.participant.{FlexChangeIndicator, ModelState} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.quantities.PowerSystemUnits.PU import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Each, Power} import java.time.ZonedDateTime @@ -67,6 +76,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ ]] extends ParticipantAgentFundamentals[ ApparentPower, LD, + ConstantState.type, ParticipantStateData[ApparentPower], LoadInput, LoadRuntimeConfig, @@ -109,8 +119,14 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig - ): ParticipantModelBaseStateData[ApparentPower, LD, LM] = { + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] + ): ParticipantModelBaseStateData[ + ApparentPower, + LD, + ConstantState.type, + LM + ] = { /* Build the calculation model */ val model = buildModel( @@ -156,7 +172,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ SortedSet.empty[Long] } - ParticipantModelBaseStateData[ApparentPower, LD, LM]( + ParticipantModelBaseStateData[ApparentPower, LD, ConstantState.type, LM]( simulationStartDate, simulationEndDate, model, @@ -175,9 +191,11 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ .doubleValue ) ), - ValueStore.forResult(resolution, 2), ValueStore(resolution), - ValueStore(resolution) + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) } @@ -203,6 +221,56 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ reference: LoadReference ): LM + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + LD, + ConstantState.type, + LM + ] + ): ModelState.ConstantState.type = ConstantState + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + LD, + ConstantState.type, + LM + ], + data: LD, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { + /* Calculate result */ + val voltage = getAndCheckNodalVoltage(baseStateData, tick) + + val reactivePower = baseStateData.model.calculateReactivePower( + setPower, + voltage + ) + val result = ApparentPower(setPower, reactivePower) + + /* Handle the request within the model */ + val (updatedState, flexChangeIndicator) = + baseStateData.model.handleControlledPowerChange(data, lastState, setPower) + (updatedState, result, flexChangeIndicator) + } + /** Calculate the power output of the participant utilising secondary data. * However, it might appear, that not the complete set of secondary data is * available for the given tick. This might especially be true, if the actor @@ -213,8 +281,10 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to * scheduler and using update result values.

* - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param maybeLastModelState + * Optional last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -223,7 +293,13 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + LD, + ConstantState.type, + LM + ], + lastModelState: ConstantState.type, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = @@ -282,9 +358,17 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar ) + + override protected def updateState( + tick: Long, + modelState: ModelState.ConstantState.type, + calcRelevantData: LD, + nodalVoltage: squants.Dimensionless, + model: LM + ): ModelState.ConstantState.type = modelState } -case object LoadAgentFundamentals { +object LoadAgentFundamentals { trait FixedLoadAgentFundamentals extends LoadAgentFundamentals[ FixedLoadModel.FixedLoadRelevantData.type, @@ -302,6 +386,17 @@ case object LoadAgentFundamentals { model } + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedLoadRelevantData.type, + ConstantState.type, + FixedLoadModel + ], + tick: Long + ): FixedLoadRelevantData.type = + FixedLoadRelevantData + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power @@ -311,19 +406,28 @@ case object LoadAgentFundamentals { ParticipantModelBaseStateData[ ApparentPower, FixedLoadRelevantData.type, + ConstantState.type, FixedLoadModel ], + ConstantState.type, Dimensionless ) => ApparentPower = ( tick: Long, baseStateData: ParticipantModelBaseStateData[ ApparentPower, FixedLoadRelevantData.type, + ConstantState.type, FixedLoadModel ], + ConstantState, voltage: Dimensionless ) => - baseStateData.model.calculatePower(tick, voltage, FixedLoadRelevantData) + baseStateData.model.calculatePower( + tick, + voltage, + ConstantState, + FixedLoadRelevantData + ) } trait ProfileLoadAgentFundamentals @@ -343,6 +447,19 @@ case object LoadAgentFundamentals { model } + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + ProfileRelevantData, + ConstantState.type, + ProfileLoadModel + ], + currentTick: Long + ): ProfileRelevantData = + ProfileRelevantData( + currentTick.toDateTime(baseStateData.startDate) + ) + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power @@ -352,15 +469,21 @@ case object LoadAgentFundamentals { ParticipantModelBaseStateData[ ApparentPower, ProfileRelevantData, + ConstantState.type, ProfileLoadModel ], + ConstantState.type, Dimensionless - ) => ApparentPower = (tick, baseStateData, voltage) => { - val profileLoadModel = baseStateData.model - val profileRelevantData = ProfileRelevantData( - tick.toDateTime(baseStateData.startDate) + ) => ApparentPower = (tick, baseStateData, _, voltage) => { + val profileRelevantData = + createCalcRelevantData(baseStateData, tick) + + baseStateData.model.calculatePower( + currentTick, + voltage, + ConstantState, + profileRelevantData ) - profileLoadModel.calculatePower(currentTick, voltage, profileRelevantData) } } @@ -381,6 +504,19 @@ case object LoadAgentFundamentals { model } + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + RandomRelevantData, + ConstantState.type, + RandomLoadModel + ], + tick: Long + ): RandomRelevantData = + RandomRelevantData( + tick.toDateTime(baseStateData.startDate) + ) + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power @@ -390,15 +526,21 @@ case object LoadAgentFundamentals { ParticipantModelBaseStateData[ ApparentPower, RandomRelevantData, + ConstantState.type, RandomLoadModel ], + ConstantState.type, Dimensionless - ) => ApparentPower = (tick, baseStateData, voltage) => { - val randomLoadModel = baseStateData.model - val profileRelevantData = RandomRelevantData( - tick.toDateTime(baseStateData.startDate) + ) => ApparentPower = (tick, baseStateData, _, voltage) => { + val profileRelevantData = + createCalcRelevantData(baseStateData, tick) + + baseStateData.model.calculatePower( + currentTick, + voltage, + ConstantState, + profileRelevantData ) - randomLoadModel.calculatePower(currentTick, voltage, profileRelevantData) } } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala index d82002aaec..68cc7aa485 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.pv -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.simona.agent.participant.ParticipantAgent import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower @@ -15,8 +14,10 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.Acto import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig.PvRuntimeConfig +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.PvModel import edu.ie3.simona.model.participant.PvModel.PvRelevantData +import org.apache.pekko.actor.{ActorRef, Props} object PvAgent { def props( @@ -59,6 +60,7 @@ class PvAgent( ) extends ParticipantAgent[ ApparentPower, PvRelevantData, + ConstantState.type, ParticipantStateData[ApparentPower], PvInput, PvRuntimeConfig, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala index 64d955ff73..68fb802091 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.pv -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.datamodel.models.result.system.{ PvResult, @@ -22,12 +21,12 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.pv.PvAgent.neededServices -import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData -import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer -import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, - ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ + FlexControlledData, + ParticipantModelBaseStateData } +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.PvRuntimeConfig @@ -38,14 +37,26 @@ import edu.ie3.simona.exceptions.agent.{ InvalidRequestException } import edu.ie3.simona.io.result.AccompaniedSimulationResult -import edu.ie3.simona.model.participant.PvModel +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.PvModel.PvRelevantData +import edu.ie3.simona.model.participant.{ + FlexChangeIndicator, + ModelState, + PvModel +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherService.FALLBACK_WEATHER_STEM_DISTANCE import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits.PU import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Each, Power} import java.time.ZonedDateTime @@ -57,6 +68,7 @@ protected trait PvAgentFundamentals extends ParticipantAgentFundamentals[ ApparentPower, PvRelevantData, + ConstantState.type, ParticipantStateData[ApparentPower], PvInput, PvRuntimeConfig, @@ -99,8 +111,14 @@ protected trait PvAgentFundamentals simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig - ): ParticipantModelBaseStateData[ApparentPower, PvRelevantData, PvModel] = { + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] + ): ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ] = { /* Check for needed services */ if ( !services.exists(serviceDefinitions => @@ -120,7 +138,12 @@ protected trait PvAgentFundamentals simulationEndDate ) - ParticipantModelBaseStateData[ApparentPower, PvRelevantData, PvModel]( + ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ]( simulationStartDate, simulationEndDate, model, @@ -130,7 +153,7 @@ protected trait PvAgentFundamentals Map.empty, requestVoltageDeviationThreshold, ValueStore.forVoltage( - resolution * 10, + resolution, Each( inputModel.electricalInputModel.getNode .getvTarget() @@ -139,9 +162,11 @@ protected trait PvAgentFundamentals .doubleValue ) ), - ValueStore.forResult(resolution, 10), - ValueStore(resolution * 10), - ValueStore(resolution * 10) + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) } @@ -157,16 +182,130 @@ protected trait PvAgentFundamentals simulationEndDate ) + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ] + ): ModelState.ConstantState.type = + ConstantState + + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ], + tick: Long + ): PvRelevantData = { + /* convert current tick to a datetime */ + implicit val startDateTime: ZonedDateTime = + baseStateData.startDate + val dateTime = tick.toDateTime + + val tickInterval = + baseStateData.receivedSecondaryDataStore + .lastKnownTick(tick - 1) match { + case Some(dataTick) => + tick - dataTick + case _ => + /* At the first tick, we are not able to determine the tick interval from last tick + * (since there is none). Then we use a fall back pv stem distance. */ + FALLBACK_WEATHER_STEM_DISTANCE + } + + // take the last weather data, not necessarily the one for the current tick: + // we might receive flex control messages for irregular ticks + val (_, secondaryData) = baseStateData.receivedSecondaryDataStore + .last(tick) + .getOrElse( + throw new InconsistentStateException( + s"The model ${baseStateData.model} was not provided with any secondary data so far." + ) + ) + + /* extract weather data from secondary data, which should have been requested and received before */ + val weatherData = + secondaryData + .collectFirst { + // filter secondary data for weather data + case (_, data: WeatherData) => + data + } + .getOrElse( + throw new InconsistentStateException( + s"The model ${baseStateData.model} was not provided with needed weather data." + ) + ) + + PvRelevantData( + dateTime, + tickInterval, + weatherData.diffIrr, + weatherData.dirIrr + ) + } + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + override def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ], + data: PvRelevantData, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { + /* Calculate result */ + val voltage = getAndCheckNodalVoltage(baseStateData, tick) + + val reactivePower = baseStateData.model.calculateReactivePower( + setPower, + voltage + ) + val result = ApparentPower(setPower, reactivePower) + + /* Handle the request within the model */ + val (updatedState, flexChangeIndicator) = + baseStateData.model.handleControlledPowerChange(data, lastState, setPower) + (updatedState, result, flexChangeIndicator) + } + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power */ override val calculateModelPowerFunc: ( Long, - ParticipantModelBaseStateData[ApparentPower, PvRelevantData, PvModel], + ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ], + ConstantState.type, Dimensionless ) => ApparentPower = - (_, _, _) => + (_, _, _, _) => throw new InvalidRequestException( "Pv model cannot be run without secondary data." ) @@ -181,8 +320,10 @@ protected trait PvAgentFundamentals * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to * scheduler and using update result values.

* - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param lastModelState + * Last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -191,78 +332,35 @@ protected trait PvAgentFundamentals * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + PvRelevantData, + ConstantState.type, + PvModel + ], + lastModelState: ConstantState.type, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { - implicit val startDateTime: ZonedDateTime = - collectionStateData.baseStateData.startDate - val voltage = - getAndCheckNodalVoltage(collectionStateData.baseStateData, currentTick) - - val (result, relevantData) = - collectionStateData.baseStateData match { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.model match { - case pvModel: PvModel => - /* convert current tick to a datetime */ - val dateTime = currentTick.toDateTime - - val tickInterval = - modelBaseStateData.calcRelevantDateStore - .last(currentTick - 1) match { - case Some((tick, _)) => - currentTick - tick - case _ => - /* At the first tick, we are not able to determine the tick interval from last tick - * (since there is none). Then we use a fall back pv stem distance. */ - FALLBACK_WEATHER_STEM_DISTANCE - } - - /* extract weather data from secondary data, which should have been requested and received before */ - val weatherData = - collectionStateData.data - .collectFirst { - // filter secondary data for weather data - case (_, Some(data: WeatherData)) => - data - } - .getOrElse( - throw new InconsistentStateException( - s"The model ${modelBaseStateData.model} was not provided with needed weather data." - ) - ) + getAndCheckNodalVoltage(baseStateData, currentTick) - val relevantData = - PvRelevantData( - dateTime, - tickInterval, - weatherData.diffIrr, - weatherData.dirIrr - ) - - val power = pvModel.calculatePower( - currentTick, - voltage, - relevantData - ) + val relevantData = + createCalcRelevantData( + baseStateData, + currentTick + ) - (power, relevantData) - case unsupportedModel => - throw new InconsistentStateException( - s"Wrong model: $unsupportedModel!" - ) - } - case _ => - throw new InconsistentStateException( - "Cannot find a model for model calculation." - ) - } + val result = baseStateData.model.calculatePower( + currentTick, + voltage, + ConstantState, + relevantData + ) updateValueStoresInformListenersAndGoToIdleWithUpdatedBaseStateData( scheduler, - collectionStateData.baseStateData, + baseStateData, AccompaniedSimulationResult(result), relevantData ) @@ -319,4 +417,28 @@ protected trait PvAgentFundamentals result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar ) + + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + override protected def updateState( + tick: Long, + modelState: ModelState.ConstantState.type, + calcRelevantData: PvRelevantData, + nodalVoltage: squants.Dimensionless, + model: PvModel + ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala index a625778779..9d13b158c5 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala @@ -6,13 +6,23 @@ package edu.ie3.simona.agent.participant.statedata -import org.apache.pekko.actor.ActorRef import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.data.Data.PrimaryData.PrimaryDataWithApparentPower import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.event.notifier.NotifierConfig -import edu.ie3.simona.model.participant.{CalcRelevantData, SystemParticipant} +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + ModelState, + SystemParticipant +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse, + ProvideFlexOptions +} +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.{ActorRef => ClassicActorRef} import squants.Dimensionless import java.time.ZonedDateTime @@ -51,7 +61,7 @@ trait BaseStateData[+PD <: PrimaryDataWithApparentPower[PD]] /** A mapping from service reference to it's foreseen next availability of * data */ - val foreseenDataTicks: Map[ActorRef, Option[Long]] + val foreseenDataTicks: Map[ClassicActorRef, Option[Long]] /** A store, holding a map from tick to active / reactive power */ @@ -89,7 +99,8 @@ object BaseStateData { trait ModelBaseStateData[ +PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, - +M <: SystemParticipant[_ <: CalcRelevantData, PD] + MS <: ModelState, + +M <: SystemParticipant[_ <: CalcRelevantData, PD, MS] ] extends BaseStateData[PD] { /** The physical system model @@ -102,7 +113,15 @@ object BaseStateData { /** Stores all data that are relevant to model calculation */ - val calcRelevantDateStore: ValueStore[CalcRelevantData] + val receivedSecondaryDataStore: ValueStore[ + Map[ClassicActorRef, _ <: SecondaryData] + ] + + val stateDataStore: ValueStore[MS] + + val flexStateData: Option[FlexControlledData] + + def isEmManaged: Boolean = flexStateData.nonEmpty } /** Basic state data, when the agent is supposed to only provide external data @@ -134,14 +153,15 @@ object BaseStateData { */ final case class FromOutsideBaseStateData[M <: SystemParticipant[ _ <: CalcRelevantData, - P + P, + _ ], +P <: PrimaryDataWithApparentPower[P]]( model: M, override val startDate: ZonedDateTime, override val endDate: ZonedDateTime, override val outputConfig: NotifierConfig, override val additionalActivationTicks: SortedSet[Long], - override val foreseenDataTicks: Map[ActorRef, Option[Long]], + override val foreseenDataTicks: Map[ClassicActorRef, Option[Long]], fillUpReactivePowerWithModelFunc: Boolean = false, requestVoltageDeviationThreshold: Double, override val voltageValueStore: ValueStore[ @@ -188,7 +208,8 @@ object BaseStateData { final case class ParticipantModelBaseStateData[ +PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, - +M <: SystemParticipant[_ <: CalcRelevantData, PD] + MS <: ModelState, + M <: SystemParticipant[_ <: CalcRelevantData, PD, MS] ]( override val startDate: ZonedDateTime, override val endDate: ZonedDateTime, @@ -198,21 +219,41 @@ object BaseStateData { ], override val outputConfig: NotifierConfig, override val additionalActivationTicks: SortedSet[Long], - override val foreseenDataTicks: Map[ActorRef, Option[Long]], + override val foreseenDataTicks: Map[ClassicActorRef, Option[Long]], requestVoltageDeviationThreshold: Double, override val voltageValueStore: ValueStore[ Dimensionless ], override val resultValueStore: ValueStore[PD], override val requestValueStore: ValueStore[PD], - override val calcRelevantDateStore: ValueStore[CD] - ) extends ModelBaseStateData[PD, CD, M] { + override val receivedSecondaryDataStore: ValueStore[ + Map[ClassicActorRef, _ <: SecondaryData] + ], + override val stateDataStore: ValueStore[MS], + override val flexStateData: Option[FlexControlledData] + ) extends ModelBaseStateData[PD, CD, MS, M] { /** Unique identifier of the simulation model */ override val modelUuid: UUID = model.getUuid } + /** The existence of this data object indicates that the corresponding agent + * is EM-controlled (by [[emAgent]]). + * + * @param emAgent + * The parent EmAgent that is controlling this agent. + * @param flexAdapter + * The flex adapter handling [[FlexRequest]] messages + * @param lastFlexOptions + * Last flex options that have been calculated for this agent. + */ + final case class FlexControlledData( + emAgent: ActorRef[FlexResponse], + flexAdapter: ActorRef[FlexRequest], + lastFlexOptions: Option[ProvideFlexOptions] = None + ) + /** Updates the base state data with the given value stores * * @param baseStateData @@ -226,7 +267,7 @@ object BaseStateData { * @param updatedAdditionalActivationTicks * Additional activation ticks * @param updatedForeseenTicks - * Mapping from [[ActorRef]] to foreseen ticks + * Mapping from [[ClassicActorRef]] to foreseen ticks * @tparam PD * Type of primary data, that is result of model calculation * @return @@ -238,7 +279,7 @@ object BaseStateData { updatedRequestValueStore: ValueStore[PD], updatedVoltageValueStore: ValueStore[Dimensionless], updatedAdditionalActivationTicks: SortedSet[Long], - updatedForeseenTicks: Map[ActorRef, Option[Long]] + updatedForeseenTicks: Map[ClassicActorRef, Option[Long]] ): BaseStateData[PD] = { baseStateData match { case external: FromOutsideBaseStateData[_, PD] => @@ -249,7 +290,7 @@ object BaseStateData { additionalActivationTicks = updatedAdditionalActivationTicks, foreseenDataTicks = updatedForeseenTicks ) - case model: ParticipantModelBaseStateData[PD, _, _] => + case model: ParticipantModelBaseStateData[PD, _, _, _] => model.copy( resultValueStore = updatedResultValueStore, requestValueStore = updatedRequestValueStore, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala index 83651c6c61..08a291afce 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala @@ -20,13 +20,14 @@ trait InitializeStateData[+PD <: PrimaryData] extends ParticipantStateData[PD] { val outputConfig: NotifierConfig } -case object InitializeStateData { +object InitializeStateData { final case class TrivialInitializeStateData[+PD <: PrimaryData]( resultEventEmitter: String ) extends InitializeStateData[PD] { val outputConfig: NotifierConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = true + powerRequestReply = true, + flexResult = false ) } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala index d52896da0c..5b759e2933 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala @@ -6,14 +6,16 @@ package edu.ie3.simona.agent.participant.statedata -import org.apache.pekko.actor.ActorRef import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.datamodel.models.input.system.SystemParticipantInput -import edu.ie3.simona.agent.participant.data.Data.{PrimaryData, SecondaryData} import edu.ie3.simona.agent.participant.data.Data.PrimaryData.PrimaryDataWithApparentPower +import edu.ie3.simona.agent.participant.data.Data.{PrimaryData, SecondaryData} import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.notifier.NotifierConfig +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.FlexResponse +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.{ActorRef => ClassicActorRef} import java.time.ZonedDateTime @@ -53,6 +55,8 @@ object ParticipantStateData { * power requests for the same tick are considered to be different * @param outputConfig * Config for the output behaviour of simulation results + * @param maybeEmAgent + * The EmAgent if this participant is em-controlled * @tparam I * Type of input model to carry * @tparam C @@ -74,7 +78,8 @@ object ParticipantStateData { simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[ActorRef[FlexResponse]] ) extends ParticipantStateData[PD] /** State data to use, when initializing the participant agent @@ -96,6 +101,8 @@ object ParticipantStateData { * power requests for the same tick are considered to be different * @param outputConfig * Config for the output behaviour of simulation results + * @param maybeEmAgent + * The EmAgent if this participant is em-controlled * @tparam I * Type of input model to carry * @tparam C @@ -110,7 +117,7 @@ object ParticipantStateData { ]( inputModel: InputModelContainer[I], modelConfig: C, - primaryServiceProxy: ActorRef, + primaryServiceProxy: ClassicActorRef, secondaryDataServices: Option[ Vector[SecondaryDataService[_ <: SecondaryData]] ], @@ -118,10 +125,12 @@ object ParticipantStateData { simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[ActorRef[FlexResponse]] = None ) extends InitializeStateData[PD] object ParticipantInitializeStateData { + def apply[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, @@ -129,7 +138,7 @@ object ParticipantStateData { ]( inputModel: I, modelConfig: C, - primaryServiceProxy: ActorRef, + primaryServiceProxy: ClassicActorRef, secondaryDataServices: Option[ Vector[SecondaryDataService[_ <: SecondaryData]] ], @@ -148,7 +157,38 @@ object ParticipantStateData { simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent = None + ) + def apply[ + I <: SystemParticipantInput, + C <: SimonaConfig.BaseRuntimeConfig, + PD <: PrimaryData + ]( + inputModel: I, + modelConfig: C, + primaryServiceProxy: ClassicActorRef, + secondaryDataServices: Option[ + Vector[SecondaryDataService[_ <: SecondaryData]] + ], + simulationStartDate: ZonedDateTime, + simulationEndDate: ZonedDateTime, + resolution: Long, + requestVoltageDeviationThreshold: Double, + outputConfig: NotifierConfig, + maybeEmAgent: Option[ActorRef[FlexResponse]] + ): ParticipantInitializeStateData[I, C, PD] = + new ParticipantInitializeStateData[I, C, PD]( + SimpleInputContainer(inputModel), + modelConfig, + primaryServiceProxy, + secondaryDataServices, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig, + maybeEmAgent ) def apply[ @@ -159,7 +199,7 @@ object ParticipantStateData { inputModel: I, thermalGrid: ThermalGrid, modelConfig: C, - primaryServiceProxy: ActorRef, + primaryServiceProxy: ClassicActorRef, secondaryDataServices: Option[ Vector[SecondaryDataService[_ <: SecondaryData]] ], @@ -178,7 +218,40 @@ object ParticipantStateData { simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent = None + ) + + def apply[ + I <: SystemParticipantInput, + C <: SimonaConfig.BaseRuntimeConfig, + PD <: PrimaryData + ]( + inputModel: I, + thermalGrid: ThermalGrid, + modelConfig: C, + primaryServiceProxy: ClassicActorRef, + secondaryDataServices: Option[ + Vector[SecondaryDataService[_ <: SecondaryData]] + ], + simulationStartDate: ZonedDateTime, + simulationEndDate: ZonedDateTime, + resolution: Long, + requestVoltageDeviationThreshold: Double, + outputConfig: NotifierConfig, + maybeEmAgent: Option[ActorRef[FlexResponse]] + ): ParticipantInitializeStateData[I, C, PD] = + new ParticipantInitializeStateData[I, C, PD]( + WithHeatInputContainer(inputModel, thermalGrid), + modelConfig, + primaryServiceProxy, + secondaryDataServices, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig, + maybeEmAgent ) } @@ -199,8 +272,8 @@ object ParticipantStateData { +PD <: PrimaryDataWithApparentPower[PD] ]( baseStateData: BaseStateData[PD], - pendingResponses: Vector[ActorRef], - foreseenNextDataTicks: Map[ActorRef, Long] = Map.empty + pendingResponses: Seq[ClassicActorRef], + foreseenNextDataTicks: Map[ClassicActorRef, Long] = Map.empty ) extends ParticipantStateData[PD] sealed trait InputModelContainer[+I <: SystemParticipantInput] { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala index 94a5c490a0..9f65245c4c 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala @@ -6,17 +6,18 @@ package edu.ie3.simona.agent.participant.wec -import org.apache.pekko.actor.{ActorRef, Props} import edu.ie3.datamodel.models.input.system.WecInput -import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.ParticipantAgent +import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.ActorWeatherService import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig.WecRuntimeConfig +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.WecModel import edu.ie3.simona.model.participant.WecModel._ +import org.apache.pekko.actor.{ActorRef, Props} object WecAgent { def props( @@ -59,6 +60,7 @@ class WecAgent( ) extends ParticipantAgent[ ApparentPower, WecRelevantData, + ConstantState.type, ParticipantStateData[ApparentPower], WecInput, WecRuntimeConfig, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala index bbb9e55c6c..8ca46cea85 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.wec -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.WecInput import edu.ie3.datamodel.models.result.system.{ SystemParticipantResult, @@ -22,11 +21,8 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData._ +import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer -import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, - ParticipantStateData -} import edu.ie3.simona.agent.participant.wec.WecAgent.neededServices import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle @@ -38,12 +34,24 @@ import edu.ie3.simona.exceptions.agent.{ InvalidRequestException } import edu.ie3.simona.io.result.AccompaniedSimulationResult -import edu.ie3.simona.model.participant.WecModel +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.WecModel.WecRelevantData +import edu.ie3.simona.model.participant.{ + FlexChangeIndicator, + ModelState, + WecModel +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Each, Power} import java.time.ZonedDateTime @@ -55,6 +63,7 @@ protected trait WecAgentFundamentals extends ParticipantAgentFundamentals[ ApparentPower, WecRelevantData, + ConstantState.type, ParticipantStateData[ApparentPower], WecInput, WecRuntimeConfig, @@ -97,8 +106,14 @@ protected trait WecAgentFundamentals simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig - ): ParticipantModelBaseStateData[ApparentPower, WecRelevantData, WecModel] = { + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] + ): ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ] = { /* Check for needed services */ if ( !services.exists(serviceDefinitions => @@ -118,7 +133,12 @@ protected trait WecAgentFundamentals simulationEndDate ) - ParticipantModelBaseStateData[ApparentPower, WecRelevantData, WecModel]( + ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ]( simulationStartDate, simulationEndDate, model, @@ -128,18 +148,20 @@ protected trait WecAgentFundamentals Map.empty, requestVoltageDeviationThreshold, ValueStore.forVoltage( - resolution * 10, + resolution, Each( inputModel.electricalInputModel.getNode .getvTarget() .to(PU) .getValue - .doubleValue() + .doubleValue ) ), - ValueStore.forResult(resolution, 10), - ValueStore(resolution * 10), - ValueStore(resolution * 10) + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) } @@ -155,13 +177,108 @@ protected trait WecAgentFundamentals simulationEndDate ) + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ] + ): ModelState.ConstantState.type = + ConstantState + + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ], + tick: Long + ): WecRelevantData = { + // take the last weather data, not necessarily the one for the current tick: + // we might receive flex control messages for irregular ticks + val (_, secondaryData) = baseStateData.receivedSecondaryDataStore + .last(tick) + .getOrElse( + throw new InconsistentStateException( + s"The model ${baseStateData.model} was not provided with any secondary data so far." + ) + ) + + val weatherData = + secondaryData + .collectFirst { + // filter secondary data for weather data + case (_, data: WeatherData) => data + } + .getOrElse( + throw new InconsistentStateException( + s"The model ${baseStateData.model} was not provided with needed weather data." + ) + ) + + WecRelevantData( + weatherData.windVel, + weatherData.temp, + None + ) + } + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ], + data: WecRelevantData, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { + /* Calculate result */ + val voltage = getAndCheckNodalVoltage(baseStateData, tick) + + val reactivePower = baseStateData.model.calculateReactivePower( + setPower, + voltage + ) + val result = ApparentPower(setPower, reactivePower) + + /* Handle the request within the model */ + val (updatedState, flexChangeIndicator) = + baseStateData.model.handleControlledPowerChange(data, lastState, setPower) + (updatedState, result, flexChangeIndicator) + } + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power */ override val calculateModelPowerFunc: ( Long, - ParticipantModelBaseStateData[ApparentPower, WecRelevantData, WecModel], + ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ], + ConstantState.type, Dimensionless ) => ApparentPower = ( @@ -169,8 +286,10 @@ protected trait WecAgentFundamentals _: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ], + _, _: Dimensionless ) => throw new InvalidRequestException( @@ -187,8 +306,10 @@ protected trait WecAgentFundamentals * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to * scheduler and using update result values.

* - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param lastModelState + * Optional last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -197,62 +318,35 @@ protected trait WecAgentFundamentals * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + WecRelevantData, + ConstantState.type, + WecModel + ], + lastModelState: ConstantState.type, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { - implicit val startDateTime: ZonedDateTime = - collectionStateData.baseStateData.startDate - val voltage = - getAndCheckNodalVoltage(collectionStateData.baseStateData, currentTick) - - val (result, relevantData) = - collectionStateData.baseStateData match { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.model match { - case wecModel: WecModel => - /* extract weather data from secondary data, which should have been requested and received before */ - val weatherData = - collectionStateData.data - .collectFirst { - // filter secondary data for weather data - case (_, Some(data: WeatherData)) => data - } - .getOrElse( - throw new InconsistentStateException( - s"The model ${modelBaseStateData.model} was not provided with needed weather data." - ) - ) - - val relevantData = - WecRelevantData( - weatherData.windVel, - weatherData.temp, - None // weather data does not support air pressure - ) + getAndCheckNodalVoltage(baseStateData, currentTick) - val power = wecModel.calculatePower( - currentTick, - voltage, - relevantData - ) + val relevantData = + createCalcRelevantData( + baseStateData, + currentTick + ) - (power, relevantData) - case unsupportedModel => - throw new InconsistentStateException( - s"Wrong model: $unsupportedModel!" - ) - } - case _ => - throw new InconsistentStateException( - "Cannot find a model for model calculation." - ) - } + val result = baseStateData.model.calculatePower( + currentTick, + voltage, + ConstantState, + relevantData + ) updateValueStoresInformListenersAndGoToIdleWithUpdatedBaseStateData( scheduler, - collectionStateData.baseStateData, + baseStateData, AccompaniedSimulationResult(result), relevantData ) @@ -309,4 +403,28 @@ protected trait WecAgentFundamentals result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar ) + + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + override protected def updateState( + tick: Long, + modelState: ModelState.ConstantState.type, + calcRelevantData: WecRelevantData, + nodalVoltage: squants.Dimensionless, + model: WecModel + ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 5072923c7c..14426ecfef 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,5 +1,5 @@ /* - * © 2023. TU Dortmund University, + * © 2024. TU Dortmund University, * Institute of Energy Systems, Energy Efficiency and Energy Economics, * Research group Distribution grid planning and operation */ @@ -393,6 +393,7 @@ object SimonaConfig { final case class ParticipantBaseOutputConfig( override val notifier: java.lang.String, override val simulationResult: scala.Boolean, + flexResult: scala.Boolean, powerRequestReply: scala.Boolean ) extends BaseOutputConfig(notifier, simulationResult) object ParticipantBaseOutputConfig { @@ -402,6 +403,8 @@ object SimonaConfig { $tsCfgValidator: $TsCfgValidator ): SimonaConfig.ParticipantBaseOutputConfig = { SimonaConfig.ParticipantBaseOutputConfig( + flexResult = + c.hasPathOrNull("flexResult") && c.getBoolean("flexResult"), powerRequestReply = $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), @@ -1727,6 +1730,7 @@ object SimonaConfig { final case class Output( base: SimonaConfig.Simona.Output.Base, + flex: scala.Boolean, grid: SimonaConfig.GridOutputConfig, participant: SimonaConfig.Simona.Output.Participant, sink: SimonaConfig.Simona.Output.Sink, @@ -1995,6 +1999,7 @@ object SimonaConfig { parentPath + "base.", $tsCfgValidator ), + flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), grid = SimonaConfig.GridOutputConfig( if (c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), diff --git a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala index 7244d941f5..81512e9a9d 100644 --- a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala @@ -12,7 +12,10 @@ import edu.ie3.datamodel.models.result.connector.{ SwitchResult, Transformer2WResult } -import edu.ie3.datamodel.models.result.system.SystemParticipantResult +import edu.ie3.datamodel.models.result.system.{ + FlexOptionsResult, + SystemParticipantResult +} import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage @@ -65,4 +68,14 @@ object ResultEvent { transformer3wResults: Iterable[PartialTransformer3wResult] ) extends ResultEvent + /** Event that holds the flexibility options result of a + * [[edu.ie3.simona.model.participant.SystemParticipant]] + * + * @param flexOptionsResult + * the flex options result + */ + final case class FlexOptionsResultEvent( + flexOptionsResult: FlexOptionsResult + ) extends ResultEvent + } diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index 38539b2baa..3abe4d831e 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -13,6 +13,7 @@ import edu.ie3.datamodel.models.result.{NodeResult, ResultEntity} import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult import edu.ie3.simona.event.Event import edu.ie3.simona.event.ResultEvent.{ + FlexOptionsResultEvent, ParticipantResultEvent, PowerFlowResultEvent, ThermalResultEvent @@ -314,6 +315,10 @@ object ResultEventListener extends Transformer3wResultSupport { } idle(updatedBaseData) + case (ctx, FlexOptionsResultEvent(flexOptionsResult)) => + val updatedBaseData = handleResult(flexOptionsResult, baseData, ctx.log) + idle(updatedBaseData) + case (ctx, _: StopMessage) => ctx.log.debug( s"${getClass.getSimpleName} received Stop message, shutting down when no message has been received in 5 seconds." diff --git a/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala b/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala index 3db8b438c6..dfcf9c9e65 100644 --- a/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala +++ b/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala @@ -14,5 +14,6 @@ package edu.ie3.simona.event.notifier */ final case class NotifierConfig( simulationResultInfo: Boolean, - powerRequestReply: Boolean + powerRequestReply: Boolean, + flexResult: Boolean ) diff --git a/src/main/scala/edu/ie3/simona/model/em/EmTools.scala b/src/main/scala/edu/ie3/simona/model/em/EmTools.scala new file mode 100644 index 0000000000..1eecffa22d --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/em/EmTools.scala @@ -0,0 +1,78 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.em + +import edu.ie3.simona.exceptions.CriticalFailureException +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + IssueFlexControl, + IssueNoControl, + IssuePowerControl, + ProvideFlexOptions +} +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions +import squants.Power + +/** Tools used by agents that engage with energy management and flexibility + */ +object EmTools { + + /** Determines the set point given a flex options message and a flex control + * message. Also validates the resulting power. + * + * @param flexOptionsMsg + * The flex options message + * @param flexCtrl + * The flex control message + * @return + * The resulting power set point + */ + def determineFlexPower( + flexOptionsMsg: ProvideFlexOptions, + flexCtrl: IssueFlexControl + ): Power = + flexOptionsMsg match { + case flexOptions: ProvideMinMaxFlexOptions => + flexCtrl match { + case IssuePowerControl(_, setPower) => + // sanity check: setPower is in range of latest flex options + checkSetPower(flexOptions, setPower) + + setPower + + case IssueNoControl(_) => + // no override, take reference power + flexOptions.ref + } + + case unknownFlexOpt => + throw new CriticalFailureException( + s"Unknown/unfitting flex messages $unknownFlexOpt" + ) + } + + /** Checks whether given setPower fits the provided flex options, i.e. whether + * the set point is feasible given the flex options. + * + * @param flexOptions + * The flex options that the set point has to fit + * @param setPower + * The set point + */ + def checkSetPower( + flexOptions: ProvideMinMaxFlexOptions, + setPower: Power + ): Unit = { + if (setPower < flexOptions.min) + throw new CriticalFailureException( + s"The set power $setPower for ${flexOptions.modelUuid} must not be lower than the minimum power ${flexOptions.min}!" + ) + else if (setPower > flexOptions.max) + throw new CriticalFailureException( + s"The set power $setPower for ${flexOptions.modelUuid} must not be greater than the maximum power ${flexOptions.max}!" + ) + } +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala index 9fe21e87ac..8e4bed893d 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala @@ -10,17 +10,22 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHe import squants.energy.Megawatts import squants.{Dimensionless, Power} -trait ApparentPowerAndHeatParticipant[CD <: CalcRelevantData] { - this: SystemParticipant[CD, ApparentPowerAndHeat] => +trait ApparentPowerAndHeatParticipant[ + CD <: CalcRelevantData, + MS <: ModelState +] { + this: SystemParticipant[CD, ApparentPowerAndHeat, MS] => override def calculatePower( tick: Long, voltage: Dimensionless, + modelState: MS, data: CD ): ApparentPowerAndHeat = { - val apparentPower = calculateApparentPower(tick, voltage, data) + val apparentPower = + calculateApparentPower(tick, voltage, modelState, data) val heat = if (isInOperation(tick)) - calculateHeat(tick, data) + calculateHeat(tick, modelState, data) else Megawatts(0d) @@ -31,10 +36,16 @@ trait ApparentPowerAndHeatParticipant[CD <: CalcRelevantData] { * are understood as consumption and negative as production * @param tick * Current instant in simulation time + * @param modelState + * Current state of the model * @param data * Needed calculation relevant data * @return * Heat production or consumption of the asset */ - def calculateHeat(tick: Long, data: CD): Power + def calculateHeat( + tick: Long, + modelState: MS, + data: CD + ): Power } diff --git a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala index 51353fe437..1819e2d2a0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala @@ -9,11 +9,13 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import squants.Dimensionless -trait ApparentPowerParticipant[CD <: CalcRelevantData] { - this: SystemParticipant[CD, ApparentPower] => +trait ApparentPowerParticipant[CD <: CalcRelevantData, MS <: ModelState] { + this: SystemParticipant[CD, ApparentPower, MS] => override def calculatePower( tick: Long, voltage: Dimensionless, + modelState: MS, data: CD - ): ApparentPower = calculateApparentPower(tick, voltage, data) + ): ApparentPower = + calculateApparentPower(tick, voltage, modelState, data) } diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index c8594f3e3c..2283bfddb7 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -7,8 +7,10 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower -import edu.ie3.simona.model.participant.BMModel.BMCalcRelevantData +import edu.ie3.simona.model.participant.BMModel.{BMCalcRelevantData, BmState} import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.EnergyPrice import squants.energy.Megawatts @@ -33,7 +35,7 @@ final case class BMModel( private val opex: Money, private val feedInTariff: EnergyPrice, private val loadGradient: Double -) extends SystemParticipant[BMCalcRelevantData, ApparentPower]( +) extends SystemParticipant[BMCalcRelevantData, ApparentPower, BmState]( uuid, id, operationInterval, @@ -42,7 +44,7 @@ final case class BMModel( sRated, cosPhi ) - with ApparentPowerParticipant[BMCalcRelevantData] { + with ApparentPowerParticipant[BMCalcRelevantData, BmState] { /** Saves power output of last cycle. Needed for load gradient */ @@ -51,9 +53,10 @@ final case class BMModel( override def calculatePower( tick: Long, voltage: Dimensionless, + modelState: BmState, data: BMCalcRelevantData ): ApparentPower = { - val result = super.calculatePower(tick, voltage, data) + val result = super.calculatePower(tick, voltage, modelState, data) _lastPower = Some(result.p) result @@ -67,6 +70,7 @@ final case class BMModel( * Active power */ override protected def calculateActivePower( + modelState: BmState, data: BMCalcRelevantData ): Power = { // Calculate heat demand // @@ -216,9 +220,26 @@ final case class BMModel( } } } + + override def determineFlexOptions( + data: BMCalcRelevantData, + lastState: BmState + ): ProvideFlexOptions = { + val power = calculateActivePower(lastState, data) + + ProvideMinMaxFlexOptions(uuid, power, power, Megawatts(0d)) + } + + override def handleControlledPowerChange( + data: BMCalcRelevantData, + lastState: BmState, + setPower: squants.Power + ): (BmState, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } -case object BMModel { +object BMModel { + + case class BmState() extends ModelState /** Data, that is needed for model calculations with the biomass model * diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 5b5baa8924..0f03864853 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -9,13 +9,15 @@ package edu.ie3.simona.model.participant import edu.ie3.datamodel.models.input.system.ChpInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.participant.ChpModel._ +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.{MutableStorage, ThermalStorage} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities -import squants.energy.{KilowattHours, Kilowatts} import squants.{Energy, Power, Seconds, Time} +import squants.energy.{KilowattHours, Kilowatts} import java.util.UUID @@ -51,7 +53,7 @@ final case class ChpModel( cosPhiRated: Double, pThermal: Power, storage: ThermalStorage with MutableStorage -) extends SystemParticipant[ChpRelevantData, ApparentPower]( +) extends SystemParticipant[ChpRelevantData, ApparentPower, ConstantState.type]( uuid, id, operationInterval, @@ -60,7 +62,7 @@ final case class ChpModel( sRated, cosPhiRated ) - with ApparentPowerParticipant[ChpRelevantData] { + with ApparentPowerParticipant[ChpRelevantData, ConstantState.type] { val pRated: Power = sRated * cosPhiRated @@ -76,6 +78,7 @@ final case class ChpModel( * active power */ override protected def calculateActivePower( + modelState: ConstantState.type, chpData: ChpRelevantData ): Power = chpData.chpState.activePower @@ -284,11 +287,23 @@ final case class ChpModel( private def timeRunning(chpData: ChpRelevantData): Time = Seconds(chpData.currentTimeTick - chpData.chpState.lastTimeTick) + + override def determineFlexOptions( + data: ChpRelevantData, + lastState: ConstantState.type + ): ProvideFlexOptions = ??? // TODO actual implementation + + override def handleControlledPowerChange( + data: ChpRelevantData, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, FlexChangeIndicator) = + ??? // TODO actual implementation } /** Create valid ChpModel by calling the apply function. */ -case object ChpModel { +object ChpModel { /** As the ChpModel class is a dynamic model, it requires a state for its * calculations. The state contains all variables needed, except the storage @@ -358,7 +373,7 @@ case object ChpModel { chpInput.getType.getsRated .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), chpInput.getType.getCosPhiRated, Kilowatts( diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index 89fd5096ce..04e3a9b7e3 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -12,10 +12,12 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval - import squants.Power import squants.energy.Kilowatts @@ -47,7 +49,11 @@ final case class FixedFeedInModel( qControl: QControl, sRated: Power, cosPhiRated: Double -) extends SystemParticipant[FixedRelevantData.type, ApparentPower]( +) extends SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ]( uuid, id, operationInterval, @@ -56,7 +62,7 @@ final case class FixedFeedInModel( sRated, cosPhiRated ) - with ApparentPowerParticipant[FixedRelevantData.type] { + with ApparentPowerParticipant[FixedRelevantData.type, ConstantState.type] { /** Calculate the active power behaviour of the model * @@ -67,12 +73,29 @@ final case class FixedFeedInModel( * Active power */ override protected def calculateActivePower( + modelState: ConstantState.type, data: FixedRelevantData.type = FixedRelevantData ): Power = sRated * (-1) * cosPhiRated * scalingFactor + + override def determineFlexOptions( + data: FixedRelevantData.type, + lastState: ConstantState.type + ): ProvideFlexOptions = + ProvideMinMaxFlexOptions.noFlexOption( + uuid, + calculateActivePower(ConstantState, data) + ) + + override def handleControlledPowerChange( + data: FixedRelevantData.type, + lastState: ConstantState.type, + setPower: Power + ): (ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) } -case object FixedFeedInModel extends LazyLogging { +object FixedFeedInModel extends LazyLogging { def apply( inputModel: FixedFeedInInput, modelConfiguration: SimonaConfig.FixedFeedInRuntimeConfig, diff --git a/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala b/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala new file mode 100644 index 0000000000..5a4b7d0839 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala @@ -0,0 +1,12 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant + +final case class FlexChangeIndicator( + changesAtNextActivation: Boolean = false, + changesAtTick: Option[Long] = None +) diff --git a/src/main/scala/edu/ie3/simona/model/participant/ModelState.scala b/src/main/scala/edu/ie3/simona/model/participant/ModelState.scala new file mode 100644 index 0000000000..1416a6a4f5 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/ModelState.scala @@ -0,0 +1,14 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant + +trait ModelState + +object ModelState { + + case object ConstantState extends ModelState +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index 847d45e5a1..94ce736644 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -9,8 +9,11 @@ package edu.ie3.simona.model.participant import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.PvModel.PvRelevantData import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities._ @@ -40,7 +43,7 @@ final case class PvModel private ( private val alphaE: Angle, private val gammaE: Angle, private val moduleSurface: Area = SquareMeters(1d) -) extends SystemParticipant[PvRelevantData, ApparentPower]( +) extends SystemParticipant[PvRelevantData, ApparentPower, ConstantState.type]( uuid, id, operationInterval, @@ -49,7 +52,7 @@ final case class PvModel private ( sRated, cosPhiRated ) - with ApparentPowerParticipant[PvRelevantData] { + with ApparentPowerParticipant[PvRelevantData, ConstantState.type] { /** Override sMax as the power output of a pv unit could become easily up to * 10% higher than the sRated value found in the technical sheets @@ -72,6 +75,7 @@ final case class PvModel private ( * Active power */ override protected def calculateActivePower( + modelState: ConstantState.type, data: PvRelevantData ): Power = { // === Weather Base Data === // @@ -707,6 +711,22 @@ final case class PvModel private ( DefaultQuantities.zeroMW else proposal } + + override def determineFlexOptions( + data: PvRelevantData, + lastState: ConstantState.type + ): ProvideFlexOptions = { + val power = calculateActivePower(ConstantState, data) + + ProvideMinMaxFlexOptions(uuid, power, power, DefaultQuantities.zeroMW) + } + + override def handleControlledPowerChange( + data: PvRelevantData, + lastState: ConstantState.type, + setPower: squants.Power + ): (ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) } object PvModel { diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index e8bbf14c5a..553d05dfd6 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -12,6 +12,7 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ } import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.{ DefaultQuantities, @@ -43,10 +44,13 @@ import java.util.UUID * Type of data, that is needed for model calculation * @tparam PD * Primary data, that this asset does produce + * @tparam MS + * Type of model state data */ abstract class SystemParticipant[ CD <: CalcRelevantData, - +PD <: PrimaryDataWithApparentPower[PD] + +PD <: PrimaryDataWithApparentPower[PD], + MS <: ModelState ]( uuid: UUID, id: String, @@ -70,6 +74,8 @@ abstract class SystemParticipant[ * Regarded instant in simulation * @param voltage * Nodal voltage magnitude + * @param modelState + * Current state of the model * @param data * Further needed, secondary data * @return @@ -78,6 +84,7 @@ abstract class SystemParticipant[ def calculatePower( tick: Long, voltage: Dimensionless, + modelState: MS, data: CD ): PD @@ -95,10 +102,11 @@ abstract class SystemParticipant[ protected def calculateApparentPower( tick: Long, voltage: Dimensionless, + modelState: MS, data: CD ): ApparentPower = { if (isInOperation(tick)) { - val activePower = calculateActivePower(data) + val activePower = calculateActivePower(modelState, data) val reactivePower = calculateReactivePower(activePower, voltage) ApparentPower(activePower, reactivePower) @@ -112,12 +120,41 @@ abstract class SystemParticipant[ /** Calculate the active power behaviour of the model * + * @param modelState + * Current state of the model * @param data * Further needed, secondary data * @return * Active power */ - protected def calculateActivePower(data: CD): Power + protected def calculateActivePower( + modelState: MS, + data: CD + ): Power + + /** @param data + * @param lastState + * @return + * flex options + */ + def determineFlexOptions( + data: CD, + lastState: MS + ): ProvideFlexOptions + + /** @param data + * @param lastState + * @param setPower + * power that has been set by EmAgent + * @return + * updated relevant data and an indication at which circumstances flex + * options will change next + */ + def handleControlledPowerChange( + data: CD, + lastState: MS, + setPower: Power + ): (MS, FlexChangeIndicator) /** Get a partial function, that transfers the current active into reactive * power based on the participants properties and the given nodal voltage diff --git a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala index ca1719dbb0..d063479c67 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala @@ -10,6 +10,7 @@ import edu.ie3.datamodel.models.input.system.WecInput import edu.ie3.datamodel.models.input.system.characteristic.WecCharacteristicInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.WecModel.{ WecCharacteristic, WecRelevantData @@ -17,14 +18,16 @@ import edu.ie3.simona.model.participant.WecModel.{ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.system.Characteristic import edu.ie3.simona.model.system.Characteristic.XYPair +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.scala.OperationInterval -import squants.energy.{Kilowatts, Watts} +import squants._ +import squants.energy.{Kilowatts, Megawatts, Watts} import squants.mass.{Kilograms, KilogramsPerCubicMeter} import squants.motion.{MetersPerSecond, Pressure} import squants.space.SquareMeters import squants.thermal.JoulesPerKelvin -import squants._ import tech.units.indriya.unit.Units._ import java.time.ZonedDateTime @@ -63,7 +66,7 @@ final case class WecModel( cosPhiRated: Double, rotorArea: Area, betzCurve: WecCharacteristic -) extends SystemParticipant[WecRelevantData, ApparentPower]( +) extends SystemParticipant[WecRelevantData, ApparentPower, ConstantState.type]( uuid, id, operationInterval, @@ -72,9 +75,9 @@ final case class WecModel( sRated, cosPhiRated ) - with ApparentPowerParticipant[WecRelevantData] { + with ApparentPowerParticipant[WecRelevantData, ConstantState.type] { - /** Universal gas constant, actually in J/(K * mol) + /** Universal gas constant */ private val UniversalGasConstantR = JoulesPerKelvin(8.31446261815324d) @@ -91,6 +94,7 @@ final case class WecModel( * active power output */ override protected def calculateActivePower( + modelState: ConstantState.type, wecData: WecRelevantData ): Power = { val activePower = determinePower(wecData) @@ -188,6 +192,22 @@ final case class WecModel( ) } } + + override def determineFlexOptions( + data: WecRelevantData, + lastState: ConstantState.type + ): ProvideFlexOptions = { + val power = calculateActivePower(ConstantState, data) + + ProvideMinMaxFlexOptions(uuid, power, power, Megawatts(0d)) + } + + override def handleControlledPowerChange( + data: WecRelevantData, + lastState: ConstantState.type, + setPower: Power + ): (ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) } /** Create valid [[WecModel]] by calling the apply function. diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 7ad8f0f339..52b0c3eb25 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -8,6 +8,7 @@ package edu.ie3.simona.model.participant.load import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.LoadReference.{ @@ -76,6 +77,7 @@ final case class FixedLoadModel( * Active power */ override protected def calculateActivePower( + modelState: ConstantState.type, data: FixedLoadRelevantData.type = FixedLoadRelevantData ): Power = activePower * scalingFactor } diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala index 3db9c720f5..72fd9f79d6 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala @@ -10,11 +10,15 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.{ ApparentPowerParticipant, + FlexChangeIndicator, SystemParticipant } +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import squants.energy.Megawatts @@ -35,7 +39,7 @@ abstract class LoadModel[D <: LoadRelevantData]( qControl: QControl, sRated: Power, cosPhiRated: Double -) extends SystemParticipant[D, ApparentPower]( +) extends SystemParticipant[D, ApparentPower, ConstantState.type]( uuid, id, operationInterval, @@ -44,7 +48,25 @@ abstract class LoadModel[D <: LoadRelevantData]( sRated, cosPhiRated ) - with ApparentPowerParticipant[D] + with ApparentPowerParticipant[D, ConstantState.type] { + + override def determineFlexOptions( + data: D, + lastState: ConstantState.type + ): ProvideFlexOptions = { + val power = calculateActivePower(lastState, data) + + // no flexibility + ProvideMinMaxFlexOptions(uuid, power, power, power) + } + + override def handleControlledPowerChange( + data: D, + lastState: ConstantState.type, + setPower: Power + ): (ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) +} case object LoadModel extends LazyLogging { diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala index b0c2877cf1..4fbfd67821 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala @@ -20,7 +20,7 @@ sealed trait LoadReference { def getKey: String = key } -case object LoadReference { +object LoadReference { /** Scale the load model behaviour to reach the given active power in max * diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala index 8c3769a9cf..e2f66635cd 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala @@ -6,10 +6,6 @@ package edu.ie3.simona.model.participant.load.profile -import java.io.{InputStreamReader, Reader} -import java.time.{Duration, ZonedDateTime} -import java.util - import breeze.numerics.round import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.profile.{ @@ -24,6 +20,9 @@ import edu.ie3.simona.model.participant.load.{DayType, profile} import org.apache.commons.csv.CSVFormat import squants.energy.{KilowattHours, Watts} +import java.io.{InputStreamReader, Reader} +import java.time.{Duration, ZonedDateTime} +import java.util import scala.jdk.CollectionConverters._ import scala.math.pow diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index 77782e4907..85a7e2218b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -6,9 +6,10 @@ package edu.ie3.simona.model.participant.load.profile -import edu.ie3.datamodel.models.profile.StandardLoadProfile import edu.ie3.datamodel.models.input.system.LoadInput +import edu.ie3.datamodel.models.profile.StandardLoadProfile import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData @@ -84,6 +85,7 @@ final case class ProfileLoadModel( * Active power */ override protected def calculateActivePower( + modelState: ConstantState.type, data: ProfileRelevantData ): Power = { /* The power comes in W and is delivered all 15 minutes */ @@ -103,7 +105,7 @@ final case class ProfileLoadModel( } } -case object ProfileLoadModel { +object ProfileLoadModel { final case class ProfileRelevantData(date: ZonedDateTime) extends LoadRelevantData diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 7d8db0c833..fc059bf845 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -10,6 +10,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.distribution.GeneralizedExtremeValueD import de.lmu.ifi.dbs.elki.utilities.random.RandomFactory import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.simona.model.participant.CalcRelevantData.LoadRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference._ import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData @@ -89,6 +90,7 @@ final case class RandomLoadModel( */ @tailrec override protected def calculateActivePower( + modelState: ConstantState.type, data: RandomRelevantData ): Power = { val gev = getGevDistribution(data.date) @@ -96,7 +98,7 @@ final case class RandomLoadModel( /* Get a next random power (in kW) */ val randomPower = gev.nextRandom() if (randomPower < 0) - calculateActivePower(data) + calculateActivePower(modelState, data) else { val profilePower = Kilowatts(randomPower) val activePower = reference match { @@ -148,7 +150,7 @@ final case class RandomLoadModel( } } -case object RandomLoadModel { +object RandomLoadModel { final case class RandomRelevantData(date: ZonedDateTime) extends LoadRelevantData diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala new file mode 100644 index 0000000000..3a88991088 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala @@ -0,0 +1,141 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.ontology.messages.flex + +import edu.ie3.datamodel.models.input.AssetInput +import edu.ie3.simona.agent.em.EmAgent.EmMessage +import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower +import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import org.apache.pekko.actor.typed.ActorRef +import squants.Power + +import java.util.UUID + +/** Messages used to facilitate flexibility-based communication between + * [[edu.ie3.simona.agent.em.EmAgent]] and + * [[edu.ie3.simona.agent.participant.ParticipantAgent]]s. + */ +object FlexibilityMessage { + + /** Trait that is extended by all messages that are supposed to be received by + * a flexibility provider, which could be any + * [[edu.ie3.simona.agent.participant.ParticipantAgent]] or + * [[edu.ie3.simona.agent.em.EmAgent]], if it is EM-controlled. + */ + sealed trait FlexRequest { + val tick: Long + } + + /** Trait that is extended by all messages that are supposed to be received by + * [[edu.ie3.simona.agent.em.EmAgent]]s. + */ + sealed trait FlexResponse extends EmMessage { + val modelUuid: UUID + } + + /** Message that registers a flex provider with an + * [[edu.ie3.simona.agent.em.EmAgent]]. + * + * @param modelUuid + * The UUID of the flex provider asset model + * @param participant + * The actor reference to the flex provider + * @param inputModel + * The asset input model of the flex provider + */ + final case class RegisterParticipant( + override val modelUuid: UUID, + participant: ActorRef[FlexRequest], + inputModel: AssetInput + ) extends FlexResponse + + /** Message that schedules a flex request for a flex provider at given tick. + * + * @param modelUuid + * The UUID of the flex provider asset model + * @param tick + * The tick to schedule the flex provider for + * @param scheduleKey + * Optionally a schedule key that unlocks the scheduler once the scheduling + * chain is completed + */ + final case class ScheduleFlexRequest( + override val modelUuid: UUID, + tick: Long, + scheduleKey: Option[ScheduleKey] = None + ) extends FlexResponse + + /** Message that requests flex options from a flex provider for given tick + * + * @param tick + * The tick to request flex options for + */ + final case class RequestFlexOptions(override val tick: Long) + extends FlexRequest + + /** Message that provides flex options to an + * [[edu.ie3.simona.agent.em.EmAgent]] after they have been requested via + * [[RequestFlexOptions]] + */ + trait ProvideFlexOptions extends FlexResponse + + /** Message that issues flexibility control to a flex provider, i.e. a + * feasible set point is delivered that the flex provider should adhere to + */ + trait IssueFlexControl extends FlexRequest + + /** Message sent by [[edu.ie3.simona.agent.em.EmAgent]] that specifies a power + * target that needs to be produced/consumed by the system participant. + * + * @param tick + * The current tick + * @param setPower + * The power that the system participant should produce (negative) or + * consume (positive) + */ + final case class IssuePowerControl( + override val tick: Long, + setPower: Power + ) extends IssueFlexControl + + /** Message sent by [[edu.ie3.simona.agent.em.EmAgent]] indicating that no + * power target is set and the reference power communicated by + * [[ProvideFlexOptions]] shall be produced/consumed. + * + * @param tick + * The current tick + */ + final case class IssueNoControl(override val tick: Long) + extends IssueFlexControl + + /** Message sent by flex providers indicating that the [[IssueFlexControl]] + * message has been handled and the flex communication for the current tick + * is completed. + * + * @param modelUuid + * The UUID of the flex provider asset model + * @param result + * The apparent power that is produced/consumed by the flex provider, which + * can deviate from the set point communicated by a [[IssueFlexControl]] + * message if it is not feasible. + * @param requestAtNextActivation + * Whether or not to request flex options at the very next activation of + * the receiving EM agent. This is the case if flex options change the very + * next second after the current tick. + * @param requestAtTick + * Optionally the tick at which flex options are foreseen to have changed, + * i.e. the tick at which the flex provider would like to be activated at the + * latest. + */ + final case class FlexCtrlCompletion( + override val modelUuid: UUID, + result: ApparentPower, + requestAtNextActivation: Boolean = false, + requestAtTick: Option[Long] = None + ) extends FlexResponse + +} diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala new file mode 100644 index 0000000000..d498fc18c0 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala @@ -0,0 +1,108 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.ontology.messages.flex + +import edu.ie3.simona.exceptions.CriticalFailureException +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import squants.Power + +import java.util.UUID + +/** Messages that communicate interval-based flexibility with minimum, reference + * and maximum power + */ +object MinMaxFlexibilityMessage { + + /** Message that provides flexibility options using reference, minimum and + * maximum power. It is possible that the power values are either all + * negative or all positive, meaning that feed-in or load is mandatory. + * + * @param modelUuid + * The UUID of the flex provider asset model + * @param ref + * The reference active power that the flex provider would produce/consume + * regularly at the current tick, i.e. if it was not flex-controlled + * @param min + * The minimum active power that the flex provider allows at the current + * tick + * @param max + * The maximum active power that the flex provider allows at the current + * tick + */ + final case class ProvideMinMaxFlexOptions private ( + override val modelUuid: UUID, + ref: Power, + min: Power, + max: Power + ) extends ProvideFlexOptions { + + /** Checks whether given power fits within the min-max interval and thus + * would be a feasible solution + * @param power + * The active power to check against the flex options + * @return + * Whether the given power is within the min-max interval or not + */ + def fits(power: Power): Boolean = + min <= power && power <= max + } + + object ProvideMinMaxFlexOptions { + + /** Creates a [[ProvideMinMaxFlexOptions]] message with sanity checks + * regarding the power values + * + * @param modelUuid + * The UUID of the flex provider asset model + * @param ref + * The reference active power that the flex provider would + * produce/consume regularly at the current tick, i.e. if it was not + * flex-controlled + * @param min + * The minimum active power that the flex provider allows at the current + * tick + * @param max + * The maximum active power that the flex provider allows at the current + * tick + * @return + * The [[ProvideMinMaxFlexOptions]] message + */ + def apply( + modelUuid: UUID, + ref: Power, + min: Power, + max: Power + ): ProvideMinMaxFlexOptions = { + if (min > ref) + throw new CriticalFailureException( + s"Minimum power $min is greater than reference power $ref" + ) + + if (ref > max) + throw new CriticalFailureException( + s"Reference power $ref is greater than maximum power $max" + ) + + new ProvideMinMaxFlexOptions(modelUuid, ref, min, max) + } + + /** Creates a [[ProvideMinMaxFlexOptions]] message that does not allow any + * flexibility, meaning that min = ref = max power. + * @param modelUuid + * The UUID of the flex provider asset model + * @param power + * The active power that the flex provider requires + * @return + * The corresponding [[ProvideMinMaxFlexOptions]] message + */ + def noFlexOption( + modelUuid: UUID, + power: Power + ): ProvideMinMaxFlexOptions = + ProvideMinMaxFlexOptions(modelUuid, power, power, power) + } +} diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala index 760a47296c..517e517fcd 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala @@ -13,6 +13,7 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ServiceRegistrationMessage } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import org.apache.pekko.actor.ActorRef import java.util.UUID @@ -45,6 +46,7 @@ object EvMessage { */ final case class ProvideEvDataMessage( override val tick: Long, + override val serviceRef: ActorRef, override val data: EvData, override val nextDataTick: Option[Long] = None, override val unlockKey: Option[ScheduleKey] = None @@ -52,12 +54,11 @@ object EvMessage { with ProvisionMessage[EvData] /** Requests number of free lots from evcs + * * @param tick * The latest tick that the data is requested for */ - final case class EvFreeLotsRequest( - tick: Long - ) + final case class EvFreeLotsRequest(tick: Long) /** Requests EV models of departing EVs with given UUIDs * @@ -73,7 +74,6 @@ object EvMessage { * @param arrivals * EVs arriving at the charging station */ - final case class ArrivingEvsData( arrivals: Seq[EvModel] ) extends EvData {} diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala index fd1d5b1cbd..6bd8f79b72 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala @@ -9,10 +9,11 @@ package edu.ie3.simona.ontology.messages.services import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.ontology.messages.services.ServiceMessage.ProvisionMessage import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import org.apache.pekko.actor.ActorRef sealed trait PrimaryDataMessage -case object PrimaryDataMessage { +object PrimaryDataMessage { /** Provides primary data in the form of [[ApparentPower]] * @@ -26,6 +27,7 @@ case object PrimaryDataMessage { @deprecated final case class ApparentPowerProvisionMessage( override val tick: Long, + override val serviceRef: ActorRef, override val data: ApparentPower, override val nextDataTick: Option[Long], override val unlockKey: Option[ScheduleKey] = None diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala index 6d31cd8a8a..3f061c201c 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala @@ -41,18 +41,24 @@ case object ServiceMessage { final case class WorkerRegistrationMessage(requestingActor: ActorRef) extends ServiceRegistrationMessage - sealed trait RegistrationResponseMessage extends ServiceMessage + sealed trait RegistrationResponseMessage extends ServiceMessage { + val serviceRef: ActorRef + } - case object RegistrationResponseMessage { + object RegistrationResponseMessage { /** Message, that is used to confirm a successful registration */ - final case class RegistrationSuccessfulMessage(nextDataTick: Option[Long]) - extends RegistrationResponseMessage + final case class RegistrationSuccessfulMessage( + override val serviceRef: ActorRef, + nextDataTick: Option[Long] + ) extends RegistrationResponseMessage /** Message, that is used to announce a failed registration */ - case object RegistrationFailedMessage extends RegistrationResponseMessage + final case class RegistrationFailedMessage( + override val serviceRef: ActorRef + ) extends RegistrationResponseMessage final case class ScheduleServiceActivation( tick: Long, @@ -67,6 +73,7 @@ case object ServiceMessage { */ trait ProvisionMessage[D <: Data] extends ServiceMessage { val tick: Long + val serviceRef: ActorRef val data: D val nextDataTick: Option[Long] val unlockKey: Option[ScheduleKey] diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala index 9d9d4ee5f6..1af4f8ae43 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala @@ -13,6 +13,7 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.util.scala.quantities.Irradiance +import org.apache.pekko.actor.ActorRef import squants.{Temperature, Velocity} sealed trait WeatherMessage @@ -50,6 +51,7 @@ object WeatherMessage { */ final case class ProvideWeatherMessage( override val tick: Long, + override val serviceRef: ActorRef, override val data: WeatherData, override val nextDataTick: Option[Long], override val unlockKey: Option[ScheduleKey] = None diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index 4bd2975747..2b886517a8 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -140,7 +140,7 @@ class ExtEvDataService(override val scheduler: ActorRef) serviceStateData.uuidToActorRef.get(evcs) match { case None => // Actor is not registered yet - agentToBeRegistered ! RegistrationSuccessfulMessage(None) + agentToBeRegistered ! RegistrationSuccessfulMessage(self, None) serviceStateData.copy( uuidToActorRef = diff --git a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala index 95103e347e..23e28146b1 100644 --- a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala +++ b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala @@ -260,7 +260,7 @@ case class PrimaryServiceProxy( s"There is no time series apparent for the model with uuid '{}'.", modelUuid ) - sender() ! RegistrationFailedMessage + sender() ! RegistrationFailedMessage(self) } case x => log.error( @@ -313,7 +313,7 @@ case class PrimaryServiceProxy( s"Will inform the requesting actor, that registration is not possible.", exception ) - requestingActor ! RegistrationFailedMessage + requestingActor ! RegistrationFailedMessage(self) } case None => @@ -321,7 +321,7 @@ case class PrimaryServiceProxy( s"There is no source information for time series '$timeSeriesUuid' (requested for model " + s"'$modelUuid'), although the mapping contains information about it." ) - requestingActor ! RegistrationFailedMessage + requestingActor ! RegistrationFailedMessage(self) } } diff --git a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala index f7d7d58fb5..c9da720690 100644 --- a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala +++ b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala @@ -171,6 +171,7 @@ final case class PrimaryServiceWorker[V <: Value]( ): Try[PrimaryServiceInitializedStateData[V]] = registrationMessage match { case ServiceMessage.WorkerRegistrationMessage(requestingActor) => requestingActor ! RegistrationSuccessfulMessage( + self, serviceStateData.maybeNextActivationTick ) val subscribers = serviceStateData.subscribers :+ requestingActor @@ -307,7 +308,7 @@ final case class PrimaryServiceWorker[V <: Value]( ) val provisionMessage = - ProvidePrimaryDataMessage(tick, primaryData, maybeNextTick) + ProvidePrimaryDataMessage(tick, self, primaryData, maybeNextTick) serviceBaseStateData.subscribers.foreach(_ ! provisionMessage) (updatedStateData, maybeNextTick) } @@ -426,6 +427,7 @@ object PrimaryServiceWorker { */ final case class ProvidePrimaryDataMessage( override val tick: Long, + override val serviceRef: ActorRef, override val data: PrimaryData, override val nextDataTick: Option[Long], override val unlockKey: Option[ScheduleKey] = None diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala index 12b2e6e2cb..52aa70bd8f 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala @@ -226,6 +226,7 @@ final case class WeatherService( ) match { case Success(weightedCoordinates) => agentToBeRegistered ! RegistrationSuccessfulMessage( + self, serviceStateData.maybeNextActivationTick ) @@ -244,13 +245,14 @@ final case class WeatherService( exception, s"Unable to obtain necessary information to register for coordinate $agentCoord." ) - sender() ! RegistrationFailedMessage + sender() ! RegistrationFailedMessage(self) serviceStateData } case Some(actorRefs) if !actorRefs.contains(agentToBeRegistered) => // coordinate is already known (= we have data for it), but this actor is not registered yet agentToBeRegistered ! RegistrationSuccessfulMessage( + self, serviceStateData.maybeNextActivationTick ) @@ -270,7 +272,7 @@ final case class WeatherService( case _ => // actor is not registered and we don't have data for it // inform the agentToBeRegistered that the registration failed as we don't have data for it - agentToBeRegistered ! RegistrationFailedMessage + agentToBeRegistered ! RegistrationFailedMessage(self) serviceStateData } } @@ -310,7 +312,12 @@ final case class WeatherService( .get(coordinate) .foreach(recipients => recipients.foreach( - _ ! ProvideWeatherMessage(tick, weatherResult, maybeNextTick) + _ ! ProvideWeatherMessage( + tick, + self, + weatherResult, + maybeNextTick + ) ) ) } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala index 1e319ecbcc..b7a843ce9a 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala @@ -12,6 +12,7 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.datamodel.models.result.ResultEntity +import edu.ie3.datamodel.models.result.system.FlexOptionsResult import edu.ie3.datamodel.utils.ContainerUtils import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.RefSystemParser.ConfigRefSystems @@ -257,5 +258,6 @@ case object SetupHelper { ).simulationResultIdentifiersToConsider ++ OutputConfigUtil( outputConfig.thermal ).simulationResultIdentifiersToConsider) - .map(notifierId => EntityMapperUtil.getResultEntityClass(notifierId)) + .map(notifierId => EntityMapperUtil.getResultEntityClass(notifierId)) ++ + (if (outputConfig.flex) Seq(classOf[FlexOptionsResult]) else Seq.empty) } diff --git a/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala b/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala index 0e3a8e412b..ca70e2d7d0 100644 --- a/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala +++ b/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala @@ -147,7 +147,7 @@ object ConfigUtil { NotifierIdentifier.values -- configs.flatMap { case ( notifierId, - NotifierConfig(resultInfo, _) + NotifierConfig(resultInfo, _, _) ) if !resultInfo => Some(notifierId) case _ => None @@ -157,7 +157,7 @@ object ConfigUtil { configs.flatMap { case ( notifierId, - NotifierConfig(resultInfo, _) + NotifierConfig(resultInfo, _, _) ) if resultInfo => Some(notifierId) case _ => None @@ -178,19 +178,25 @@ object ConfigUtil { case ParticipantBaseOutputConfig( _, simulationResult, + flexResult, powerRequestReply ) => - NotifierConfig(simulationResult, powerRequestReply) + NotifierConfig(simulationResult, powerRequestReply, flexResult) } val configMap = subConfig.individualConfigs.map { case ParticipantBaseOutputConfig( notifier, simulationResult, + flexResult, powerRequestReply ) => try { val id = NotifierIdentifier(notifier) - id -> NotifierConfig(simulationResult, powerRequestReply) + id -> NotifierConfig( + simulationResult, + powerRequestReply, + flexResult + ) } catch { case e: NoSuchElementException => throw new InvalidConfigParameterException( @@ -207,13 +213,21 @@ object ConfigUtil { ): OutputConfigUtil = { val defaultConfig = subConfig.defaultConfig match { case SimpleOutputConfig(_, simulationResult) => - NotifierConfig(simulationResult, powerRequestReply = false) + NotifierConfig( + simulationResult, + powerRequestReply = false, + flexResult = false + ) } val configMap = subConfig.individualConfigs.map { case SimpleOutputConfig(notifier, simulationResult) => try { val id = NotifierIdentifier(notifier) - id -> NotifierConfig(simulationResult, powerRequestReply = false) + id -> NotifierConfig( + simulationResult, + powerRequestReply = false, + flexResult = false + ) } catch { case e: NoSuchElementException => throw new InvalidConfigParameterException( diff --git a/src/main/scala/edu/ie3/simona/util/TickUtil.scala b/src/main/scala/edu/ie3/simona/util/TickUtil.scala index c95fc3b987..b705eb63c2 100644 --- a/src/main/scala/edu/ie3/simona/util/TickUtil.scala +++ b/src/main/scala/edu/ie3/simona/util/TickUtil.scala @@ -19,8 +19,7 @@ import java.time.temporal.ChronoUnit object TickUtil { /** Provides conversions from ZonedDateTime into ticks (actually seconds) */ - implicit class RichZonedDateTime(private val zdt: ZonedDateTime) - extends AnyVal { + implicit class RichZonedDateTime(private val zdt: ZonedDateTime) { /** Calculates the difference between this date time and the provided date * time in ticks (= actual seconds) @@ -33,7 +32,7 @@ object TickUtil { /** Provides conversions from ticks (seconds) into instances of * [[ZonedDateTime]] */ - implicit class TickLong(private val tick: Long) extends AnyVal { + implicit class TickLong(private val tick: Long) { /** Calculates the current [[ZonedDateTime]] based on this tick */ def toDateTime(implicit startDateTime: ZonedDateTime): ZonedDateTime = diff --git a/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala b/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala index 02458bcd89..bc696b759c 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala @@ -7,7 +7,7 @@ package edu.ie3.util.scala.quantities import squants.energy._ -import squants.time.{Hours, Time, TimeDerivative, TimeIntegral} +import squants.time.{Hours, Time, TimeIntegral} import squants._ import scala.util.Try diff --git a/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy index 6d6779194c..612004ab7e 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy @@ -240,7 +240,7 @@ class BMModelTest extends Specification { bmModel._lastPower = new Some(Sq.create(lastPower, Kilowatts$.MODULE$)) when: "the power from the grid is calculated" - def powerCalc = bmModel.calculateActivePower(relevantData) + def powerCalc = bmModel.calculateActivePower(new BMModel.BmState(), relevantData) then: "compare in kilowatts" powerCalc - Sq.create(powerSol, Kilowatts$.MODULE$) < Sq.create(1e-12d, Kilowatts$.MODULE$) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/FixedFeedModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/FixedFeedModelTest.groovy index e501b09c70..3333fdae99 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/FixedFeedModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/FixedFeedModelTest.groovy @@ -77,6 +77,6 @@ class FixedFeedModelTest extends Specification { ) then: - actualModel.calculateActivePower(CalcRelevantData.FixedRelevantData$.MODULE$) =~ expectedPower + actualModel.calculateActivePower(ModelState.ConstantState$.MODULE$, CalcRelevantData.FixedRelevantData$.MODULE$) =~ expectedPower } } diff --git a/src/test/groovy/edu/ie3/simona/model/participant/PvModelIT.groovy b/src/test/groovy/edu/ie3/simona/model/participant/PvModelIT.groovy index 52a7fcca1d..0fd8cfee48 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/PvModelIT.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/PvModelIT.groovy @@ -94,7 +94,7 @@ class PvModelIT extends Specification implements PvModelITHelper { Dimensionless voltage = Sq.create(1.414213562d, Each$.MODULE$) "collect the results and calculate the difference between the provided results and the calculated ones" - double calc = model.calculatePower(0L, voltage, neededData).p().toMegawatts() + double calc = model.calculatePower(0L, voltage, ModelState.ConstantState$.MODULE$, neededData).p().toMegawatts() double sol = resultsMap.get(dateTime).get(modelId).toMegawatts() testRes.add(Math.abs(calc - sol)) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/WecModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/WecModelTest.groovy index 9bef96267e..1855245f02 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/WecModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/WecModelTest.groovy @@ -6,9 +6,6 @@ package edu.ie3.simona.model.participant -import squants.energy.Kilowatts$ -import squants.space.SquareMeters$ - import static edu.ie3.util.quantities.PowerSystemUnits.* import static edu.ie3.datamodel.models.StandardUnits.* import static edu.ie3.simona.model.participant.WecModel.WecRelevantData @@ -33,6 +30,8 @@ import squants.Each$ import squants.motion.MetersPerSecond$ import squants.motion.Pascals$ +import squants.energy.Kilowatts$ +import squants.space.SquareMeters$ import squants.thermal.Celsius$ @@ -121,25 +120,25 @@ class WecModelTest extends Specification { new Some (Sq.create(101325d, Pascals$.MODULE$))) when: - def result = wecModel.calculateActivePower(wecData) + def result = wecModel.calculateActivePower(ModelState.ConstantState$.MODULE$, wecData) then: Math.abs((result.toWatts() - power.doubleValue())) < TOLERANCE where: - velocity | power - 1.0d | 0 - 2.0d | -2948.80958 - 3.0d | -24573.41320 - 7.0d | -522922.23257 - 9.0d | -1140000 - 13.0d | -1140000 - 15.0d | -1140000 - 19.0d | -1140000 - 23.0d | -1140000 - 27.0d | -1140000 - 34.0d | -24573.39638 - 40.0d | 0 + velocity || power + 1.0d || 0 + 2.0d || -2948.80958 + 3.0d || -24573.41320 + 7.0d || -522922.23257 + 9.0d || -1140000 + 13.0d || -1140000 + 15.0d || -1140000 + 19.0d || -1140000 + 23.0d || -1140000 + 27.0d || -1140000 + 34.0d || -24573.39638 + 40.0d || 0 } @Unroll @@ -150,7 +149,7 @@ class WecModelTest extends Specification { Sq.create(temperature, Celsius$.MODULE$), new Some( Sq.create(101325d, Pascals$.MODULE$))) when: - def result = wecModel.calculateActivePower(wecData) + def result = wecModel.calculateActivePower(ModelState.ConstantState$.MODULE$, wecData) then: result.toWatts() =~ power diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/FixedLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/FixedLoadModelTest.groovy index 1d45f021b5..cd0f9034e9 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/FixedLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/FixedLoadModelTest.groovy @@ -19,6 +19,7 @@ import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.ModelState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.util.TimeUtil import spock.lang.Specification @@ -104,7 +105,7 @@ class FixedLoadModelTest extends Specification { then: for (cnt in 0..10000) { - abs((dut.calculateActivePower(FixedLoadModel.FixedLoadRelevantData$.MODULE$)).toWatts().doubleValue() + abs((dut.calculateActivePower(ModelState.ConstantState$.MODULE$, FixedLoadModel.FixedLoadRelevantData$.MODULE$)).toWatts().doubleValue() - (expectedPower).toMegawatts().doubleValue()) < wattTolerance } @@ -131,7 +132,7 @@ class FixedLoadModelTest extends Specification { reference ) - abs(dut.calculateActivePower(relevantData).toWatts() - ((expectedPower * scale).doubleValue())) < wattTolerance + abs((dut.calculateActivePower(ModelState.ConstantState$.MODULE$, relevantData)).toWatts() - (expectedPower * scale).doubleValue()) < wattTolerance } where: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy index b155a34eae..7b514257f5 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy @@ -19,6 +19,7 @@ import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.ModelState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.util.TimeUtil @@ -113,7 +114,7 @@ class ProfileLoadModelTest extends Specification { when: def max = relevantData.stream().mapToDouble({ data -> - dut.calculateActivePower(data).toMegawatts().doubleValue() + dut.calculateActivePower(ModelState.ConstantState$.MODULE$, data).toMegawatts().doubleValue() }).max().getAsDouble() then: @@ -147,7 +148,7 @@ class ProfileLoadModelTest extends Specification { when: def max = relevantDatas.stream().mapToDouble({ relevantData -> - dut.calculateActivePower(relevantData).toMegawatts().doubleValue() + dut.calculateActivePower(ModelState.ConstantState$.MODULE$, relevantData).toMegawatts().doubleValue() }).max().asDouble then: @@ -191,7 +192,7 @@ class ProfileLoadModelTest extends Specification { when: def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$)).toKilowattHours())) + (dut.calculateActivePower(ModelState.ConstantState$.MODULE$, relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() }).sum() then: @@ -230,7 +231,7 @@ class ProfileLoadModelTest extends Specification { when: def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$)).toKilowattHours())) + (dut.calculateActivePower(ModelState.ConstantState$.MODULE$, relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() }).sum() then: diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index 9ea389751c..2a46493569 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -19,6 +19,7 @@ import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.ModelState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.random.RandomLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadParameters @@ -34,7 +35,7 @@ import java.time.temporal.ChronoUnit import java.util.stream.Collectors class RandomLoadModelTest extends Specification { - def loadInput = new LoadInput( + def loadInput = new LoadInput( UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), "testLoad", OperatorInput.NO_OPERATOR_ASSIGNED, @@ -142,7 +143,7 @@ class RandomLoadModelTest extends Specification { when: def avgEnergy = (0..10).parallelStream().mapToDouble( { runCnt -> relevantDatas.parallelStream().mapToDouble( { relevantData -> - (dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() + (dut.calculateActivePower(ModelState.ConstantState$.MODULE$, relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() }).sum() }).average().orElse(0d) @@ -171,7 +172,7 @@ class RandomLoadModelTest extends Specification { when: def powers = (0..10).parallelStream().flatMap({ runCnt -> relevantDatas.stream().parallel().map({ data -> - dut.calculateActivePower(data).toWatts().doubleValue() + dut.calculateActivePower(ModelState.ConstantState$.MODULE$, data).toWatts().doubleValue() }) }).sorted().toArray() as Double[] def quantilePower = get95Quantile(powers) diff --git a/src/test/groovy/edu/ie3/simona/test/common/model/MockParticipant.groovy b/src/test/groovy/edu/ie3/simona/test/common/model/MockParticipant.groovy index 804626e253..57a8d51ab6 100644 --- a/src/test/groovy/edu/ie3/simona/test/common/model/MockParticipant.groovy +++ b/src/test/groovy/edu/ie3/simona/test/common/model/MockParticipant.groovy @@ -8,16 +8,17 @@ package edu.ie3.simona.test.common.model import edu.ie3.simona.agent.participant.data.Data import edu.ie3.simona.model.participant.CalcRelevantData - +import edu.ie3.simona.model.participant.ModelState import edu.ie3.simona.model.participant.SystemParticipant import edu.ie3.simona.model.participant.control.QControl - +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.Sq +import scala.Tuple2 import squants.Dimensionless import squants.energy.* -class MockParticipant extends SystemParticipant { +class MockParticipant extends SystemParticipant { MockParticipant( UUID uuid, @@ -40,12 +41,22 @@ class MockParticipant extends SystemParticipant "One", 2L -> "Two", 3L -> "Three", 4L -> "Four") + SortedMap(1L -> "One", 2L -> "Two", 3L -> "Three", 4L -> "Four") ) "be properly instantiated" in { diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index f104f20bbf..76c91a359f 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -143,7 +143,10 @@ class DBFSAlgorithmParticipantSpec PrimaryServiceRegistrationMessage(load1.getUuid) ) - primaryService.send(loadAgent.toClassic, RegistrationFailedMessage) + primaryService.send( + loadAgent.toClassic, + RegistrationFailedMessage(primaryService.ref) + ) scheduler.expectMsg(Completion(loadAgent, Some(0))) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index 0f19e2055d..6cf410ecaa 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -73,7 +73,7 @@ trait DBFSMockGridAgents extends UnitSpec { _.nodeUuid == expectedVoltage.nodeUuid ) match { case Some(ExchangeVoltage(_, actualE, actualF)) => - actualE ~= Volts(3d) + actualE ~= expectedVoltage.e actualF ~= expectedVoltage.f case None => fail( diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index 1b3046f6f4..3c535d76ea 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -49,6 +49,7 @@ import squants.energy.{Kilowatts, Megawatts, Watts} import java.time.ZonedDateTime import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class FixedFeedInAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -86,7 +87,8 @@ class FixedFeedInAgentModelCalculationSpec ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) private val fixedFeedConfigUtil = ConfigUtil.ParticipantConfigUtil( @@ -163,7 +165,8 @@ class FixedFeedInAgentModelCalculationSpec simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -173,12 +176,16 @@ class FixedFeedInAgentModelCalculationSpec resolution shouldBe this.resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } /* Refuse registration */ - primaryServiceProxy.send(fixedFeedAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + fixedFeedAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a completion notification */ scheduler.expectMsg(Completion(fixedFeedAgent.toTyped, Some(0))) @@ -198,6 +205,8 @@ class FixedFeedInAgentModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ) => /* Base state data */ @@ -209,12 +218,9 @@ class FixedFeedInAgentModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - Map(0L -> Each(1.0)) - ) - resultValueStore shouldBe ValueStore.forResult( - resolution, - 2 + SortedMap(0L -> Each(1.0)) ) + resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( resolution ) @@ -238,7 +244,10 @@ class FixedFeedInAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(fixedFeedAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + fixedFeedAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -259,12 +268,12 @@ class FixedFeedInAgentModelCalculationSpec ) inside(fixedFeedAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.requestValueStore shouldBe ValueStore[ + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( resolution, - Map( + SortedMap( 0L -> ApparentPower( Megawatts(0d), Megavars(0d) @@ -291,7 +300,10 @@ class FixedFeedInAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(fixedFeedAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + fixedFeedAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I am not interested in the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -308,12 +320,8 @@ class FixedFeedInAgentModelCalculationSpec awaitAssert(fixedFeedAgent.stateName shouldBe Idle) inside(fixedFeedAgent.stateData) { - case participantModelBaseStateData: ParticipantModelBaseStateData[ - _, - _, - _ - ] => - participantModelBaseStateData.resultValueStore.last(0L) match { + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.resultValueStore.last(0L) match { case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => @@ -344,7 +352,10 @@ class FixedFeedInAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(fixedFeedAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + fixedFeedAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(fixedFeedAgent.toTyped, Some(0))) @@ -384,7 +395,10 @@ class FixedFeedInAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(fixedFeedAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + fixedFeedAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(fixedFeedAgent.toTyped, Some(0))) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index d7252f1dab..e06a53a179 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -48,6 +48,7 @@ import squants.Each import squants.energy.{Kilowatts, Megawatts, Watts} import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class LoadAgentFixedModelCalculationSpec extends ParticipantAgentSpec( @@ -78,7 +79,8 @@ class LoadAgentFixedModelCalculationSpec ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -157,7 +159,8 @@ class LoadAgentFixedModelCalculationSpec simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -167,12 +170,16 @@ class LoadAgentFixedModelCalculationSpec resolution shouldBe this.resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } /* Refuse registration */ - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a completion notification */ scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -192,6 +199,8 @@ class LoadAgentFixedModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ) => /* Base state data */ @@ -203,12 +212,9 @@ class LoadAgentFixedModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - Map(0L -> Each(1.0)) - ) - resultValueStore shouldBe ValueStore.forResult( - resolution, - 2 + SortedMap(0L -> Each(1.0)) ) + resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( resolution ) @@ -232,7 +238,10 @@ class LoadAgentFixedModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -253,12 +262,12 @@ class LoadAgentFixedModelCalculationSpec ) inside(loadAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.requestValueStore shouldBe ValueStore[ + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( resolution, - Map( + SortedMap( 0L -> ApparentPower( Megawatts(0d), Megavars(0d) @@ -285,7 +294,10 @@ class LoadAgentFixedModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I am not interested in the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -302,12 +314,8 @@ class LoadAgentFixedModelCalculationSpec awaitAssert(loadAgent.stateName shouldBe Idle) inside(loadAgent.stateData) { - case participantModelBaseStateData: ParticipantModelBaseStateData[ - _, - _, - _ - ] => - participantModelBaseStateData.resultValueStore.last(0L) match { + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.resultValueStore.last(0L) match { case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => @@ -338,7 +346,10 @@ class LoadAgentFixedModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -378,7 +389,10 @@ class LoadAgentFixedModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index ee17a58989..a98f5a05fc 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -48,6 +48,7 @@ import squants.Each import squants.energy.{Kilowatts, Megawatts, Watts} import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class LoadAgentProfileModelCalculationSpec extends ParticipantAgentSpec( @@ -78,7 +79,8 @@ class LoadAgentProfileModelCalculationSpec ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -156,7 +158,8 @@ class LoadAgentProfileModelCalculationSpec simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -166,12 +169,16 @@ class LoadAgentProfileModelCalculationSpec resolution shouldBe this.resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } /* Refuse registration */ - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a completion notification */ scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -191,6 +198,8 @@ class LoadAgentProfileModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ) => /* Base state data */ @@ -203,12 +212,9 @@ class LoadAgentProfileModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - Map(0L -> Each(1.0)) - ) - resultValueStore shouldBe ValueStore.forResult( - resolution, - 2 + SortedMap(0L -> Each(1.0)) ) + resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( resolution ) @@ -232,7 +238,10 @@ class LoadAgentProfileModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -253,12 +262,12 @@ class LoadAgentProfileModelCalculationSpec ) inside(loadAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.requestValueStore shouldBe ValueStore[ + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( resolution, - Map( + SortedMap( 0L -> ApparentPower( Megawatts(0d), Megavars(0d) @@ -285,7 +294,10 @@ class LoadAgentProfileModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I am not interested in the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -302,12 +314,8 @@ class LoadAgentProfileModelCalculationSpec awaitAssert(loadAgent.stateName shouldBe Idle) inside(loadAgent.stateData) { - case participantModelBaseStateData: ParticipantModelBaseStateData[ - _, - _, - _ - ] => - participantModelBaseStateData.resultValueStore.last(0L) match { + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.resultValueStore.last(0L) match { case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => @@ -338,7 +346,10 @@ class LoadAgentProfileModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(loadAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + loadAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 1007da8e77..963112261a 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -108,7 +108,8 @@ class ParticipantAgent2ListenerSpec /* Let the agent send announcements, when there is anew request reply */ val outputConfig = NotifierConfig( simulationResultInfo = true, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) val mockAgent = TestFSMRef( @@ -124,7 +125,10 @@ class ParticipantAgent2ListenerSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(mockAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + mockAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -156,7 +160,8 @@ class ParticipantAgent2ListenerSpec /* Let the agent send announcements, when there is anew request reply */ val outputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) val mockAgent = TestFSMRef( @@ -172,7 +177,10 @@ class ParticipantAgent2ListenerSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(mockAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + mockAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -188,7 +196,8 @@ class ParticipantAgent2ListenerSpec /* Let the agent send announcements, when there is anew request reply */ val outputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = true + powerRequestReply = true, + flexResult = false ) val mockAgent = TestFSMRef( @@ -204,7 +213,10 @@ class ParticipantAgent2ListenerSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(mockAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + mockAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -245,7 +257,8 @@ class ParticipantAgent2ListenerSpec /* Let the agent send announcements, when there is anew request reply */ val outputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) val mockAgent = TestFSMRef( @@ -261,7 +274,10 @@ class ParticipantAgent2ListenerSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(mockAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + mockAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) scheduler.expectMsg(Completion(mockAgent.toTyped)) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index bff18f7a87..5edf14ad42 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -35,6 +35,7 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.BaseRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference} import edu.ie3.simona.model.participant.{CalcRelevantData, SystemParticipant} import edu.ie3.simona.ontology.messages.Activation @@ -61,7 +62,7 @@ import tech.units.indriya.quantity.Quantities import java.util.UUID import java.util.concurrent.TimeUnit -import scala.collection.SortedSet +import scala.collection.{SortedMap, SortedSet} import scala.util.{Failure, Success} /** Tests a mock participant agent with external data (primary data). Since @@ -94,9 +95,11 @@ class ParticipantAgentExternalSourceSpec when(mockInputModel.getId).thenReturn(testID) when(mockInputModel.getNode).thenReturn(mockNode) private val mockModel = - mock[ - SystemParticipant[CalcRelevantData.FixedRelevantData.type, ApparentPower] - ] + mock[SystemParticipant[ + CalcRelevantData.FixedRelevantData.type, + ApparentPower, + ConstantState.type + ]] when(mockModel.getUuid).thenReturn(testUUID) private val activeToReactivePowerFunction: squants.Power => ReactivePower = (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) @@ -112,7 +115,8 @@ class ParticipantAgentExternalSourceSpec ) private val defaultOutputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds @@ -183,7 +187,8 @@ class ParticipantAgentExternalSourceSpec simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(mockInputModel) modelConfig shouldBe modelConfig @@ -193,6 +198,7 @@ class ParticipantAgentExternalSourceSpec resolution shouldBe this.resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } @@ -200,7 +206,7 @@ class ParticipantAgentExternalSourceSpec /* Reply, that registration was successful */ primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(4711L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(4711L)) ) scheduler.expectMsg(Completion(mockAgent.toTyped, Some(4711L))) @@ -210,7 +216,8 @@ class ParticipantAgentExternalSourceSpec mockAgent.stateData match { case baseStateData: FromOutsideBaseStateData[SystemParticipant[ FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map( @@ -237,7 +244,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) ) /* I'm not interested in the content of the CompletionMessage */ @@ -274,7 +281,7 @@ class ParticipantAgentExternalSourceSpec ) => requestValueStore shouldBe ValueStore[ApparentPower]( resolution, - Map( + SortedMap( 0L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -302,7 +309,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) ) /* I'm not interested in the content of the CompletionMessage */ @@ -314,6 +321,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 900L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), Kilovars(900.0) @@ -328,7 +336,8 @@ class ParticipantAgentExternalSourceSpec case DataCollectionStateData( baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower], expectedSenders, isYetTriggered @@ -367,7 +376,8 @@ class ParticipantAgentExternalSourceSpec mockAgent.stateData match { case baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower] => /* The new data is apparent in the result value store */ baseStateData.resultValueStore match { @@ -400,7 +410,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) ) /* I'm not interested in the content of the CompletionMessage */ @@ -416,7 +426,8 @@ class ParticipantAgentExternalSourceSpec case DataCollectionStateData( baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower], expectedSenders, isYetTriggered @@ -442,6 +453,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 900L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), Kilovars(900.0) @@ -458,7 +470,8 @@ class ParticipantAgentExternalSourceSpec mockAgent.stateData match { case baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower] => /* The new data is apparent in the result value store */ baseStateData.resultValueStore match { @@ -492,7 +505,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) ) /* I'm not interested in the content of the CompletionMessage */ @@ -513,6 +526,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 900L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), Kilovars(900.0) @@ -540,10 +554,12 @@ class ParticipantAgentExternalSourceSpec "correctly determine the reactive power function when trivial reactive power is requested" in { val baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower] = FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower]( mockModel, defaultSimulationStart, @@ -569,10 +585,12 @@ class ParticipantAgentExternalSourceSpec "correctly determine the reactive power function from model when requested" in { val baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower] = FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ], ApparentPower]( mockModel, defaultSimulationStart, @@ -603,7 +621,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) ) /* I'm not interested in the content of the CompletionMessage */ @@ -616,6 +634,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 900L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(100.0), Kilovars(33.0) @@ -631,6 +650,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 1800L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(150.0), Kilovars(49.0) @@ -646,6 +666,7 @@ class ParticipantAgentExternalSourceSpec mockAgent, ProvidePrimaryDataMessage( 2700L, + primaryServiceProxy.ref, ApparentPower( Kilowatts(200.0), Kilovars(66.0) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala index 3d87971bca..8b22195fc5 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala @@ -28,6 +28,7 @@ import edu.ie3.simona.exceptions.agent.{ } import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData import edu.ie3.simona.model.participant.SystemParticipant +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl.CosPhiFixed import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.{FixedLoadModel, LoadReference} @@ -35,17 +36,17 @@ import edu.ie3.simona.test.common.AgentSpec import edu.ie3.simona.test.common.model.participant.LoadTestData import edu.ie3.util.TimeUtil import edu.ie3.util.scala.OperationInterval -import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} +import edu.ie3.util.scala.quantities.{Megavars, ReactivePower, Vars} import org.mockito.Mockito.when import org.scalatest.PrivateMethodTester import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor3, TableFor5} import org.scalatestplus.mockito.MockitoSugar -import squants.Each -import squants.energy.{Kilowatts, Megawatts} +import squants.{Each, Power} +import squants.energy.{Kilowatts, Megawatts, Watts} import java.util.UUID import java.util.concurrent.TimeUnit -import scala.collection.SortedSet +import scala.collection.{SortedMap, SortedSet} class ParticipantAgentFundamentalsSpec extends AgentSpec( @@ -64,13 +65,14 @@ class ParticipantAgentFundamentalsSpec with MockitoSugar { implicit val receiveTimeOut: Timeout = Timeout(10, TimeUnit.SECONDS) implicit val noReceiveTimeOut: Timeout = Timeout(1, TimeUnit.SECONDS) - implicit val pTolerance: squants.Power = Megawatts(0.001) - implicit val qTolerance: ReactivePower = Megavars(0.001) + private implicit val pTolerance: Power = Watts(0.1) + private implicit val qTolerance: ReactivePower = Vars(0.1) private val outputConfig: NotifierConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) /* Get one instance of the mock for participant agent */ @@ -89,7 +91,7 @@ class ParticipantAgentFundamentalsSpec ) val mockAgent: ParticipantAgentMock = mockAgentTestRef.underlyingActor - private val powerValues: Map[Long, ApparentPower] = + private val powerValues = Map( 0L -> ApparentPower( Megawatts(1.0), @@ -406,7 +408,7 @@ class ParticipantAgentFundamentalsSpec val requestTick = 1800L val resultValueStore = ValueStore( 900, - Map( + SortedMap( 800L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -435,7 +437,7 @@ class ParticipantAgentFundamentalsSpec ) val requestValueStore = ValueStore( 900, - Map( + SortedMap( 900L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -485,7 +487,7 @@ class ParticipantAgentFundamentalsSpec val requestTick = 1800L val resultValueStore = ValueStore( 900, - Map( + SortedMap( 800L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -494,7 +496,7 @@ class ParticipantAgentFundamentalsSpec ) val requestValueStore = ValueStore( 900, - Map( + SortedMap( 900L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -526,6 +528,7 @@ class ParticipantAgentFundamentalsSpec val baseStateData = ParticipantModelBaseStateData[ ApparentPower, FixedLoadRelevantData.type, + ConstantState.type, FixedLoadModel ]( simulationStartDate, @@ -548,7 +551,9 @@ class ParticipantAgentFundamentalsSpec ValueStore.forVoltage(901L, Each(1.0)), ValueStore(901L), ValueStore(901L), - ValueStore(901L) + ValueStore(901L), + ValueStore(901L), + None ) ParticipantAgent.getAndCheckNodalVoltage( @@ -561,6 +566,7 @@ class ParticipantAgentFundamentalsSpec val baseStateData = ParticipantModelBaseStateData[ ApparentPower, FixedLoadRelevantData.type, + ConstantState.type, FixedLoadModel ]( simulationStartDate, @@ -583,7 +589,9 @@ class ParticipantAgentFundamentalsSpec ValueStore(901L), ValueStore(901L), ValueStore(901L), - ValueStore(901L) + ValueStore(901L), + ValueStore(901L), + None ) intercept[InconsistentStateException] { @@ -611,16 +619,25 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, - SystemParticipant[FixedRelevantData.type, ApparentPower] + ConstantState.type, + SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type] ] = { - val modelMock = - mock[SystemParticipant[FixedRelevantData.type, ApparentPower]] + val modelMock = mock[SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ]] when(modelMock.getUuid).thenReturn(UUID.randomUUID()) ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, - SystemParticipant[FixedRelevantData.type, ApparentPower] + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] ]( TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00"), TimeUtil.withDefaults.toZonedDateTime("2020-01-01 23:59:00"), @@ -628,7 +645,8 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { None, NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ), additionalActivationTicks, foreseenDataTicks, @@ -636,7 +654,9 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { ValueStore(0L), ValueStore(0L), ValueStore(0L), - ValueStore(0L) + ValueStore(0L), + ValueStore(0L), + None ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala index 2b0264258d..9dec4de3d4 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala @@ -7,6 +7,7 @@ package edu.ie3.simona.agent.participant import org.apache.pekko.actor.{ActorRef, FSM, Props} +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.datamodel.models.result.system.SystemParticipantResult import edu.ie3.simona.agent.ValueStore @@ -23,7 +24,6 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ } import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, - DataCollectionStateData, ParticipantStateData } import edu.ie3.simona.agent.state.AgentState @@ -33,10 +33,17 @@ import edu.ie3.simona.config.SimonaConfig.BaseRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.InvalidRequestException import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData -import edu.ie3.simona.model.participant.SystemParticipant +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl.CosPhiFixed +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + FlexChangeIndicator, + ModelState, + SystemParticipant +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.FlexResponse import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble -import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} +import edu.ie3.util.scala.quantities.{Kilovars, Megavars, ReactivePower} import org.mockito.ArgumentMatchers.any import org.mockito.Mockito import org.mockito.Mockito.doReturn @@ -65,18 +72,28 @@ class ParticipantAgentMock( ) extends ParticipantAgent[ ApparentPower, FixedRelevantData.type, + ConstantState.type, ParticipantStateData[ApparentPower], SystemParticipantInput, SimonaConfig.BaseRuntimeConfig, - SystemParticipant[FixedRelevantData.type, ApparentPower] + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] ](scheduler, initStateData) with ParticipantAgentFundamentals[ ApparentPower, FixedRelevantData.type, + ConstantState.type, ParticipantStateData[ApparentPower], SystemParticipantInput, SimonaConfig.BaseRuntimeConfig, - SystemParticipant[FixedRelevantData.type, ApparentPower] + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] ] { override protected val pdClassTag: ClassTag[ApparentPower] = classTag[ApparentPower] @@ -91,10 +108,16 @@ class ParticipantAgentMock( ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, - SystemParticipant[FixedRelevantData.type, ApparentPower] + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] ], + ConstantState.type, squants.Dimensionless - ) => ApparentPower = (_, _, _) => + ) => ApparentPower = (_, _, _, _) => // output different from default (0, 0) ApparentPower( Megawatts(2.0), @@ -108,8 +131,8 @@ class ParticipantAgentMock( * secondary data is also put to storage. Actual implementation can be found * in each participant's fundamentals. * - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -118,7 +141,17 @@ class ParticipantAgentMock( * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] + ], + modelState: ConstantState.type, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = @@ -158,25 +191,40 @@ class ParticipantAgentMock( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, - SystemParticipant[FixedRelevantData.type, ApparentPower] + ConstantState.type, + SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type] ] = { val func = CosPhiFixed(0.95).activeToReactivePowerFunc( Kilowatts(0.0), 0.95d, Each(1.0) ) - val participant: SystemParticipant[FixedRelevantData.type, ApparentPower] = - mock[SystemParticipant[FixedRelevantData.type, ApparentPower]] + val participant: SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] = + mock[SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ]] doReturn(func).when(participant).activeToReactivePowerFunc(any()) ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, - SystemParticipant[FixedRelevantData.type, ApparentPower] + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] ]( simulationStartDate, simulationEndDate, @@ -192,7 +240,9 @@ class ParticipantAgentMock( ), ValueStore.forResult(resolution, 2), ValueStore(resolution), - ValueStore(resolution) + ValueStore(resolution), + ValueStore(resolution), + None ) } @@ -215,18 +265,49 @@ class ParticipantAgentMock( simulationEndDate: ZonedDateTime ): SystemParticipant[ FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ] = { val mockModel = mock[SystemParticipant[ FixedRelevantData.type, - ApparentPower + ApparentPower, + ConstantState.type ]] val uuid = inputModel.electricalInputModel.getUuid Mockito.when(mockModel.getUuid).thenReturn(uuid) mockModel } + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] + ] + ): ModelState.ConstantState.type = + ConstantState + + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + FixedRelevantData.type, + ConstantState.type, + SystemParticipant[ + FixedRelevantData.type, + ApparentPower, + ConstantState.type + ] + ], + tick: Long + ): FixedRelevantData.type = + FixedRelevantData + /** To clean up agent value stores after power flow convergence. This is * necessary for agents whose results are time dependent e.g. storage agents * @param baseStateData @@ -293,6 +374,73 @@ class ParticipantAgentMock( result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar ) {} + + /** Handle an active power change by flex control. + * + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + override def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + CalcRelevantData.FixedRelevantData.type, + ModelState.ConstantState.type, + SystemParticipant[ + CalcRelevantData.FixedRelevantData.type, + ApparentPower, + ModelState.ConstantState.type + ] + ], + data: CalcRelevantData.FixedRelevantData.type, + lastState: ModelState.ConstantState.type, + setPower: squants.Power + ): (ModelState.ConstantState.type, ApparentPower, FlexChangeIndicator) = ( + ConstantState, + ApparentPower( + Kilowatts(0.0), + Kilovars(0.0) + ), + FlexChangeIndicator() + ) + + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + override protected def updateState( + tick: Long, + modelState: ModelState.ConstantState.type, + calcRelevantData: CalcRelevantData.FixedRelevantData.type, + nodalVoltage: squants.Dimensionless, + model: SystemParticipant[ + CalcRelevantData.FixedRelevantData.type, + ApparentPower, + ModelState.ConstantState.type + ] + ): ModelState.ConstantState.type = modelState } object ParticipantAgentMock { diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index 3a0882ed1c..ca99e4142f 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -25,7 +25,6 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.PvRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig -import edu.ie3.simona.model.participant.PvModel.PvRelevantData import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference} import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -48,20 +47,21 @@ import edu.ie3.simona.test.ParticipantAgentSpec import edu.ie3.simona.test.common.input.PvInputTestData import edu.ie3.simona.util.ConfigUtil import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK -import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.TimeUtil import edu.ie3.util.scala.quantities.{ Megavars, ReactivePower, Vars, WattsPerSquareMeter } -import org.scalatest.PrivateMethodTester import squants.energy.{Kilowatts, Megawatts, Watts} import squants.motion.MetersPerSecond import squants.thermal.Celsius import squants.{Each, Power} +import java.time.ZonedDateTime import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class PvAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -74,13 +74,18 @@ class PvAgentModelCalculationSpec """.stripMargin) ) ) - with PrivateMethodTester with PvInputTestData { + + private implicit val simulationStartDate: ZonedDateTime = + TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00") + private val simulationEndDate: ZonedDateTime = + TimeUtil.withDefaults.toZonedDateTime("2020-01-01 01:00:00") + implicit val receiveTimeOut: Timeout = Timeout(10, TimeUnit.SECONDS) implicit val noReceiveTimeOut: Timeout = Timeout(1, TimeUnit.SECONDS) /* Alter the input model to have a voltage sensitive reactive power calculation */ - val voltageSensitiveInput: PvInput = pvInputModel + val voltageSensitiveInput: PvInput = pvInput .copy() .qCharacteristics(new QV("qV:{(0.95,-0.625),(1.05,0.625)}")) .build() @@ -95,7 +100,8 @@ class PvAgentModelCalculationSpec ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) private val configUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -169,7 +175,10 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) deathProbe.expectTerminated(pvAgent.ref) } @@ -239,7 +248,8 @@ class PvAgentModelCalculationSpec simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -249,12 +259,16 @@ class PvAgentModelCalculationSpec resolution shouldBe this.resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } /* Refuse registration */ - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg( @@ -277,6 +291,8 @@ class PvAgentModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ), awaitRegistrationResponsesFrom, @@ -292,16 +308,17 @@ class PvAgentModelCalculationSpec ) outputConfig shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( - resolution * 10, - Map(0L -> Each(1.0)) + resolution, + SortedMap(0L -> Each(1.0)) ) - resultValueStore shouldBe ValueStore.forResult(resolution, 10) - requestValueStore shouldBe ValueStore[ApparentPower](resolution * 10) + resultValueStore shouldBe ValueStore(resolution) + requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ awaitRegistrationResponsesFrom shouldBe Vector(weatherService.ref) @@ -313,7 +330,10 @@ class PvAgentModelCalculationSpec } /* Reply, that registration was successful */ - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(4711L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + ) /* Expect a completion message */ scheduler.expectMsg(Completion(pvAgent.toTyped, Some(4711L))) @@ -321,7 +341,7 @@ class PvAgentModelCalculationSpec /* ... as well as corresponding state and state data */ pvAgent.stateName shouldBe Idle pvAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map( weatherService.ref -> Some(4711L) @@ -346,13 +366,19 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg( RegisterForWeatherMessage(52.02083574, 7.40110716) ) - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -373,12 +399,12 @@ class PvAgentModelCalculationSpec ) inside(pvAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.requestValueStore shouldBe ValueStore[ + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( - resolution * 10, - Map( + resolution, + SortedMap( 0L -> ApparentPower( Megawatts(0d), Megavars(0d) @@ -405,11 +431,17 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -426,14 +458,14 @@ class PvAgentModelCalculationSpec weatherService.send( pvAgent, - ProvideWeatherMessage(0L, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) ) /* Find yourself in corresponding state and state data */ pvAgent.stateName shouldBe HandleInformation pvAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -464,17 +496,12 @@ class PvAgentModelCalculationSpec pvAgent.stateName shouldBe Idle pvAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.receivedSecondaryDataStore match { case ValueStore(_, store) => store shouldBe Map( - 0L -> PvRelevantData( - 0L.toDateTime, - 3600L, - weatherData.diffIrr, - weatherData.dirIrr - ) + 0L -> Map(weatherService.ref -> weatherData) ) } @@ -511,11 +538,17 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -528,7 +561,7 @@ class PvAgentModelCalculationSpec pvAgent.stateName shouldBe HandleInformation pvAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -558,7 +591,7 @@ class PvAgentModelCalculationSpec weatherService.send( pvAgent, - ProvideWeatherMessage(0L, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) ) /* Expect confirmation */ @@ -567,17 +600,12 @@ class PvAgentModelCalculationSpec /* Expect the state change to idle with updated base state data */ pvAgent.stateName shouldBe Idle pvAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.receivedSecondaryDataStore match { case ValueStore(_, store) => store shouldBe Map( - 0L -> PvRelevantData( - 0L.toDateTime, - 3600L, - weatherData.diffIrr, - weatherData.dirIrr - ) + 0L -> Map(weatherService.ref -> weatherData) ) } @@ -615,11 +643,17 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(3600L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -643,7 +677,12 @@ class PvAgentModelCalculationSpec ) weatherService.send( pvAgent, - ProvideWeatherMessage(3600L, weatherData, Some(7200L)) + ProvideWeatherMessage( + 3600L, + weatherService.ref, + weatherData, + Some(7200L) + ) ) /* Trigger the agent */ @@ -675,11 +714,17 @@ class PvAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(pvAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + pvAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(pvAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + pvAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -691,6 +736,7 @@ class PvAgentModelCalculationSpec pvAgent, ProvideWeatherMessage( 0L, + weatherService.ref, WeatherData( WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), @@ -708,6 +754,7 @@ class PvAgentModelCalculationSpec pvAgent, ProvideWeatherMessage( 3600L, + weatherService.ref, WeatherData( WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), @@ -725,6 +772,7 @@ class PvAgentModelCalculationSpec pvAgent, ProvideWeatherMessage( 7200L, + weatherService.ref, WeatherData( WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index 24ccac5f34..c8e048daec 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -29,6 +29,7 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.WecRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.WecModel import edu.ie3.simona.model.participant.WecModel.WecRelevantData import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference} @@ -68,6 +69,7 @@ import squants.thermal.Celsius import java.time.ZonedDateTime import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class WecAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -138,7 +140,8 @@ class WecAgentModelCalculationSpec secondaryDataServices = None, outputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) ) @@ -179,7 +182,10 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) deathProbe.expectTerminated(wecAgent.ref) } @@ -202,7 +208,8 @@ class WecAgentModelCalculationSpec secondaryDataServices = withServices, outputConfig = NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) ) @@ -239,7 +246,10 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg(RegisterForWeatherMessage(51.4843281, 7.4116482)) @@ -260,6 +270,8 @@ class WecAgentModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ), awaitRegistrationResponsesFrom, @@ -271,16 +283,17 @@ class WecAgentModelCalculationSpec services shouldBe withServices outputConfig shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( - resolution * 10, - Map(0L -> Each(1.0)) + resolution, + SortedMap(0L -> Each(1.0)) ) - resultValueStore shouldBe ValueStore.forResult(resolution, 10) - requestValueStore shouldBe ValueStore[ApparentPower](resolution * 10) + resultValueStore shouldBe ValueStore(resolution) + requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ awaitRegistrationResponsesFrom shouldBe Vector(weatherService.ref) @@ -292,7 +305,10 @@ class WecAgentModelCalculationSpec } /* Reply, that registration was successful */ - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(4711L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + ) /* Expect a completion message */ scheduler.expectMsg(Completion(wecAgent.toTyped, Some(4711L))) @@ -303,6 +319,7 @@ class WecAgentModelCalculationSpec case baseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ] => /* Only check the awaited next data ticks, as the rest has yet been checked */ @@ -329,11 +346,17 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg(RegisterForWeatherMessage(51.4843281, 7.4116482)) - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -357,13 +380,14 @@ class WecAgentModelCalculationSpec case modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ] => modelBaseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( - resolution * 10, - Map( + resolution, + SortedMap( 0L -> ApparentPower( Megawatts(0d), Megavars(0d) @@ -390,11 +414,17 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -411,7 +441,12 @@ class WecAgentModelCalculationSpec weatherService.send( wecAgent, - ProvideWeatherMessage(900L, weatherData, Some(1800L)) + ProvideWeatherMessage( + 900L, + weatherService.ref, + weatherData, + Some(1800L) + ) ) /* Find yourself in corresponding state and state data */ @@ -421,6 +456,7 @@ class WecAgentModelCalculationSpec baseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ], expectedSenders, @@ -456,17 +492,14 @@ class WecAgentModelCalculationSpec case baseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.receivedSecondaryDataStore match { case ValueStore(_, store) => store shouldBe Map( - 900L -> WecRelevantData( - weatherData.windVel, - weatherData.temp, - None - ) + 900L -> Map(weatherService.ref -> weatherData) ) } @@ -503,11 +536,17 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -523,6 +562,7 @@ class WecAgentModelCalculationSpec baseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ], expectedSenders, @@ -554,7 +594,12 @@ class WecAgentModelCalculationSpec weatherService.send( wecAgent, - ProvideWeatherMessage(900L, weatherData, Some(1800L)) + ProvideWeatherMessage( + 900L, + weatherService.ref, + weatherData, + Some(1800L) + ) ) /* Expect confirmation */ @@ -566,17 +611,14 @@ class WecAgentModelCalculationSpec case baseStateData: ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, + ConstantState.type, WecModel ] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.receivedSecondaryDataStore match { case ValueStore(_, store) => store shouldBe Map( - 900L -> WecRelevantData( - weatherData.windVel, - weatherData.temp, - None - ) + 900L -> Map(weatherService.ref -> weatherData) ) } @@ -614,11 +656,17 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -642,7 +690,12 @@ class WecAgentModelCalculationSpec ) weatherService.send( wecAgent, - ProvideWeatherMessage(900L, weatherData, Some(1800L)) + ProvideWeatherMessage( + 900L, + weatherService.ref, + weatherData, + Some(1800L) + ) ) /* Trigger the agent */ @@ -674,11 +727,17 @@ class WecAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(wecAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + wecAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(wecAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + wecAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -690,6 +749,7 @@ class WecAgentModelCalculationSpec wecAgent, ProvideWeatherMessage( 900L, + weatherService.ref, WeatherData( WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), @@ -707,6 +767,7 @@ class WecAgentModelCalculationSpec wecAgent, ProvideWeatherMessage( 1800L, + weatherService.ref, WeatherData( WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), @@ -724,6 +785,7 @@ class WecAgentModelCalculationSpec wecAgent, ProvideWeatherMessage( 2700L, + weatherService.ref, WeatherData( WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 33f9914a0f..df2333ca9f 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -687,17 +687,20 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ) ) @@ -713,17 +716,20 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = false, - simulationResult = true + simulationResult = true, + flexResult = false ) ) diff --git a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala index a654ec289a..a2a72a34ce 100644 --- a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala @@ -18,7 +18,6 @@ import edu.ie3.simona.test.common.TestKitWithShutdown import edu.ie3.simona.util.ConfigUtil.NotifierIdentifier._ import edu.ie3.simona.util.EntityMapperUtil import org.scalatest.matchers.should.Matchers -import org.scalatest.wordspec.AnyWordSpecLike import scala.concurrent.duration._ import scala.language.postfixOps diff --git a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala index b77e2a8ed9..1b496727d3 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala @@ -9,12 +9,15 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHeat import edu.ie3.simona.model.participant.ApparentPowerAndHeatSpec.ApparentPowerAndHeatMock import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl.CosPhiFixed +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.{Megavars, ReactivePower, Vars} -import squants.Each -import squants.energy.{Kilowatts, Megawatts, Power, Watts} +import squants.energy.{Kilowatts, Megawatts, Watts} +import squants.{Each, Power} import java.util.UUID @@ -27,13 +30,13 @@ class ApparentPowerAndHeatSpec extends UnitSpec { ApparentPowerAndHeatMock.calculatePower( 50L, Each(1.0d), + ConstantState, FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => (p =~ Megawatts(0d)) shouldBe true (q =~ Megavars(0d)) shouldBe true (qDot =~ Megawatts(0d)) shouldBe true - } } } @@ -42,13 +45,13 @@ class ApparentPowerAndHeatSpec extends UnitSpec { ApparentPowerAndHeatMock.calculatePower( 10L, Each(1.0d), + ConstantState, FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => (p =~ Megawatts(43d)) shouldBe true (q =~ Megavars(0d)) shouldBe true (qDot =~ Megawatts(42d)) shouldBe true - } } } @@ -57,7 +60,11 @@ class ApparentPowerAndHeatSpec extends UnitSpec { object ApparentPowerAndHeatSpec { object ApparentPowerAndHeatMock - extends SystemParticipant[FixedRelevantData.type, ApparentPowerAndHeat]( + extends SystemParticipant[ + FixedRelevantData.type, + ApparentPowerAndHeat, + ConstantState.type + ]( UUID.randomUUID(), "ParticipantMock", OperationInterval.apply(0L, 42L), @@ -66,7 +73,10 @@ object ApparentPowerAndHeatSpec { Kilowatts(42d), 0.97 ) - with ApparentPowerAndHeatParticipant[FixedRelevantData.type] { + with ApparentPowerAndHeatParticipant[ + FixedRelevantData.type, + ConstantState.type + ] { this.enable() /** Calculate the heat of the asset. As for electrical assets, positive @@ -81,9 +91,9 @@ object ApparentPowerAndHeatSpec { */ override def calculateHeat( tick: Long, + modelState: ConstantState.type, data: CalcRelevantData.FixedRelevantData.type - ): Power = - Megawatts(42d) + ): Power = Megawatts(42d) /** Calculate the active power behaviour of the model * @@ -93,8 +103,37 @@ object ApparentPowerAndHeatSpec { * Active power */ override protected def calculateActivePower( + modelState: ConstantState.type, data: CalcRelevantData.FixedRelevantData.type - ): Power = - Megawatts(43d) + ): Power = Megawatts(43d) + + /** @param data + * @param lastState + * @return + * flex options + */ + override def determineFlexOptions( + data: CalcRelevantData.FixedRelevantData.type, + lastState: ModelState.ConstantState.type + ): FlexibilityMessage.ProvideFlexOptions = + ProvideMinMaxFlexOptions.noFlexOption( + this.getUuid, + calculateActivePower(ConstantState, data) + ) + + /** @param data + * @param lastState + * @param setPower + * power that has been set by EmAgent + * @return + * updated relevant data and an indication at which circumstances flex + * options will change next + */ + override def handleControlledPowerChange( + data: CalcRelevantData.FixedRelevantData.type, + lastState: ModelState.ConstantState.type, + setPower: Power + ): (ModelState.ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) } } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala index 25f32e4c46..008cc0c1fc 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala @@ -588,7 +588,7 @@ class PrimaryServiceProxySpec maliciousStateData, self ) - expectMsg(RegistrationFailedMessage) + expectMsg(RegistrationFailedMessage(proxyRef)) } "forward the registration request, if worker is already known" in { @@ -623,7 +623,7 @@ class PrimaryServiceProxySpec maliciousStateData, self ) - expectMsg(RegistrationFailedMessage) + expectMsg(RegistrationFailedMessage(proxyRef)) } "spin off a worker, if needed and forward the registration request" in { @@ -677,7 +677,7 @@ class PrimaryServiceProxySpec ) proxyRef ! request - expectMsg(RegistrationFailedMessage) + expectMsg(RegistrationFailedMessage(proxyRef)) } "succeed, if model is handled" in { diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala index 99418e035f..82f3e5932a 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala @@ -148,7 +148,9 @@ class PrimaryServiceProxySqlIT scheduler.expectMsg(Completion(workerRef, Some(0))) - systemParticipantProbe.expectMsg(RegistrationSuccessfulMessage(Some(0L))) + systemParticipantProbe.expectMsg( + RegistrationSuccessfulMessage(workerRef.toClassic, Some(0L)) + ) } "handle participant request correctly if participant does not have primary data" in { @@ -168,7 +170,7 @@ class PrimaryServiceProxySqlIT scheduler.expectNoMessage() - systemParticipantProbe.expectMsg(RegistrationFailedMessage) + systemParticipantProbe.expectMsg(RegistrationFailedMessage(proxyRef)) } } } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala index 6f1aa171a6..0818d539f4 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala @@ -180,7 +180,9 @@ class PrimaryServiceWorkerSpec serviceRef ! WorkerRegistrationMessage(systemParticipant.ref) /* Wait for request approval */ - systemParticipant.expectMsg(RegistrationSuccessfulMessage(Some(0L))) + systemParticipant.expectMsg( + RegistrationSuccessfulMessage(serviceRef, Some(0L)) + ) /* We cannot directly check, if the requesting actor is among the subscribers, therefore we ask the actor to * provide data to all subscribed actors and check, if the subscribed probe gets one */ @@ -243,11 +245,13 @@ class PrimaryServiceWorkerSpec expectMsgClass(classOf[ProvidePrimaryDataMessage]) match { case ProvidePrimaryDataMessage( actualTick, + actualServiceRef, actualData, actualNextDataTick, unlockKey ) => actualTick shouldBe 0L + actualServiceRef shouldBe serviceRef actualData shouldBe primaryData actualNextDataTick shouldBe Some(900L) unlockKey shouldBe None @@ -322,6 +326,7 @@ class PrimaryServiceWorkerSpec expectMsg( ProvidePrimaryDataMessage( tick, + serviceRef, ActivePower(Kilowatts(50.0)), Some(900L) ) @@ -342,15 +347,23 @@ class PrimaryServiceWorkerSpec inside( systemParticipant.expectMsgClass(classOf[ProvidePrimaryDataMessage]) - ) { case ProvidePrimaryDataMessage(tick, data, nextDataTick, unlockKey) => - tick shouldBe 900L - inside(data) { - case ActivePower(p) => - (p ~= Kilowatts(1250.0)) shouldBe true - case _ => fail("Expected to get active power only.") - } - nextDataTick shouldBe None - unlockKey shouldBe None + ) { + case ProvidePrimaryDataMessage( + tick, + actualServiceRef, + data, + nextDataTick, + unlockKey + ) => + tick shouldBe 900L + actualServiceRef shouldBe serviceRef + inside(data) { + case ActivePower(p) => + (p ~= Kilowatts(1250.0)) shouldBe true + case _ => fail("Expected to get active power only.") + } + nextDataTick shouldBe None + unlockKey shouldBe None } } } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala index 8d0c4a9299..a194e9f352 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala @@ -168,7 +168,9 @@ class PrimaryServiceWorkerSqlIT serviceRef, WorkerRegistrationMessage(participant.ref) ) - participant.expectMsg(RegistrationSuccessfulMessage(Some(firstTick))) + participant.expectMsg( + RegistrationSuccessfulMessage(serviceRef, Some(firstTick)) + ) scheduler.send(serviceRef, Activation(firstTick)) scheduler.expectMsg(Completion(serviceRef.toTyped, maybeNextTick)) diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala index 8830f6c2ec..1f5c0ddc12 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala @@ -6,14 +6,6 @@ package edu.ie3.simona.service.weather -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.testkit.{ - EventFilter, - ImplicitSender, - TestActorRef, - TestProbe -} import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.config.SimonaConfig @@ -39,6 +31,14 @@ import edu.ie3.simona.test.common.{ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil import edu.ie3.util.scala.quantities.WattsPerSquareMeter +import org.apache.pekko.actor.ActorSystem +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.testkit.{ + EventFilter, + ImplicitSender, + TestActorRef, + TestProbe +} import org.scalatest.PrivateMethodTester import org.scalatest.wordspec.AnyWordSpecLike import squants.motion.MetersPerSecond @@ -146,7 +146,7 @@ class WeatherServiceSpec ) } - expectMsg(RegistrationFailedMessage) + expectMsg(RegistrationFailedMessage(weatherActor)) } "announce, that a valid coordinate is registered" in { @@ -156,7 +156,7 @@ class WeatherServiceSpec validCoordinate.longitude ) - expectMsg(RegistrationSuccessfulMessage(Some(0L))) + expectMsg(RegistrationSuccessfulMessage(weatherActor.ref, Some(0L))) } "recognize, that a valid coordinate yet is registered" in { @@ -184,6 +184,7 @@ class WeatherServiceSpec expectMsg( ProvideWeatherMessage( 0, + weatherActor, WeatherData( WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), @@ -205,6 +206,7 @@ class WeatherServiceSpec expectMsg( ProvideWeatherMessage( 3600, + weatherActor, WeatherData( WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), diff --git a/src/test/scala/edu/ie3/simona/test/ParticipantAgentSpec.scala b/src/test/scala/edu/ie3/simona/test/ParticipantAgentSpec.scala index b7de3f6435..e6a3d9e6e0 100644 --- a/src/test/scala/edu/ie3/simona/test/ParticipantAgentSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/ParticipantAgentSpec.scala @@ -6,11 +6,12 @@ package edu.ie3.simona.test +import edu.ie3.simona.test.common.AgentSpec import org.apache.pekko.actor.ActorSystem import org.apache.pekko.testkit.TestProbe -import edu.ie3.simona.test.common.AgentSpec -/** Class to help building tests for [[ParticipantAgent]] s +/** Class to help building tests for + * [[edu.ie3.simona.agent.participant.ParticipantAgent]]s * * @param actorSystem * The actor system to use for building actors diff --git a/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala b/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala index 579589316e..4334c91c59 100644 --- a/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala @@ -98,6 +98,7 @@ trait DefaultTestData { | notifier = "default" | powerRequestReply = false | simulationResult = false + | flexResult = false |} |simona.output.participant.individualConfigs = [] | diff --git a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala index 3fd0600aa4..e50e1f9c62 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala @@ -52,7 +52,8 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { protected val defaultOutputConfig: NotifierConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) protected val modelConfig: SimonaConfig.EvcsRuntimeConfig = diff --git a/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala b/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala index 931ae996c5..f9d98acc0d 100644 --- a/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala +++ b/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala @@ -620,23 +620,27 @@ class ConfigUtilSpec SimonaConfig.ParticipantBaseOutputConfig( notifier = "default", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ) ) ) @@ -646,20 +650,24 @@ class ConfigUtilSpec inside(configUtil) { case OutputConfigUtil(default, configs) => default shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) configs shouldBe Map( Load -> NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ), PvPlant -> NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ), ChpPlant -> NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) ) } @@ -670,14 +678,16 @@ class ConfigUtilSpec val actual = configUtil.getOrDefault(PvPlant) actual shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) } "return default config, when the requested model type is not apparent" in { configUtil.getOrDefault(Wec) shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) } @@ -686,23 +696,27 @@ class ConfigUtilSpec SimonaConfig.ParticipantBaseOutputConfig( notifier = "default", powerRequestReply = false, - simulationResult = true + simulationResult = true, + flexResult = false ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ) ) ) @@ -719,23 +733,27 @@ class ConfigUtilSpec SimonaConfig.ParticipantBaseOutputConfig( notifier = "default", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ) ) ) @@ -751,23 +769,27 @@ class ConfigUtilSpec SimonaConfig.ParticipantBaseOutputConfig( notifier = "default", powerRequestReply = false, - simulationResult = false + simulationResult = false, + flexResult = false ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, - simulationResult = false + simulationResult = false, + flexResult = false ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, - simulationResult = true + simulationResult = true, + flexResult = false ) ) ) From 5eda3247f4e45868a84a7eaf4b0d27bca8b81435 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 12:05:21 +0100 Subject: [PATCH 132/305] Solving some general compile errors --- .../agent/participant/evcs/EvcsAgent.scala | 7 +- .../exceptions/CriticalFailureException.scala | 19 ++++++ .../messages/flex/FlexibilityMessage.scala | 3 +- .../simona/service/ev/ExtEvDataService.scala | 1 + .../service/ev/ExtEvDataServiceSpec.scala | 65 +++++-------------- 5 files changed, 38 insertions(+), 57 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala index 59516ff5ab..5e0ca563d6 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala @@ -22,11 +22,8 @@ import edu.ie3.simona.agent.participant.{ } import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig -import edu.ie3.simona.model.participant.evcs.EvcsModel -import edu.ie3.simona.model.participant.evcs.EvcsModel.{ - EvcsRelevantData, - EvcsState -} +import edu.ie3.simona.model.participant.EvcsModel +import edu.ie3.simona.model.participant.EvcsModel.{EvcsRelevantData, EvcsState} import edu.ie3.simona.ontology.messages.services.EvMessage.{ DepartingEvsRequest, EvFreeLotsRequest diff --git a/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala b/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala new file mode 100644 index 0000000000..6ab75e8af6 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/exceptions/CriticalFailureException.scala @@ -0,0 +1,19 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.exceptions + +/** Error that should cause an actor to fail, which might terminate the whole + * simulation + * @param message + * The error message + */ +class CriticalFailureException(message: String) extends Exception(message) { + def this(message: String, cause: Throwable) = { + this(message) + initCause(cause) + } +} diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala index 3a88991088..5e264425fe 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala @@ -7,7 +7,6 @@ package edu.ie3.simona.ontology.messages.flex import edu.ie3.datamodel.models.input.AssetInput -import edu.ie3.simona.agent.em.EmAgent.EmMessage import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import org.apache.pekko.actor.typed.ActorRef @@ -33,7 +32,7 @@ object FlexibilityMessage { /** Trait that is extended by all messages that are supposed to be received by * [[edu.ie3.simona.agent.em.EmAgent]]s. */ - sealed trait FlexResponse extends EmMessage { + sealed trait FlexResponse { val modelUuid: UUID } diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index 2b886517a8..b2a7c854f6 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -282,6 +282,7 @@ class ExtEvDataService(override val scheduler: ActorRef) actorToEvs.zip(keys).foreach { case ((actor, arrivingEvs), key) => actor ! ProvideEvDataMessage( tick, + self, ArrivingEvsData(arrivingEvs), unlockKey = Some(key) ) diff --git a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala index 3326252b6d..c08b4e827d 100644 --- a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala @@ -102,10 +102,7 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") // this one should be stashed - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectNoMessage() scheduler.expectNoMessage() @@ -125,7 +122,7 @@ class ExtEvDataServiceSpec scheduler.send(evService, Activation(INIT_SIM_TICK)) scheduler.expectMsg(Completion(evService.toTyped)) - evcs1.expectMsg(RegistrationSuccessfulMessage(None)) + evcs1.expectMsg(RegistrationSuccessfulMessage(evService.ref, None)) } } @@ -154,23 +151,14 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") val evcs2 = TestProbe("evcs2") - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) - evcs1.expectMsg(RegistrationSuccessfulMessage(None)) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) + evcs1.expectMsg(RegistrationSuccessfulMessage(evService.ref, None)) - evcs2.send( - evService, - RegisterForEvDataMessage(evcs2UUID) - ) - evcs2.expectMsg(RegistrationSuccessfulMessage(None)) + evcs2.send(evService, RegisterForEvDataMessage(evcs2UUID)) + evcs2.expectMsg(RegistrationSuccessfulMessage(evService.ref, None)) // register first one again - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectNoMessage() evcs2.expectNoMessage() } @@ -233,16 +221,10 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") val evcs2 = TestProbe("evcs2") - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectMsgType[RegistrationSuccessfulMessage] - evcs2.send( - evService, - RegisterForEvDataMessage(evcs2UUID) - ) + evcs2.send(evService, RegisterForEvDataMessage(evcs2UUID)) evcs2.expectMsgType[RegistrationSuccessfulMessage] extData.sendExtMsg( @@ -374,16 +356,10 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") val evcs2 = TestProbe("evcs1") - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectMsgType[RegistrationSuccessfulMessage] - evcs2.send( - evService, - RegisterForEvDataMessage(evcs2UUID) - ) + evcs2.send(evService, RegisterForEvDataMessage(evcs2UUID)) evcs2.expectMsgType[RegistrationSuccessfulMessage] val departures = Map( @@ -450,9 +426,7 @@ class ExtEvDataServiceSpec "handle ev arrivals correctly and forward them to the correct evcs" in { val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) + new ExtEvDataService(scheduler.ref) ) val extData = extEvData(evService) @@ -473,16 +447,10 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") val evcs2 = TestProbe("evcs2") - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectMsgType[RegistrationSuccessfulMessage] - evcs2.send( - evService, - RegisterForEvDataMessage(evcs2UUID) - ) + evcs2.send(evService, RegisterForEvDataMessage(evcs2UUID)) evcs2.expectMsgType[RegistrationSuccessfulMessage] val arrivals = Map( @@ -545,10 +513,7 @@ class ExtEvDataServiceSpec val evcs1 = TestProbe("evcs1") - evcs1.send( - evService, - RegisterForEvDataMessage(evcs1UUID) - ) + evcs1.send(evService, RegisterForEvDataMessage(evcs1UUID)) evcs1.expectMsgType[RegistrationSuccessfulMessage] val arrivals = Map( From d11511fe8f385ad50351023ea9ca1b2e06664af5 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 13:15:58 +0100 Subject: [PATCH 133/305] Also taking EVCS and HP changes --- .../resources/config/config-template.conf | 2 + .../agent/participant/evcs/EvcsAgent.scala | 7 +- .../evcs/EvcsAgentFundamentals.scala | 886 +++-- .../participant/hp/HpAgentFundamentals.scala | 308 +- .../edu/ie3/simona/config/SimonaConfig.scala | 3093 +++++------------ .../simona/model/participant/EvcsModel.scala | 359 -- .../simona/model/participant/HpModel.scala | 181 +- .../participant/evcs/ChargingSchedule.scala | 56 + .../participant/evcs/ChargingStrategy.scala | 25 + .../participant/evcs/EvModelWrapper.scala | 50 + .../model/participant/evcs/EvcsModel.scala | 1083 ++++++ .../evcs/SchedulingTimeWindows.scala | 79 + .../uncontrolled/ConstantPowerCharging.scala | 54 + .../uncontrolled/MaximumPowerCharging.scala | 57 + .../thermal/CylindricalThermalStorage.scala | 55 +- .../model/thermal/RandomStorageState.scala | 4 +- .../simona/model/thermal/ThermalGrid.scala | 145 +- .../simona/model/thermal/ThermalHouse.scala | 136 +- .../simona/model/thermal/ThermalStorage.scala | 18 +- .../messages/services/EvMessage.scala | 7 +- .../simona/service/ev/ExtEvDataService.scala | 58 +- .../model/participant/EvcsModelTest.groovy | 122 - .../CylindricalThermalStorageTest.groovy | 96 +- .../model/thermal/ThermalHouseTest.groovy | 31 +- .../simona/test/common/model/MockEvModel.java | 45 +- .../EvcsAgentModelCalculationSpec.scala | 1281 ++++++- .../HpAgentModelCalculationSpec.scala | 377 +- .../model/participant/HpModelSpec.scala | 158 +- .../model/participant/HpModelTestData.scala | 10 +- .../participant/evcs/EvcsModelSpec.scala | 848 +++++ .../ConstantPowerChargingSpec.scala | 181 + .../MaximumPowerChargingSpec.scala | 176 + .../model/thermal/ThermalGridSpec.scala | 2 - .../model/thermal/ThermalGridTestData.scala | 12 +- .../ThermalGridWithHouseAndStorageSpec.scala | 43 +- .../ThermalGridWithHouseOnlySpec.scala | 8 +- .../ThermalGridWithStorageOnlySpec.scala | 3 - .../flex/MinMaxFlexibilityMessageTest.scala | 66 + .../service/ev/ExtEvDataServiceSpec.scala | 11 +- .../ie3/simona/test/common/EvTestData.scala | 8 +- .../test/common/input/EvcsInputTestData.scala | 7 + .../test/common/input/PvInputTestData.scala | 12 +- .../model/participant/EvcsTestData.scala | 38 + .../common/model/participant/HpTestData.scala | 2 +- .../test/helper/TableDrivenHelper.scala | 19 + .../test/matchers/QuantityMatchers.scala | 41 +- 46 files changed, 6466 insertions(+), 3794 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingStrategy.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala create mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala delete mode 100644 src/test/groovy/edu/ie3/simona/model/participant/EvcsModelTest.groovy create mode 100644 src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala create mode 100644 src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala create mode 100644 src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala diff --git a/src/main/resources/config/config-template.conf b/src/main/resources/config/config-template.conf index 8e0a5f4882..859d98e016 100644 --- a/src/main/resources/config/config-template.conf +++ b/src/main/resources/config/config-template.conf @@ -50,6 +50,8 @@ WecRuntimeConfig { EvcsRuntimeConfig { baseRuntimeConfig: BaseRuntimeConfig # this entry is ignored by the config generator, # but cannot removed bc otherwise EvcsRuntimeConfig is handled as String + chargingStrategy: String | "maxPower" # can be one of maxPower, constantPower, gridOrientedScheduling or marketOrientedScheduling + lowestEvSoc: Double | 0.2 # Defines the lowest possible state of charge (SoC) that an EV is allowed to uncharge in vehicle to grid (V2G) mode } #@define extends BaseRuntimeConfig diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala index 5e0ca563d6..59516ff5ab 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala @@ -22,8 +22,11 @@ import edu.ie3.simona.agent.participant.{ } import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig -import edu.ie3.simona.model.participant.EvcsModel -import edu.ie3.simona.model.participant.EvcsModel.{EvcsRelevantData, EvcsState} +import edu.ie3.simona.model.participant.evcs.EvcsModel +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsRelevantData, + EvcsState +} import edu.ie3.simona.ontology.messages.services.EvMessage.{ DepartingEvsRequest, EvFreeLotsRequest diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 1f3be0eff2..a84b68353b 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.agent.participant.evcs -import org.apache.pekko.actor.{ActorRef, FSM} -import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.datamodel.models.result.system.{ EvcsResult, @@ -21,35 +19,46 @@ import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.ActorEvMovementsService import edu.ie3.simona.agent.participant.evcs.EvcsAgent.neededServices -import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData +import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ + FlexControlledData, + ParticipantModelBaseStateData +} import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer import edu.ie3.simona.agent.participant.statedata.{ - DataCollectionStateData, + BaseStateData, ParticipantStateData } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle -import edu.ie3.simona.api.data.ev.model.EvModel import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig +import edu.ie3.simona.event.ResultEvent.ParticipantResultEvent import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, InconsistentStateException, InvalidRequestException } -import edu.ie3.simona.io.result.AccompaniedSimulationResult -import edu.ie3.simona.model.participant.EvcsModel -import edu.ie3.simona.model.participant.EvcsModel.EvcsRelevantData -import edu.ie3.simona.ontology.messages.services.EvMessage.{ - ArrivingEvsData, - DepartingEvsResponse, - FreeLotsResponse +import edu.ie3.simona.model.participant.FlexChangeIndicator +import edu.ie3.simona.model.participant.evcs.EvcsModel +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsRelevantData, + EvcsState } -import edu.ie3.simona.service.ev.ExtEvDataService.FALLBACK_EV_MOVEMENTS_STEM_DISTANCE -import edu.ie3.util.quantities.PowerSystemUnits.PU +import edu.ie3.simona.ontology.messages.PowerMessage.AssetPowerChangedMessage +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} +import edu.ie3.simona.ontology.messages.services.EvMessage._ +import edu.ie3.simona.util.SimonaConstants +import edu.ie3.simona.util.TickUtil.{RichZonedDateTime, TickLong} +import edu.ie3.util.quantities.PowerSystemUnits.{MEGAVAR, MEGAWATT, PU} import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble -import edu.ie3.util.scala.quantities.Kilovars -import squants.energy.Kilowatts +import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} +import squants.energy.Megawatts import squants.{Dimensionless, Each} import java.time.ZonedDateTime @@ -61,12 +70,12 @@ protected trait EvcsAgentFundamentals extends ParticipantAgentFundamentals[ ApparentPower, EvcsRelevantData, + EvcsState, ParticipantStateData[ApparentPower], EvcsInput, EvcsRuntimeConfig, EvcsModel - ] - with LazyLogging { + ] { this: EvcsAgent => override protected val pdClassTag: ClassTag[ApparentPower] = classTag[ApparentPower] @@ -84,7 +93,7 @@ protected trait EvcsAgentFundamentals * Real world time date time, when the simulation starts * @param simulationEndDate * Real world time date time, when the simulation ends - * @param timeBin + * @param resolution * Agents regular time bin it wants to be triggered e.g one hour * @param requestVoltageDeviationThreshold * Threshold, after which two nodal voltage magnitudes from participant @@ -101,12 +110,14 @@ protected trait EvcsAgentFundamentals services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, - timeBin: Long, + resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ] = { /* Check for needed services */ @@ -119,55 +130,6 @@ protected trait EvcsAgentFundamentals s"EvcsAgent cannot be initialized without an ev data service!" ) - baseStateDataForModelCalculation( - inputModel, - modelConfig, - services, - simulationStartDate, - simulationEndDate, - timeBin, - requestVoltageDeviationThreshold, - outputConfig - ) - } - - /** Determine needed base state data for model calculation simulation mode. - * - * @param inputModel - * Input model - * @param modelConfig - * Configuration for the model - * @param servicesOpt - * [[Option]] on a vector of [[SecondaryDataService]] s - * @param simulationStartDate - * Real world time date time, when the simulation starts - * @param simulationEndDate - * Real world time date time, when the simulation ends - * @param timeBin - * Agents regular time bin it wants to be triggered e.g one hour - * @param requestVoltageDeviationThreshold - * Threshold, after which two nodal voltage magnitudes from participant - * power requests for the same tick are considered to be different - * @param outputConfig - * Config of the output behaviour for simulation results - * @return - * Needed base state data for model calculation - */ - def baseStateDataForModelCalculation( - inputModel: InputModelContainer[EvcsInput], - modelConfig: EvcsRuntimeConfig, - servicesOpt: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], - simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime, - timeBin: Long, - requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig - ): ParticipantModelBaseStateData[ - ApparentPower, - EvcsRelevantData, - EvcsModel - ] = { - /* Build the calculation model */ val model = buildModel( @@ -177,17 +139,22 @@ protected trait EvcsAgentFundamentals simulationEndDate ) - ParticipantModelBaseStateData[ApparentPower, EvcsRelevantData, EvcsModel]( + ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ]( simulationStartDate, simulationEndDate, model, - servicesOpt, + services, outputConfig, SortedSet.empty, // Additional activation of the evcs agent is not needed Map.empty, requestVoltageDeviationThreshold, ValueStore.forVoltage( - timeBin * 10, + resolution, // FIXME probably need to increase this for grid oriented scheduling Each( inputModel.electricalInputModel.getNode .getvTarget() @@ -196,9 +163,11 @@ protected trait EvcsAgentFundamentals .doubleValue ) ), - ValueStore.forResult(timeBin, 10), - ValueStore(timeBin * 10), - ValueStore(timeBin * 10) + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + ValueStore(resolution), + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) } @@ -211,19 +180,109 @@ protected trait EvcsAgentFundamentals inputModel.electricalInputModel, modelConfig.scaling, simulationStartDate, - simulationEndDate + simulationEndDate, + modelConfig.chargingStrategy, + modelConfig.lowestEvSoc ) + override protected def createInitialState( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ] + ): EvcsState = + EvcsState( + Set.empty, + Map.empty, + SimonaConstants.FIRST_TICK_IN_SIMULATION + ) + + override protected def createCalcRelevantData( + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ], + tick: Long + ): EvcsRelevantData = { + // always only take arrivals for the current tick + // or empty sequence if none arrived + val movements = baseStateData.receivedSecondaryDataStore + .getOrElse(tick, Map.empty) + .collectFirst { + // filter secondary data for arriving EVs data + case (_, evcsData: ArrivingEvsData) => + evcsData.arrivals + } + .getOrElse(Seq.empty) + + val voltages = baseStateData.voltageValueStore.asMap + .map { case (tick, voltage) => + tick.toDateTime(baseStateData.startDate) -> voltage + } + EvcsRelevantData(tick, movements, voltages) + } + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ], + data: EvcsRelevantData, + lastState: EvcsState, + setPower: squants.Power + ): (EvcsState, ApparentPower, FlexChangeIndicator) = { + /* Calculate the power */ + val voltage = getAndCheckNodalVoltage(baseStateData, tick) + + val reactivePower = baseStateData.model.calculateReactivePower( + setPower, + voltage + ) + val result = ApparentPower(setPower, reactivePower) + + /* Handle the request within the model */ + val (updatedState, flexChangeIndicator) = + baseStateData.model.handleControlledPowerChange(data, lastState, setPower) + (updatedState, result, flexChangeIndicator) + } + /** Partial function, that is able to transfer * [[ParticipantModelBaseStateData]] (holding the actual calculation model) * into a pair of active and reactive power */ override val calculateModelPowerFunc: ( Long, - ParticipantModelBaseStateData[ApparentPower, EvcsRelevantData, EvcsModel], + ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ], + EvcsState, Dimensionless ) => ApparentPower = - (_, _, _) => + (_, _, _, _) => throw new InvalidRequestException( "Evcs model cannot be run without secondary data." ) @@ -238,8 +297,10 @@ protected trait EvcsAgentFundamentals * [[edu.ie3.simona.ontology.messages.SchedulerMessage.Completion]] to * scheduler and using update result values.

* - * @param collectionStateData - * State data with collected, comprehensive secondary data. + * @param baseStateData + * The base state data with collected secondary data + * @param lastModelState + * Last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -248,40 +309,35 @@ protected trait EvcsAgentFundamentals * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPower], + baseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ], + lastModelState: EvcsState, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { - - collectionStateData.baseStateData match { - case modelBaseStateData: ParticipantModelBaseStateData[ - ApparentPower, - EvcsRelevantData, - EvcsModel - ] => - /* extract EV data from secondary data, which should have been requested and received before */ - collectionStateData.data.values - .collectFirst { - // filter secondary data for arriving EVs data - case Some(arrivingEvs: ArrivingEvsData) => - handleArrivingEvsAndGoIdle( - currentTick, - scheduler, - modelBaseStateData, - arrivingEvs.arrivals - ) - } - .getOrElse( - throw new InconsistentStateException( - s"The model ${modelBaseStateData.model} was not provided with needed EV data." - ) + /* extract EV data from secondary data, which should have been requested and received before */ + baseStateData.receivedSecondaryDataStore + .getOrElse(currentTick, Map.empty) + .values + .collectFirst { + // filter secondary data for arriving EVs data + case _: ArrivingEvsData => + handleArrivingEvsAndGoIdle( + currentTick, + scheduler, + baseStateData ) - - case _ => + } + .getOrElse( throw new InconsistentStateException( - "Cannot find a model for model calculation." + s"The model ${baseStateData.model} was not provided with needed EV data." ) - } + ) + } /** Returns the number of free parking lots based on the last available state @@ -294,23 +350,22 @@ protected trait EvcsAgentFundamentals protected def handleFreeLotsRequest( tick: Long, modelBaseStateData: ParticipantModelBaseStateData[ - _ <: ApparentPower, - _, - _ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel ] ): Unit = { val evServiceRef = getService[ActorEvMovementsService]( modelBaseStateData.services ) - val (_, lastEvs) = - getTickIntervalAndLastEvs(tick, modelBaseStateData) - - val evcsModel = getEvcsModel(modelBaseStateData) + val lastState = + getLastOrInitialStateData(modelBaseStateData, tick - 1) evServiceRef ! FreeLotsResponse( - evcsModel.uuid, - evcsModel.chargingPoints - lastEvs.size + modelBaseStateData.model.uuid, + modelBaseStateData.model.chargingPoints - lastState.evs.size ) } @@ -320,266 +375,444 @@ protected trait EvcsAgentFundamentals * * @param tick * The current simulation tick - * @param modelBaseStateData + * @param baseStateData * The current Base state data * @param requestedDepartingEvs * The UUIDs of EVs that are requested to be returned */ protected def handleDepartingEvsRequest( tick: Long, - modelBaseStateData: ParticipantModelBaseStateData[ + requestedDepartingEvs: Seq[UUID], + baseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel - ], - requestedDepartingEvs: Seq[UUID] + ] ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ] = { - val evServiceRef = getService[ActorEvMovementsService]( - modelBaseStateData.services + baseStateData.services ) - // retrieve the last updated set of parked EVs - val (tickInterval, lastEvs) = - getTickIntervalAndLastEvs(tick, modelBaseStateData) + // we don't take the state at the current tick, since + // that one cannot contain the departing EVs anymore + val lastState = baseStateData.stateDataStore + .last(tick - 1) + .map { case (_, lastState) => + lastState + } + .getOrElse( + throw new InvalidRequestException( + s"Cannot return departing EVs from EVCS ${baseStateData.modelUuid} since we have no parked EVs" + ) + ) - validateDepartures(lastEvs, requestedDepartingEvs) + baseStateData.model.validateDepartures(lastState.evs, requestedDepartingEvs) - val evcsModel = getEvcsModel(modelBaseStateData) + val updatedEvs = baseStateData.model.applySchedule( + lastState, + tick + ) - val voltage = - getAndCheckNodalVoltage(modelBaseStateData, tick) + val (departingEvs, stayingEvs) = updatedEvs.partition { ev => + requestedDepartingEvs.contains(ev.uuid) + } - // calculate power with evs that have been parked up until now - val relevantData = - EvcsRelevantData( - tickInterval, - lastEvs + // send back departing EVs + if (requestedDepartingEvs.nonEmpty) { + evServiceRef ! DepartingEvsResponse( + baseStateData.modelUuid, + departingEvs ) + } + + val voltage = baseStateData.voltageValueStore + .last(tick) + .map { case (_, voltage) => + voltage + } + .getOrElse(Each(1d)) - val (result, evModelsCalculated) = - evcsModel.calculatePowerAndEvSoc( + /* Calculate evcs power for interval since last update, save for updating value store, and inform listeners */ + val updatedResultValueStore = + determineResultsAnnounceUpdateValueStore( + lastState, tick, voltage, - relevantData + baseStateData ) - val (departingEvs, stayingEvs) = - evModelsCalculated.partition { ev => - // EV has been parked up until now and is now departing - requestedDepartingEvs.contains(ev.getUuid) - } - - val updatedRelevantData = relevantData.copy( - currentEvs = stayingEvs - ) - - if (departingEvs.nonEmpty) { - evServiceRef ! DepartingEvsResponse( - evcsModel.uuid, - departingEvs - ) + val stayingSchedules = lastState.schedule.flatMap { + case (ev, maybeSchedule) if !requestedDepartingEvs.contains(ev.uuid) => + Some( + ev -> maybeSchedule.map(scheduleContainer => + scheduleContainer.copy(schedule = + scheduleContainer.schedule.filter(_.tickStop >= tick) + // filter(_.tickStop > currentTick) + // TODO is it possible to remove also the schedules that ended at currentTick? -> probably yes, test required + ) + ) + ) + case _ => None } - /* Update the base state data */ - updateValueStoresInformListeners( - modelBaseStateData, - tick, - AccompaniedSimulationResult(result), - updatedRelevantData + val newState = EvcsState(stayingEvs, stayingSchedules, tick) + + baseStateData.copy( + stateDataStore = ValueStore.updateValueStore( + baseStateData.stateDataStore, + tick, + newState + ), + resultValueStore = updatedResultValueStore ) } - /** Handles EV arrivals as part of ExtEvDataService secondary data. After - * adding the arriving EVs to the set of staying evs, resulting charging - * power is calculated. A completion message is sent to scheduler without - * scheduling new activations. + /** Handles a evcs movements message that contains information on arriving and + * departing vehicles. After applying the movements to the last known set of + * parked evs, returns departing evs and calculates new scheduling. Sends + * completion message to scheduler without scheduling new activations. FIXME + * scaladoc * - * @param tick + * @param currentTick * The current tick that has been triggered * @param scheduler * The scheduler ref * @param modelBaseStateData * The state data - * @param arrivingEvs - * The movement data on arrivingEvs that has been received * @return - * [[Idle]] with updated result values + * [[Idle]] with updated relevant data store */ private def handleArrivingEvsAndGoIdle( - tick: Long, + currentTick: Long, scheduler: ActorRef, modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel - ], - arrivingEvs: Seq[EvModel] + ] ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { - val evcsModel = getEvcsModel(modelBaseStateData) + val relevantData = + createCalcRelevantData(modelBaseStateData, currentTick) - // retrieve the last updated set of parked EVs, which could stem from - // the current tick if there were departures for this tick as well - val (tickInterval, lastEvs) = - getTickIntervalAndLastEvs(tick, modelBaseStateData) + val lastState = getLastOrInitialStateData(modelBaseStateData, currentTick) - validateArrivals(lastEvs, arrivingEvs, evcsModel.chargingPoints) + val currentEvs = modelBaseStateData.model.determineCurrentState( + relevantData, + lastState + ) - val relevantData = - EvcsRelevantData( - tickInterval, - lastEvs + // if new EVs arrived, a new scheduling must be calculated. + val newSchedule = modelBaseStateData.model + .calculateNewScheduling( + relevantData, + currentEvs ) - val updatedStateData = - if (tickInterval > 0) { - // if we haven't had any departing EVs for this tick, - // this also means that we have not caught up with - // calculating the current SOC - - val voltage = - getAndCheckNodalVoltage(modelBaseStateData, tick) - - // calculate power with evs that have been parked up until now - val (result, evModelsCalculated) = - evcsModel.calculatePowerAndEvSoc( - tick, - voltage, - relevantData - ) + // create new current state + val newState = EvcsState(currentEvs, newSchedule, currentTick) - val updatedRelevantData = relevantData.copy( - currentEvs = evModelsCalculated ++ arrivingEvs - ) + val updatedStateDataStore = + ValueStore.updateValueStore( + modelBaseStateData.stateDataStore, + currentTick, + newState + ) - updateValueStoresInformListeners( - modelBaseStateData, - tick, - AccompaniedSimulationResult(result), - updatedRelevantData - ) - } else { - // if some EVs were departing at the current tick, - // we're already up-to-date in that regard + /* Update the base state data with the updated result value store and relevant data store */ + val updatedBaseStateData = + modelBaseStateData.copy( + stateDataStore = updatedStateDataStore + ) + + // FIXME no completion anymore with flex + goToIdleReplyCompletionAndScheduleTriggerForNextAction( + updatedBaseStateData, + scheduler + ) + } - val updatedRelevantData = relevantData.copy( - currentEvs = lastEvs ++ arrivingEvs + /** Determine a reply on a + * [[edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage]] + * by looking up the detailed simulation results, averaging them and + * returning the equivalent state transition. + * + * @param requestTick + * The tick, the request belongs to + * @param baseStateData + * Base state data + * @param mostRecentRequest + * The request reply, that most recently has been sent + * @param nodalVoltage + * Current nodal voltage + * @param updatedVoltageValueStore + * Value store with updated nodal voltages + * @param alternativeResult + * Alternative result to use, if no reasonable result can be obtained + * @return + * Matching state transition + */ + override def determineReply( + requestTick: Long, + baseStateData: BaseStateData[ApparentPower], + mostRecentRequest: Option[(Long, ApparentPower)], + nodalVoltage: squants.Dimensionless, + updatedVoltageValueStore: ValueStore[squants.Dimensionless], + alternativeResult: ApparentPower + ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { + /* No fast reply possible --> Some calculations have to be made */ + mostRecentRequest match { + case Some((lastRequestTick, _)) if lastRequestTick > requestTick => + throw new InvalidRequestException( + "Got a request for a tick, whereas a later tick already has been answered. This behaviour is not yet specified!" ) + case Some((lastRequestTick, lastResult)) + if lastRequestTick == requestTick => + /* Repetitive request for the same tick, but with different voltage */ + baseStateData match { + case modelBaseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ] => + /* Active power is yet calculated, but reactive power needs update */ + val nextReactivePower = modelBaseStateData.model + .calculateReactivePower(lastResult.p, nodalVoltage) + + /* Determine the reply, based new circumstances */ + val updatedRequestValueStore = + ValueStore.updateValueStore( + baseStateData.requestValueStore, + requestTick, + lastResult.withReactivePower(nextReactivePower) + ) - val updatedRelevantDataStore = - ValueStore.updateValueStore( - modelBaseStateData.calcRelevantDateStore, - tick, - updatedRelevantData - ) + val nextStateData = + modelBaseStateData.copy( + requestValueStore = updatedRequestValueStore, + voltageValueStore = updatedVoltageValueStore + ) - modelBaseStateData.copy( - calcRelevantDateStore = updatedRelevantDataStore - ) - } + stay() using nextStateData replying AssetPowerChangedMessage( + lastResult.p, + nextReactivePower + ) + case unexpectedStateData => + throw new IllegalStateException( + s"The request reply should not be re-calculated for state data '$unexpectedStateData'" + ) + } - goToIdleReplyCompletionAndScheduleTriggerForNextAction( - updatedStateData, - scheduler - ) + case _ => + /* There hasn't been a request for this tick, yet. Check, if there are simulation results. If at least one + * is apparent, average them and answer the request. If no simulation results is apparent at all, reply with + * zero power, although this case should have been handled earlier */ + + /* ADDED: Update base state data before answering the power request to include the scheduling up to this tick. + * Also, save the new voltage information for the calc relevant data store. + */ + val updatedBaseStateData = + baseStateData match { + case modelBaseStateData: ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ] => + // FIXME this is still incomplete ? + + val lastState = + getLastOrInitialStateData(modelBaseStateData, requestTick) + + val voltage = modelBaseStateData.voltageValueStore + .last(requestTick) + .map { case (_, voltage) => + voltage + } + .getOrElse( + Each(1d) + ) + + val updatedResultValueStore = + determineResultsAnnounceUpdateValueStore( + lastState, + requestTick, + voltage, + modelBaseStateData + ) + + modelBaseStateData.copy( + resultValueStore = updatedResultValueStore + ) + + case unexpectedStateData => + throw new IllegalStateException( + s"Unexpected state data '$unexpectedStateData'" + ) + } + + getRelevantResultData( + requestTick, + updatedBaseStateData.resultValueStore, + updatedBaseStateData.requestValueStore + ) match { + case Some(relevantData) => + /* There is at least one relevant simulation result apparent, which might also be the most recent one + * before the last request. But this is still the most recent one considered being valid. */ + averagePowerAndStay( + updatedBaseStateData, + relevantData, + requestTick, + nodalVoltage, + updatedVoltageValueStore, + alternativeResult + ) + case None => + /* There is no simulation result at all. Reply with zero power */ + stayWithUpdatedRequestValueStore( + updatedBaseStateData, + alternativeResult, + requestTick, + updatedVoltageValueStore + ) + } + } } - /** Update the result and calc relevant data value stores and inform all - * registered listeners + /** Speciality with EVCS: result are always calculated up until the current + * tick. Thus, the result received as a parameter is discarded. * * @param baseStateData - * The base state data of the collection state - * @param tick - * The current tick + * The base state data * @param result - * Result of simulation - * @param relevantData - * Data, that have been relevant to this calculation + * Is ignored here, result up until this tick are calculated + * @param currentTick + * the current tick * @return - * Desired state change + * updated base state data */ - private final def updateValueStoresInformListeners( + override def handleCalculatedResult( baseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ], - tick: Long, - result: AccompaniedSimulationResult[ApparentPower], - relevantData: EvcsRelevantData + result: ApparentPower, + currentTick: Long ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, + EvcsState, EvcsModel ] = { - /* Update the value stores */ - val updatedValueStore = - ValueStore.updateValueStore( - baseStateData.resultValueStore, - tick, - result.primaryData - ) - val updatedRelevantDataStore = - ValueStore.updateValueStore( - baseStateData.calcRelevantDateStore, - tick, - relevantData - ) - /* Inform the listeners about new result */ - announceSimulationResult( - baseStateData, - tick, - result - )(baseStateData.outputConfig) + // calculate results from last schedule + baseStateData.stateDataStore + .last(currentTick - 1) + .map { case (lastTick, lastState) => + baseStateData.resultValueStore.get(lastTick) match { + case Some(_) => + // We already have a result for this tick, likely + // because EVs already departed at this tick. + // Thus, skip recalculating and sending out results. + baseStateData + case None => + val voltage = baseStateData.voltageValueStore + .last(currentTick - 1) + .map { case (_, voltage) => + voltage + } + .getOrElse( + Each(1d) + ) + + val updatedResultValueStore = + determineResultsAnnounceUpdateValueStore( + lastState, + currentTick, + voltage, + baseStateData + ) + + baseStateData.copy( + resultValueStore = updatedResultValueStore + ): ParticipantModelBaseStateData[ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel + ] + } + } + .getOrElse(baseStateData) - /* Update the base state data */ - baseStateData.copy( - resultValueStore = updatedValueStore, - calcRelevantDateStore = updatedRelevantDataStore - ) } - private def getTickIntervalAndLastEvs( + /** Determine evcs results, announce them to listeners and update the result + * value store. + * + * @param lastState + * The state (including schedule) to calculate results for + * @param currentTick + * The tick up to which results should be calculated for + * @param voltage + * The voltage magnitude used for reactive power calculation + * @param modelBaseStateData + * Model base state data + * @return + * The updated result value store + */ + private def determineResultsAnnounceUpdateValueStore( + lastState: EvcsState, currentTick: Long, + voltage: squants.Dimensionless, modelBaseStateData: ParticipantModelBaseStateData[ - _ <: ApparentPower, - _, - _ + ApparentPower, + EvcsRelevantData, + EvcsState, + EvcsModel ] - ): (Long, Set[EvModel]) = { - modelBaseStateData.calcRelevantDateStore - .last(currentTick) match { - case Some((tick, EvcsRelevantData(_, evs))) => - (currentTick - tick, evs) - case _ => - /* At the first tick, we are not able to determine the tick interval from last tick - * (since there is none). Then we use a fall back ev stem distance. - * As no evs are charging then, the tick interval should be ignored anyway. */ - (FALLBACK_EV_MOVEMENTS_STEM_DISTANCE, Set.empty[EvModel]) + ): ValueStore[ApparentPower] = { + + val (evResults, evcsResults) = modelBaseStateData.model.createResults( + lastState, + currentTick, + voltage + ) + + // send out EV results + evResults.foreach { result => + listener.foreach(_ ! ParticipantResultEvent(result)) } - } - private def getEvcsModel( - modelBaseStateData: ParticipantModelBaseStateData[ - _ <: ApparentPower, - _, - _ - ] - ): EvcsModel = - modelBaseStateData.model match { - case model: EvcsModel => - model - case unsupportedModel => - throw new InconsistentStateException( - s"Wrong model: $unsupportedModel!" + evcsResults.foldLeft(modelBaseStateData.resultValueStore) { + case (resultValueStore, result) => + /* Inform the listeners about new result */ + if (modelBaseStateData.outputConfig.simulationResultInfo) + notifyListener( + ParticipantResultEvent(result) + ) + + /* Update resultValueStore with result */ + ValueStore.updateValueStore( + resultValueStore, + result.getTime.toTick(modelBaseStateData.startDate), + ApparentPower( + Megawatts(result.getP.to(MEGAWATT).getValue.doubleValue), + Megavars(result.getQ.to(MEGAVAR).getValue.doubleValue) + ) ) } + } /** Determines the correct result. * @@ -604,58 +837,27 @@ protected trait EvcsAgentFundamentals result.q.toMegavars.asMegaVar ) - /** Checks whether requested departing EVs are consistent with currently - * connected EVs. Only logs warnings, does not throw exceptions. + /** Update the last known model state with the given external, relevant data * - * @param lastEvs - * EVs of the last tick - * @param departures - * Departing EVs at the current tick - */ - protected def validateDepartures( - lastEvs: Set[EvModel], - departures: Seq[UUID] - ): Unit = { - departures.foreach { ev => - if (!lastEvs.exists(_.getUuid == ev)) - logger.warn( - s"EV $ev should depart from this station (according to external simulation), but has not been parked here." - ) - } - } - - /** Checks whether provided arriving EVs are consistent with charging station - * specifications and currently connected EVs. Only logs warnings, does not - * throw exceptions. - * - * @param lastEvs - * EVs of the last tick - * @param arrivals - * Arriving EVs at the current tick - * @param chargingPoints - * max number of charging points available at this CS + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data */ - protected def validateArrivals( - lastEvs: Set[EvModel], - arrivals: Seq[EvModel], - chargingPoints: Int - ): Unit = { - - arrivals.foreach { ev => - if (lastEvs.exists(_.getUuid == ev.getUuid)) - logger.warn( - s"EV ${ev.getId} should arrive at this station (according to external simulation), but is already parked here." - ) - } - - val newCount = lastEvs.size + - arrivals.count { ev => - !lastEvs.exists(_.getUuid == ev.getUuid) - } - - if (newCount > chargingPoints) - logger.warn( - "More EVs are parking at this station than physically possible." - ) - } + override protected def updateState( + tick: Long, + modelState: EvcsState, + calcRelevantData: EvcsRelevantData, + nodalVoltage: squants.Dimensionless, + model: EvcsModel + ): EvcsState = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index a804bd5671..159b2555d2 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.participant.hp -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.datamodel.models.result.system.{ HpResult, @@ -19,14 +18,16 @@ import edu.ie3.simona.agent.participant.data.Data import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHeat import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.hp.HpAgent.neededServices -import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData +import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ + FlexControlledData, + ParticipantModelBaseStateData +} import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ InputModelContainer, WithHeatInputContainer } import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, - DataCollectionStateData, ParticipantStateData } import edu.ie3.simona.agent.state.AgentState @@ -39,16 +40,23 @@ import edu.ie3.simona.exceptions.agent.{ InvalidRequestException } import edu.ie3.simona.io.result.AccompaniedSimulationResult -import edu.ie3.simona.model.participant.HpModel import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} +import edu.ie3.simona.model.participant.{FlexChangeIndicator, HpModel} import edu.ie3.simona.model.thermal.ThermalGrid +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ + FlexRequest, + FlexResponse +} import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData -import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.quantities.PowerSystemUnits.PU +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} +import org.apache.pekko.actor.{ActorRef, FSM} import squants.energy.Megawatts +import squants.thermal.Celsius import squants.{Dimensionless, Each, Power} -import tech.units.indriya.quantity.Quantities import java.time.ZonedDateTime import java.util.UUID @@ -59,6 +67,7 @@ trait HpAgentFundamentals extends ParticipantAgentFundamentals[ ApparentPowerAndHeat, HpRelevantData, + HpState, ParticipantStateData[ApparentPowerAndHeat], HpInput, HpRuntimeConfig, @@ -82,15 +91,102 @@ trait HpAgentFundamentals BaseStateData.ParticipantModelBaseStateData[ ApparentPowerAndHeat, HpRelevantData, + HpState, HpModel ], + HpState, Dimensionless ) => ApparentPowerAndHeat = - (_, _, _) => + (_, _, _, _) => throw new InvalidRequestException( - "HP model cannot be run without secondary data." + "Heat pump model cannot be run without secondary data." ) + override protected def createInitialState( + baseStateData: BaseStateData.ParticipantModelBaseStateData[ + ApparentPowerAndHeat, + HpRelevantData, + HpState, + HpModel + ] + ): HpState = startingState(baseStateData.model.thermalGrid) + + private def startingState( + thermalGrid: ThermalGrid + ): HpState = HpState( + isRunning = false, + -1, + Celsius(10d), // TODO + Megawatts(0d), + Megawatts(0d), + ThermalGrid.startingState(thermalGrid), + None + ) + + /** Handle an active power change by flex control. + * @param tick + * Tick, in which control is issued + * @param baseStateData + * Base state data of the agent + * @param data + * Calculation relevant data + * @param lastState + * Last known model state + * @param setPower + * Setpoint active power + * @return + * Updated model state, a result model and a [[FlexChangeIndicator]] + */ + def handleControlledPowerChange( + tick: Long, + baseStateData: ParticipantModelBaseStateData[ + ApparentPowerAndHeat, + HpRelevantData, + HpState, + HpModel + ], + data: HpRelevantData, + lastState: HpState, + setPower: squants.Power + ): (HpState, ApparentPowerAndHeat, FlexChangeIndicator) = { + /* Determine needed information */ + val voltage = + getAndCheckNodalVoltage(baseStateData, tick) + val relevantData = createCalcRelevantData(baseStateData, tick) + + val modelState = baseStateData.stateDataStore.last(tick) match { + case Some((lastTick, _)) if lastTick == tick => + /* We already updated the state for this tick, take the one before */ + baseStateData.stateDataStore.last(tick - 1) match { + case Some((_, earlierModelState)) => earlierModelState + case None => + throw new InconsistentStateException( + s"Unable to get state for heat pump '${baseStateData.model.getUuid}' in tick ${tick - 1}." + ) + } + case Some((_, lastModelState)) => + lastModelState + case None => + throw new InconsistentStateException( + s"Unable to get state for heat pump '${baseStateData.model.getUuid}' in tick $tick." + ) + } + + /* Handle the control request */ + val (updatedState, flexChangeIndicator) = baseStateData.model + .handleControlledPowerChange(relevantData, modelState, setPower) + + /* Calculate power results */ + val result = baseStateData.model.calculatePower( + tick, + voltage, + updatedState, + relevantData + ) + + (updatedState, result, flexChangeIndicator) + } + /** Abstractly calculate the power output of the participant utilising * secondary data. However, it might appear, that not the complete set of * secondary data is available for the given tick. This might especially be @@ -102,8 +198,10 @@ trait HpAgentFundamentals * scheduler and using update result values.

Actual implementation * can be found in each participant's fundamentals.

* - * @param collectionStateData + * @param baseStateData * State data with collected secondary data. + * @param lastModelState + * Optional last model state * @param currentTick * Tick, the trigger belongs to * @param scheduler @@ -112,86 +210,82 @@ trait HpAgentFundamentals * [[Idle]] with updated result values */ override def calculatePowerWithSecondaryDataAndGoToIdle( - collectionStateData: DataCollectionStateData[ApparentPowerAndHeat], + baseStateData: BaseStateData.ParticipantModelBaseStateData[ + ApparentPowerAndHeat, + HpRelevantData, + HpState, + HpModel + ], + lastModelState: HpState, currentTick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPowerAndHeat]] = { - val voltage = - getAndCheckNodalVoltage(collectionStateData.baseStateData, currentTick) - - val (result, relevantData) = - collectionStateData.baseStateData match { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.model match { - case hpModel: HpModel => - /* extract weather data from secondary data, which should have been requested and received before */ - val weatherData = - collectionStateData.data - .collectFirst { - // filter secondary data for weather data - case (_, Some(data: WeatherData)) => data - } - .getOrElse( - throw new InconsistentStateException( - s"The model ${modelBaseStateData.model} was not provided with needed weather data." - ) - ) - - /* Try to get the last calc relevant data. It contains the hp state after the last calculation. If no data - * can be found, this is the first calculation step and therefore define starting state. */ - val hpState = modelBaseStateData.calcRelevantDateStore.last( - currentTick - ) match { - case Some((_, HpRelevantData(lastState, _, _))) => lastState - case None => - startingState(hpModel.thermalGrid) - } - - val relevantData = - HpRelevantData( - hpState, - currentTick, - weatherData.temp - ) - val power = hpModel.calculatePower( - currentTick, - voltage, - relevantData - ) + /* Determine needed information */ + val voltage = + getAndCheckNodalVoltage(baseStateData, currentTick) + val relevantData = createCalcRelevantData(baseStateData, currentTick) - val accompanyingResults = hpModel.thermalGrid.results( - relevantData.hpState.thermalGridState - )(modelBaseStateData.startDate) + /* Determine the next state */ + val updatedState = + updateState( + currentTick, + lastModelState, + relevantData, + voltage, + baseStateData.model + ) - ( - AccompaniedSimulationResult(power, accompanyingResults), - relevantData - ) - case _ => - throw new InconsistentStateException( - "Cannot find a model for model calculation." - ) - } - } + /* Calculate power results */ + val power = baseStateData.model.calculatePower( + currentTick, + voltage, + updatedState, + relevantData + ) + val accompanyingResults = baseStateData.model.thermalGrid.results( + lastModelState.thermalGridState + )(baseStateData.startDate) + val result = AccompaniedSimulationResult(power, accompanyingResults) + val updatedStateDataStore = ValueStore.updateValueStore( + baseStateData.stateDataStore, + currentTick, + updatedState + ) + val updatedBaseStateData = + baseStateData.copy(stateDataStore = updatedStateDataStore) updateValueStoresInformListenersAndGoToIdleWithUpdatedBaseStateData( scheduler, - collectionStateData.baseStateData, + updatedBaseStateData, result, relevantData ) } - private def startingState( - thermalGrid: ThermalGrid - ): HpState = HpState( - isRunning = false, - -1, - Megawatts(0d), - Megawatts(0d), - ThermalGrid.startingState(thermalGrid) - ) + /** Update the last known model state with the given external, relevant data + * + * @param tick + * Tick to update state for + * @param modelState + * Last known model state + * @param calcRelevantData + * Data, relevant for calculation + * @param nodalVoltage + * Current nodal voltage of the agent + * @param model + * Model for calculation + * @return + * The updated state at given tick under consideration of calculation + * relevant data + */ + protected override def updateState( + tick: Long, + modelState: HpState, + calcRelevantData: HpRelevantData, + nodalVoltage: squants.Dimensionless, + model: HpModel + ): HpState = model.calculateNextState(modelState, calcRelevantData) /** Abstract definition, individual implementations found in individual agent * fundamental classes @@ -204,10 +298,12 @@ trait HpAgentFundamentals simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, + maybeEmAgent: Option[TypedActorRef[FlexResponse]] ): BaseStateData.ParticipantModelBaseStateData[ ApparentPowerAndHeat, HpRelevantData, + HpState, HpModel ] = { if (!services.exists(_.map(_.getClass).containsSlice(neededServices))) @@ -224,9 +320,19 @@ trait HpAgentFundamentals simulationStartDate, simulationEndDate ) + + /* Determine a proper starting model state and safe it into the base state data */ + val startingModelState = startingState(model.thermalGrid) + val stateDataStore = ValueStore.updateValueStore( + ValueStore(resolution), + -1L, + startingModelState + ) + ParticipantModelBaseStateData[ ApparentPowerAndHeat, HpRelevantData, + HpState, HpModel ]( simulationStartDate, @@ -244,12 +350,14 @@ trait HpAgentFundamentals .getvTarget() .to(PU) .getValue - .doubleValue() + .doubleValue ) ), ValueStore(resolution), ValueStore(resolution), - ValueStore(resolution) + ValueStore(resolution), + stateDataStore, + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) ) case unsupported => throw new AgentInitializationException( @@ -259,6 +367,44 @@ trait HpAgentFundamentals } } + override protected def createCalcRelevantData( + baseStateData: BaseStateData.ParticipantModelBaseStateData[ + ApparentPowerAndHeat, + HpRelevantData, + HpState, + HpModel + ], + tick: Long + ): HpRelevantData = { + /* extract weather data from secondary data, which should have been requested and received before */ + val weatherData = + baseStateData.receivedSecondaryDataStore + .last(tick) + .flatMap { case (receivedTick, receivedValues) => + // FIXME: This fallback should check if the activation comes from an internal event. Only then it's valid to + // take previously received values + if (receivedTick != tick) + log.debug( + s"The model ${baseStateData.model.getUuid} needs to do calculations with values received " + + s"in tick $receivedTick, as no weather data has been received in tick $tick." + ) + receivedValues.collectFirst { + // filter secondary data for weather data + case (_, data: WeatherData) => data + } + } + .getOrElse( + throw new InconsistentStateException( + s"The model ${baseStateData.model} was not provided with needed weather data." + ) + ) + + HpRelevantData( + tick, + weatherData.temp.inKelvin + ) + } + /** Abstract method to build the calculation model from input * * @param inputModel @@ -339,8 +485,8 @@ trait HpAgentFundamentals ): SystemParticipantResult = new HpResult( dateTime, uuid, - Quantities.getQuantity(result.p.toKilowatts, PowerSystemUnits.KILOWATT), - Quantities.getQuantity(result.q.toKilovars, PowerSystemUnits.KILOVAR), - Quantities.getQuantity(result.qDot.toKilowatts, PowerSystemUnits.KILOWATT) + result.p.toMegawatts.asMegaWatt, + result.q.toMegavars.asMegaVar, + result.qDot.toMegawatts.asMegaWatt ) } diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 14426ecfef..3bc7b13b79 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,2734 +1,1451 @@ -/* - * © 2024. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ +// generated by tscfg 1.0.0 on Thu Jan 25 13:15:53 CET 2024 +// source: src/main/resources/config/config-template.conf package edu.ie3.simona.config final case class SimonaConfig( - simona: SimonaConfig.Simona + simona : SimonaConfig.Simona ) object SimonaConfig { final case class BaseCsvParams( - override val csvSep: java.lang.String, - override val directoryPath: java.lang.String, - override val isHierarchic: scala.Boolean - ) extends CsvParams(csvSep, directoryPath, isHierarchic) + override val csvSep : java.lang.String, + override val directoryPath : java.lang.String, + override val isHierarchic : scala.Boolean + ) extends CsvParams(csvSep,directoryPath,isHierarchic) object BaseCsvParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.BaseCsvParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseCsvParams = { SimonaConfig.BaseCsvParams( csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = - $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - sealed abstract class BaseOutputConfig( - val notifier: java.lang.String, - val simulationResult: scala.Boolean + + sealed abstract class BaseOutputConfig ( + val notifier : java.lang.String, + val simulationResult : scala.Boolean ) - - sealed abstract class BaseRuntimeConfig( - val calculateMissingReactivePowerWithModel: scala.Boolean, - val scaling: scala.Double, - val uuids: scala.List[java.lang.String] + + sealed abstract class BaseRuntimeConfig ( + val calculateMissingReactivePowerWithModel : scala.Boolean, + val scaling : scala.Double, + val uuids : scala.List[java.lang.String] ) extends java.io.Serializable - - sealed abstract class CsvParams( - val csvSep: java.lang.String, - val directoryPath: java.lang.String, - val isHierarchic: scala.Boolean + + sealed abstract class CsvParams ( + val csvSep : java.lang.String, + val directoryPath : java.lang.String, + val isHierarchic : scala.Boolean ) - + final case class EvcsRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String], + chargingStrategy : java.lang.String, + lowestEvSoc : scala.Double + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object EvcsRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.EvcsRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.EvcsRuntimeConfig = { SimonaConfig.EvcsRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + chargingStrategy = if(c.hasPathOrNull("chargingStrategy")) c.getString("chargingStrategy") else "maxPower", + lowestEvSoc = if(c.hasPathOrNull("lowestEvSoc")) c.getDouble("lowestEvSoc") else 0.2, + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class FixedFeedInRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object FixedFeedInRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.FixedFeedInRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.FixedFeedInRuntimeConfig = { SimonaConfig.FixedFeedInRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class GridOutputConfig( - lines: scala.Boolean, - nodes: scala.Boolean, - notifier: java.lang.String, - switches: scala.Boolean, - transformers2w: scala.Boolean, - transformers3w: scala.Boolean + lines : scala.Boolean, + nodes : scala.Boolean, + notifier : java.lang.String, + switches : scala.Boolean, + transformers2w : scala.Boolean, + transformers3w : scala.Boolean ) object GridOutputConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.GridOutputConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.GridOutputConfig = { SimonaConfig.GridOutputConfig( - lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), - nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), - transformers2w = - c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), - transformers3w = - c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") + lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), + nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), + transformers2w = c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), + transformers3w = c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class HpRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object HpRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.HpRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.HpRuntimeConfig = { SimonaConfig.HpRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - sealed abstract class KafkaParams( - val bootstrapServers: java.lang.String, - val linger: scala.Int, - val runId: java.lang.String, - val schemaRegistryUrl: java.lang.String + + sealed abstract class KafkaParams ( + val bootstrapServers : java.lang.String, + val linger : scala.Int, + val runId : java.lang.String, + val schemaRegistryUrl : java.lang.String ) - + final case class LoadRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String], - modelBehaviour: java.lang.String, - reference: java.lang.String - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String], + modelBehaviour : java.lang.String, + reference : java.lang.String + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object LoadRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.LoadRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.LoadRuntimeConfig = { SimonaConfig.LoadRuntimeConfig( - modelBehaviour = - $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), - reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + modelBehaviour = $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), + reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class ParticipantBaseOutputConfig( - override val notifier: java.lang.String, - override val simulationResult: scala.Boolean, - flexResult: scala.Boolean, - powerRequestReply: scala.Boolean - ) extends BaseOutputConfig(notifier, simulationResult) + override val notifier : java.lang.String, + override val simulationResult : scala.Boolean, + flexResult : scala.Boolean, + powerRequestReply : scala.Boolean + ) extends BaseOutputConfig(notifier,simulationResult) object ParticipantBaseOutputConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.ParticipantBaseOutputConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.ParticipantBaseOutputConfig = { SimonaConfig.ParticipantBaseOutputConfig( - flexResult = - c.hasPathOrNull("flexResult") && c.getBoolean("flexResult"), - powerRequestReply = - $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - simulationResult = - $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + flexResult = c.hasPathOrNull("flexResult") && c.getBoolean("flexResult"), + powerRequestReply = $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PrimaryDataCsvParams( - override val csvSep: java.lang.String, - override val directoryPath: java.lang.String, - override val isHierarchic: scala.Boolean, - timePattern: java.lang.String - ) extends CsvParams(csvSep, directoryPath, isHierarchic) + override val csvSep : java.lang.String, + override val directoryPath : java.lang.String, + override val isHierarchic : scala.Boolean, + timePattern : java.lang.String + ) extends CsvParams(csvSep,directoryPath,isHierarchic) object PrimaryDataCsvParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.PrimaryDataCsvParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PrimaryDataCsvParams = { SimonaConfig.PrimaryDataCsvParams( - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = - $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), + directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PvRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object PvRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.PvRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PvRuntimeConfig = { SimonaConfig.PvRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class RefSystemConfig( - gridIds: scala.Option[scala.List[java.lang.String]], - sNom: java.lang.String, - vNom: java.lang.String, - voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + gridIds : scala.Option[scala.List[java.lang.String]], + sNom : java.lang.String, + vNom : java.lang.String, + voltLvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object RefSystemConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.RefSystemConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RefSystemConfig = { SimonaConfig.RefSystemConfig( - gridIds = - if (c.hasPathOrNull("gridIds")) - scala.Some( - $_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator) - ) - else None, - sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), - vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), - voltLvls = - if (c.hasPathOrNull("voltLvls")) - scala.Some( - $_LSimonaConfig_VoltLvlConfig( - c.getList("voltLvls"), - parentPath, - $tsCfgValidator - ) - ) - else None + gridIds = if(c.hasPathOrNull("gridIds")) scala.Some($_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator)) else None, + sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), + vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), + voltLvls = if(c.hasPathOrNull("voltLvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("voltLvls"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_VoltLvlConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.VoltLvlConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class ResultKafkaParams( - override val bootstrapServers: java.lang.String, - override val linger: scala.Int, - override val runId: java.lang.String, - override val schemaRegistryUrl: java.lang.String, - topicNodeRes: java.lang.String - ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) + override val bootstrapServers : java.lang.String, + override val linger : scala.Int, + override val runId : java.lang.String, + override val schemaRegistryUrl : java.lang.String, + topicNodeRes : java.lang.String + ) extends KafkaParams(bootstrapServers,linger,runId,schemaRegistryUrl) object ResultKafkaParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.ResultKafkaParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.ResultKafkaParams = { SimonaConfig.ResultKafkaParams( topicNodeRes = $_reqStr(parentPath, c, "topicNodeRes", $tsCfgValidator), - bootstrapServers = - $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), - linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), - runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), - schemaRegistryUrl = - $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + bootstrapServers = $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), + linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), + runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), + schemaRegistryUrl = $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class RuntimeKafkaParams( - override val bootstrapServers: java.lang.String, - override val linger: scala.Int, - override val runId: java.lang.String, - override val schemaRegistryUrl: java.lang.String, - topic: java.lang.String - ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) + override val bootstrapServers : java.lang.String, + override val linger : scala.Int, + override val runId : java.lang.String, + override val schemaRegistryUrl : java.lang.String, + topic : java.lang.String + ) extends KafkaParams(bootstrapServers,linger,runId,schemaRegistryUrl) object RuntimeKafkaParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.RuntimeKafkaParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RuntimeKafkaParams = { SimonaConfig.RuntimeKafkaParams( topic = $_reqStr(parentPath, c, "topic", $tsCfgValidator), - bootstrapServers = - $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), + bootstrapServers = $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), - schemaRegistryUrl = - $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + schemaRegistryUrl = $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SimpleOutputConfig( - override val notifier: java.lang.String, - override val simulationResult: scala.Boolean - ) extends BaseOutputConfig(notifier, simulationResult) + override val notifier : java.lang.String, + override val simulationResult : scala.Boolean + ) extends BaseOutputConfig(notifier,simulationResult) object SimpleOutputConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.SimpleOutputConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.SimpleOutputConfig = { SimonaConfig.SimpleOutputConfig( notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - simulationResult = - $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class VoltLvlConfig( - id: java.lang.String, - vNom: java.lang.String + id : java.lang.String, + vNom : java.lang.String ) object VoltLvlConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.VoltLvlConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.VoltLvlConfig = { SimonaConfig.VoltLvlConfig( - id = $_reqStr(parentPath, c, "id", $tsCfgValidator), + id = $_reqStr(parentPath, c, "id", $tsCfgValidator), vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class WecRuntimeConfig( - override val calculateMissingReactivePowerWithModel: scala.Boolean, - override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] - ) extends BaseRuntimeConfig( - calculateMissingReactivePowerWithModel, - scaling, - uuids - ) + override val calculateMissingReactivePowerWithModel : scala.Boolean, + override val scaling : scala.Double, + override val uuids : scala.List[java.lang.String] + ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) object WecRuntimeConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.WecRuntimeConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.WecRuntimeConfig = { SimonaConfig.WecRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln( - parentPath, - c, - "calculateMissingReactivePowerWithModel", - $tsCfgValidator - ), + calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Boolean = { + private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { if (c == null) false - else - try c.getBoolean(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else try c.getBoolean(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Simona( - event: SimonaConfig.Simona.Event, - gridConfig: SimonaConfig.Simona.GridConfig, - input: SimonaConfig.Simona.Input, - output: SimonaConfig.Simona.Output, - powerflow: SimonaConfig.Simona.Powerflow, - runtime: SimonaConfig.Simona.Runtime, - simulationName: java.lang.String, - time: SimonaConfig.Simona.Time + event : SimonaConfig.Simona.Event, + gridConfig : SimonaConfig.Simona.GridConfig, + input : SimonaConfig.Simona.Input, + output : SimonaConfig.Simona.Output, + powerflow : SimonaConfig.Simona.Powerflow, + runtime : SimonaConfig.Simona.Runtime, + simulationName : java.lang.String, + time : SimonaConfig.Simona.Time ) object Simona { final case class Event( - listener: scala.Option[ - scala.List[SimonaConfig.Simona.Event.Listener$Elm] - ] + listener : scala.Option[scala.List[SimonaConfig.Simona.Event.Listener$Elm]] ) object Event { final case class Listener$Elm( - eventsToProcess: scala.Option[scala.List[java.lang.String]], - fullClassPath: java.lang.String + eventsToProcess : scala.Option[scala.List[java.lang.String]], + fullClassPath : java.lang.String ) object Listener$Elm { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Event.Listener$Elm = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event.Listener$Elm = { SimonaConfig.Simona.Event.Listener$Elm( - eventsToProcess = - if (c.hasPathOrNull("eventsToProcess")) - scala.Some( - $_L$_str( - c.getList("eventsToProcess"), - parentPath, - $tsCfgValidator - ) - ) - else None, - fullClassPath = - $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) + eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, + fullClassPath = $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Event = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event = { SimonaConfig.Simona.Event( - listener = - if (c.hasPathOrNull("listener")) - scala.Some( - $_LSimonaConfig_Simona_Event_Listener$Elm( - c.getList("listener"), - parentPath, - $tsCfgValidator - ) - ) - else None + listener = if(c.hasPathOrNull("listener")) scala.Some($_LSimonaConfig_Simona_Event_Listener$Elm(c.getList("listener"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_Simona_Event_Listener$Elm( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { + private def $_LSimonaConfig_Simona_Event_Listener$Elm(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.Simona.Event.Listener$Elm( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.Simona.Event.Listener$Elm(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class GridConfig( - refSystems: scala.List[SimonaConfig.RefSystemConfig] + refSystems : scala.List[SimonaConfig.RefSystemConfig] ) object GridConfig { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.GridConfig = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.GridConfig = { SimonaConfig.Simona.GridConfig( - refSystems = $_LSimonaConfig_RefSystemConfig( - c.getList("refSystems"), - parentPath, - $tsCfgValidator - ) + refSystems = $_LSimonaConfig_RefSystemConfig(c.getList("refSystems"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_RefSystemConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.RefSystemConfig] = { + private def $_LSimonaConfig_RefSystemConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.RefSystemConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.RefSystemConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.RefSystemConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Input( - grid: SimonaConfig.Simona.Input.Grid, - primary: SimonaConfig.Simona.Input.Primary, - weather: SimonaConfig.Simona.Input.Weather + grid : SimonaConfig.Simona.Input.Grid, + primary : SimonaConfig.Simona.Input.Primary, + weather : SimonaConfig.Simona.Input.Weather ) object Input { final case class Grid( - datasource: SimonaConfig.Simona.Input.Grid.Datasource + datasource : SimonaConfig.Simona.Input.Grid.Datasource ) object Grid { final case class Datasource( - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - id: java.lang.String + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + id : java.lang.String ) object Datasource { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Grid.Datasource = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid.Datasource = { SimonaConfig.Simona.Input.Grid.Datasource( - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - id = $_reqStr(parentPath, c, "id", $tsCfgValidator) + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + id = $_reqStr(parentPath, c, "id", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Grid = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid = { SimonaConfig.Simona.Input.Grid( - datasource = SimonaConfig.Simona.Input.Grid.Datasource( - if (c.hasPathOrNull("datasource")) c.getConfig("datasource") - else - com.typesafe.config.ConfigFactory.parseString("datasource{}"), - parentPath + "datasource.", - $tsCfgValidator - ) + datasource = SimonaConfig.Simona.Input.Grid.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) ) } } - + final case class Primary( - couchbaseParams: scala.Option[ - SimonaConfig.Simona.Input.Primary.CouchbaseParams - ], - csvParams: scala.Option[SimonaConfig.PrimaryDataCsvParams], - influxDb1xParams: scala.Option[ - SimonaConfig.Simona.Input.Primary.InfluxDb1xParams - ], - sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] + couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Primary.CouchbaseParams], + csvParams : scala.Option[SimonaConfig.PrimaryDataCsvParams], + influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Primary.InfluxDb1xParams], + sqlParams : scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] ) object Primary { final case class CouchbaseParams( - bucketName: java.lang.String, - coordinateColumnName: java.lang.String, - keyPrefix: java.lang.String, - password: java.lang.String, - timePattern: java.lang.String, - url: java.lang.String, - userName: java.lang.String + bucketName : java.lang.String, + coordinateColumnName : java.lang.String, + keyPrefix : java.lang.String, + password : java.lang.String, + timePattern : java.lang.String, + url : java.lang.String, + userName : java.lang.String ) object CouchbaseParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { SimonaConfig.Simona.Input.Primary.CouchbaseParams( - bucketName = - $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr( - parentPath, - c, - "coordinateColumnName", - $tsCfgValidator - ), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database: java.lang.String, - port: scala.Int, - timePattern: java.lang.String, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + timePattern : java.lang.String, + url : java.lang.String ) object InfluxDb1xParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + database = $_reqStr(parentPath, c, "database", $tsCfgValidator), + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SqlParams( - jdbcUrl: java.lang.String, - password: java.lang.String, - schemaName: java.lang.String, - timePattern: java.lang.String, - userName: java.lang.String + jdbcUrl : java.lang.String, + password : java.lang.String, + schemaName : java.lang.String, + timePattern : java.lang.String, + userName : java.lang.String ) object SqlParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary.SqlParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.SqlParams = { SimonaConfig.Simona.Input.Primary.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = - if (c.hasPathOrNull("schemaName")) c.getString("schemaName") - else "public", - timePattern = - if (c.hasPathOrNull("timePattern")) c.getString("timePattern") - else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", + timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Primary = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary = { SimonaConfig.Simona.Input.Primary( - couchbaseParams = - if (c.hasPathOrNull("couchbaseParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.CouchbaseParams( - c.getConfig("couchbaseParams"), - parentPath + "couchbaseParams.", - $tsCfgValidator - ) - ) - else None, - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.PrimaryDataCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - influxDb1xParams = - if (c.hasPathOrNull("influxDb1xParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - c.getConfig("influxDb1xParams"), - parentPath + "influxDb1xParams.", - $tsCfgValidator - ) - ) - else None, - sqlParams = - if (c.hasPathOrNull("sqlParams")) - scala.Some( - SimonaConfig.Simona.Input.Primary.SqlParams( - c.getConfig("sqlParams"), - parentPath + "sqlParams.", - $tsCfgValidator - ) - ) - else None + couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Primary.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.PrimaryDataCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Primary.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, + sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Primary.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None ) } } - + final case class Weather( - datasource: SimonaConfig.Simona.Input.Weather.Datasource + datasource : SimonaConfig.Simona.Input.Weather.Datasource ) object Weather { final case class Datasource( - coordinateSource: SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, - couchbaseParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams - ], - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - influxDb1xParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams - ], - maxCoordinateDistance: scala.Double, - resolution: scala.Option[scala.Long], - sampleParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.SampleParams - ], - scheme: java.lang.String, - sqlParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.SqlParams - ], - timestampPattern: scala.Option[java.lang.String] + coordinateSource : SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, + couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams], + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams], + maxCoordinateDistance : scala.Double, + resolution : scala.Option[scala.Long], + sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SampleParams], + scheme : java.lang.String, + sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SqlParams], + timestampPattern : scala.Option[java.lang.String] ) object Datasource { final case class CoordinateSource( - csvParams: scala.Option[SimonaConfig.BaseCsvParams], - gridModel: java.lang.String, - sampleParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams - ], - sqlParams: scala.Option[ - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams - ] + csvParams : scala.Option[SimonaConfig.BaseCsvParams], + gridModel : java.lang.String, + sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams], + sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams] ) object CoordinateSource { final case class SampleParams( - use: scala.Boolean + use : scala.Boolean ) object SampleParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SampleParams( - use = !c.hasPathOrNull("use") || c.getBoolean("use") - ) + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams( + use = !c.hasPathOrNull("use") || c.getBoolean("use") + ) } } - + final case class SqlParams( - jdbcUrl: java.lang.String, - password: java.lang.String, - schemaName: java.lang.String, - tableName: java.lang.String, - userName: java.lang.String + jdbcUrl : java.lang.String, + password : java.lang.String, + schemaName : java.lang.String, + tableName : java.lang.String, + userName : java.lang.String ) object SqlParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SqlParams( - jdbcUrl = - $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = - $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = - if (c.hasPathOrNull("schemaName")) - c.getString("schemaName") - else "public", - tableName = - $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = - $_reqStr(parentPath, c, "userName", $tsCfgValidator) - ) + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams( + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", + tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - gridModel = - if (c.hasPathOrNull("gridModel")) c.getString("gridModel") - else "icon", - sampleParams = - if (c.hasPathOrNull("sampleParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SampleParams( - c.getConfig("sampleParams"), - parentPath + "sampleParams.", - $tsCfgValidator - ) - ) - else None, - sqlParams = - if (c.hasPathOrNull("sqlParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource - .SqlParams( - c.getConfig("sqlParams"), - parentPath + "sqlParams.", - $tsCfgValidator - ) - ) - else None + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + gridModel = if(c.hasPathOrNull("gridModel")) c.getString("gridModel") else "icon", + sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, + sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None ) } } - + final case class CouchbaseParams( - bucketName: java.lang.String, - coordinateColumnName: java.lang.String, - keyPrefix: java.lang.String, - password: java.lang.String, - url: java.lang.String, - userName: java.lang.String + bucketName : java.lang.String, + coordinateColumnName : java.lang.String, + keyPrefix : java.lang.String, + password : java.lang.String, + url : java.lang.String, + userName : java.lang.String ) object CouchbaseParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams( - bucketName = - $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr( - parentPath, - c, - "coordinateColumnName", - $tsCfgValidator - ), - keyPrefix = - $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database: java.lang.String, - port: scala.Int, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + url : java.lang.String ) object InfluxDb1xParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SampleParams( - use: scala.Boolean + use : scala.Boolean ) object SampleParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( use = !c.hasPathOrNull("use") || c.getBoolean("use") ) } } - + final case class SqlParams( - jdbcUrl: java.lang.String, - password: java.lang.String, - schemaName: java.lang.String, - tableName: java.lang.String, - userName: java.lang.String + jdbcUrl : java.lang.String, + password : java.lang.String, + schemaName : java.lang.String, + tableName : java.lang.String, + userName : java.lang.String ) object SqlParams { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = - if (c.hasPathOrNull("schemaName")) c.getString("schemaName") - else "public", - tableName = - $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", + tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather.Datasource = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource = { SimonaConfig.Simona.Input.Weather.Datasource( - coordinateSource = - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - if (c.hasPathOrNull("coordinateSource")) - c.getConfig("coordinateSource") - else - com.typesafe.config.ConfigFactory - .parseString("coordinateSource{}"), - parentPath + "coordinateSource.", - $tsCfgValidator - ), - couchbaseParams = - if (c.hasPathOrNull("couchbaseParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource - .CouchbaseParams( - c.getConfig("couchbaseParams"), - parentPath + "couchbaseParams.", - $tsCfgValidator - ) - ) - else None, - csvParams = - if (c.hasPathOrNull("csvParams")) - scala.Some( - SimonaConfig.BaseCsvParams( - c.getConfig("csvParams"), - parentPath + "csvParams.", - $tsCfgValidator - ) - ) - else None, - influxDb1xParams = - if (c.hasPathOrNull("influxDb1xParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource - .InfluxDb1xParams( - c.getConfig("influxDb1xParams"), - parentPath + "influxDb1xParams.", - $tsCfgValidator - ) - ) - else None, - maxCoordinateDistance = - if (c.hasPathOrNull("maxCoordinateDistance")) - c.getDouble("maxCoordinateDistance") - else 50000, - resolution = - if (c.hasPathOrNull("resolution")) - Some(c.getLong("resolution").longValue()) - else None, - sampleParams = - if (c.hasPathOrNull("sampleParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( - c.getConfig("sampleParams"), - parentPath + "sampleParams.", - $tsCfgValidator - ) - ) - else None, - scheme = - if (c.hasPathOrNull("scheme")) c.getString("scheme") - else "icon", - sqlParams = - if (c.hasPathOrNull("sqlParams")) - scala.Some( - SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - c.getConfig("sqlParams"), - parentPath + "sqlParams.", - $tsCfgValidator - ) - ) - else None, - timestampPattern = - if (c.hasPathOrNull("timestampPattern")) - Some(c.getString("timestampPattern")) - else None + coordinateSource = SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource(if(c.hasPathOrNull("coordinateSource")) c.getConfig("coordinateSource") else com.typesafe.config.ConfigFactory.parseString("coordinateSource{}"), parentPath + "coordinateSource.", $tsCfgValidator), + couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, + csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, + influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, + maxCoordinateDistance = if(c.hasPathOrNull("maxCoordinateDistance")) c.getDouble("maxCoordinateDistance") else 50000, + resolution = if(c.hasPathOrNull("resolution")) Some(c.getLong("resolution").longValue()) else None, + sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, + scheme = if(c.hasPathOrNull("scheme")) c.getString("scheme") else "icon", + sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None, + timestampPattern = if(c.hasPathOrNull("timestampPattern")) Some(c.getString("timestampPattern")) else None ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input.Weather = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather = { SimonaConfig.Simona.Input.Weather( - datasource = SimonaConfig.Simona.Input.Weather.Datasource( - if (c.hasPathOrNull("datasource")) c.getConfig("datasource") - else - com.typesafe.config.ConfigFactory.parseString("datasource{}"), - parentPath + "datasource.", - $tsCfgValidator - ) + datasource = SimonaConfig.Simona.Input.Weather.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Input = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input = { SimonaConfig.Simona.Input( - grid = SimonaConfig.Simona.Input.Grid( - if (c.hasPathOrNull("grid")) c.getConfig("grid") - else com.typesafe.config.ConfigFactory.parseString("grid{}"), - parentPath + "grid.", - $tsCfgValidator - ), - primary = SimonaConfig.Simona.Input.Primary( - if (c.hasPathOrNull("primary")) c.getConfig("primary") - else com.typesafe.config.ConfigFactory.parseString("primary{}"), - parentPath + "primary.", - $tsCfgValidator - ), - weather = SimonaConfig.Simona.Input.Weather( - if (c.hasPathOrNull("weather")) c.getConfig("weather") - else com.typesafe.config.ConfigFactory.parseString("weather{}"), - parentPath + "weather.", - $tsCfgValidator - ) + grid = SimonaConfig.Simona.Input.Grid(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), + primary = SimonaConfig.Simona.Input.Primary(if(c.hasPathOrNull("primary")) c.getConfig("primary") else com.typesafe.config.ConfigFactory.parseString("primary{}"), parentPath + "primary.", $tsCfgValidator), + weather = SimonaConfig.Simona.Input.Weather(if(c.hasPathOrNull("weather")) c.getConfig("weather") else com.typesafe.config.ConfigFactory.parseString("weather{}"), parentPath + "weather.", $tsCfgValidator) ) } } - + final case class Output( - base: SimonaConfig.Simona.Output.Base, - flex: scala.Boolean, - grid: SimonaConfig.GridOutputConfig, - participant: SimonaConfig.Simona.Output.Participant, - sink: SimonaConfig.Simona.Output.Sink, - thermal: SimonaConfig.Simona.Output.Thermal + base : SimonaConfig.Simona.Output.Base, + flex : scala.Boolean, + grid : SimonaConfig.GridOutputConfig, + participant : SimonaConfig.Simona.Output.Participant, + sink : SimonaConfig.Simona.Output.Sink, + thermal : SimonaConfig.Simona.Output.Thermal ) object Output { final case class Base( - addTimestampToOutputDir: scala.Boolean, - dir: java.lang.String + addTimestampToOutputDir : scala.Boolean, + dir : java.lang.String ) object Base { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Base = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Base = { SimonaConfig.Simona.Output.Base( - addTimestampToOutputDir = !c.hasPathOrNull( - "addTimestampToOutputDir" - ) || c.getBoolean("addTimestampToOutputDir"), - dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) + addTimestampToOutputDir = !c.hasPathOrNull("addTimestampToOutputDir") || c.getBoolean("addTimestampToOutputDir"), + dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class Participant( - defaultConfig: SimonaConfig.ParticipantBaseOutputConfig, - individualConfigs: scala.List[ - SimonaConfig.ParticipantBaseOutputConfig - ] + defaultConfig : SimonaConfig.ParticipantBaseOutputConfig, + individualConfigs : scala.List[SimonaConfig.ParticipantBaseOutputConfig] ) object Participant { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Participant = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Participant = { SimonaConfig.Simona.Output.Participant( - defaultConfig = SimonaConfig.ParticipantBaseOutputConfig( - if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_ParticipantBaseOutputConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.ParticipantBaseOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_ParticipantBaseOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_ParticipantBaseOutputConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.ParticipantBaseOutputConfig] = { + private def $_LSimonaConfig_ParticipantBaseOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.ParticipantBaseOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.ParticipantBaseOutputConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.ParticipantBaseOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Sink( - csv: scala.Option[SimonaConfig.Simona.Output.Sink.Csv], - influxDb1x: scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x], - kafka: scala.Option[SimonaConfig.ResultKafkaParams] + csv : scala.Option[SimonaConfig.Simona.Output.Sink.Csv], + influxDb1x : scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x], + kafka : scala.Option[SimonaConfig.ResultKafkaParams] ) object Sink { final case class Csv( - fileFormat: java.lang.String, - filePrefix: java.lang.String, - fileSuffix: java.lang.String, - isHierarchic: scala.Boolean + fileFormat : java.lang.String, + filePrefix : java.lang.String, + fileSuffix : java.lang.String, + isHierarchic : scala.Boolean ) object Csv { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink.Csv = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.Csv = { SimonaConfig.Simona.Output.Sink.Csv( - fileFormat = - if (c.hasPathOrNull("fileFormat")) c.getString("fileFormat") - else ".csv", - filePrefix = - if (c.hasPathOrNull("filePrefix")) c.getString("filePrefix") - else "", - fileSuffix = - if (c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") - else "", - isHierarchic = - c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") + fileFormat = if(c.hasPathOrNull("fileFormat")) c.getString("fileFormat") else ".csv", + filePrefix = if(c.hasPathOrNull("filePrefix")) c.getString("filePrefix") else "", + fileSuffix = if(c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") else "", + isHierarchic = c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") ) } } - + final case class InfluxDb1x( - database: java.lang.String, - port: scala.Int, - url: java.lang.String + database : java.lang.String, + port : scala.Int, + url : java.lang.String ) object InfluxDb1x { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Sink = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink = { SimonaConfig.Simona.Output.Sink( - csv = - if (c.hasPathOrNull("csv")) - scala.Some( - SimonaConfig.Simona.Output.Sink.Csv( - c.getConfig("csv"), - parentPath + "csv.", - $tsCfgValidator - ) - ) - else None, - influxDb1x = - if (c.hasPathOrNull("influxDb1x")) - scala.Some( - SimonaConfig.Simona.Output.Sink.InfluxDb1x( - c.getConfig("influxDb1x"), - parentPath + "influxDb1x.", - $tsCfgValidator - ) - ) - else None, - kafka = - if (c.hasPathOrNull("kafka")) - scala.Some( - SimonaConfig.ResultKafkaParams( - c.getConfig("kafka"), - parentPath + "kafka.", - $tsCfgValidator - ) - ) - else None + csv = if(c.hasPathOrNull("csv")) scala.Some(SimonaConfig.Simona.Output.Sink.Csv(c.getConfig("csv"), parentPath + "csv.", $tsCfgValidator)) else None, + influxDb1x = if(c.hasPathOrNull("influxDb1x")) scala.Some(SimonaConfig.Simona.Output.Sink.InfluxDb1x(c.getConfig("influxDb1x"), parentPath + "influxDb1x.", $tsCfgValidator)) else None, + kafka = if(c.hasPathOrNull("kafka")) scala.Some(SimonaConfig.ResultKafkaParams(c.getConfig("kafka"), parentPath + "kafka.", $tsCfgValidator)) else None ) } } - + final case class Thermal( - defaultConfig: SimonaConfig.SimpleOutputConfig, - individualConfigs: scala.List[SimonaConfig.SimpleOutputConfig] + defaultConfig : SimonaConfig.SimpleOutputConfig, + individualConfigs : scala.List[SimonaConfig.SimpleOutputConfig] ) object Thermal { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output.Thermal = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Thermal = { SimonaConfig.Simona.Output.Thermal( - defaultConfig = SimonaConfig.SimpleOutputConfig( - if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_SimpleOutputConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.SimpleOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_SimpleOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_SimpleOutputConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.SimpleOutputConfig] = { + private def $_LSimonaConfig_SimpleOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.SimpleOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.SimpleOutputConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.SimpleOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Output = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output = { SimonaConfig.Simona.Output( - base = SimonaConfig.Simona.Output.Base( - if (c.hasPathOrNull("base")) c.getConfig("base") - else com.typesafe.config.ConfigFactory.parseString("base{}"), - parentPath + "base.", - $tsCfgValidator - ), - flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), - grid = SimonaConfig.GridOutputConfig( - if (c.hasPathOrNull("grid")) c.getConfig("grid") - else com.typesafe.config.ConfigFactory.parseString("grid{}"), - parentPath + "grid.", - $tsCfgValidator - ), - participant = SimonaConfig.Simona.Output.Participant( - if (c.hasPathOrNull("participant")) c.getConfig("participant") - else com.typesafe.config.ConfigFactory.parseString("participant{}"), - parentPath + "participant.", - $tsCfgValidator - ), - sink = SimonaConfig.Simona.Output.Sink( - if (c.hasPathOrNull("sink")) c.getConfig("sink") - else com.typesafe.config.ConfigFactory.parseString("sink{}"), - parentPath + "sink.", - $tsCfgValidator - ), - thermal = SimonaConfig.Simona.Output.Thermal( - if (c.hasPathOrNull("thermal")) c.getConfig("thermal") - else com.typesafe.config.ConfigFactory.parseString("thermal{}"), - parentPath + "thermal.", - $tsCfgValidator - ) + base = SimonaConfig.Simona.Output.Base(if(c.hasPathOrNull("base")) c.getConfig("base") else com.typesafe.config.ConfigFactory.parseString("base{}"), parentPath + "base.", $tsCfgValidator), + flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), + grid = SimonaConfig.GridOutputConfig(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), + participant = SimonaConfig.Simona.Output.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), + sink = SimonaConfig.Simona.Output.Sink(if(c.hasPathOrNull("sink")) c.getConfig("sink") else com.typesafe.config.ConfigFactory.parseString("sink{}"), parentPath + "sink.", $tsCfgValidator), + thermal = SimonaConfig.Simona.Output.Thermal(if(c.hasPathOrNull("thermal")) c.getConfig("thermal") else com.typesafe.config.ConfigFactory.parseString("thermal{}"), parentPath + "thermal.", $tsCfgValidator) ) } } - + final case class Powerflow( - maxSweepPowerDeviation: scala.Double, - newtonraphson: SimonaConfig.Simona.Powerflow.Newtonraphson, - resolution: java.time.Duration, - stopOnFailure: scala.Boolean, - sweepTimeout: java.time.Duration + maxSweepPowerDeviation : scala.Double, + newtonraphson : SimonaConfig.Simona.Powerflow.Newtonraphson, + resolution : java.time.Duration, + stopOnFailure : scala.Boolean, + sweepTimeout : java.time.Duration ) object Powerflow { final case class Newtonraphson( - epsilon: scala.List[scala.Double], - iterations: scala.Int + epsilon : scala.List[scala.Double], + iterations : scala.Int ) object Newtonraphson { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Powerflow.Newtonraphson = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow.Newtonraphson = { SimonaConfig.Simona.Powerflow.Newtonraphson( - epsilon = - $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), + epsilon = $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator) ) } - private def $_reqInt( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Int = { + private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { if (c == null) 0 - else - try c.getInt(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getInt(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Powerflow = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow = { SimonaConfig.Simona.Powerflow( - maxSweepPowerDeviation = - $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), - newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson( - if (c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") - else - com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), - parentPath + "newtonraphson.", - $tsCfgValidator - ), - resolution = - if (c.hasPathOrNull("resolution")) c.getDuration("resolution") - else java.time.Duration.parse("PT1H"), - stopOnFailure = - c.hasPathOrNull("stopOnFailure") && c.getBoolean("stopOnFailure"), - sweepTimeout = - if (c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") - else java.time.Duration.parse("PT30S") + maxSweepPowerDeviation = $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), + newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson(if(c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") else com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), parentPath + "newtonraphson.", $tsCfgValidator), + resolution = if(c.hasPathOrNull("resolution")) c.getDuration("resolution") else java.time.Duration.parse("PT1H"), + stopOnFailure = c.hasPathOrNull("stopOnFailure") && c.getBoolean("stopOnFailure"), + sweepTimeout = if(c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") else java.time.Duration.parse("PT30S") ) } - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.Double = { + private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else try c.getDouble(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Runtime( - listener: SimonaConfig.Simona.Runtime.Listener, - participant: SimonaConfig.Simona.Runtime.Participant, - selected_subgrids: scala.Option[scala.List[scala.Int]], - selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + listener : SimonaConfig.Simona.Runtime.Listener, + participant : SimonaConfig.Simona.Runtime.Participant, + selected_subgrids : scala.Option[scala.List[scala.Int]], + selected_volt_lvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object Runtime { final case class Listener( - eventsToProcess: scala.Option[scala.List[java.lang.String]], - kafka: scala.Option[SimonaConfig.RuntimeKafkaParams] + eventsToProcess : scala.Option[scala.List[java.lang.String]], + kafka : scala.Option[SimonaConfig.RuntimeKafkaParams] ) object Listener { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Listener = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Listener = { SimonaConfig.Simona.Runtime.Listener( - eventsToProcess = - if (c.hasPathOrNull("eventsToProcess")) - scala.Some( - $_L$_str( - c.getList("eventsToProcess"), - parentPath, - $tsCfgValidator - ) - ) - else None, - kafka = - if (c.hasPathOrNull("kafka")) - scala.Some( - SimonaConfig.RuntimeKafkaParams( - c.getConfig("kafka"), - parentPath + "kafka.", - $tsCfgValidator - ) - ) - else None + eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, + kafka = if(c.hasPathOrNull("kafka")) scala.Some(SimonaConfig.RuntimeKafkaParams(c.getConfig("kafka"), parentPath + "kafka.", $tsCfgValidator)) else None ) } } - + final case class Participant( - evcs: SimonaConfig.Simona.Runtime.Participant.Evcs, - fixedFeedIn: SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, - hp: SimonaConfig.Simona.Runtime.Participant.Hp, - load: SimonaConfig.Simona.Runtime.Participant.Load, - pv: SimonaConfig.Simona.Runtime.Participant.Pv, - requestVoltageDeviationThreshold: scala.Double, - wec: SimonaConfig.Simona.Runtime.Participant.Wec + evcs : SimonaConfig.Simona.Runtime.Participant.Evcs, + fixedFeedIn : SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, + hp : SimonaConfig.Simona.Runtime.Participant.Hp, + load : SimonaConfig.Simona.Runtime.Participant.Load, + pv : SimonaConfig.Simona.Runtime.Participant.Pv, + requestVoltageDeviationThreshold : scala.Double, + wec : SimonaConfig.Simona.Runtime.Participant.Wec ) object Participant { final case class Evcs( - defaultConfig: SimonaConfig.EvcsRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig] + defaultConfig : SimonaConfig.EvcsRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.EvcsRuntimeConfig] ) object Evcs { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Evcs = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Evcs = { SimonaConfig.Simona.Runtime.Participant.Evcs( - defaultConfig = SimonaConfig.EvcsRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.EvcsRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_EvcsRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.EvcsRuntimeConfig] = { + private def $_LSimonaConfig_EvcsRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.EvcsRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.EvcsRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.EvcsRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class FixedFeedIn( - defaultConfig: SimonaConfig.FixedFeedInRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig] + defaultConfig : SimonaConfig.FixedFeedInRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.FixedFeedInRuntimeConfig] ) object FixedFeedIn { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_FixedFeedInRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { + private def $_LSimonaConfig_FixedFeedInRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.FixedFeedInRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.FixedFeedInRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Hp( - defaultConfig: SimonaConfig.HpRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.HpRuntimeConfig] + defaultConfig : SimonaConfig.HpRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.HpRuntimeConfig] ) object Hp { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Hp = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Hp = { SimonaConfig.Simona.Runtime.Participant.Hp( - defaultConfig = SimonaConfig.HpRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_HpRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.HpRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_HpRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_HpRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.HpRuntimeConfig] = { + private def $_LSimonaConfig_HpRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.HpRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.HpRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.HpRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Load( - defaultConfig: SimonaConfig.LoadRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig] + defaultConfig : SimonaConfig.LoadRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.LoadRuntimeConfig] ) object Load { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Load = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Load = { SimonaConfig.Simona.Runtime.Participant.Load( - defaultConfig = SimonaConfig.LoadRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_LoadRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.LoadRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_LoadRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_LoadRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.LoadRuntimeConfig] = { + private def $_LSimonaConfig_LoadRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.LoadRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.LoadRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.LoadRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Pv( - defaultConfig: SimonaConfig.PvRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig] + defaultConfig : SimonaConfig.PvRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.PvRuntimeConfig] ) object Pv { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Pv = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Pv = { SimonaConfig.Simona.Runtime.Participant.Pv( - defaultConfig = SimonaConfig.PvRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_PvRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.PvRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_PvRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_PvRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.PvRuntimeConfig] = { + private def $_LSimonaConfig_PvRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.PvRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.PvRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.PvRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Wec( - defaultConfig: SimonaConfig.WecRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig] + defaultConfig : SimonaConfig.WecRuntimeConfig, + individualConfigs : scala.List[SimonaConfig.WecRuntimeConfig] ) object Wec { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant.Wec = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Wec = { SimonaConfig.Simona.Runtime.Participant.Wec( - defaultConfig = SimonaConfig.WecRuntimeConfig( - if (c.hasPathOrNull("defaultConfig")) - c.getConfig("defaultConfig") - else - com.typesafe.config.ConfigFactory - .parseString("defaultConfig{}"), - parentPath + "defaultConfig.", - $tsCfgValidator - ), - individualConfigs = $_LSimonaConfig_WecRuntimeConfig( - c.getList("individualConfigs"), - parentPath, - $tsCfgValidator - ) + defaultConfig = SimonaConfig.WecRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), + individualConfigs = $_LSimonaConfig_WecRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) ) } - private def $_LSimonaConfig_WecRuntimeConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.WecRuntimeConfig] = { + private def $_LSimonaConfig_WecRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.WecRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.WecRuntimeConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.WecRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime.Participant = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant = { SimonaConfig.Simona.Runtime.Participant( - evcs = SimonaConfig.Simona.Runtime.Participant.Evcs( - if (c.hasPathOrNull("evcs")) c.getConfig("evcs") - else com.typesafe.config.ConfigFactory.parseString("evcs{}"), - parentPath + "evcs.", - $tsCfgValidator - ), - fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - if (c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") - else - com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), - parentPath + "fixedFeedIn.", - $tsCfgValidator - ), - hp = SimonaConfig.Simona.Runtime.Participant.Hp( - if (c.hasPathOrNull("hp")) c.getConfig("hp") - else com.typesafe.config.ConfigFactory.parseString("hp{}"), - parentPath + "hp.", - $tsCfgValidator - ), - load = SimonaConfig.Simona.Runtime.Participant.Load( - if (c.hasPathOrNull("load")) c.getConfig("load") - else com.typesafe.config.ConfigFactory.parseString("load{}"), - parentPath + "load.", - $tsCfgValidator - ), - pv = SimonaConfig.Simona.Runtime.Participant.Pv( - if (c.hasPathOrNull("pv")) c.getConfig("pv") - else com.typesafe.config.ConfigFactory.parseString("pv{}"), - parentPath + "pv.", - $tsCfgValidator - ), - requestVoltageDeviationThreshold = - if (c.hasPathOrNull("requestVoltageDeviationThreshold")) - c.getDouble("requestVoltageDeviationThreshold") - else 1e-14, - wec = SimonaConfig.Simona.Runtime.Participant.Wec( - if (c.hasPathOrNull("wec")) c.getConfig("wec") - else com.typesafe.config.ConfigFactory.parseString("wec{}"), - parentPath + "wec.", - $tsCfgValidator - ) + evcs = SimonaConfig.Simona.Runtime.Participant.Evcs(if(c.hasPathOrNull("evcs")) c.getConfig("evcs") else com.typesafe.config.ConfigFactory.parseString("evcs{}"), parentPath + "evcs.", $tsCfgValidator), + fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn(if(c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") else com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), parentPath + "fixedFeedIn.", $tsCfgValidator), + hp = SimonaConfig.Simona.Runtime.Participant.Hp(if(c.hasPathOrNull("hp")) c.getConfig("hp") else com.typesafe.config.ConfigFactory.parseString("hp{}"), parentPath + "hp.", $tsCfgValidator), + load = SimonaConfig.Simona.Runtime.Participant.Load(if(c.hasPathOrNull("load")) c.getConfig("load") else com.typesafe.config.ConfigFactory.parseString("load{}"), parentPath + "load.", $tsCfgValidator), + pv = SimonaConfig.Simona.Runtime.Participant.Pv(if(c.hasPathOrNull("pv")) c.getConfig("pv") else com.typesafe.config.ConfigFactory.parseString("pv{}"), parentPath + "pv.", $tsCfgValidator), + requestVoltageDeviationThreshold = if(c.hasPathOrNull("requestVoltageDeviationThreshold")) c.getDouble("requestVoltageDeviationThreshold") else 1E-14, + wec = SimonaConfig.Simona.Runtime.Participant.Wec(if(c.hasPathOrNull("wec")) c.getConfig("wec") else com.typesafe.config.ConfigFactory.parseString("wec{}"), parentPath + "wec.", $tsCfgValidator) ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Runtime = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime = { SimonaConfig.Simona.Runtime( - listener = SimonaConfig.Simona.Runtime.Listener( - if (c.hasPathOrNull("listener")) c.getConfig("listener") - else com.typesafe.config.ConfigFactory.parseString("listener{}"), - parentPath + "listener.", - $tsCfgValidator - ), - participant = SimonaConfig.Simona.Runtime.Participant( - if (c.hasPathOrNull("participant")) c.getConfig("participant") - else com.typesafe.config.ConfigFactory.parseString("participant{}"), - parentPath + "participant.", - $tsCfgValidator - ), - selected_subgrids = - if (c.hasPathOrNull("selected_subgrids")) - scala.Some( - $_L$_int( - c.getList("selected_subgrids"), - parentPath, - $tsCfgValidator - ) - ) - else None, - selected_volt_lvls = - if (c.hasPathOrNull("selected_volt_lvls")) - scala.Some( - $_LSimonaConfig_VoltLvlConfig( - c.getList("selected_volt_lvls"), - parentPath, - $tsCfgValidator - ) - ) - else None + listener = SimonaConfig.Simona.Runtime.Listener(if(c.hasPathOrNull("listener")) c.getConfig("listener") else com.typesafe.config.ConfigFactory.parseString("listener{}"), parentPath + "listener.", $tsCfgValidator), + participant = SimonaConfig.Simona.Runtime.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), + selected_subgrids = if(c.hasPathOrNull("selected_subgrids")) scala.Some($_L$_int(c.getList("selected_subgrids"), parentPath, $tsCfgValidator)) else None, + selected_volt_lvls = if(c.hasPathOrNull("selected_volt_lvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("selected_volt_lvls"), parentPath, $tsCfgValidator)) else None ) } - private def $_LSimonaConfig_VoltLvlConfig( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala - .map(cv => - SimonaConfig.VoltLvlConfig( - cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, - parentPath, - $tsCfgValidator - ) - ) - .toList + cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList } } - + final case class Time( - endDateTime: java.lang.String, - schedulerReadyCheckWindow: scala.Option[scala.Int], - startDateTime: java.lang.String + endDateTime : java.lang.String, + schedulerReadyCheckWindow : scala.Option[scala.Int], + startDateTime : java.lang.String ) object Time { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona.Time = { + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Time = { SimonaConfig.Simona.Time( - endDateTime = - if (c.hasPathOrNull("endDateTime")) c.getString("endDateTime") - else "2011-05-01 01:00:00", - schedulerReadyCheckWindow = - if (c.hasPathOrNull("schedulerReadyCheckWindow")) - Some(c.getInt("schedulerReadyCheckWindow")) - else None, - startDateTime = - if (c.hasPathOrNull("startDateTime")) c.getString("startDateTime") - else "2011-05-01 00:00:00" + endDateTime = if(c.hasPathOrNull("endDateTime")) c.getString("endDateTime") else "2011-05-01 01:00:00", + schedulerReadyCheckWindow = if(c.hasPathOrNull("schedulerReadyCheckWindow")) Some(c.getInt("schedulerReadyCheckWindow")) else None, + startDateTime = if(c.hasPathOrNull("startDateTime")) c.getString("startDateTime") else "2011-05-01 00:00:00" ) } } - - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): SimonaConfig.Simona = { + + def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona = { SimonaConfig.Simona( - event = SimonaConfig.Simona.Event( - if (c.hasPathOrNull("event")) c.getConfig("event") - else com.typesafe.config.ConfigFactory.parseString("event{}"), - parentPath + "event.", - $tsCfgValidator - ), - gridConfig = SimonaConfig.Simona.GridConfig( - if (c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") - else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), - parentPath + "gridConfig.", - $tsCfgValidator - ), - input = SimonaConfig.Simona.Input( - if (c.hasPathOrNull("input")) c.getConfig("input") - else com.typesafe.config.ConfigFactory.parseString("input{}"), - parentPath + "input.", - $tsCfgValidator - ), - output = SimonaConfig.Simona.Output( - if (c.hasPathOrNull("output")) c.getConfig("output") - else com.typesafe.config.ConfigFactory.parseString("output{}"), - parentPath + "output.", - $tsCfgValidator - ), - powerflow = SimonaConfig.Simona.Powerflow( - if (c.hasPathOrNull("powerflow")) c.getConfig("powerflow") - else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), - parentPath + "powerflow.", - $tsCfgValidator - ), - runtime = SimonaConfig.Simona.Runtime( - if (c.hasPathOrNull("runtime")) c.getConfig("runtime") - else com.typesafe.config.ConfigFactory.parseString("runtime{}"), - parentPath + "runtime.", - $tsCfgValidator - ), - simulationName = - $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), - time = SimonaConfig.Simona.Time( - if (c.hasPathOrNull("time")) c.getConfig("time") - else com.typesafe.config.ConfigFactory.parseString("time{}"), - parentPath + "time.", - $tsCfgValidator - ) + event = SimonaConfig.Simona.Event(if(c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), parentPath + "event.", $tsCfgValidator), + gridConfig = SimonaConfig.Simona.GridConfig(if(c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), parentPath + "gridConfig.", $tsCfgValidator), + input = SimonaConfig.Simona.Input(if(c.hasPathOrNull("input")) c.getConfig("input") else com.typesafe.config.ConfigFactory.parseString("input{}"), parentPath + "input.", $tsCfgValidator), + output = SimonaConfig.Simona.Output(if(c.hasPathOrNull("output")) c.getConfig("output") else com.typesafe.config.ConfigFactory.parseString("output{}"), parentPath + "output.", $tsCfgValidator), + powerflow = SimonaConfig.Simona.Powerflow(if(c.hasPathOrNull("powerflow")) c.getConfig("powerflow") else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), parentPath + "powerflow.", $tsCfgValidator), + runtime = SimonaConfig.Simona.Runtime(if(c.hasPathOrNull("runtime")) c.getConfig("runtime") else com.typesafe.config.ConfigFactory.parseString("runtime{}"), parentPath + "runtime.", $tsCfgValidator), + simulationName = $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), + time = SimonaConfig.Simona.Time(if(c.hasPathOrNull("time")) c.getConfig("time") else com.typesafe.config.ConfigFactory.parseString("time{}"), parentPath + "time.", $tsCfgValidator) ) } - private def $_reqStr( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): java.lang.String = { + private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { if (c == null) null - else - try c.getString(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else try c.getString(path) + catch { + case e:com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + def apply(c: com.typesafe.config.Config): SimonaConfig = { val $tsCfgValidator: $TsCfgValidator = new $TsCfgValidator() val parentPath: java.lang.String = "" val $result = SimonaConfig( - simona = SimonaConfig.Simona( - if (c.hasPathOrNull("simona")) c.getConfig("simona") - else com.typesafe.config.ConfigFactory.parseString("simona{}"), - parentPath + "simona.", - $tsCfgValidator - ) + simona = SimonaConfig.Simona(if(c.hasPathOrNull("simona")) c.getConfig("simona") else com.typesafe.config.ConfigFactory.parseString("simona{}"), parentPath + "simona.", $tsCfgValidator) ) $tsCfgValidator.validate() $result } - private def $_L$_dbl( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[scala.Double] = { + private def $_L$_dbl(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Double] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_dbl(cv)).toList } - private def $_L$_int( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[scala.Int] = { + private def $_L$_int(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Int] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_int(cv)).toList } - private def $_L$_str( - cl: com.typesafe.config.ConfigList, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator - ): scala.List[java.lang.String] = { + private def $_L$_str(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[java.lang.String] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_str(cv)).toList } - private def $_dbl(cv: com.typesafe.config.ConfigValue): scala.Double = { + private def $_dbl(cv:com.typesafe.config.ConfigValue): scala.Double = { val u: Any = cv.unwrapped - if ( - (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[java.lang.Number] - ) throw $_expE(cv, "double") + if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[java.lang.Number]) throw $_expE(cv, "double") u.asInstanceOf[java.lang.Number].doubleValue() } - private def $_expE( - cv: com.typesafe.config.ConfigValue, - exp: java.lang.String - ) = { + private def $_expE(cv:com.typesafe.config.ConfigValue, exp:java.lang.String) = { val u: Any = cv.unwrapped - new java.lang.RuntimeException( - s"${cv.origin.lineNumber}: " + - "expecting: " + exp + " got: " + - (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u) - ) + new java.lang.RuntimeException(s"${cv.origin.lineNumber}: " + + "expecting: " + exp + " got: " + + (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u)) } - private def $_int(cv: com.typesafe.config.ConfigValue): scala.Int = { + private def $_int(cv:com.typesafe.config.ConfigValue): scala.Int = { val u: Any = cv.unwrapped - if ( - (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[Integer] - ) throw $_expE(cv, "integer") + if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[Integer]) throw $_expE(cv, "integer") u.asInstanceOf[Integer] } - private def $_str(cv: com.typesafe.config.ConfigValue): java.lang.String = { + private def $_str(cv:com.typesafe.config.ConfigValue): java.lang.String = { java.lang.String.valueOf(cv.unwrapped()) } final class $TsCfgValidator { - private val badPaths = - scala.collection.mutable.ArrayBuffer[java.lang.String]() + private val badPaths = scala.collection.mutable.ArrayBuffer[java.lang.String]() - def addBadPath( - path: java.lang.String, - e: com.typesafe.config.ConfigException - ): Unit = { + def addBadPath(path: java.lang.String, e: com.typesafe.config.ConfigException): Unit = { badPaths += s"'$path': ${e.getClass.getName}(${e.getMessage})" } - def addInvalidEnumValue( - path: java.lang.String, - value: java.lang.String, - enumName: java.lang.String - ): Unit = { + def addInvalidEnumValue(path: java.lang.String, value: java.lang.String, enumName: java.lang.String): Unit = { badPaths += s"'$path': invalid value $value for enumeration $enumName" } @@ -2736,7 +1453,7 @@ object SimonaConfig { if (badPaths.nonEmpty) { throw new com.typesafe.config.ConfigException( badPaths.mkString("Invalid configuration:\n ", "\n ", "") - ) {} + ){} } } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala deleted file mode 100644 index 710e62b02a..0000000000 --- a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala +++ /dev/null @@ -1,359 +0,0 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant - -import com.typesafe.scalalogging.LazyLogging -import edu.ie3.datamodel.models.input.system.EvcsInput -import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower -import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.EvcsModel.EvcsRelevantData -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.util.quantities.PowerSystemUnits -import edu.ie3.util.scala.OperationInterval -import edu.ie3.util.scala.quantities.{DefaultQuantities, Megavars} -import squants.energy -import squants.energy.{KilowattHours, Kilowatts, Megawatts} -import squants.time.Seconds -import tech.units.indriya.quantity.Quantities.getQuantity - -import java.time.ZonedDateTime -import java.util.UUID - -/** EV charging station model - * - * @param uuid - * the element's uuid - * @param id - * the element's human readable id - * @param operationInterval - * Interval, in which the system is in operation - * @param scalingFactor - * Scaling the output of the system - * @param qControl - * Type of reactive power control - * @param sRated - * Rated apparent power - * @param cosPhiRated - * Rated power factor - * @param chargingPoints - * Number of charging points available at this charging station - * @param locationType - * The location type - */ -final case class EvcsModel( - uuid: UUID, - id: String, - operationInterval: OperationInterval, - scalingFactor: Double, - qControl: QControl, - sRated: squants.Power, - cosPhiRated: Double, - chargingPoints: Int, - locationType: EvcsLocationType -) extends SystemParticipant[EvcsRelevantData, ApparentPower]( - uuid, - id, - operationInterval, - scalingFactor, - qControl, - sRated, - cosPhiRated - ) - with ApparentPowerParticipant[EvcsRelevantData] - with LazyLogging { - - /** Calculate the power behaviour based on the given data. - * - * @param tick - * Regarded instant in simulation - * @param voltage - * Nodal voltage magnitude - * @param data - * Further needed, secondary data - * @return - * A tuple of active and reactive power - */ - def calculatePowerAndEvSoc( - tick: Long, - voltage: squants.Dimensionless, - data: EvcsRelevantData - ): (ApparentPower, Set[EvModel]) = { - if (isInOperation(tick) && data.evMovementsDataFrameLength > 0) { - val (activePower, evModels) = calculateActivePowerAndEvSoc(data) - val reactivePower = - calculateReactivePower(activePower, voltage) - ( - ApparentPower( - activePower, - reactivePower - ), - evModels - ) - } else { - ( - ApparentPower( - Megawatts(0d), - Megavars(0d) - ), - data.currentEvs - ) - } - } - - /** Calculates active power based on given data. If sRated of this evcs is - * exceeded, evs are dropped from charging at this time span. - * @param data - * The needed data. evMovementsDataFrameLength > 0 is required. - * @return - * Active power and ev models with updated stored energy - */ - def calculateActivePowerAndEvSoc( - data: EvcsRelevantData - ): (squants.Power, Set[EvModel]) = { - val (powerSum, models) = calculateActivePowerAndEvSoc( - data.currentEvs, - data.evMovementsDataFrameLength - ) - if (powerSum <= sRated) { - (powerSum, models) - } else { - // if we exceed sRated, we scale down charging power of all evs proportionally - logger.warn( - s"Set of charging evs is charging with $powerSum and thus exceeding evcs sRated $sRated." - ) - - val (calcEvs, noCalcEvs, _) = - data.currentEvs.foldLeft( - ( - Set.empty[EvModel], - Set.empty[EvModel], - DefaultQuantities.zeroKW - ) - ) { case ((calcEvs, noCalcEvs, powerSum), ev) => - val newPower = - powerSum + Kilowatts(ev.getSRatedAC.getValue.doubleValue()) - if (newPower <= sRated) - (calcEvs + ev, noCalcEvs, newPower) - else - (calcEvs, noCalcEvs + ev, powerSum) - } - - val (power, newCalcEvs) = - calculateActivePowerAndEvSoc( - calcEvs, - data.evMovementsDataFrameLength - ) - // include ignored evs - (power, newCalcEvs ++ noCalcEvs) - } - } - - /** Calculates active power based on given set of evs - * @param currentEvs - * The currently charging evs - * @param dataFrameLength - * The duration that all evs are charging - * @return - * Active power and ev models with updated stored energy - */ - private def calculateActivePowerAndEvSoc( - currentEvs: Set[EvModel], - dataFrameLength: Long - ): (squants.Power, Set[EvModel]) = { - val tickDuration = Seconds(dataFrameLength) - - currentEvs.foldLeft(DefaultQuantities.zeroKW, Set.empty[EvModel]) { - case ((powerSum, models), evModel) => - val (chargedEnergy, newEvModel) = charge( - evModel, - tickDuration - ) - - val chargingPower = - chargedEnergy / tickDuration - - ( - powerSum + chargingPower, - models + newEvModel - ) - } - } - - /** Charging given ev model (inside a copy) for given duration. - * @param evModel - * The ev model to charge - * @param duration - * The duration of charging - * @return - * Charged energy and updated ev model as a copy - */ - def charge( - evModel: EvModel, - duration: squants.Time - ): (squants.Energy, EvModel) = { - if (evModel.getStoredEnergy.isLessThan(evModel.getEStorage)) { - val chargingPower = - sRated.min( - Kilowatts( - evModel.getSRatedAC - .to(PowerSystemUnits.KILOWATT) - .getValue - .doubleValue() - ) - ) - - val chargeLeftToFull = KilowattHours( - evModel.getEStorage - .to(PowerSystemUnits.KILOWATTHOUR) - .getValue - .doubleValue() - ) - KilowattHours( - evModel.getStoredEnergy - .to(PowerSystemUnits.KILOWATTHOUR) - .getValue - .doubleValue() - ) - - val potentialChargeDuringTick = chargingPower * duration - - val actualCharge = chargeLeftToFull.min(potentialChargeDuringTick) - val newStoredEnergy = KilowattHours( - evModel.getStoredEnergy - .to(PowerSystemUnits.KILOWATTHOUR) - .getValue - .doubleValue() - ) + actualCharge - - ( - actualCharge, - evModel.copyWith( - getQuantity( - newStoredEnergy.value.doubleValue(), - PowerSystemUnits.KILOWATTHOUR - ) - ) - ) - } else - ( - DefaultQuantities.zeroKWH, - evModel - ) - } - - /** Calculate the active power behaviour of the model - * - * @param data - * Further needed, secondary data - * @return - * Active power - */ - override protected def calculateActivePower( - data: EvcsRelevantData - ): energy.Power = - throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") -} - -object EvcsModel { - - /** Class that holds all relevant data for an Evcs model calculation - * - * @param evMovementsDataFrameLength - * the duration in ticks (= seconds) until next tick - * @param currentEvs - * EVs that have been charging up until this tick. Can include EVs that are - * departing - */ - final case class EvcsRelevantData( - evMovementsDataFrameLength: Long, - currentEvs: Set[EvModel] - ) extends CalcRelevantData - - def apply( - inputModel: EvcsInput, - scalingFactor: Double, - simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime - ): EvcsModel = { - /* Determine the operation interval */ - val operationInterval: OperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - inputModel.getOperationTime - ) - - apply( - inputModel.getUuid, - inputModel.getId, - operationInterval, - scalingFactor, - QControl(inputModel.getqCharacteristics), - Kilowatts( - inputModel.getType.getsRated - .to(PowerSystemUnits.KILOWATT) - .getValue - .doubleValue() - ), - inputModel.getCosPhiRated, - inputModel.getChargingPoints, - inputModel.getLocationType - ) - } - - /** Default factory method to create an EvcsModel instance. - * - * @param uuid - * the unique id of the model - * @param id - * the human readable id - * @param operationInterval - * the operation interval of the model - * @param scalingFactor - * the scaling factor of the power output - * @param qControl - * the q control this model is using - * @param sRated - * the rated apparent power of the model - * @param cosPhiRated - * the rated cosine phi of the model - * @param chargingPoints - * Number of charging points available at this charging station - * @param locationType - * The location type - * @return - * the enabled EvcsModel - */ - def apply( - uuid: UUID, - id: String, - operationInterval: OperationInterval, - scalingFactor: Double, - qControl: QControl, - sRated: squants.Power, - cosPhiRated: Double, - chargingPoints: Int, - locationType: EvcsLocationType - ): EvcsModel = { - val model = new EvcsModel( - uuid, - id, - operationInterval, - scalingFactor, - qControl, - sRated, - cosPhiRated, - chargingPoints, - locationType - ) - - model.enable() - - model - } -} diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 8b727a7390..af97ac1ed5 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -11,8 +11,10 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHe import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.thermal.ThermalGrid import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState +import edu.ie3.simona.model.thermal.{ThermalGrid, ThermalThreshold} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities @@ -59,7 +61,8 @@ final case class HpModel( thermalGrid: ThermalGrid ) extends SystemParticipant[ HpRelevantData, - ApparentPowerAndHeat + ApparentPowerAndHeat, + HpState ]( uuid, id, @@ -69,7 +72,7 @@ final case class HpModel( sRated, cosPhiRated ) - with ApparentPowerAndHeatParticipant[HpRelevantData] { + with ApparentPowerAndHeatParticipant[HpRelevantData, HpState] { private val pRated: Power = sRated * cosPhiRated * scalingFactor @@ -80,17 +83,17 @@ final case class HpModel( * [[HpModel.calculateNextState]]. This state then is fed into the power * calculation logic by hpData. * + * @param modelState + * Current state of the heat pump * @param relevantData * data of heat pump including state of the heat pump * @return * active power */ override protected def calculateActivePower( + modelState: HpState, relevantData: HpRelevantData - ): Power = { - relevantData.hpState = calculateNextState(relevantData) - relevantData.hpState.activePower - } + ): Power = modelState.activePower /** "Calculate" the heat output of the heat pump. The hp's state is already * updated, because the calculation of apparent power in @@ -98,6 +101,8 @@ final case class HpModel( * extract the information * @param tick * Current simulation time for the calculation + * @param modelState + * Current state of the heat pump * @param data * Relevant (external) data for calculation * @return @@ -105,23 +110,28 @@ final case class HpModel( */ override def calculateHeat( tick: Long, + modelState: HpState, data: HpRelevantData ): Power = - data.hpState.qDot + modelState.qDot - /** Given a [[HpRelevantData]] object, containing the [[HpState]], other - * values and the current time tick, this function calculates the heat pump's - * next state To get the actual active power of this state use - * [[calculateActivePower]] with the generated state + /** Given a [[HpRelevantData]] object and the current [[HpState]], this + * function calculates the heat pump's next state To get the actual active + * power of this state use [[calculateActivePower]] with the generated state * - * @param hpData - * data of heat pump including state of the heat pump + * @param state + * Current state of the heat pump + * @param relevantData + * data of heat pump including * @return * next [[HpState]] */ - def calculateNextState(hpData: HpRelevantData): HpState = { - val turnOn = operatesInNextState(hpData) - calcState(hpData, turnOn) + def calculateNextState( + state: HpState, + relevantData: HpRelevantData + ): HpState = { + val turnOn = operatesInNextState(state, relevantData) + calcState(state, relevantData, turnOn) } /** Depending on the input, this function decides whether the heat pump will @@ -130,60 +140,147 @@ final case class HpModel( * met or the heat pump currently is in operation and the grid is able to * handle additional energy * + * @param state + * Current state of the heat pump + * @param relevantData + * Relevant (external) data * @return * boolean defining if heat pump runs in next time step */ - private def operatesInNextState(hpData: HpRelevantData): Boolean = - hpData match { - case HpRelevantData(hpState, currentTimeTick, ambientTemperature) => + def operatesInNextState( + state: HpState, + relevantData: HpRelevantData + ): Boolean = + relevantData match { + case HpRelevantData(currentTimeTick, ambientTemperature) => val demand = thermalGrid.energyDemand( currentTimeTick, ambientTemperature, - hpState.thermalGridState + state.thermalGridState ) - demand.hasRequiredDemand || (hpState.isRunning && demand.hasAdditionalDemand) + demand.hasRequiredDemand || (state.isRunning && demand.hasAdditionalDemand) } /** Calculate state depending on whether heat pump is needed or not. Also * calculate inner temperature change of thermal house and update its inner * temperature. * - * @param hpData + * @param state + * Current state of the heat pump + * @param relevantData * data of heat pump including state of the heat pump * @param isRunning * determines whether the heat pump is running or not * @return * next [[HpState]] */ - private def calcState(hpData: HpRelevantData, isRunning: Boolean): HpState = { + private def calcState( + state: HpState, + relevantData: HpRelevantData, + isRunning: Boolean + ): HpState = { val (newActivePower, newThermalPower) = if (isRunning) (pRated, pThermal * scalingFactor) else (DefaultQuantities.zeroKW, DefaultQuantities.zeroKW) + /* Push thermal energy to the thermal grid and get it's updated state in return */ - val thermalGridState = hpData match { - case HpRelevantData(hpState, currentTimeTick, ambientTemperature) => + val (thermalGridState, maybeThreshold) = relevantData match { + case HpRelevantData(currentTimeTick, _) => thermalGrid.updateState( currentTimeTick, - hpState.thermalGridState, - ambientTemperature, + state.thermalGridState, + state.ambientTemperature, newThermalPower ) } HpState( isRunning, - hpData.currentTimeTick, + relevantData.currentTimeTick, + relevantData.ambientTemperature, newActivePower, newThermalPower, - thermalGridState._1 + thermalGridState, + maybeThreshold + ) + } + + override def determineFlexOptions( + data: HpRelevantData, + lastState: HpState + ): ProvideFlexOptions = { + /* Determine the operating state in the given tick */ + val updatedState = calculateNextState(lastState, data) + + /* Determine the options we have */ + val thermalEnergyDemand = thermalGrid.energyDemand( + data.currentTimeTick, + data.ambientTemperature, + lastState.thermalGridState + ) + val canOperate = + thermalEnergyDemand.hasRequiredDemand || thermalEnergyDemand.hasAdditionalDemand + val canBeOutOfOperation = !thermalEnergyDemand.hasRequiredDemand + + val lowerBoundary = + if (canBeOutOfOperation) + Kilowatts(0d) + else + updatedState.activePower + val upperBoundary = + if (canOperate) + sRated * cosPhiRated + else + Kilowatts(0d) + + ProvideMinMaxFlexOptions( + uuid, + updatedState.activePower, + lowerBoundary, + upperBoundary + ) + } + + /** Handle a controlled power change. If the requested active power is greater + * than 50 % of the rated electrical power switch on the heat pump, otherwise + * switch it off. If it is already in the requested state, return old state + * and next trigger information, otherwise, update the state with new + * operating state and give back the next tick in which something will + * change. + * + * @param data + * Relevant data for model calculation + * @param lastState + * The last known model state + * @param setPower + * power that has been set by EmAgent + * @return + * updated relevant data and an indication at which circumstances flex + * options will change next + */ + override def handleControlledPowerChange( + data: HpRelevantData, + lastState: HpState, + setPower: squants.Power + ): (HpState, FlexChangeIndicator) = { + /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ + val turnOn = setPower > (sRated * cosPhiRated * 0.5) + val updatedState = calcState(lastState, data, turnOn) + + ( + updatedState, + FlexChangeIndicator( + changesAtNextActivation = true, + updatedState.maybeThermalThreshold.map(_.tick) + ) ) } } /** Create valid [[HpModel]] by calling the apply function. */ -case object HpModel { +object HpModel { def apply( inputModel: HpInput, @@ -209,16 +306,14 @@ case object HpModel { scaling, qControl, Kilowatts( - inputModel.getType - .getsRated() + inputModel.getType.getsRated .to(PowerSystemUnits.KILOWATT) .getValue .doubleValue ), inputModel.getType.getCosPhiRated, Kilowatts( - inputModel.getType - .getpThermal() + inputModel.getType.getpThermal .to(PowerSystemUnits.KILOWATT) .getValue .doubleValue @@ -238,20 +333,27 @@ case object HpModel { * indicates if CHP is turned on * @param lastTimeTick * contains last time tick + * @param ambientTemperature + * Ambient temperature * @param activePower * result active power * @param qDot * result heat power * @param thermalGridState * Currently applicable state of the thermal grid + * @param maybeThermalThreshold + * An optional threshold of the thermal grid, indicating the next state + * change */ final case class HpState( isRunning: Boolean, lastTimeTick: Long, + ambientTemperature: Temperature, activePower: Power, qDot: Power, - thermalGridState: ThermalGridState - ) + thermalGridState: ThermalGridState, + maybeThermalThreshold: Option[ThermalThreshold] + ) extends ModelState /** Main data required for simulation/calculation, containing a [[HpState]] * and the current time tick.

[[HpRelevantData.currentTimeTick]] and @@ -259,13 +361,12 @@ case object HpModel { * calculation. One time tick represents one second (3600 time ticks = 1 * hour). * - * @param hpState - * a [[HpState]] * @param currentTimeTick * contains current time tick + * @param ambientTemperature + * Ambient temperature */ final case class HpRelevantData( - var hpState: HpState, currentTimeTick: Long, ambientTemperature: Temperature ) extends CalcRelevantData diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala new file mode 100644 index 0000000000..33a645970c --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala @@ -0,0 +1,56 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry + +import java.util.UUID +import scala.collection.immutable.{SortedSet, TreeSet} + +/** Charging schedule for an EV for several time intervals + * + * @param ev + * Unique identifier of the car + * @param schedule + * Actual schedule + */ +final case class ChargingSchedule(ev: UUID, schedule: SortedSet[Entry]) {} + +object ChargingSchedule { + def apply(ev: EvModelWrapper, entries: Seq[Entry]) = + new ChargingSchedule(ev.uuid, TreeSet.from(entries)) + + /** Schedule entry specifying a time interval in which the EV should be + * charged with some given power + * + * @param tickStart + * start of charging interval + * @param tickStop + * end of charging interval + * @param chargingPower + * charging power for the charging interval + */ + final case class Entry( + tickStart: Long, + tickStop: Long, + chargingPower: squants.Power + ) extends Ordered[Entry] { + override def compare(that: Entry): Int = { + val startComp = tickStart.compare(that.tickStart) + if (startComp != 0) + startComp + else { + // important for checking equality: consider other fields as well + val stopComp = tickStop.compare(that.tickStop) + if (stopComp != 0) + stopComp + else + chargingPower.compareTo(that.chargingPower) + } + } + } +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingStrategy.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingStrategy.scala new file mode 100644 index 0000000000..d21965f8d1 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingStrategy.scala @@ -0,0 +1,25 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +/** Enumeration that represents all implemented charging strategies + */ +object ChargingStrategy extends Enumeration { + val MAX_POWER, CONSTANT_POWER, GRID_ORIENTED, MARKET_ORIENTED = Value + + def apply(token: String): ChargingStrategy.Value = + "[-_]".r.replaceAllIn(token.trim.toLowerCase, "") match { + case "maxpower" => MAX_POWER + case "constantpower" => CONSTANT_POWER + case "gridorientedscheduling" => GRID_ORIENTED + case "marketorientedscheduling" => MARKET_ORIENTED + case malformed => + throw new RuntimeException( + s"The token '$malformed' cannot be parsed to charging strategy." + ) + } +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala new file mode 100644 index 0000000000..ee8a4b58c5 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala @@ -0,0 +1,50 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +import edu.ie3.simona.api.data.ev.model.EvModel +import edu.ie3.util.quantities.PowerSystemUnits._ +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble +import squants.energy.{KilowattHours, Kilowatts} + +import java.util.UUID + +case class EvModelWrapper( + storedEnergy: squants.Energy, + private val original: EvModel +) { + + def uuid: UUID = original.getUuid + def id: String = original.getId + lazy val sRatedAc: squants.Power = + Kilowatts(original.getSRatedAC.to(KILOWATT).getValue.doubleValue) + lazy val sRatedDc: squants.Power = + Kilowatts(original.getSRatedDC.to(KILOWATT).getValue.doubleValue) + lazy val eStorage: squants.Energy = KilowattHours( + original.getEStorage.to(KILOWATTHOUR).getValue.doubleValue + ) + def departureTick: Long = original.getDepartureTick + + def unwrap(): EvModel = { + original.copyWith( + storedEnergy.toKilowattHours.asKiloWattHour + ) + } + +} + +object EvModelWrapper { + + def apply(evModel: EvModel): EvModelWrapper = { + new EvModelWrapper( + KilowattHours( + evModel.getStoredEnergy.to(KILOWATTHOUR).getValue.doubleValue + ), + evModel + ) + } +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala new file mode 100644 index 0000000000..e302537dc2 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -0,0 +1,1083 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +import com.typesafe.scalalogging.LazyLogging +import edu.ie3.datamodel.models.ElectricCurrentType +import edu.ie3.datamodel.models.input.system.EvcsInput +import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType +import edu.ie3.datamodel.models.result.system.{EvResult, EvcsResult} +import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower +import edu.ie3.simona.model.SystemComponent +import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsRelevantData, + EvcsState +} +import edu.ie3.simona.model.participant.evcs.uncontrolled.{ + ConstantPowerCharging, + MaximumPowerCharging +} +import edu.ie3.simona.model.participant.{ + CalcRelevantData, + FlexChangeIndicator, + ModelState, + SystemParticipant +} +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions +import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.quantities.PowerSystemUnits._ +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble +import edu.ie3.util.scala.OperationInterval +import squants.energy +import squants.energy.{KilowattHours, Kilowatts} +import tech.units.indriya.ComparableQuantity +import tech.units.indriya.unit.Units.PERCENT + +import java.time.ZonedDateTime +import java.util.UUID +import javax.measure.quantity.Power +import scala.collection.SortedMap +import scala.collection.immutable.SortedSet + +/** EV charging station model + * + * @param uuid + * the element's uuid + * @param id + * the element's human readable id + * @param operationInterval + * Interval, in which the system is in operation + * @param scalingFactor + * Scaling the output of the system + * @param simulationStartDate + * The start date of the simulation + * @param qControl + * Type of reactive power control + * @param sRated + * Rated apparent power per charging point + * @param cosPhiRated + * Rated power factor + * @param chargingPoints + * Number of charging points available at this charging station + * @param locationType + * The location type + * @param strategy + * Strategy to follow in oder to determine the charging habits + */ +final case class EvcsModel( + uuid: UUID, + id: String, + operationInterval: OperationInterval, + scalingFactor: Double, + simulationStartDate: ZonedDateTime, + qControl: QControl, + sRated: energy.Power, + currentType: ElectricCurrentType, + cosPhiRated: Double, + chargingPoints: Int, + locationType: EvcsLocationType, + vehicle2grid: Boolean, + strategy: ChargingStrategy.Value, + lowestEvSoc: Double +) extends SystemParticipant[EvcsRelevantData, ApparentPower, EvcsState]( + uuid, + id, + operationInterval, + scalingFactor, + qControl, + (sRated * chargingPoints), + cosPhiRated + ) + with LazyLogging + with MaximumPowerCharging + with ConstantPowerCharging { + + /** Determine scheduling for charging the EVs currently parked at the charging + * station until their departure. The scheduling depends on the chosen + * strategy. + * + * @param data + * data including the current EVs parked at the charging station + * @return + * scheduling for charging the EVs + */ + def calculateNewScheduling( + data: EvcsRelevantData, + evs: Set[EvModelWrapper] + ): Map[EvModelWrapper, Option[ChargingSchedule]] = { + if ( + locationType == EvcsLocationType.CHARGING_HUB_TOWN || locationType == EvcsLocationType.CHARGING_HUB_HIGHWAY + ) { + /* Cars at charging hubs always charge eagerly */ + chargeWithMaximumPower( + data.tick, + evs + ) + } else + scheduleByStrategy( + strategy, + data.tick, + simulationStartDate, + evs, + data.voltages + ) + } + + /** Determine the schedule by defined charging strategy + * + * @param strategy + * Chosen charging strategy + * @param currentTick + * Current simulation time + * @param simulationStartDate + * The simulation start time + * @param evs + * Collection of currently apparent evs + * @param voltages + * Mapping from simulation time to nodal voltage + * @return + * A set of [[ChargingSchedule]]s + */ + private def scheduleByStrategy( + strategy: ChargingStrategy.Value, + currentTick: Long, + simulationStartDate: ZonedDateTime, + evs: Set[EvModelWrapper], + voltages: Map[ZonedDateTime, squants.Dimensionless] + ): Map[EvModelWrapper, Option[ChargingSchedule]] = strategy match { + case ChargingStrategy.MAX_POWER => + chargeWithMaximumPower( + currentTick, + evs + ) + case ChargingStrategy.CONSTANT_POWER => + chargeWithConstantPower( + currentTick, + evs + ) + case ChargingStrategy.GRID_ORIENTED => + throw new NotImplementedError( + "Grid oriented strategy currently not implemented" + ) + case ChargingStrategy.MARKET_ORIENTED => + throw new NotImplementedError( + "Market oriented strategy currently not implemented" + ) + + } + + /** Update EVs for the timeframe since the last scheduling + * + * @param state + * the last state + * @param currentTick + * current tick + * @return + * updated EVs + */ + def applySchedule( + state: EvcsState, + currentTick: Long + ): Set[EvModelWrapper] = if (state.schedule.nonEmpty) { + state.evs + .map(ev => + state + .getSchedule(ev) + .map { + chargeEv( + ev, + _, + state.tick, + currentTick + ) + } + .getOrElse(ev) + ) + } else { + logger.debug( + "There are EVs parked at this charging station, but there was no scheduling since the last" + + "update. Probably the EVs already finished charging." + ) + state.evs + } + + /** Charge the given EV under consideration a applicable schedule + * + * @param ev + * Electric vehicle to charge + * @param schedule + * Schedule for this car + * @param lastSchedulingTick + * Last tick, that a schedule has been processed + * @param currentTick + * Current time in Simulation + * @return + * The charged EV + */ + private def chargeEv( + ev: EvModelWrapper, + schedule: ChargingSchedule, + lastSchedulingTick: Long, + currentTick: Long + ): EvModelWrapper = { + /* Determine charged energy in the charging interval */ + val chargedEnergySinceLastScheduling = + schedule.schedule.toSeq + .filter { case ChargingSchedule.Entry(tickStart, tickStop, _) => + /* Filter for entries, that end after the last schedule application (that slice is not yet fully applied) + * and that start before the current tick */ + tickStop > lastSchedulingTick && tickStart < currentTick + } + .sortBy(_.tickStart) + .foldLeft(KilowattHours(0d)) { + case (accumulatedEnergy, scheduleEntry) => + /* Only the timeframe from the start of last scheduling update and current tick must be considered */ + val trimmedEntry = trimScheduleEntry( + scheduleEntry, + lastSchedulingTick, + currentTick + ) + + /* Determine the energy charged within this slice of the schedule and accumulate it */ + accumulatedEnergy + chargedEnergyInScheduleEntry(trimmedEntry) + } + /* Update EV with the charged energy during the charging interval */ + ev.copy( + storedEnergy = ev.storedEnergy + chargedEnergySinceLastScheduling + ) + } + + def createResults( + lastState: EvcsState, + currentTick: Long, + voltageMagnitude: squants.Dimensionless + ): (Iterable[EvResult], Iterable[EvcsResult]) = { + + val lastTick = lastState.tick + + val lastEvMap = lastState.evs.map(ev => ev.uuid -> ev).toMap + + val prefilteredSchedules = lastState.schedule.values.flatten + .map { case schedule @ ChargingSchedule(_, entries) => + val filteredEntries = entries + .filter { case ChargingSchedule.Entry(tickStart, tickStop, _) => + /* Filter for entries, that end after the last schedule application + and that start before the current tick. + Entries that end at lastTick are not included because schedule + intervals are open at the right hand side. + Entries that start at currentTick are not included because these + will be calculated with the next state. + */ + tickStop > lastTick && tickStart < currentTick + } + + schedule.copy( + schedule = filteredEntries + ) + } + + val entriesByStartTick = prefilteredSchedules + .flatMap { case ChargingSchedule(evUuid, schedule) => + schedule.unsorted + .map { entry => + // trim down entries to the currently considered window of the charging schedule + evUuid -> trimScheduleEntry( + entry, + lastTick, + currentTick + ) + } + } + .groupBy { case _ -> entry => + entry.tickStart + } + .to(SortedMap) + + val startAndStopTicks = prefilteredSchedules + .flatMap { case ChargingSchedule(_, schedule) => + schedule.unsorted.flatMap { + case ChargingSchedule.Entry(start, stop, _) => + Iterable(start, stop) + } + } + .filter(tick => tick >= lastTick && tick < currentTick) + .to(SortedSet) + // the last tick needs to be included, + // the current tick excluded + .incl(lastTick) + .excl(currentTick) + + // in order to create 0kW entries for EVs that do not + // start charging right away at lastTick, create mock + // schedule entries that end before lastTick + val startingSchedules = lastEvMap.keys.map { + _ -> ChargingSchedule.Entry(lastTick, lastTick, Kilowatts(0d)) + } + + val (currentEvs, currentSchedules, evResults, evcsResults) = + startAndStopTicks.foldLeft( + lastEvMap, + startingSchedules, + Seq.empty[EvResult], + Seq.empty[EvcsResult] + ) { case ((evMap, lastActiveEntries, evResults, evcsResults), tick) => + val time = tick.toDateTime(simulationStartDate) + + val (stillActive, endedEntries) = lastActiveEntries.partition { + case (_, entry) => + entry.tickStop > tick + } + + val newActiveEntries = + entriesByStartTick.getOrElse(tick, Iterable.empty).toMap + + val noChargingEvResults = + endedEntries + .filterNot { case evUuid -> _ => + newActiveEntries.contains(evUuid) + } + .map { case evUuid -> _ => + val ev = evMap(evUuid) + + createEvResult( + ev, + tick, + Kilowatts(0d), + voltageMagnitude + ) + } + + val (updatedEvMap, chargingEvResults) = + newActiveEntries.foldLeft(evMap, Seq.empty[EvResult]) { + case ((evMap, results), evUuid -> entry) => + val ev = evMap(evUuid) + + val result = createEvResult( + ev, + entry.tickStart, + entry.chargingPower, + voltageMagnitude + ) + + // update EV + val newEvStoredEnergy = ev.storedEnergy + + chargedEnergyInScheduleEntry(entry) + val newEv = ev.copy(storedEnergy = newEvStoredEnergy) + + ( + evMap.updated(evUuid, newEv), + results.appended(result) + ) + } + + val currentActiveEntries = stillActive ++ newActiveEntries + + val evcsP = currentActiveEntries.foldLeft(Kilowatts(0d)) { + case (powerSum, _ -> entry) => + powerSum + entry.chargingPower + } + + val evcsQ = calculateReactivePower( + evcsP, + voltageMagnitude + ) + + val evcsResult = new EvcsResult( + time, + uuid, + evcsP.toMegawatts.asMegaWatt, + evcsQ.toMegavars.asMegaVar + ) + + ( + updatedEvMap, + currentActiveEntries, + evResults ++ chargingEvResults ++ noChargingEvResults, + evcsResults :+ evcsResult + ) + } + + // special case: also add EVs that are departing at current tick + // because they won't be included when the next results are created + val departingEvResults = currentSchedules + .map { case evUuid -> _ => + currentEvs(evUuid) + } + .filter { + // only take those that are departing now + _.departureTick == currentTick + } + .map { + createEvResult( + _, + currentTick, + Kilowatts(0d), + voltageMagnitude + ) + } + + (evResults ++ departingEvResults, evcsResults) + } + + private def createEvResult( + ev: EvModelWrapper, + tick: Long, + p: squants.Power, + voltageMagnitude: squants.Dimensionless + ) = { + val q = calculateReactivePower( + p, + voltageMagnitude + ) + val soc = (ev.storedEnergy / ev.eStorage).asPu + .to(PERCENT) + + new EvResult( + tick.toDateTime(simulationStartDate), + ev.uuid, + p.toMegawatts.asMegaWatt, + q.toMegavars.asMegaVar, + soc + ) + } + + /** Limit the actual charging window. The beginning is determined by the + * latest tick of either the schedule start or the last scheduled tick. The + * end is determined by the earlier tick of either the schedule end or the + * current tick. + * + * @param scheduleEntry + * Section of a scheduled + * @param lastSchedulingTick + * The last scheduling tick + * @param currentTick + * The current tick + * @return + * A trimmed version of given scheduleEntry + */ + private def trimScheduleEntry( + scheduleEntry: ChargingSchedule.Entry, + lastSchedulingTick: Long, + currentTick: Long + ): ChargingSchedule.Entry = + scheduleEntry.copy( + tickStart = math.max(scheduleEntry.tickStart, lastSchedulingTick), + tickStop = math.min(scheduleEntry.tickStop, currentTick) + ) + + /** Determine the energy, that has been charged during the schedule entry time + * interval. + * + * @param scheduleEntry + * The schedule entry + * @return + * The energy charged during the time interval of the schedule entry + */ + private def chargedEnergyInScheduleEntry( + scheduleEntry: ChargingSchedule.Entry + ): squants.Energy = + scheduleEntry.chargingPower * squants.time.Seconds( + scheduleEntry.tickStop - scheduleEntry.tickStart + ) + + /** Returns the maximum available charging power for an EV, which depends on + * ev and charging station limits for AC and DC current + * + * @param ev + * ev for which the max charging power should be returned + * @return + * maximum charging power for the EV at this charging station + */ + def getMaxAvailableChargingPower( + ev: EvModelWrapper + ): squants.Power = { + val evPower = currentType match { + case ElectricCurrentType.AC => + ev.sRatedAc + case ElectricCurrentType.DC => + ev.sRatedDc + } + /* Limit the charging power to the minimum of ev's and evcs' permissible power */ + evPower.min(sRated) + } + + /** Calculate the power behaviour based on the given data. + * + * @param tick + * Regarded instant in simulation + * @param voltage + * Nodal voltage magnitude + * @param modelState + * Current state of the model + * @param data + * Further needed, secondary data + * @return + * A tuple of active and reactive power + */ + override def calculatePower( + tick: Long, + voltage: squants.Dimensionless, + modelState: EvcsState, + data: EvcsRelevantData + ): ApparentPower = ??? + + /** Calculate the active power behaviour of the model + * + * @param modelState + * Current state of the model + * @param data + * Further needed, secondary data + * @return + * Active power + */ + override protected def calculateActivePower( + modelState: EvcsState, + data: EvcsRelevantData + ): squants.Power = + throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") + + override def determineFlexOptions( + data: EvcsRelevantData, + lastState: EvcsState + ): FlexibilityMessage.ProvideFlexOptions = { + + val currentEvs = determineCurrentState(data, lastState) + + val preferredScheduling = calculateNewScheduling(data, currentEvs) + + val preferredPower = + preferredScheduling.values.flatten.foldLeft(Kilowatts(0d)) { + case (sum, ChargingSchedule(_, schedule)) => + val power = + schedule + .find { case ChargingSchedule.Entry(tickStart, tickStop, _) => + tickStart <= data.tick && tickStop > data.tick + } + .map(_.chargingPower) + .getOrElse(Kilowatts(0d)) + sum + power + } + + val (maxCharging, forcedCharging, maxDischarging) = + preferredScheduling.foldLeft( + (Kilowatts(0d), Kilowatts(0d), Kilowatts(0d)) + ) { case ((chargingSum, forcedSum, dischargingSum), (ev, _)) => + val maxPower = getMaxAvailableChargingPower(ev) + + val maxCharging = + if (!isFull(ev)) + maxPower + else + Kilowatts(0d) + + val forcedCharging = + if (isEmpty(ev) && !isInLowerMargin(ev)) + maxPower // TODO maybe use preferred power instead + else + Kilowatts(0d) + + val maxDischarging = + if (!isEmpty(ev) && vehicle2grid) + maxPower * -1 + else + Kilowatts(0d) + + ( + chargingSum + maxCharging, + forcedSum + forcedCharging, + dischargingSum + maxDischarging + ) + } + + // if we need to charge at least one EV, we cannot discharge any other + val (adaptedMin, adaptedPreferred) = + if (forcedCharging > Kilowatts(0d)) + (forcedCharging, preferredPower.max(forcedCharging)) + else + (maxDischarging, preferredPower) + + ProvideMinMaxFlexOptions( + uuid, + adaptedPreferred, + adaptedMin, + maxCharging + ) + } + + // TODO sometimes we issue too early nextTicks, since remaining power might be added to remaining non-full vehicles + // (minor) TODO? if IssueNoControl is sent, there might be a different result than anticipated when calculating flex options (strat is not used) + override def handleControlledPowerChange( + data: EvcsRelevantData, + lastState: EvcsState, + setPower: squants.Power + ): (EvcsState, FlexChangeIndicator) = { + val currentEvs = determineCurrentState(data, lastState) + + if (setPower == Kilowatts(0d)) + return ( + EvcsState( + evs = currentEvs, + schedule = currentEvs.map(_ -> None).toMap, + tick = data.tick + ), + FlexChangeIndicator() + ) + + // applicable evs can be charged/discharged, other evs cannot + val (applicableEvs, otherEvs) = currentEvs.partition { ev => + if (setPower > Kilowatts(0d)) + !isFull(ev) + else + !isEmpty(ev) + } + + val (forcedChargingEvs, regularChargingEvs) = + if (setPower > Kilowatts(0d)) + // lower margin is excluded since charging is not required here anymore + applicableEvs.partition { ev => + isEmpty(ev) && !isInLowerMargin(ev) + } + else + (Set.empty[EvModelWrapper], applicableEvs) + + val (forcedSchedules, remainingPower) = + createScheduleWithSetPower(data.tick, forcedChargingEvs, setPower) + + val (regularSchedules, _) = + createScheduleWithSetPower(data.tick, regularChargingEvs, remainingPower) + + val combinedSchedules = forcedSchedules ++ regularSchedules + + val schedulesOnly = combinedSchedules.flatMap { case (_, scheduleOpt) => + scheduleOpt + } + + val scheduleAtNextActivation = schedulesOnly + .map { case (_, _, scheduleAtNext) => scheduleAtNext } + .reduceOption(_ || _) + .getOrElse(false) + + val nextScheduledTick = schedulesOnly.map { case (_, endTick, _) => + endTick + }.minOption + + val allSchedules = combinedSchedules.map { + case (ev, Some((schedule, _, _))) => + ev -> Some(schedule) + case (ev, None) => ev -> None + }.toMap ++ otherEvs.map(_ -> None).toMap + + ( + EvcsState( + evs = allSchedules.keys.toSet, + schedule = allSchedules, + tick = data.tick + ), + FlexChangeIndicator( + scheduleAtNextActivation, + nextScheduledTick + ) + ) + } + + /** @param currentTick + * The current tick + * @param evs + * The collection of EVs to assign charging power to + * @param setPower + * The remaining power to assign to given EVs + * @return + * A set of EV model and possibly charging schedule and activation + * indicators, as well as the remaining power that could not be assigned to + * given EVs + */ + private def createScheduleWithSetPower( + currentTick: Long, + evs: Set[EvModelWrapper], + setPower: squants.Power + ): ( + Set[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])], + squants.Power + ) = { + + if (evs.isEmpty) return (Set.empty, setPower) + + if (setPower.~=(Kilowatts(0d))(Kilowatts(1e-6))) { + // No power left. Rest is not charging + return (evs.map { _ -> None }, Kilowatts(0d)) + } + + val proposedPower = setPower.divide(evs.size) + + val (exceedingPowerEvs, fittingPowerEvs) = evs.partition { ev => + if (setPower > Kilowatts(0d)) + proposedPower > getMaxAvailableChargingPower(ev) + else + proposedPower < (getMaxAvailableChargingPower(ev) * -1) + } + + if (exceedingPowerEvs.isEmpty) { + // end of recursion, rest of charging power fits to all + + val results = fittingPowerEvs.map { ev => + val chargingTicks = calculateChargingDuration(ev, proposedPower) + val endTick = Math.min(currentTick + chargingTicks, ev.departureTick) + + ( + ev, + Some( + ChargingSchedule( + ev, + Seq(ChargingSchedule.Entry(currentTick, endTick, proposedPower)) + ), + endTick, + isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) + ) + ) + }: Set[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])] + + (results, Kilowatts(0d)) + } else { + // not all evs can be charged with proposed power + + // charge all exceeded evs with their respective maximum power + val maxCharged = exceedingPowerEvs.map { ev => + val maxPower = getMaxAvailableChargingPower(ev) + val power = + if (setPower > Kilowatts(0d)) + maxPower + else + maxPower * (-1) + + val chargingTicks = calculateChargingDuration(ev, power) + val endTick = Math.min(currentTick + chargingTicks, ev.departureTick) + + (ev, power, endTick) + } + + // sum up allocated power + val chargingPowerSum = maxCharged.foldLeft(Kilowatts(0d)) { + case (powerSum, (_, chargingPower, _)) => + powerSum + chargingPower + } + + val remainingAfterAllocation = setPower - chargingPowerSum + + // go into the next recursion step with the remaining power + val (nextIterationResults, remainingAfterRecursion) = + createScheduleWithSetPower( + currentTick, + fittingPowerEvs, + remainingAfterAllocation + ) + + val combinedResults = maxCharged.map { case (ev, power, endTick) => + ( + ev, + Some( + ChargingSchedule( + ev, + Seq(ChargingSchedule.Entry(currentTick, endTick, power)) + ), + endTick, + isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) + ) + ) + } ++ nextIterationResults + + (combinedResults, remainingAfterRecursion) + } + + } + + private def calculateChargingDuration( + ev: EvModelWrapper, + power: squants.Power + ): Long = { + val timeUntilFullOrEmpty = + if (power > Kilowatts(0d)) { + + // if we're below lowest SOC, flex options will change at that point + val targetEnergy = + if (isEmpty(ev) && !isInLowerMargin(ev)) + ev.eStorage * lowestEvSoc + else + ev.eStorage + + (targetEnergy - ev.storedEnergy) / power + } else + (ev.storedEnergy - (ev.eStorage * lowestEvSoc)) / (power * (-1)) + + Math.round(timeUntilFullOrEmpty.toSeconds) + } + + /** @param ev + * the ev whose stored energy is to be checked + * @return + * whether the given ev's stored energy is greater than the maximum charged + * energy allowed (minus a tolerance margin) + */ + private def isFull(ev: EvModelWrapper): Boolean = + ev.storedEnergy >= (ev.eStorage - calcToleranceMargin(ev)) + + /** @param ev + * the ev whose stored energy is to be checked + * @return + * whether the given ev's stored energy is less than the minimal charged + * energy allowed (plus a tolerance margin) + */ + private def isEmpty(ev: EvModelWrapper): Boolean = + ev.storedEnergy <= ( + ev.eStorage * lowestEvSoc + calcToleranceMargin(ev) + ) + + /** @param ev + * the ev whose stored energy is to be checked + * @return + * whether the given ev's stored energy is within +- tolerance of the + * minimal charged energy allowed + */ + private def isInLowerMargin(ev: EvModelWrapper): Boolean = { + val toleranceMargin = calcToleranceMargin(ev) + val lowestSoc = ev.eStorage * lowestEvSoc + + ev.storedEnergy <= ( + lowestSoc + toleranceMargin + ) && ev.storedEnergy >= ( + lowestSoc - toleranceMargin + ) + } + + private def calcToleranceMargin(ev: EvModelWrapper): squants.Energy = + getMaxAvailableChargingPower(ev) * squants.time.Seconds(1) + + /** Determines the current state of staying and arriving EVs. + * + * @param data + * the EvcsRelevantData containing arriving EVs, the current tick etc. + * @param lastState + * the last known state of the EVCS. Could be the state at the current + * tick. + * @return + * The EVs currently parked at the EVCS, including the arriving EVs + */ + def determineCurrentState( + data: EvcsRelevantData, + lastState: EvcsState + ): Set[EvModelWrapper] = { + // TODO use Seq instead of Set as return value + + // if last state is from before current tick, determine current state + val currentEVs = + if (lastState.tick < data.tick) + applySchedule(lastState, data.tick) + else + lastState.evs + + validateArrivals( + lastState.evs, + data.arrivals, + chargingPoints + ) + + currentEVs ++ data.arrivals + } + + /** Checks whether requested departing EVs are consistent with currently + * connected EVs. Only logs warnings, does not throw exceptions. + * + * @param lastEvs + * EVs of the last tick + * @param departures + * Departing EVs at the current tick + */ + def validateDepartures( + lastEvs: Set[EvModelWrapper], + departures: Seq[UUID] + ): Unit = { + departures.foreach { ev => + if (!lastEvs.exists(_.uuid == ev)) + logger.warn( + s"EV $ev should depart from this station (according to external simulation), but has not been parked here." + ) + } + + } + + /** Checks whether provided arriving EVs are consistent with charging station + * specifications and currently connected EVs. Only logs warnings, does not + * throw exceptions. + * + * @param lastEvs + * EVs of the last tick + * @param arrivals + * Arriving EVs at the current tick + * @param chargingPoints + * max number of charging points available at this CS + */ + def validateArrivals( + lastEvs: Set[EvModelWrapper], + arrivals: Seq[EvModelWrapper], + chargingPoints: Int + ): Unit = { + + arrivals.foreach { ev => + if (lastEvs.exists(_.uuid == ev.uuid)) + logger.warn( + s"EV ${ev.id} should arrive at this station (according to external simulation), but is already parked here." + ) + } + + val newCount = lastEvs.size + + arrivals.count { ev => + !lastEvs.exists(_.uuid == ev.uuid) + } + + if (newCount > chargingPoints) + logger.warn( + "More EVs are parking at this station than physically possible." + ) + } +} + +object EvcsModel { + + /** Class that holds all relevant data for an Evcs model calculation + * + * @param tick + * The current tick + * @param arrivals + * The evs arriving at the current tick + * @param voltages + * Nodal voltage per known time instant + */ + final case class EvcsRelevantData( + tick: Long, + arrivals: Seq[EvModelWrapper], + voltages: Map[ZonedDateTime, squants.Dimensionless] + ) extends CalcRelevantData + + /** Class that represents the state of the charging station at a given point + * in time + * + * @param evs + * EVs that are staying at the charging station + * @param schedule + * the schedule determining when to load which EVs with which power + * @param tick + * The tick that the data has been calculated for + */ + final case class EvcsState( + evs: Set[EvModelWrapper], + schedule: Map[EvModelWrapper, Option[ChargingSchedule]], + tick: Long + ) extends ModelState { + def getSchedule(ev: EvModelWrapper): Option[ChargingSchedule] = + schedule.getOrElse(ev, None) + } + + def apply( + inputModel: EvcsInput, + scalingFactor: Double, + simulationStartDate: ZonedDateTime, + simulationEndDate: ZonedDateTime, + chargingStrategy: String, + lowestEvSoc: Double + ): EvcsModel = { + /* Determine the operation interval */ + val operationInterval: OperationInterval = + SystemComponent.determineOperationInterval( + simulationStartDate, + simulationEndDate, + inputModel.getOperationTime + ) + + apply( + inputModel.getUuid, + inputModel.getId, + operationInterval, + scalingFactor, + simulationStartDate, + QControl(inputModel.getqCharacteristics), + inputModel.getType.getsRated, + inputModel.getType.getElectricCurrentType, + inputModel.getCosPhiRated, + inputModel.getChargingPoints, + inputModel.getLocationType, + inputModel.getV2gSupport, + ChargingStrategy(chargingStrategy), + lowestEvSoc + ) + } + + /** Default factory method to create an EvcsModel instance. + * + * @param uuid + * the unique id of the model + * @param id + * the human readable id + * @param operationInterval + * the operation interval of the model + * @param scalingFactor + * the scaling factor of the power output + * @param simulationStartDate + * The start date of the simulation + * @param qControl + * the q control this model is using + * @param sRated + * the rated apparent power of the model + * @param cosPhiRated + * the rated cosine phi of the model + * @param chargingPoints + * Number of charging points available at this charging station + * @param locationType + * The location type + * @param chargingStrategy + * The charging strategy to use + * @return + * the enabled EvcsModel + */ + def apply( + uuid: UUID, + id: String, + operationInterval: OperationInterval, + scalingFactor: Double, + simulationStartDate: ZonedDateTime, + qControl: QControl, + sRated: ComparableQuantity[Power], + currentType: ElectricCurrentType, + cosPhiRated: Double, + chargingPoints: Int, + locationType: EvcsLocationType, + vehicle2grid: Boolean, + chargingStrategy: ChargingStrategy.Value, + lowestEvSoc: Double + ): EvcsModel = { + val model = new EvcsModel( + uuid, + id, + operationInterval, + scalingFactor, + simulationStartDate, + qControl, + energy.Kilowatts(sRated.to(KILOWATT).getValue.doubleValue), + currentType, + cosPhiRated, + chargingPoints, + locationType, + vehicle2grid, + chargingStrategy, + lowestEvSoc + ) + + model.enable() + + model + } +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala new file mode 100644 index 0000000000..b0e21a468b --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala @@ -0,0 +1,79 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +import edu.ie3.simona.api.data.ev.model.EvModel +import edu.ie3.util.quantities.interfaces.EnergyPrice +import tech.units.indriya.ComparableQuantity + +import javax.measure.quantity.Dimensionless + +object SchedulingTimeWindows { + + /** Time window used for the scheduling of ev charging. */ + trait SchedulingTimeWindow { + val start: Long + val end: Long + + /** @return + * Length of the window in seconds + */ + def length: Long = end - start + 1 + } + + /** Time window used for the scheduling of ev charging. Additional information + * on the voltages in the time window. + * + * @param start + * start of time window + * @param end + * end of time window + * @param voltage + * predicted voltage in this time window + * @param voltageDeviation + * deviation from reference voltage in the schedule time + * @param size + * size of the time window expressed as voltage deviation * length + * @param parkedEvs + * still parked ev in this time window + */ + case class SchedulingTimeWindowWithVoltage( + override val start: Long, + override val end: Long, + voltage: ComparableQuantity[Dimensionless], + voltageDeviation: ComparableQuantity[Dimensionless], + size: Double, + parkedEvs: Set[EvModel] + ) extends SchedulingTimeWindow { + override def toString: String = + s"SchedulingTimeWindow(start=$start, end=$end, voltage=$voltage, voltageDeviation=$voltageDeviation, " + + s"timeBoxLength=$length, timeBoxSize=$size, parkedEvs=${parkedEvs + .foldLeft(Set.empty[String])((names: Set[String], ev: EvModel) => { + names + ev.getId + })})" + } + + /** Time window used for the scheduling of ev charging. Additional information + * on the voltages in the time window. + * + * @param start + * start of time window + * @param end + * end of time window + * @param price + * predicted price in this time window + */ + case class SchedulingSliceWithPrice( + start: Long, + end: Long, + price: ComparableQuantity[EnergyPrice] + ) extends SchedulingTimeWindow { + override def toString: String = + s"SchedulingTimeWindow(start=$start, end=$end, price=$price, timeBoxLength=$length)" + } + +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala new file mode 100644 index 0000000000..82fa7d6249 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala @@ -0,0 +1,54 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs.uncontrolled + +import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry +import edu.ie3.simona.model.participant.evcs.{ + ChargingSchedule, + EvModelWrapper, + EvcsModel +} +import squants.time.Seconds + +trait ConstantPowerCharging { + this: EvcsModel => + + /** Determine scheduling for charging the EVs currently parked at the charging + * station until their departure. In this case, each EV is charged with + * constant power from current time until departure. If less than the maximum + * power is required to reach 100% SoC, the power is reduced accordingly. + * + * @param currentTick + * current tick + * @param evs + * currently parked evs at the charging station + * @return + * scheduling for charging the EVs + */ + def chargeWithConstantPower( + currentTick: Long, + evs: Set[EvModelWrapper] + ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => + ev -> Option.when(ev.storedEnergy < ev.eStorage) { + val maxChargingPower = getMaxAvailableChargingPower(ev) + val remainingParkingTime = Seconds(ev.departureTick - currentTick) + + val requiredEnergyUntilFull = ev.eStorage - ev.storedEnergy + val maxChargedEnergyUntilDeparture = + maxChargingPower * remainingParkingTime + val actualChargedEnergy = + requiredEnergyUntilFull.min(maxChargedEnergyUntilDeparture) + + val chargingPower = actualChargedEnergy / remainingParkingTime + + ChargingSchedule( + ev, + Seq(Entry(currentTick, ev.departureTick, chargingPower)) + ) + } + }.toMap +} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala new file mode 100644 index 0000000000..d068f0b7ba --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala @@ -0,0 +1,57 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs.uncontrolled + +import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry +import edu.ie3.simona.model.participant.evcs.{ + ChargingSchedule, + EvModelWrapper, + EvcsModel +} + +trait MaximumPowerCharging { + this: EvcsModel => + + /** Determine scheduling for charging the EVs currently parked at the charging + * station until their departure. In this case, each EV is charged with + * maximum power from current time until it reaches either 100% SoC or its + * departure time. + * + * @param currentTick + * current tick + * @param evs + * currently parked evs at the charging station + * @return + * scheduling for charging the EVs + */ + def chargeWithMaximumPower( + currentTick: Long, + evs: Set[EvModelWrapper] + ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => + ev -> Option.when(ev.storedEnergy < ev.eStorage) { + val chargingPower = getMaxAvailableChargingPower(ev) + val remainingParkingTime = + squants.Seconds(ev.departureTick - currentTick) + + val possibleChargeableEnergyUntilDeparture = + chargingPower * remainingParkingTime + + val endTick: Long = + if ( + ev.storedEnergy + possibleChargeableEnergyUntilDeparture <= ev.eStorage + ) { + /* Charge with full power, if battery can accommodate the energy */ + ev.departureTick + } else { + /* Charge only until the car is full */ + ((ev.eStorage - ev.storedEnergy) / chargingPower).toSeconds.toLong + currentTick + } + + ChargingSchedule(ev, Seq(Entry(currentTick, endTick, chargingPower))) + } + }.toMap +} diff --git a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala index 19d3470526..1d750cae6f 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala @@ -97,35 +97,35 @@ final case class CylindricalThermalStorage( ): (ThermalStorageState, Option[ThermalThreshold]) = { /* Determine new state based on time difference and given state */ val energyBalance = lastState.qDot * Seconds(tick - lastState.tick) - val newEnergy = lastState.storedEnergy + energyBalance - val updatedEnergy = newEnergy match { - case energy if energy > maxEnergyThreshold => maxEnergyThreshold - case energy if energy < minEnergyThreshold => minEnergyThreshold - case energy => energy - } + val updatedEnergy = + if (isFull(newEnergy)) + maxEnergyThreshold + else if (isEmpty(newEnergy)) + minEnergyThreshold + else + newEnergy /* Determine, when a threshold is reached */ - val nextThreshold = { - qDot match { - case positive if qDot > Megawatts(0d) => { - val duration = (maxEnergyThreshold - updatedEnergy) / qDot - Some(StorageFull(tick + Math.max(duration.toSeconds.toLong, 0L))) - } - case negative if qDot < Megawatts(0d) => { - val duration = ((updatedEnergy - minEnergyThreshold) / qDot * (-1)) - Some(StorageEmpty(tick + Math.max(duration.toSeconds.toLong, 0L))) - } - - case equal if qDot == Megawatts(0d) => { - - ThermalStorageState(tick, updatedEnergy, qDot) + val nextThreshold = + if (qDot > Megawatts(0d)) { + val duration = (maxEnergyThreshold - updatedEnergy) / qDot + val durationInTicks = Math.round(duration.toSeconds) + if (durationInTicks <= 0L) None - } - + else + Some(StorageFull(tick + durationInTicks)) + } else if (qDot < Megawatts(0d)) { + val duration = (updatedEnergy - minEnergyThreshold) / qDot * (-1) + val durationInTicks = Math.round(duration.toSeconds) + if (durationInTicks <= 0L) + None + else + Some(StorageEmpty(tick + durationInTicks)) + } else { + return (ThermalStorageState(tick, updatedEnergy, qDot), None) } - } (ThermalStorageState(tick, updatedEnergy, qDot), nextThreshold) } @@ -197,8 +197,8 @@ case object CylindricalThermalStorage { .getValue .doubleValue ), - Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue), - Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue) + Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue()), + Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()) ) val maxEnergyThreshold: Energy = @@ -212,13 +212,14 @@ case object CylindricalThermalStorage { .getValue .doubleValue ), - Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue), - Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue) + Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue()), + Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()) ) /* TODO: Currently, the input model does not define any maximum charge power. Assume, that the usable energy can * be charged / discharged within the interval of an hour */ val chargingPower = (maxEnergyThreshold - minEnergyThreshold) / Hours(1d) + new CylindricalThermalStorage( input.getUuid, input.getId, diff --git a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala index acd5c33317..f9a1a5aa91 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala @@ -18,7 +18,9 @@ trait RandomStorageState { override def startingState: ThermalStorage.ThermalStorageState = { def rnd: Double = new Random(seed).nextDouble() - def storedEnergy: Energy = getMaxEnergyThreshold * rnd + def storedEnergy: Energy = getMinEnergyThreshold + ( + getMaxEnergyThreshold - (getMinEnergyThreshold * rnd) + ) ThermalStorageState( -1L, diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala index a1342c34ee..fc56536e97 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -19,15 +19,11 @@ import edu.ie3.simona.model.thermal.ThermalGrid.{ ThermalGridState } import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState -import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.HouseTemperatureUpperBoundaryReached import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState -import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.StorageEmpty import edu.ie3.simona.util.TickUtil.TickLong -import edu.ie3.util.quantities.PowerSystemUnits +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import squants.energy.{Kilowatts, MegawattHours, Megawatts} import squants.{Energy, Power, Temperature} -import tech.units.indriya.quantity.Quantities -import tech.units.indriya.unit.Units import java.time.ZonedDateTime import scala.jdk.CollectionConverters.SetHasAsScala @@ -86,10 +82,7 @@ final case class ThermalGrid( ) } .getOrElse( - ( - MegawattHours(0d), - MegawattHours(0d) - ) + (MegawattHours(0d), MegawattHours(0d)) ) } @@ -98,8 +91,7 @@ final case class ThermalGrid( houseDemand.required else storedEnergy - val finallyRemaining = - remainingCapacity + usedEnergy + val finallyRemaining = remainingCapacity + usedEnergy ThermalEnergyDemand( houseDemand.required - usedEnergy, @@ -124,10 +116,7 @@ final case class ThermalGrid( state: ThermalGridState, ambientTemperature: Temperature, qDot: Power - ): (ThermalGridState, Option[ThermalThreshold]) = if ( - qDot > - Kilowatts(0d) - ) + ): (ThermalGridState, Option[ThermalThreshold]) = if (qDot > Kilowatts(0d)) handleInfeed(tick, ambientTemperature, state, qDot) else handleConsumption(tick, ambientTemperature, state, qDot) @@ -155,7 +144,7 @@ final case class ThermalGrid( case Some((thermalHouse, lastHouseState)) => /* Set thermal power exchange with storage to zero */ // TODO: We would need to issue a storage result model here... - val zeroStorageState = storage.zip(state.storageState) match { + val updatedStorageState = storage.zip(state.storageState) match { case Some((thermalStorage, storageState)) => Some( thermalStorage @@ -169,51 +158,59 @@ final case class ThermalGrid( case _ => state.storageState } - thermalHouse.updateState( + val (updatedHouseState, maybeHouseThreshold) = thermalHouse.updateState( tick, lastHouseState, ambientTemperature, qDot - ) match { - case (_, Some(HouseTemperatureUpperBoundaryReached(thresholdTick))) - if thresholdTick == tick => - /* The house is already heated up fully, set back the infeed and put it into storage, if available */ - val (updatedHouseState, maybeHouseThreshold) = - thermalHouse.updateState( - tick, - lastHouseState, - ambientTemperature, - Kilowatts(0d) + ) + + if ( + thermalHouse.isInnerTemperatureTooHigh( + updatedHouseState.innerTemperature + ) + ) { + /* The house is already heated up fully, set back the infeed and put it into storage, if available */ + val (fullHouseState, maybeFullHouseThreshold) = + thermalHouse.updateState( + tick, + lastHouseState, + ambientTemperature, + Kilowatts(0d) + ) + storage.zip(updatedStorageState) match { + case Some((thermalStorage, storageState)) => + val (updatedStorageState, maybeStorageThreshold) = + thermalStorage.updateState(tick, qDot, storageState) + + /* Both house and storage are updated. Determine what reaches the next threshold */ + val nextThreshold = determineMostRecentThreshold( + maybeFullHouseThreshold, + maybeStorageThreshold ) - storage.zip(zeroStorageState) match { - case Some((thermalStorage, storageState)) => - val (updatedStorageState, maybeStorageThreshold) = - thermalStorage.updateState(tick, qDot, storageState) - - /* Both house and storage are updated. Determine what reaches the next threshold */ - val nextThreshold = determineMostRecentThreshold( - maybeHouseThreshold, - maybeStorageThreshold - ) - ( - state.copy( - houseState = Some(updatedHouseState), - storageState = Some(updatedStorageState) - ), - nextThreshold - ) - case None => - /* There is no storage, house determines the next activation */ - ( - state.copy(houseState = Some(updatedHouseState)), - maybeHouseThreshold - ) - } - case (updatedState, maybeThreshold) => - /* The house can handle the infeed */ - (state.copy(houseState = Some(updatedState)), maybeThreshold) + ( + state.copy( + houseState = Some(fullHouseState), + storageState = Some(updatedStorageState) + ), + nextThreshold + ) + case None => + /* There is no storage, house determines the next activation */ + ( + state.copy(houseState = Some(fullHouseState)), + maybeFullHouseThreshold + ) + } + } else { + /* The house can handle the infeed */ + ( + state.copy(houseState = Some(updatedHouseState)), + maybeHouseThreshold + ) } + case None => storage.zip(state.storageState) match { case Some((thermalStorage, storageState)) => @@ -343,17 +340,17 @@ final case class ThermalGrid( case Some( ( (thermalHouse, (houseState, _)), - (thermalStorage, (_, maybeStorageThreshold)) + (thermalStorage, (storageState, _)) ) ) - if (Math.abs(qDot.toKilowatts) < 10e-3) && thermalHouse - .isInnerTemperatureTooLow( + if qDot.~=(Kilowatts(0d))(Kilowatts(10e-3)) && + thermalHouse.isInnerTemperatureTooLow( houseState.innerTemperature - ) && !maybeStorageThreshold.contains(StorageEmpty(tick)) => + ) && !thermalStorage.isEmpty(storageState.storedEnergy) => /* Storage is meant to heat the house only, if there is no infeed from external (+/- 10 W) and the house is cold */ val revisedStorageState = thermalStorage.updateState( tick, - thermalStorage.getChargingPower * (-1), + thermalStorage.getChargingPower * -1, formerStorageState.getOrElse( throw new InconsistentStateException( "Impossible to find no storage state" @@ -396,12 +393,8 @@ final case class ThermalGrid( Seq.empty[ResultEntity] :+ new ThermalHouseResult( tick.toDateTime, thermalHouse.uuid, - Quantities.getQuantity( - thermalInfeed.toMegawatts, - PowerSystemUnits.MEGAWATT - ), - Quantities - .getQuantity(innerTemperature.toCelsiusScale, Units.CELSIUS) + thermalInfeed.toMegawatts.asMegaWatt, + innerTemperature.toKelvinScale.asKelvin ) } .getOrElse(Seq.empty[ResultEntity]) @@ -416,15 +409,9 @@ final case class ThermalGrid( houseResults :+ new CylindricalStorageResult( tick.toDateTime, storage.uuid, - Quantities.getQuantity( - storedEnergy.toMegawattHours, - PowerSystemUnits.MEGAWATTHOUR - ), - Quantities.getQuantity(qDot.toMegawatts, PowerSystemUnits.MEGAWATT), - Quantities.getQuantity( - storage.maxEnergyThreshold.toKilowattHours / storedEnergy.toKilowattHours, - Units.PERCENT - ) + storedEnergy.toMegawattHours.asMegaWattHour, + qDot.toMegawatts.asMegaWatt, + (storage.maxEnergyThreshold / storedEnergy).asPu ) case _ => throw new NotImplementedError( @@ -512,15 +499,9 @@ object ThermalGrid { possible: Energy ): ThermalEnergyDemand = { if (possible < required) - new ThermalEnergyDemand( - possible, - possible - ) + new ThermalEnergyDemand(possible, possible) else - new ThermalEnergyDemand( - required, - possible - ) + new ThermalEnergyDemand(required, possible) } def noDemand: ThermalEnergyDemand = ThermalEnergyDemand( diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala index b5eb9cbf48..263ded3683 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -21,19 +21,17 @@ import edu.ie3.simona.model.thermal.ThermalHouse.{ ThermalHouseState, temperatureTolerance } -import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.{ThermalConductance, WattsPerKelvin} -import squants.energy.{KilowattHours, MegawattHours, Megawatts} -import squants.thermal.{Celsius, JoulesPerKelvin, Kelvin, ThermalCapacity} -import squants.time.Hours +import squants.energy.{KilowattHours, Kilowatts, MegawattHours, Megawatts} +import squants.thermal.{Kelvin, ThermalCapacity} +import squants.time.{Hours, Seconds} import squants.{Energy, Power, Temperature, Time} import tech.units.indriya.unit.Units import java.util.UUID -/** A thermal house model including a variable inner temperature

* - * Important: The field innerTemperature is a variable. +/** A thermal house model * * @param uuid * the element's uuid @@ -98,7 +96,7 @@ final case class ThermalHouse( state: ThermalHouseState ): ThermalEnergyDemand = { /* Calculate the inner temperature of the house, at the questioned instance in time */ - val duration = state.tick.durationUntil(tick) + val duration = Seconds(tick - state.tick) val innerTemperature = newInnerTemperature( state.qDot, duration, @@ -106,11 +104,22 @@ final case class ThermalHouse( ambientTemperature ) - /* Determine the needed energy */ + /* Determine, which temperature boundary triggers a needed energy to reach the temperature constraints */ + val temperatureToTriggerRequiredEnergy = + if ( + innerTemperature <= state.innerTemperature && + state.qDot <= Kilowatts(0d) + ) + lowerBoundaryTemperature + else targetTemperature val requiredEnergy = - if (isInnerTemperatureTooLow(innerTemperature)) { - energy(targetTemperature, innerTemperature) - } else + if ( + isInnerTemperatureTooLow( + innerTemperature, + temperatureToTriggerRequiredEnergy + ) + ) energy(targetTemperature, innerTemperature) + else MegawattHours(0d) val possibleEnergy = @@ -148,7 +157,9 @@ final case class ThermalHouse( def isInnerTemperatureTooHigh( innerTemperature: Temperature ): Boolean = - innerTemperature > (upperBoundaryTemperature - temperatureTolerance) + innerTemperature > Kelvin( + upperBoundaryTemperature.toKelvinScale - temperatureTolerance.toKelvinScale + ) /** Check if inner temperature is lower than preferred minimum temperature * @@ -156,9 +167,12 @@ final case class ThermalHouse( * true, if inner temperature is too low */ def isInnerTemperatureTooLow( - innerTemperature: Temperature + innerTemperature: Temperature, + boundaryTemperature: Temperature = lowerBoundaryTemperature ): Boolean = - innerTemperature < (lowerBoundaryTemperature + temperatureTolerance) + innerTemperature < Kelvin( + boundaryTemperature.toKelvinScale + temperatureTolerance.toKelvinScale + ) /** Calculate the new inner temperature of the thermal house. * @@ -293,7 +307,7 @@ final case class ThermalHouse( ambientTemperature: Temperature, qDot: Power ): (ThermalHouseState, Option[ThermalThreshold]) = { - val duration = state.tick.durationUntil(tick) + val duration = Seconds(tick - state.tick) val updatedInnerTemperature = newInnerTemperature( state.qDot, duration, @@ -327,7 +341,6 @@ final case class ThermalHouse( * @return * The next threshold, that will be reached */ - private def nextThreshold( tick: Long, qDotExternal: Power, @@ -340,33 +353,34 @@ final case class ThermalHouse( ambientTemperature, artificialDuration ) / artificialDuration - val resultingQDot = qDotExternal - loss - - resultingQDot match { - case qDot if qDot < Megawatts(0d) => - /* House has more losses than gain */ - val nextTick = nextActivation( - tick, - innerTemperature, - lowerBoundaryTemperature, - resultingQDot - ) - Some(HouseTemperatureLowerBoundaryReached(nextTick)) - - case qDot if qDot > Megawatts(0d) => - /* House has more gain than losses */ - val nextTick = nextActivation( - tick, - upperBoundaryTemperature, - innerTemperature, - resultingQDot - ) - Some(HouseTemperatureUpperBoundaryReached(nextTick)) - - case _ => - /* House is in perfect balance */ - None + if ( + resultingQDot < Megawatts(0d) && !isInnerTemperatureTooLow( + innerTemperature + ) + ) { + /* House has more losses than gain */ + nextActivation( + tick, + innerTemperature, + lowerBoundaryTemperature, + resultingQDot + ).map(HouseTemperatureLowerBoundaryReached) + } else if ( + resultingQDot > Megawatts(0d) && !isInnerTemperatureTooHigh( + innerTemperature + ) + ) { + /* House has more gain than losses */ + nextActivation( + tick, + upperBoundaryTemperature, + innerTemperature, + resultingQDot + ).map(HouseTemperatureUpperBoundaryReached) + } else { + /* House is in perfect balance */ + None } } @@ -375,24 +389,21 @@ final case class ThermalHouse( higherTemperature: Temperature, lowerTemperature: Temperature, qDot: Power - ): Long = { + ): Option[Long] = { val flexibleEnergy = energy(higherTemperature, lowerTemperature) - if ( - flexibleEnergy < - KilowattHours(0d) - ) - tick + if (flexibleEnergy < MegawattHours(0d)) + None else { - val duration = - flexibleEnergy / (qDot * math.signum(qDot.value.doubleValue())) - tick + duration.toSeconds.toLong + val duration = Math.round( + (flexibleEnergy / (qDot * math.signum(qDot.toWatts))).toSeconds + ) + Some(tick + duration) } } } object ThermalHouse { - protected def temperatureTolerance: Temperature = - Kelvin(0.01d) + protected def temperatureTolerance: Temperature = Kelvin(0.01d) def apply(input: ThermalHouseInput): ThermalHouse = new ThermalHouse( input.getUuid, @@ -405,23 +416,22 @@ object ThermalHouse { .to(PowerSystemUnits.KILOWATT_PER_KELVIN) .getValue .doubleValue - // Kilowatt in Watt - * 1000 + * 1000 // kW/K to W/K ), - JoulesPerKelvin( + KilowattHours( input.getEthCapa .to(PowerSystemUnits.KILOWATTHOUR_PER_KELVIN) .getValue .doubleValue - // from kWh to Joule - * 3.6e6 + ) / Kelvin(1d), + Kelvin( + input.getTargetTemperature.to(Units.KELVIN).getValue.doubleValue ), - Celsius(input.getTargetTemperature.to(Units.CELSIUS).getValue.doubleValue), - Celsius( - input.getLowerTemperatureLimit.to(Units.CELSIUS).getValue.doubleValue + Kelvin( + input.getLowerTemperatureLimit.to(Units.KELVIN).getValue.doubleValue ), - Celsius( - input.getUpperTemperatureLimit.to(Units.CELSIUS).getValue.doubleValue + Kelvin( + input.getUpperTemperatureLimit.to(Units.KELVIN).getValue.doubleValue ) ) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala index cc8cd36745..33304c8974 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala @@ -10,8 +10,8 @@ import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState -import edu.ie3.util.scala.quantities.DefaultQuantities -import squants.{Energy, Power} +import squants.{Energy, Power, Seconds} +import squants.energy.KilowattHours import java.util.UUID @@ -44,8 +44,12 @@ abstract class ThermalStorage( maxEnergyThreshold: Energy, chargingPower: Power ) { - protected val zeroEnergy: Energy = - DefaultQuantities.zeroKWH + protected val zeroEnergy: Energy = KilowattHours(0d) + + /** In order to avoid faulty flexibility options, we want to avoid offering + * charging/discharging that could last less than one second. + */ + private val toleranceMargin = chargingPower * Seconds(1d) def getUuid: UUID = uuid @@ -57,6 +61,12 @@ abstract class ThermalStorage( def startingState: ThermalStorageState + def isFull(energy: Energy): Boolean = + energy > (maxEnergyThreshold - toleranceMargin) + + def isEmpty(energy: Energy): Boolean = + energy < (minEnergyThreshold + toleranceMargin) + def updateState( tick: Long, qDot: Power, diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala index 517e517fcd..ff485e5f99 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala @@ -7,7 +7,7 @@ package edu.ie3.simona.ontology.messages.services import edu.ie3.simona.agent.participant.data.Data.SecondaryData -import edu.ie3.simona.api.data.ev.model.EvModel +import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ProvisionMessage, ServiceRegistrationMessage @@ -75,7 +75,7 @@ object EvMessage { * EVs arriving at the charging station */ final case class ArrivingEvsData( - arrivals: Seq[EvModel] + arrivals: Seq[EvModelWrapper] ) extends EvData {} trait EvResponseMessage extends EvMessage @@ -87,6 +87,7 @@ object EvMessage { final case class DepartingEvsResponse( evcs: UUID, - evModels: Set[EvModel] + evModels: Set[EvModelWrapper] ) extends EvResponseMessage + } diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index b2a7c854f6..6bdba6e8c4 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -14,6 +14,7 @@ import edu.ie3.simona.api.data.ev.ontology._ import edu.ie3.simona.api.data.ontology.DataMessageFromExt import edu.ie3.simona.exceptions.WeatherServiceException.InvalidRegistrationRequestException import edu.ie3.simona.exceptions.{InitializationException, ServiceException} +import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.ServiceRegistrationMessage @@ -27,6 +28,7 @@ import edu.ie3.simona.service.ev.ExtEvDataService.{ InitExtEvData } import edu.ie3.simona.service.{ExtDataSupport, ServiceStateData, SimonaService} +import edu.ie3.simona.util.ReceiveDataMap import java.util.UUID import scala.jdk.CollectionConverters._ @@ -43,15 +45,16 @@ object ExtEvDataService { extEvData: ExtEvData, uuidToActorRef: Map[UUID, ActorRef] = Map.empty[UUID, ActorRef], extEvMessage: Option[EvDataMessageFromExt] = None, - freeLots: Map[UUID, Option[Int]] = Map.empty, - departingEvResponses: Map[UUID, Option[Seq[EvModel]]] = Map.empty + freeLots: ReceiveDataMap[UUID, Int] = ReceiveDataMap.empty, + currentPrices: ReceiveDataMap[UUID, Double] = ReceiveDataMap.empty, + departingEvResponses: ReceiveDataMap[UUID, Seq[EvModelWrapper]] = + ReceiveDataMap.empty ) extends ServiceBaseStateData final case class InitExtEvData( extEvData: ExtEvData ) extends InitializeServiceStateData - val FALLBACK_EV_MOVEMENTS_STEM_DISTANCE: Long = 3600L } class ExtEvDataService(override val scheduler: ActorRef) @@ -197,10 +200,10 @@ class ExtEvDataService(override val scheduler: ActorRef) evcsActor ! EvFreeLotsRequest(tick) } - val freeLots: Map[UUID, Option[Int]] = + val freeLots = serviceStateData.uuidToActorRef.map { case (evcs, _) => - evcs -> None - } + evcs + }.toSet // if there are no evcs, we're sending response right away if (freeLots.isEmpty) @@ -209,7 +212,7 @@ class ExtEvDataService(override val scheduler: ActorRef) ( serviceStateData.copy( extEvMessage = None, - freeLots = freeLots + freeLots = ReceiveDataMap(freeLots) ), None ) @@ -222,13 +225,13 @@ class ExtEvDataService(override val scheduler: ActorRef) serviceStateData: ExtEvStateData ): (ExtEvStateData, Option[Long]) = { - val departingEvResponses: Map[UUID, Option[Seq[EvModel]]] = + val departingEvResponses = requestedDepartingEvs.asScala.flatMap { case (evcs, departingEvs) => serviceStateData.uuidToActorRef.get(evcs) match { case Some(evcsActor) => evcsActor ! DepartingEvsRequest(tick, departingEvs.asScala.toSeq) - Some(evcs -> None) + Some(evcs) case None => log.warning( @@ -238,7 +241,7 @@ class ExtEvDataService(override val scheduler: ActorRef) None } - }.toMap + } // if there are no departing evs during this tick, // we're sending response right away @@ -248,7 +251,7 @@ class ExtEvDataService(override val scheduler: ActorRef) ( serviceStateData.copy( extEvMessage = None, - departingEvResponses = departingEvResponses + departingEvResponses = ReceiveDataMap(departingEvResponses.toSet) ), None ) @@ -265,7 +268,7 @@ class ExtEvDataService(override val scheduler: ActorRef) case (evcs, arrivingEvs) => serviceStateData.uuidToActorRef .get(evcs) - .map((_, arrivingEvs.asScala.toSeq)) + .map((_, arrivingEvs.asScala.map(EvModelWrapper.apply).toSeq)) .orElse { log.warning( "A corresponding actor ref for UUID {} could not be found", @@ -313,50 +316,51 @@ class ExtEvDataService(override val scheduler: ActorRef) )(implicit serviceStateData: ExtEvStateData): ExtEvStateData = { extResponseMsg match { case DepartingEvsResponse(evcs, evModels) => - val updatedResponses = serviceStateData.departingEvResponses + - (evcs -> Some(evModels.toList)) + val updatedResponses = + serviceStateData.departingEvResponses.addData(evcs, evModels.toList) - if (updatedResponses.values.toSeq.contains(None)) { + if (updatedResponses.nonComplete) { // responses are still incomplete serviceStateData.copy( departingEvResponses = updatedResponses ) } else { // all responses received, forward them to external simulation in a bundle - val departingEvs = updatedResponses.values.flatten.flatten + val departingEvs = + updatedResponses.receivedData.values.flatten.map(_.unwrap()) serviceStateData.extEvData.queueExtResponseMsg( new ProvideDepartingEvs(departingEvs.toList.asJava) ) serviceStateData.copy( - departingEvResponses = Map.empty + departingEvResponses = ReceiveDataMap.empty ) } case FreeLotsResponse(evcs, freeLots) => - val updatedFreeLots = serviceStateData.freeLots + - (evcs -> Some(freeLots)) + val updatedFreeLots = serviceStateData.freeLots.addData(evcs, freeLots) - if (updatedFreeLots.values.toSeq.contains(None)) { + if (updatedFreeLots.nonComplete) { // responses are still incomplete serviceStateData.copy( freeLots = updatedFreeLots ) } else { // all responses received, forward them to external simulation in a bundle - val freeLotsResponse = updatedFreeLots.flatMap { - case (evcs, Some(freeLotsCount)) if freeLotsCount > 0 => - Some(evcs -> Integer.valueOf(freeLotsCount)) - case _ => - None - } + val freeLotsResponse = updatedFreeLots.receivedData + .filter { case (_, freeLotsCount) => + freeLotsCount > 0 + } + .map { case (evcs, freeLotsCount) => + evcs -> Integer.valueOf(freeLotsCount) + } serviceStateData.extEvData.queueExtResponseMsg( new ProvideEvcsFreeLots(freeLotsResponse.asJava) ) serviceStateData.copy( - freeLots = Map.empty + freeLots = ReceiveDataMap.empty ) } } diff --git a/src/test/groovy/edu/ie3/simona/model/participant/EvcsModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/EvcsModelTest.groovy deleted file mode 100644 index eca95f9342..0000000000 --- a/src/test/groovy/edu/ie3/simona/model/participant/EvcsModelTest.groovy +++ /dev/null @@ -1,122 +0,0 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant - -import static edu.ie3.util.quantities.PowerSystemUnits.* - -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.input.system.type.evcslocation.EvcsLocationType -import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.test.common.model.MockEvModel -import edu.ie3.util.scala.OperationInterval -import edu.ie3.util.scala.quantities.Sq -import spock.lang.Shared -import spock.lang.Specification -import squants.energy.* -import squants.time.* -import tech.units.indriya.quantity.Quantities - -import scala.collection.immutable.Set - -class EvcsModelTest extends Specification { - - static final double TESTING_TOLERANCE = 1e-10 - - @Shared - double scalingFactor = 1.0d - @Shared - int chargingPoints = 2 - - def getStandardModel(Power sRated) { - return new EvcsModel( - UUID.fromString("06a14909-366e-4e94-a593-1016e1455b30"), - "Evcs Model Test", - OperationInterval.apply(0L, 86400L), - scalingFactor, - QControl.apply(new CosPhiFixed("cosPhiFixed:{(0.0,1.0)}")), - sRated, - 1d, - chargingPoints, - EvcsLocationType.HOME - ) - } - - def "Test charge"() { - given: - EvcsModel evcsModel = getStandardModel( - Sq.create(evcsSRated, Kilowatts$.MODULE$) - ) - EvModel evModel = new MockEvModel( - UUID.fromString("73c041c7-68e9-470e-8ca2-21fd7dbd1797"), - "TestEv", - Quantities.getQuantity(evSRated, KILOWATT), - Quantities.getQuantity(evEStorage, KILOWATTHOUR), - Quantities.getQuantity(evStoredEnergy.doubleValue(), KILOWATTHOUR) - ) - def chargingTime = Sq.create( - durationMins, Minutes$.MODULE$ - ) - - when: - def res = evcsModel.charge(evModel, chargingTime) - - then: - res._1().value().doubleValue() =~ solChargedEnergy.doubleValue() - Sq.create(res._2().storedEnergy.value.doubleValue(), KilowattHours$.MODULE$) =~ Sq.create(solStoredEnergy, KilowattHours$.MODULE$) - - where: - evcsSRated | evSRated | evEStorage | evStoredEnergy | durationMins || solStoredEnergy | solChargedEnergy - 100d | 10d | 20d | 0d | 60d || 10d | 10d // charge a bit - 100d | 100d | 20d | 0d | 60d || 20d | 20d // charge to full - 100d | 100d | 80d | 30d | 30d || 80d | 50d // charge to full with non-empty start - 100d | 10d | 20d | 20d | 60d || 20d | 0d // already full - } - - def "Test calcActivePowerAndEvSoc"() { - given: - def evsRated = 100d - - EvcsModel evcsModel = getStandardModel(Sq.create(evsRated, Kilowatts$.MODULE$)) - EvModel ev1Model = new MockEvModel( - UUID.fromString("73c041c7-68e9-470e-8ca2-21fd7dbd1797"), - "TestEv1", - Quantities.getQuantity(ev1SRated, KILOWATT), - Quantities.getQuantity(50d, KILOWATTHOUR), - Quantities.getQuantity(ev1StoredEnergy, KILOWATTHOUR) - ) - EvModel ev2Model = new MockEvModel( - UUID.fromString("5e86454d-3434-4d92-856e-2f62dd1d0d90"), - "TestEv2", - Quantities.getQuantity(ev2SRated, KILOWATT), - Quantities.getQuantity(50d, KILOWATTHOUR), - Quantities.getQuantity(ev2StoredEnergy, KILOWATTHOUR) - ) - Set mySet = new Set.Set2(ev1Model, ev2Model) - def data = new EvcsModel.EvcsRelevantData(durationTicks, mySet) - - when: - def res = evcsModel.calculateActivePowerAndEvSoc(data) - - then: - Sq.create(res._1().toKilowatts(), KilowattHours$.MODULE$) =~ solPower - res._2().size() == 2 - Sq.create(res._2().head().storedEnergy.value.doubleValue(), KilowattHours$.MODULE$) =~ solEv1Stored - Sq.create(res._2().last().storedEnergy.value.doubleValue(), KilowattHours$.MODULE$) =~ solEv2Stored - - where: - ev1SRated | ev1StoredEnergy | ev2SRated | ev2StoredEnergy | durationTicks || solPower | solEv1Stored | solEv2Stored - 10d | 0d | 10d | 0d | 3600L || 20d | 10d | 10d // well below evcs sRated - 10d | 0d | 10d | 0d | 900L || 20d | 2.5d | 2.5d - 50d | 0d | 50d | 0d | 7200L || 50d | 50d | 50d - 50d | 0d | 50d | 0d | 1800L || 100d | 25d | 25d // hitting evcs sRated exactly - 100d | 0d | 25d | 0d | 1800L || 100d | 50d | 0d // going above evcs sRated - 50d | 25d | 50d | 25d | 1800L || 100d | 50d | 50d // with non-zero start - 50d | 45d | 50d | 35d | 3600L || 20d | 50d | 50d - 200d | 25d | 50d | 50d | 3600L || 25d | 50d | 50d - } -} diff --git a/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy b/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy index 1513aa2b34..b3c17eb4e0 100644 --- a/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy @@ -8,7 +8,6 @@ package edu.ie3.simona.model.thermal import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput -import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.KilowattHoursPerKelvinCubicMeters$ import edu.ie3.util.scala.quantities.Sq import spock.lang.Shared @@ -17,12 +16,14 @@ import squants.energy.KilowattHours$ import squants.energy.Kilowatts$ import squants.space.CubicMeters$ import squants.thermal.Celsius$ -import tech.units.indriya.unit.Units +import static edu.ie3.util.quantities.PowerSystemUnits.KILOWATTHOUR import static tech.units.indriya.quantity.Quantities.getQuantity class CylindricalThermalStorageTest extends Specification { + static final double TESTING_TOLERANCE = 1e-10 + @Shared CylindricalStorageInput storageInput @@ -31,32 +32,28 @@ class CylindricalThermalStorageTest extends Specification { UUID.randomUUID(), "ThermalStorage", null, - getQuantity(100d, StandardUnits.VOLUME), - getQuantity(20d, StandardUnits.VOLUME), - getQuantity(30d, StandardUnits.TEMPERATURE), - getQuantity(40d, StandardUnits.TEMPERATURE), - getQuantity(1.15d, StandardUnits.SPECIFIC_HEAT_CAPACITY)) + getQuantity(100, StandardUnits.VOLUME), + getQuantity(20, StandardUnits.VOLUME), + getQuantity(30, StandardUnits.TEMPERATURE), + getQuantity(40, StandardUnits.TEMPERATURE), + getQuantity(1.15, StandardUnits.SPECIFIC_HEAT_CAPACITY)) } static def buildThermalStorage(CylindricalStorageInput storageInput, Double volume) { - def storedEnergy = - CylindricalThermalStorage.volumeToEnergy( - Sq.create(volume, CubicMeters$.MODULE$), + def storedEnergy = CylindricalThermalStorage.volumeToEnergy(Sq.create(volume, CubicMeters$.MODULE$), Sq.create(storageInput.c.value.doubleValue(), KilowattHoursPerKelvinCubicMeters$.MODULE$), Sq.create(storageInput.inletTemp.value.doubleValue(), Celsius$.MODULE$), - Sq.create(storageInput.returnTemp.value.doubleValue(), Celsius$.MODULE$) - ) + Sq.create(storageInput.returnTemp.value.doubleValue(), Celsius$.MODULE$)) def thermalStorage = CylindricalThermalStorage.apply(storageInput, storedEnergy) return thermalStorage } def vol2Energy(Double volume) { - return CylindricalThermalStorage.volumeToEnergy( + return CylindricalThermalStorage.volumeToEnergy( // FIXME below: get values in units with to..() Sq.create(volume, CubicMeters$.MODULE$), - Sq.create(storageInput.c.to(PowerSystemUnits.KILOWATTHOUR_PER_KELVIN_TIMES_CUBICMETRE).value.doubleValue(), KilowattHoursPerKelvinCubicMeters$.MODULE$), - Sq.create(storageInput.inletTemp.to(Units.CELSIUS).value.doubleValue(), Celsius$.MODULE$), - Sq.create(storageInput.returnTemp.to(Units.CELSIUS).value.doubleValue(), Celsius$.MODULE$) - ) + Sq.create(storageInput.c.value.doubleValue(), KilowattHoursPerKelvinCubicMeters$.MODULE$), + Sq.create(storageInput.inletTemp.value.doubleValue(), Celsius$.MODULE$), + Sq.create(storageInput.returnTemp.value.doubleValue(), Celsius$.MODULE$)) } def "Check storage level operations:"() { @@ -64,26 +61,43 @@ class CylindricalThermalStorageTest extends Specification { def storage = buildThermalStorage(storageInput, 70) when: - def initialLevel = storage._storedEnergy() - storage._storedEnergy_$eq(vol2Energy(50)) - def newLevel1 = storage._storedEnergy() - def surplus = storage.tryToStoreAndReturnRemainder(vol2Energy(55)).get() - def newLevel2 = storage._storedEnergy() - def isCovering = storage.isDemandCoveredByStorage(Sq.create(5d, KilowattHours$.MODULE$)) - def lack = storage.tryToTakeAndReturnLack(vol2Energy(95)).get() - def newLevel3 = storage._storedEnergy() - def notCovering = storage.isDemandCoveredByStorage(Sq.create(1d, KilowattHours$.MODULE$)) + def initialLevel = + getQuantity(storage._storedEnergy().toKilowattHours(), KILOWATTHOUR) + storage._storedEnergy_$eq(vol2Energy(50d),) + def newLevel1 = getQuantity(storage._storedEnergy().toKilowattHours(), KILOWATTHOUR) + def surplus = storage.tryToStoreAndReturnRemainder( + vol2Energy(55d)) + def newLevel2 = getQuantity(storage._storedEnergy().toKilowattHours(), KILOWATTHOUR) + def isCovering = storage.isDemandCoveredByStorage(Sq.create(5, KilowattHours$.MODULE$)) + def lack = + storage.tryToTakeAndReturnLack( + vol2Energy(95d) + ) + def newLevel3 = getQuantity(storage._storedEnergy().toKilowattHours(), KILOWATTHOUR) + def notCovering = storage.isDemandCoveredByStorage(Sq.create(1, KilowattHours$.MODULE$)) + then: - initialLevel =~ vol2Energy(70d) - newLevel1 =~ vol2Energy(50d) + initialLevel.value.doubleValue() =~ vol2Energy(70d).toKilowattHours() + newLevel1.value.doubleValue() =~ vol2Energy(50d).toKilowattHours() surplus =~ vol2Energy(5d) - newLevel2 =~ vol2Energy(100d) + newLevel2.value.doubleValue() =~ vol2Energy(100d).toKilowattHours() lack =~ vol2Energy(15d) - newLevel3 =~ vol2Energy(20d) + newLevel3.value.doubleValue() =~ vol2Energy(20d).toKilowattHours() isCovering !notCovering } + def "Check converting methods:"() { + given: + def storage = buildThermalStorage(storageInput, 70) + + when: + def usableThermalEnergy = storage.usableThermalEnergy() + + then: + Math.abs(usableThermalEnergy.toKilowattHours() - 5 * 115) < TESTING_TOLERANCE + } + def "Check apply, validation and build method:"() { when: def storage = buildThermalStorage(storageInput, 70) @@ -98,24 +112,24 @@ class CylindricalThermalStorageTest extends Specification { def "Check mutable state update:"() { when: - def storage = buildThermalStorage(storageInput, 70d) + def storage = buildThermalStorage(storageInput, 70) def lastState = new ThermalStorage.ThermalStorageState(tick, Sq.create(storedEnergy, KilowattHours$.MODULE$), Sq.create(qDot, Kilowatts$.MODULE$)) def result = storage.updateState(newTick, Sq.create(newQDot, Kilowatts$.MODULE$), lastState) then: - result._1().storedEnergy() =~ Sq.create(expectedStoredEnergy, KilowattHours$.MODULE$) + Math.abs(result._1().storedEnergy().toKilowattHours() - expectedStoredEnergy.doubleValue()) < TESTING_TOLERANCE result._2.defined result._2.get() == expectedThreshold where: - tick | storedEnergy | qDot | newTick | newQDot || expectedStoredEnergy | expectedThreshold - 0L | 250.0d | 10.0d | 3600L | 42.0d || 260.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(79885L) - 0L | 250.0d | 10.0d | 3600L | -42.0d || 260.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(6171L) - 0L | 250.0d | -10.0d | 3600L | 42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(81600L) - 0L | 250.0d | -10.0d | 3600L | -42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(4457L) - 0L | 250.0d | -10.0d | 3600L | -42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(4457L) - 0L | 1000.0d | 149.0d | 3600L | 5000.0d || 1149.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(3600L) - 0L | 240.0d | -9.0d | 3600L | -5000.0d || 231.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(3600L) + tick | storedEnergy | qDot | newTick | newQDot || expectedStoredEnergy | expectedThreshold + 0L | 250.0d | 10.0d | 3600L | 42.0d || 260.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(79886L) + 0L | 250.0d | 10.0d | 3600L | -42.0d || 260.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(6171L) + 0L | 250.0d | -10.0d | 3600L | 42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(81600L) + 0L | 250.0d | -10.0d | 3600L | -42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(4457L) + 0L | 250.0d | -10.0d | 3600L | -42.0d || 240.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(4457L) + 0L | 1000.0d | 149.0d | 3600L | 5000.0d || 1149.0d | new ThermalStorage.ThermalStorageThreshold.StorageFull(3601L) + 0L | 240.0d | -9.0d | 3600L | -5000.0d || 231.0d | new ThermalStorage.ThermalStorageThreshold.StorageEmpty(3601L) } def "Check mutable state update, if no threshold is reached:"() { @@ -125,7 +139,7 @@ class CylindricalThermalStorageTest extends Specification { def result = storage.updateState(newTick, Sq.create(newQDot, Kilowatts$.MODULE$), lastState) then: - result._1().storedEnergy() =~ Sq.create(expectedStoredEnergy, KilowattHours$.MODULE$) + Math.abs(result._1().storedEnergy().toKilowattHours() - expectedStoredEnergy.doubleValue()) < TESTING_TOLERANCE result._2.empty where: diff --git a/src/test/groovy/edu/ie3/simona/model/thermal/ThermalHouseTest.groovy b/src/test/groovy/edu/ie3/simona/model/thermal/ThermalHouseTest.groovy index 2b66f3b9f6..f23d532b03 100644 --- a/src/test/groovy/edu/ie3/simona/model/thermal/ThermalHouseTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/thermal/ThermalHouseTest.groovy @@ -21,7 +21,6 @@ import squants.thermal.* import squants.time.* - class ThermalHouseTest extends Specification { @Shared @@ -49,21 +48,21 @@ class ThermalHouseTest extends Specification { when: Temperature innerTemp = Sq.create(innerTemperature, Celsius$.MODULE$) def isHigher = thermalHouse.isInnerTemperatureTooHigh(innerTemp) - def isLower = thermalHouse.isInnerTemperatureTooLow(innerTemp) + def isLower = thermalHouse.isInnerTemperatureTooLow(innerTemp, thermalHouse.lowerBoundaryTemperature()) then: isHigher == isTooHigh isLower == isTooLow where: - innerTemperature || isTooHigh | isTooLow - 17d || false | true - 17.98d || false | true - 18d || false | true - 20d || false | false - 22d || true | false - 22.02d || true | false - 23d || true | false + innerTemperature || isTooHigh | isTooLow + 17d || false | true + 17.98d || false | true + 18d || false | true + 20d || false | false + 22d || true | false + 22.02d || true | false + 23d || true | false } def "Calculation of thermal energy change and new inner temperature is performed correctly"() { @@ -79,11 +78,11 @@ class ThermalHouseTest extends Specification { def newInnerTemperature = thermalHouse.calcNewInnerTemperature(innerTemperature, innerTemperatureChange) then: - Sq.create(100d, KilowattHours$.MODULE$) - thermalEnergyGain < Sq.create(TOLERANCE, KilowattHours$.MODULE$) - Sq.create(10d, KilowattHours$.MODULE$) - thermalEnergyLoss < Sq.create(TOLERANCE, KilowattHours$.MODULE$) - Sq.create(90d, KilowattHours$.MODULE$) - thermalEnergyChange < Sq.create(TOLERANCE, KilowattHours$.MODULE$) - Sq.create(9d, Kelvin$.MODULE$) - innerTemperatureChange < Sq.create(TOLERANCE, Kelvin$.MODULE$) - Sq.create(29d, Celsius$.MODULE$) - newInnerTemperature < Sq.create(TOLERANCE, Celsius$.MODULE$) + Math.abs(100d - thermalEnergyGain.toKilowattHours()) < TOLERANCE + Math.abs(10d - thermalEnergyLoss.toKilowattHours()) < TOLERANCE + Math.abs(90d - thermalEnergyChange.toKilowattHours()) < TOLERANCE + Math.abs(9d - innerTemperatureChange.toKelvinScale()) < TOLERANCE + Math.abs(29d - newInnerTemperature.toCelsiusScale()) < TOLERANCE } def "Comprising function to calculate new inner temperature works as expected"() { @@ -122,7 +121,7 @@ class ThermalHouseTest extends Specification { thermalHouse.operatorInput() == thermalHouseInput.operator thermalHouse.operationTime() == thermalHouseInput.operationTime thermalHouse.bus() == thermalHouseInput.thermalBus - thermalHouse.ethLosses().value().doubleValue() == thermalHouseInput.ethLosses.to(KILOWATT_PER_KELVIN).value.doubleValue() * 1000 + thermalHouse.ethLosses().toWattsPerKelvin() == thermalHouseInput.ethLosses.to(KILOWATT_PER_KELVIN).value.doubleValue() * 1000 (thermalHouse.ethCapa().$times(Sq.create(1d, Kelvin$.MODULE$))).toKilowattHours() == thermalHouseInput.ethCapa.to(KILOWATTHOUR_PER_KELVIN).value.doubleValue() thermalHouse.lowerBoundaryTemperature() == Sq.create(18, Celsius$.MODULE$) thermalHouse.upperBoundaryTemperature() == Sq.create(22, Celsius$.MODULE$) diff --git a/src/test/java/edu/ie3/simona/test/common/model/MockEvModel.java b/src/test/java/edu/ie3/simona/test/common/model/MockEvModel.java index 384f953e77..12cb693568 100644 --- a/src/test/java/edu/ie3/simona/test/common/model/MockEvModel.java +++ b/src/test/java/edu/ie3/simona/test/common/model/MockEvModel.java @@ -18,30 +18,43 @@ public class MockEvModel implements EvModel { private final UUID uuid; private final String id; - private final ComparableQuantity sRated; + private final ComparableQuantity sRatedAC; + private final ComparableQuantity sRatedDC; private final ComparableQuantity eStorage; private final ComparableQuantity storedEnergy; + private final Long departureTick; public MockEvModel( UUID uuid, String id, - ComparableQuantity sRated, + ComparableQuantity sRatedAC, + ComparableQuantity sRatedDC, ComparableQuantity eStorage, - ComparableQuantity storedEnergy) { + ComparableQuantity storedEnergy, + Long departureTick) { this.uuid = uuid; this.id = id; - this.sRated = sRated; + this.sRatedAC = sRatedAC; + this.sRatedDC = sRatedDC; this.eStorage = eStorage; this.storedEnergy = storedEnergy; + this.departureTick = departureTick; } public MockEvModel( - UUID uuid, String id, ComparableQuantity sRated, ComparableQuantity eStorage) { + UUID uuid, + String id, + ComparableQuantity sRatedAC, + ComparableQuantity sRatedDC, + ComparableQuantity eStorage, + Long departureTick) { this.uuid = uuid; this.id = id; - this.sRated = sRated; + this.sRatedAC = sRatedAC; + this.sRatedDC = sRatedDC; this.eStorage = eStorage; this.storedEnergy = Quantities.getQuantity(0d, PowerSystemUnits.KILOWATTHOUR); + this.departureTick = departureTick; } @Override @@ -56,12 +69,12 @@ public String getId() { @Override public ComparableQuantity getSRatedAC() { - return sRated; + return sRatedAC; } @Override public ComparableQuantity getSRatedDC() { - return sRated; + return sRatedDC; } @Override @@ -76,12 +89,16 @@ public ComparableQuantity getStoredEnergy() { @Override public Long getDepartureTick() { - return 0L; + return departureTick; } @Override public MockEvModel copyWith(ComparableQuantity newStoredEnergy) { - return new MockEvModel(uuid, id, sRated, eStorage, newStoredEnergy); + return new MockEvModel(uuid, id, sRatedAC, sRatedDC, eStorage, newStoredEnergy, departureTick); + } + + public MockEvModel copyWithDeparture(Long departureTick) { + return new MockEvModel(uuid, id, sRatedAC, sRatedDC, eStorage, storedEnergy, departureTick); } @Override @@ -91,13 +108,15 @@ public boolean equals(Object o) { MockEvModel that = (MockEvModel) o; return uuid.equals(that.uuid) && id.equals(that.id) - && sRated.equals(that.sRated) + && sRatedAC.equals(that.sRatedAC) + && sRatedDC.equals(that.sRatedDC) && eStorage.equals(that.eStorage) - && storedEnergy.equals(that.storedEnergy); + && storedEnergy.equals(that.storedEnergy) + && departureTick.equals(that.departureTick); } @Override public int hashCode() { - return Objects.hash(uuid, id, sRated, eStorage, storedEnergy); + return Objects.hash(uuid, id, sRatedAC, sRatedDC, eStorage, storedEnergy, departureTick); } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 5f53c56304..65009a72e2 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -9,6 +9,7 @@ package edu.ie3.simona.agent.participant import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.datamodel.models.input.system.characteristic.QV +import edu.ie3.datamodel.models.result.system.{EvResult, EvcsResult} import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.ActorEvMovementsService @@ -19,9 +20,16 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData._ import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig +import edu.ie3.simona.event.ResultEvent.{ + FlexOptionsResultEvent, + ParticipantResultEvent +} import edu.ie3.simona.event.notifier.NotifierConfig -import edu.ie3.simona.model.participant.EvcsModel.EvcsRelevantData +import edu.ie3.simona.model.participant.evcs.EvcsModel.EvcsState +import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} import edu.ie3.simona.ontology.messages.Activation +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, @@ -38,20 +46,22 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResp RegistrationSuccessfulMessage } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey -import edu.ie3.simona.service.ev.ExtEvDataService.FALLBACK_EV_MOVEMENTS_STEM_DISTANCE import edu.ie3.simona.test.ParticipantAgentSpec import edu.ie3.simona.test.common.input.EvcsInputTestData import edu.ie3.simona.test.common.{EvTestData, TestSpawnerClassic} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.{Megavars, ReactivePower, Vars} import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.testkit.{TestFSMRef, TestProbe} -import squants.energy.{Megawatts, Watts} -import squants.{Each, Power} +import squants.energy._ +import squants.{Each, Energy, Power} import java.util.UUID +import scala.collection.SortedMap class EvcsAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -69,10 +79,11 @@ class EvcsAgentModelCalculationSpec with TestSpawnerClassic { private implicit val powerTolerance: Power = Watts(0.1) + private implicit val energyTolerance: Energy = WattHours(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) /* Alter the input model to have a voltage sensitive reactive power calculation */ - private val voltageSensitiveInput = evcsInputModel + private val evcsInputModelQv = evcsInputModel .copy() .qCharacteristics(new QV("qV:{(0.95,-0.625),(1.05,0.625)}")) .build() @@ -111,7 +122,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) evcsAgent.stateName shouldBe Uninitialized @@ -132,7 +143,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -142,7 +153,10 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) deathProbe.expectTerminated(evcsAgent.ref) } @@ -171,7 +185,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -191,7 +205,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -212,27 +226,30 @@ class EvcsAgentModelCalculationSpec simulationEndDate, timeBin, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + maybeEmAgent ) => inputModel shouldBe SimpleInputContainer(evcsInputModel) modelConfig shouldBe modelConfig secondaryDataServices shouldBe withServices - simulationStartDate shouldBe this.simulationStartDate - simulationEndDate shouldBe this.simulationEndDate - timeBin shouldBe this.resolution + simulationStartDate shouldBe simulationStartDate + simulationEndDate shouldBe simulationEndDate + timeBin shouldBe resolution requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe None case unsuitableStateData => fail(s"Agent has unsuitable state data '$unsuitableStateData'.") } /* Refuse registration */ - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ - evService.expectMsg( - RegisterForEvDataMessage(evcsInputModel.getUuid) - ) + evService.expectMsg(RegisterForEvDataMessage(evcsInputModel.getUuid)) /* ... as well as corresponding state and state data */ evcsAgent.stateName shouldBe HandleInformation @@ -250,6 +267,8 @@ class EvcsAgentModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ), awaitRegistrationResponsesFrom, @@ -265,16 +284,17 @@ class EvcsAgentModelCalculationSpec ) outputConfig shouldBe NotifierConfig( simulationResultInfo = false, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( - resolution * 10, - Map(0L -> Each(1.0)) + resolution, + SortedMap(0L -> Each(1.0)) ) - resultValueStore shouldBe ValueStore.forResult(resolution, 10) - requestValueStore shouldBe ValueStore[ApparentPower](resolution * 10) + resultValueStore shouldBe ValueStore(resolution) + requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ awaitRegistrationResponsesFrom shouldBe Vector(evService.ref) @@ -286,7 +306,10 @@ class EvcsAgentModelCalculationSpec } /* Reply, that registration was successful */ - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* Expect a completion message */ scheduler.expectMsg(Completion(evcsAgent.toTyped, None)) @@ -294,7 +317,7 @@ class EvcsAgentModelCalculationSpec /* ... as well as corresponding state and state data */ evcsAgent.stateName shouldBe Idle evcsAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map(evService.ref -> None) case _ => @@ -309,7 +332,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -317,13 +340,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ - evService.expectMsg( - RegisterForEvDataMessage(evcsInputModel.getUuid) + evService.expectMsg(RegisterForEvDataMessage(evcsInputModel.getUuid)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, Some(900L)) ) - evService.send(evcsAgent, RegistrationSuccessfulMessage(Some(900L))) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -344,12 +371,12 @@ class EvcsAgentModelCalculationSpec ) inside(evcsAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => - modelBaseStateData.requestValueStore shouldBe ValueStore[ + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.requestValueStore shouldBe ValueStore[ ApparentPower ]( - resolution * 10, - Map( + resolution, + SortedMap( 0L -> ApparentPower( Megawatts(0.0), Megavars(0.0) @@ -370,7 +397,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -381,11 +408,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -394,12 +427,17 @@ class EvcsAgentModelCalculationSpec /* Send out new data */ val arrivingEvsData = - ArrivingEvsData(scala.collection.immutable.Seq(evA, evB)) + ArrivingEvsData(Seq(EvModelWrapper(evA), EvModelWrapper(evB))) val key1 = Some(ScheduleKey(lock.ref.toTyped, UUID.randomUUID())) evService.send( evcsAgent, - ProvideEvDataMessage(0L, arrivingEvsData, unlockKey = key1) + ProvideEvDataMessage( + 0L, + evService.ref, + arrivingEvsData, + unlockKey = key1 + ) ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) @@ -407,7 +445,7 @@ class EvcsAgentModelCalculationSpec evcsAgent.stateName shouldBe HandleInformation evcsAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -440,30 +478,51 @@ class EvcsAgentModelCalculationSpec ) evcsAgent.stateName shouldBe Idle evcsAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.stateDataStore match { case ValueStore(_, store) => - store shouldBe Map( - 0L -> EvcsRelevantData( - FALLBACK_EV_MOVEMENTS_STEM_DISTANCE, - Set(evA, evB) - ) - ) + store.keys should contain only 0L + store.get(0L) match { + case Some(EvcsState(currentEvs, schedule, tick)) => + currentEvs should contain theSameElementsAs Set( + EvModelWrapper(evA), + EvModelWrapper(evB) + ) + + schedule.values.flatten should contain allOf ( + ChargingSchedule( + EvModelWrapper(evA), + Seq( + ChargingSchedule.Entry( + 0, + 200, + Kilowatts(11.0) + ) + ) + ), + ChargingSchedule( + EvModelWrapper(evB), + Seq( + ChargingSchedule.Entry( + 0, + 200, + Kilowatts(11.0) + ) + ) + ) + ) + + tick shouldBe 0L + case None => fail("Entry for tick 0 expected.") + } } /* The store for simulation results has been extended */ baseStateData.resultValueStore match { case ValueStore(_, store) => - store.size shouldBe 1 - store.getOrElse( - 0L, - fail("Expected a simulation result for tick 900.") - ) match { - case ApparentPower(p, q) => - (p ~= Megawatts(0d)) shouldBe true - (q ~= Megavars(0d)) shouldBe true - } + // FIXME: Please double-check if an empty result store is actually correct here! + store.keys shouldBe empty } case _ => fail( @@ -479,7 +538,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -490,11 +549,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -511,7 +576,7 @@ class EvcsAgentModelCalculationSpec evcsAgent.stateName shouldBe HandleInformation evcsAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -531,12 +596,17 @@ class EvcsAgentModelCalculationSpec /* Send out new data */ val arrivingEvsData = - ArrivingEvsData(Seq(evA, evB)) + ArrivingEvsData(Seq(EvModelWrapper(evA), EvModelWrapper(evB))) val key1 = Some(ScheduleKey(lock.ref.toTyped, UUID.randomUUID())) evService.send( evcsAgent, - ProvideEvDataMessage(0L, arrivingEvsData, unlockKey = key1) + ProvideEvDataMessage( + 0L, + evService.ref, + arrivingEvsData, + unlockKey = key1 + ) ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) @@ -547,30 +617,50 @@ class EvcsAgentModelCalculationSpec ) evcsAgent.stateName shouldBe Idle evcsAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { + baseStateData.stateDataStore match { case ValueStore(_, store) => - store shouldBe Map( - 0L -> EvcsRelevantData( - FALLBACK_EV_MOVEMENTS_STEM_DISTANCE, - Set(evA, evB) - ) - ) + store.keys should contain only 0L + store.get(0L) match { + case Some(EvcsState(currentEvs, schedule, tick)) => + currentEvs should contain theSameElementsAs Set( + EvModelWrapper(evA), + EvModelWrapper(evB) + ) + schedule.values.flatten should contain allOf ( + ChargingSchedule( + EvModelWrapper(evA), + Seq( + ChargingSchedule.Entry( + 0, + 200, + Kilowatts(11.0) + ) + ) + ), + ChargingSchedule( + EvModelWrapper(evB), + Seq( + ChargingSchedule.Entry( + 0, + 200, + Kilowatts(11.0) + ) + ) + ) + ) + + tick shouldBe 0L + case None => fail("Entry for tick 0 expected.") + } } /* The store for simulation results has been extended */ baseStateData.resultValueStore match { case ValueStore(_, store) => - store.size shouldBe 1 - store.getOrElse( - 0L, - fail("Expected a simulation result for tick 900.") - ) match { - case ApparentPower(p, q) => - (p ~= Megawatts(0d)) shouldBe true - (q ~= Megavars(0d)) shouldBe true - } + // FIXME: Please double-check if an empty result store is actually correct here! + store shouldBe empty } case _ => fail( @@ -584,7 +674,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -595,11 +685,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -625,7 +721,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = Iterable.empty ) ) @@ -636,11 +732,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -667,7 +769,8 @@ class EvcsAgentModelCalculationSpec evcsAgent, ProvideEvDataMessage( 0L, - ArrivingEvsData(Seq(evA)), + evService.ref, + ArrivingEvsData(Seq(EvModelWrapper(evA))), unlockKey = key1 ) ) @@ -700,7 +803,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = ParticipantInitializeStateData( - inputModel = voltageSensitiveInput, + inputModel = evcsInputModelQv, modelConfig = modelConfig, secondaryDataServices = withServices, simulationStartDate = simulationStartDate, @@ -722,11 +825,17 @@ class EvcsAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(evcsAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] - evService.send(evcsAgent, RegistrationSuccessfulMessage(None)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -739,7 +848,8 @@ class EvcsAgentModelCalculationSpec evcsAgent, ProvideEvDataMessage( 0L, - ArrivingEvsData(Seq(evA)), + evService.ref, + ArrivingEvsData(Seq(EvModelWrapper(evA.copyWithDeparture(3600L)))), unlockKey = key1 ) ) @@ -755,14 +865,15 @@ class EvcsAgentModelCalculationSpec DepartingEvsRequest(3600L, Seq(evA.getUuid)) ) evService.expectMsgType[DepartingEvsResponse] match { - case DepartingEvsResponse(evcs, evs) => - evcs shouldBe evcsInputModel.getUuid - - evs should have size 1 - - val ev = evs.headOption.getOrElse(fail("No EV departed")) - ev.getUuid shouldBe evA.getUuid - ev.getStoredEnergy should equalWithTolerance(11d.asKiloWattHour) + case DepartingEvsResponse(evcs, evModels) => + evcs shouldBe evcsInputModelQv.getUuid + evModels should have size 1 + evModels.headOption match { + case Some(evModel) => + evModel.uuid shouldBe evA.getUuid + (evModel.storedEnergy ~= KilowattHours(11.0)) shouldBe true + case None => fail("Expected to get at least one ev.") + } } // arrivals second @@ -771,7 +882,8 @@ class EvcsAgentModelCalculationSpec evcsAgent, ProvideEvDataMessage( 3600L, - ArrivingEvsData(Seq(evB)), + evService.ref, + ArrivingEvsData(Seq(EvModelWrapper(evB.copyWithDeparture(7200L)))), unlockKey = key2 ) ) @@ -789,14 +901,12 @@ class EvcsAgentModelCalculationSpec ) evService.expectMsgType[DepartingEvsResponse] match { case DepartingEvsResponse(evcs, evModels) => - evcs shouldBe evcsInputModel.getUuid + evcs shouldBe evcsInputModelQv.getUuid evModels should have size 1 evModels.headOption match { case Some(evModel) => - evModel.getUuid shouldBe evB.getUuid - evModel.getStoredEnergy should equalWithTolerance( - 11d.asKiloWattHour - ) + evModel.uuid shouldBe evB.getUuid + (evModel.storedEnergy ~= KilowattHours(11.0)) shouldBe true case None => fail("Expected to get at least one ev.") } } @@ -806,7 +916,8 @@ class EvcsAgentModelCalculationSpec evcsAgent, ProvideEvDataMessage( 7200L, - ArrivingEvsData(Seq(evA)), + evService.ref, + ArrivingEvsData(Seq(EvModelWrapper(evA.copyWithDeparture(10800L)))), unlockKey = key3 ) ) @@ -825,7 +936,7 @@ class EvcsAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true + (p ~= Megawatts(0.011)) shouldBe true (q ~= Megavars(0.0)) shouldBe true case answer => fail(s"Did not expect to get that answer: $answer") } @@ -843,7 +954,7 @@ class EvcsAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true + (p ~= Megawatts(0.011)) shouldBe true (q ~= Megavars(0.0)) shouldBe true } } @@ -859,9 +970,959 @@ class EvcsAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true - (q ~= Megavars(-0.00335669)) shouldBe true + (p ~= Megawatts(0.011)) shouldBe true + (q ~= Megavars(-0.0067133728)) shouldBe true } } } + + "An evcs agent with model calculation controlled by an EmAgent" should { + + "be initialized correctly" in { + val emAgent = TestProbe("EmAgentProbe") + + val evcsAgent = TestFSMRef( + new EvcsAgent( + scheduler = scheduler.ref, + initStateData = ParticipantInitializeStateData( + inputModel = evcsInputModelQv, + modelConfig = modelConfig, + secondaryDataServices = withServices, + simulationStartDate = simulationStartDate, + simulationEndDate = simulationEndDate, + resolution = resolution, + requestVoltageDeviationThreshold = + simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + outputConfig = defaultOutputConfig, + primaryServiceProxy = primaryServiceProxy.ref, + maybeEmAgent = Some(emAgent.ref.toTyped) + ), + listener = Iterable.empty + ) + ) + + scheduler.send(evcsAgent, Activation(INIT_SIM_TICK)) + + /* Actor should ask for registration with primary service */ + primaryServiceProxy.expectMsg( + PrimaryServiceRegistrationMessage(evcsInputModelQv.getUuid) + ) + /* State should be information handling and having correct state data */ + evcsAgent.stateName shouldBe HandleInformation + evcsAgent.stateData match { + case ParticipantInitializingStateData( + inputModel, + modelConfig, + secondaryDataServices, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig, + maybeEmAgent + ) => + inputModel shouldBe SimpleInputContainer(evcsInputModelQv) + modelConfig shouldBe modelConfig + secondaryDataServices shouldBe withServices + simulationStartDate shouldBe simulationStartDate + simulationEndDate shouldBe simulationEndDate + resolution shouldBe resolution + requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold + outputConfig shouldBe defaultOutputConfig + maybeEmAgent shouldBe Some(emAgent.ref.toTyped) + case unsuitableStateData => + fail(s"Agent has unsuitable state data '$unsuitableStateData'.") + } + + /* Refuse registration */ + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) + + emAgent.expectMsg( + RegisterParticipant( + evcsInputModelQv.getUuid, + evcsAgent.toTyped, + evcsInputModelQv + ) + ) + // only receive registration message. ScheduleFlexRequest after secondary service initialized + emAgent.expectNoMessage() + + evService.expectMsg(RegisterForEvDataMessage(evcsInputModelQv.getUuid)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) + + emAgent.expectMsg( + ScheduleFlexRequest(evcsInputModelQv.getUuid, 0) + ) + + scheduler.expectMsg(Completion(evcsAgent.toTyped)) + + /* ... as well as corresponding state and state data */ + evcsAgent.stateName shouldBe Idle + evcsAgent.stateData match { + case ParticipantModelBaseStateData( + startDate, + endDate, + _, + services, + outputConfig, + additionalActivationTicks, + foreseenDataTicks, + _, + voltageValueStore, + resultValueStore, + requestValueStore, + _, + _, + _ + ) => + /* Base state data */ + startDate shouldBe simulationStartDate + endDate shouldBe simulationEndDate + services shouldBe withServices + outputConfig shouldBe defaultOutputConfig + additionalActivationTicks shouldBe empty + foreseenDataTicks shouldBe Map(evService.ref -> None) + voltageValueStore shouldBe ValueStore( + resolution, + SortedMap(0L -> Each(1.0)) + ) + resultValueStore shouldBe ValueStore( + resolution + ) + requestValueStore shouldBe ValueStore[ApparentPower]( + resolution + ) + case unrecognized => + fail( + s"Did not find expected state data $ParticipantModelBaseStateData, but $unrecognized" + ) + } + } + + "provide correct flex options when in Idle" in { + val emAgent = TestProbe("EmAgentProbe") + val resultListener = TestProbe("ResultListener") + + val evcsAgent = TestFSMRef( + new EvcsAgent( + scheduler = scheduler.ref, + initStateData = ParticipantInitializeStateData( + inputModel = SimpleInputContainer(evcsInputModelQv), + modelConfig = modelConfig, + secondaryDataServices = withServices, + simulationStartDate = simulationStartDate, + simulationEndDate = simulationEndDate, + resolution = resolution, + requestVoltageDeviationThreshold = + simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + outputConfig = NotifierConfig( + simulationResultInfo = true, + powerRequestReply = false, + flexResult = true + ), + primaryServiceProxy = primaryServiceProxy.ref, + maybeEmAgent = Some(emAgent.ref.toTyped) + ), + listener = Iterable(resultListener.ref) + ) + ) + + scheduler.send(evcsAgent, Activation(INIT_SIM_TICK)) + + /* Actor should ask for registration with primary service */ + primaryServiceProxy.expectMsg( + PrimaryServiceRegistrationMessage(evcsInputModelQv.getUuid) + ) + /* State should be information handling and having correct state data */ + evcsAgent.stateName shouldBe HandleInformation + evcsAgent.stateData match { + case ParticipantInitializingStateData( + inputModel, + modelConfig, + secondaryDataServices, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig, + maybeEmAgent + ) => + inputModel shouldBe SimpleInputContainer(evcsInputModelQv) + modelConfig shouldBe modelConfig + secondaryDataServices shouldBe withServices + simulationStartDate shouldBe simulationStartDate + simulationEndDate shouldBe simulationEndDate + resolution shouldBe resolution + requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold + outputConfig shouldBe NotifierConfig( + simulationResultInfo = true, + powerRequestReply = false, + flexResult = true + ) + maybeEmAgent shouldBe Some(emAgent.ref.toTyped) + case unsuitableStateData => + fail(s"Agent has unsuitable state data '$unsuitableStateData'.") + } + + /* Refuse registration */ + primaryServiceProxy.send( + evcsAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) + + emAgent.expectMsg( + RegisterParticipant( + evcsInputModelQv.getUuid, + evcsAgent.toTyped, + evcsInputModelQv + ) + ) + emAgent.expectNoMessage() + + evService.expectMsg(RegisterForEvDataMessage(evcsInputModelQv.getUuid)) + evService.send( + evcsAgent, + RegistrationSuccessfulMessage(evService.ref, None) + ) + + emAgent.expectMsg( + ScheduleFlexRequest(evcsInputModelQv.getUuid, 0) + ) + + scheduler.expectMsg(Completion(evcsAgent.toTyped)) + + /* TICK 0 (expected activation) + - currently no cars + */ + + emAgent.send(evcsAgent, RequestFlexOptions(0)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + refPower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (refPower ~= Kilowatts(0.0)) shouldBe true + (minPower ~= Kilowatts(0.0)) shouldBe true + (maxPower ~= Kilowatts(0.0)) shouldBe true + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 0.toDateTime + flexResult.getpRef should beEquivalentTo(0d.asKiloWatt) + flexResult.getpMin should beEquivalentTo(0d.asKiloWatt) + flexResult.getpMax should beEquivalentTo(0d.asKiloWatt) + } + + emAgent.send( + evcsAgent, + IssueNoControl(0) + ) + + // next potential activation at fully charged battery: + // net power = 12.961kW * 0.92 = 11.92412kW + // time to charge fully ~= 16.7727262054h = 60382 ticks (rounded) + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(0)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe false + requestAtTick shouldBe None + } + + // results arrive after next activation + resultListener.expectNoMessage() + + /* TICK 900 + - ev 900 arrives + - charging with 11 kW + */ + + val ev900 = EvModelWrapper(evA.copyWithDeparture(4500)) + + evService.send( + evcsAgent, + ProvideEvDataMessage( + 900, + evService.ref, + ArrivingEvsData(Seq(ev900)) + ) + ) + + emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 900)) + emAgent.send(evcsAgent, RequestFlexOptions(900)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe ev900.sRatedAc + minPower shouldBe ev900.sRatedAc // battery is empty + maxPower shouldBe ev900.sRatedAc + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 900.toDateTime + flexResult.getpRef should beEquivalentTo(ev900.unwrap().getSRatedAC) + flexResult.getpMin should beEquivalentTo(ev900.unwrap().getSRatedAC) + flexResult.getpMax should beEquivalentTo(ev900.unwrap().getSRatedAC) + } + + emAgent.send(evcsAgent, IssueNoControl(900)) + + // at 4500 ev is departing + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts( + ev900 + .unwrap() + .getSRatedAC + .to(PowerSystemUnits.KILOWATT) + .getValue + .doubleValue + )) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe true + requestAtTick shouldBe Some(4500) + } + + // result of tick 0 + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 0.toDateTime + result.getP should beEquivalentTo(0d.asMegaWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 4500 + - ev900 departs, ev4500 arrives + - charging with 11 kW + */ + + // departure first + evService.send( + evcsAgent, + DepartingEvsRequest(4500, Seq(ev900.uuid)) + ) + + evService.expectMsgPF() { case DepartingEvsResponse(uuid, evs) => + evs.size shouldBe 1 + uuid shouldBe evcsInputModelQv.getUuid + evs.headOption.foreach { ev => + ev.uuid shouldBe ev900.uuid + (ev.storedEnergy ~= KilowattHours(11.0)) shouldBe true + } + } + + // results arrive right after departure request + Range(0, 2) + .map { _ => + resultListener.expectMsgType[ParticipantResultEvent] + } + .foreach { + case ParticipantResultEvent(result: EvResult) + if result.getTime.equals(900.toDateTime) => + result.getInputModel shouldBe ev900.uuid + result.getP should beEquivalentTo(ev900.unwrap().getSRatedAC) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(0d.asPercent) + case ParticipantResultEvent(result: EvResult) + if result.getTime.equals(4500.toDateTime) => + result.getInputModel shouldBe ev900.uuid + result.getP should beEquivalentTo(0d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(18.96551724137931d.asPercent) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 900.toDateTime + result.getP should beEquivalentTo(ev900.unwrap().getSRatedAC) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + val ev4500 = EvModelWrapper(evB.copyWithDeparture(72000)) + + evService.send( + evcsAgent, + ProvideEvDataMessage( + 4500, + evService.ref, + ArrivingEvsData(Seq(ev4500)) + ) + ) + + emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 4500)) + emAgent.send(evcsAgent, RequestFlexOptions(4500)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe ev4500.sRatedAc + minPower shouldBe ev900.sRatedAc // battery is empty + maxPower shouldBe ev4500.sRatedAc + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 4500.toDateTime + flexResult.getpRef should beEquivalentTo(ev4500.unwrap().getSRatedAC) + flexResult.getpMin should beEquivalentTo(ev4500.unwrap().getSRatedAC) + flexResult.getpMax should beEquivalentTo(ev4500.unwrap().getSRatedAC) + } + + emAgent.send(evcsAgent, IssueNoControl(4500)) + + // we currently have an empty battery in ev4500 + // time to charge to minimal soc ~= 1.45454545455h = 5236 ticks (rounded) from now + // current tick is 4500, thus: 4500 + 5236 = 9736 + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(11)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe true + requestAtTick shouldBe Some(9736) + } + + // already sent out after EV departed + resultListener.expectNoMessage() + + /* TICK 9736 + - flex control changes + - charging with 10 kW + */ + + // sending flex request at very next activated tick + emAgent.send(evcsAgent, RequestFlexOptions(9736)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe ev4500.sRatedAc + minPower shouldBe Kilowatts(0.0) // battery is exactly at margin + maxPower shouldBe ev4500.sRatedAc + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 9736.toDateTime + flexResult.getpRef should beEquivalentTo(ev4500.unwrap().getSRatedAC) + flexResult.getpMin should beEquivalentTo(0d.asKiloWatt) + flexResult.getpMax should beEquivalentTo(ev4500.unwrap().getSRatedAC) + } + + emAgent.send(evcsAgent, IssuePowerControl(9736, Kilowatts(10.0))) + + evService.expectNoMessage() + + // ev4500 is now at 16 kWh + // time to charge fully = 6.4 h = 23040 ticks from now + // current tick is 9736, thus: 9736 + 23040 = 32776 + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(10)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + // since battery is still below lowest soc, it's still considered empty + requestAtNextActivation shouldBe true + requestAtTick shouldBe Some(32776) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvResult) => + result.getInputModel shouldBe ev4500.uuid + result.getTime shouldBe 4500.toDateTime + result.getP should beEquivalentTo(11d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(0d.asPercent) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 4500.toDateTime + result.getP should beEquivalentTo(11d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 11700 + - ev11700 arrives + - charging with 16 kW + */ + + // with stored energy right at minimal SOC + val ev11700 = EvModelWrapper( + evA.copyWithDeparture(36000).copyWith(11.6d.asKiloWattHour) + ) + + evService.send( + evcsAgent, + ProvideEvDataMessage( + 11700, + evService.ref, + ArrivingEvsData(Seq(ev11700)) + ) + ) + + emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 11700)) + emAgent.send(evcsAgent, RequestFlexOptions(11700)) + + val combinedChargingPower = + ev11700.unwrap().getSRatedAC.add(ev4500.unwrap().getSRatedAC) + val combinedChargingPowerSq = Kilowatts( + combinedChargingPower.to(PowerSystemUnits.KILOWATT).getValue.doubleValue + ) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + refPower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + refPower shouldBe combinedChargingPowerSq + minPower shouldBe ev4500.sRatedAc * -1 // battery of earlier ev is above lowest soc now + maxPower shouldBe combinedChargingPowerSq + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 11700.toDateTime + flexResult.getpRef should beEquivalentTo(combinedChargingPower) + flexResult.getpMin should beEquivalentTo( + ev4500.unwrap().getSRatedAC.multiply(-1) + ) + flexResult.getpMax should beEquivalentTo(combinedChargingPower) + } + + emAgent.send(evcsAgent, IssuePowerControl(11700, Kilowatts(16))) + + // no departing evs here + evService.expectNoMessage() + + // ev4500 is now at ~ 21.45555556 kWh, ev11700 just arrived with 11.6 kWh + // ev4500: time to charge fully ~= 7.3180556 h = 26345 ticks from now + // ev11700: time to charge fully = 5.8 h = 20880 ticks from now + // current tick is 11700, thus: 11700 + 20880 = 32580 + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(16)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + // since battery is still below lowest soc, it's still considered empty + requestAtNextActivation shouldBe true + requestAtTick shouldBe Some(32580) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvResult) => + result.getInputModel shouldBe ev4500.uuid + result.getTime shouldBe 9736.toDateTime + result.getP should beEquivalentTo(10d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(20d.asPercent, 1e-2) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 9736.toDateTime + result.getP should beEquivalentTo(10d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 18000 + - flex control changes + - discharging with 20 kW + */ + + // sending flex request at very next activated tick + emAgent.send(evcsAgent, RequestFlexOptions(18000)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe combinedChargingPowerSq + minPower shouldBe combinedChargingPowerSq * -1 // battery of both evs is above lowest soc now + maxPower shouldBe combinedChargingPowerSq + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 18000.toDateTime + flexResult.getpRef should beEquivalentTo(combinedChargingPower) + flexResult.getpMin should beEquivalentTo( + combinedChargingPower.multiply( + -1 + ) + ) + flexResult.getpMax should beEquivalentTo(combinedChargingPower) + } + + emAgent.send(evcsAgent, IssuePowerControl(18000, Kilowatts(-20))) + + // no departing evs here + evService.expectNoMessage() + + // ev4500 is now at ~ 35.455556 kWh, ev11700 at 25.6 kWh + // ev4500: time to discharge to lowest soc ~= 1.9455556 h = 7004 ticks from now + // ev11700: time to discharge to lowest soc ~= 1.4 h = 5040 ticks from now + // current tick is 18000, thus: 18000 + 5040 = 23040 + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(-20)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe false + requestAtTick shouldBe Some(23040) + } + + Range(0, 2) + .map { _ => + resultListener.expectMsgType[ParticipantResultEvent] + } + .foreach { + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev4500.uuid => + result.getTime shouldBe 11700.toDateTime + result.getP should beEquivalentTo(8d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(26.819d.asPercent, 1e-2) + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev11700.uuid => + result.getTime shouldBe 11700.toDateTime + result.getP should beEquivalentTo(8d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(20.0d.asPercent) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 11700.toDateTime + result.getP should beEquivalentTo(16d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 23040 + - ev11700 at lowest soc + - discharging with 10 kW + */ + + emAgent.send(evcsAgent, RequestFlexOptions(23040)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe combinedChargingPowerSq + minPower shouldBe ev4500.sRatedAc * -1 // battery of ev11700 is below lowest soc now + maxPower shouldBe combinedChargingPowerSq + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 23040.toDateTime + flexResult.getpRef should beEquivalentTo(combinedChargingPower) + flexResult.getpMin should beEquivalentTo( + ev4500 + .unwrap() + .getSRatedAC + .multiply( + -1 + ) + ) + flexResult.getpMax should beEquivalentTo(combinedChargingPower) + } + + emAgent.send(evcsAgent, IssuePowerControl(23040, Kilowatts(-10))) + + // no departing evs here + evService.expectNoMessage() + + // ev4500 is now at 21.455556 kWh, ev11700 at 11.6 kWh (lowest soc) + // ev4500: time to discharge to lowest soc = 0.5455556 h = 1964 ticks from now + // current tick is 18864, thus: 23040 + 1964 = 25004 + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(-10)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe false + requestAtTick shouldBe Some(25004) + } + + Range(0, 2) + .map { _ => + resultListener.expectMsgType[ParticipantResultEvent] + } + .foreach { + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev4500.uuid => + result.getTime shouldBe 18000.toDateTime + result.getP should beEquivalentTo((-10d).asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(44.3194d.asPercent, 1e-2) + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev11700.uuid => + result.getTime shouldBe 18000.toDateTime + result.getP should beEquivalentTo((-10d).asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(44.137931034d.asPercent, 1e-6) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 18000.toDateTime + result.getP should beEquivalentTo((-20d).asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 25004 + - both evs at lowest soc + - no power + */ + + emAgent.send(evcsAgent, RequestFlexOptions(25004)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe combinedChargingPowerSq + minPower shouldBe Kilowatts(0.0) // both at lowest soc + maxPower shouldBe combinedChargingPowerSq + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 25004.toDateTime + flexResult.getpRef should beEquivalentTo(combinedChargingPower) + flexResult.getpMin should beEquivalentTo(0.asKiloWatt) + flexResult.getpMax should beEquivalentTo(combinedChargingPower) + } + + emAgent.send(evcsAgent, IssuePowerControl(25004, Kilowatts(0.0))) + + // no departing evs here + evService.expectNoMessage() + + // no new activation + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(0)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + requestAtNextActivation shouldBe false + requestAtTick shouldBe None + } + + Range(0, 2) + .map { _ => + resultListener.expectMsgType[ParticipantResultEvent] + } + .foreach { + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev4500.uuid => + result.getTime shouldBe 23040.toDateTime + result.getP should beEquivalentTo((-10d).asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(26.819445d.asPercent, 1e-2) + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev11700.uuid => + result.getTime shouldBe 23040.toDateTime + result.getP should beEquivalentTo(0d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(20d.asPercent) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 23040.toDateTime + result.getP should beEquivalentTo((-10d).asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + /* TICK 36000 + - ev11700 departs + - charging with 4 kW + */ + + // departure first + evService.send( + evcsAgent, + DepartingEvsRequest(36000, Seq(ev900.uuid)) + ) + + evService.expectMsgPF() { case DepartingEvsResponse(uuid, evs) => + evs.size shouldBe 1 + uuid shouldBe evcsInputModelQv.getUuid + evs.headOption.foreach { ev => + ev.uuid shouldBe ev11700.uuid + (ev.storedEnergy ~= KilowattHours(11.6)) shouldBe true + } + } + + Range(0, 2) + .map { _ => + resultListener.expectMsgType[ParticipantResultEvent] + } + .foreach { + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev4500.uuid => + result.getTime shouldBe 25004.toDateTime + result.getP should beEquivalentTo(0d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(20d.asPercent, 1e-2) + case ParticipantResultEvent(result: EvResult) + if result.getInputModel == ev11700.uuid => + result.getTime shouldBe 25004.toDateTime + result.getP should beEquivalentTo(0d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + result.getSoc should beEquivalentTo(20d.asPercent) + } + + resultListener.expectMsgPF() { + case ParticipantResultEvent(result: EvcsResult) => + result.getInputModel shouldBe evcsInputModelQv.getUuid + result.getTime shouldBe 25004.toDateTime + result.getP should beEquivalentTo(0d.asKiloWatt) + result.getQ should beEquivalentTo(0d.asMegaVar) + } + + // sending flex request at very next activated tick + emAgent.send(evcsAgent, RequestFlexOptions(36000)) + + emAgent.expectMsgType[ProvideFlexOptions] match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + referencePower shouldBe ev4500.sRatedAc + minPower shouldBe Kilowatts(0d) + maxPower shouldBe ev4500.sRatedAc + } + + resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => + flexResult.getInputModel shouldBe evcsInputModelQv.getUuid + flexResult.getTime shouldBe 36000.toDateTime + flexResult.getpRef should beEquivalentTo(ev4500.unwrap().getSRatedAC) + flexResult.getpMin should beEquivalentTo(0.asKiloWatt) + flexResult.getpMax should beEquivalentTo(ev4500.unwrap().getSRatedAC) + } + + emAgent.send(evcsAgent, IssuePowerControl(36000, Kilowatts(4.0))) + + // ev11700 is now at 16 kWh + // ev11700: time to charge fully = 16 h = 57600 ticks from now + // current tick is 36000, thus: 36000 + 57600 = 93600 + // BUT: departing tick 72000 is earlier + emAgent.expectMsgPF() { + case FlexCtrlCompletion( + modelUuid, + result, + requestAtNextActivation, + requestAtTick + ) => + modelUuid shouldBe evcsInputModelQv.getUuid + (result.p ~= Kilowatts(4)) shouldBe true + (result.q ~= Megavars(0)) shouldBe true + // since we're starting from lowest again + requestAtNextActivation shouldBe true + requestAtTick shouldBe Some(72000) + } + + } + + } + } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 9ac4aac473..077736af2b 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -6,10 +6,6 @@ package edu.ie3.simona.agent.participant -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.testkit.{TestFSMRef, TestProbe} -import org.apache.pekko.util.Timeout import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.simona.agent.ValueStore @@ -25,7 +21,7 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.HpRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.integration.common.IntegrationSpecCommon -import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} +import edu.ie3.simona.model.participant.HpModel.HpState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -54,15 +50,20 @@ import edu.ie3.util.scala.quantities.{ Vars, WattsPerSquareMeter } +import org.apache.pekko.actor.ActorSystem +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.testkit.{TestFSMRef, TestProbe} +import org.apache.pekko.util.Timeout import org.scalatest.PrivateMethodTester import squants.energy.{Kilowatts, Megawatts, Watts} import squants.motion.MetersPerSecond import squants.thermal.Celsius -import squants.{Dimensionless, Each, Power, Temperature} +import squants.{Dimensionless, Each} import java.io.File import java.time.ZonedDateTime import java.util.concurrent.TimeUnit +import scala.collection.SortedMap class HpAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -81,12 +82,15 @@ class HpAgentModelCalculationSpec implicit val simulationStart: ZonedDateTime = defaultSimulationStart implicit val receiveTimeOut: Timeout = Timeout(10, TimeUnit.SECONDS) implicit val noReceiveTimeOut: Timeout = Timeout(1, TimeUnit.SECONDS) - implicit val powerTolerance: Power = Watts(1e-3) - implicit val reactivepowerTolerance: ReactivePower = Vars(1e-3) - implicit val temperatureTolerance: Temperature = Celsius(1e-10) - implicit val dimensionlessTolerance: Dimensionless = Each(1e-10) + + private implicit val powerTolerance: squants.Power = Watts(0.1) + private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) + private implicit val temperatureTolerance: squants.Temperature = Celsius( + 1e-10 + ) + /* Alter the input model to have a voltage sensitive reactive power calculation */ - val hpInput: HpInput = inputModel + val hpInput: HpInput = hpInputModel private val simonaConfig: SimonaConfig = SimonaConfig( ConfigFactory @@ -96,7 +100,8 @@ class HpAgentModelCalculationSpec ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply + simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, + simonaConfig.simona.output.participant.defaultConfig.flexResult ) private val participantConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -128,7 +133,8 @@ class HpAgentModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, + maybeEmAgent = None ) "be instantiated correctly" in { @@ -168,7 +174,10 @@ class HpAgentModelCalculationSpec /* Agent attempts to register with primary data service -- refuse this */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) deathProbe.expectTerminated(hpAgent) } @@ -190,7 +199,8 @@ class HpAgentModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, + maybeEmAgent = None ) "be instantiated correctly" in { @@ -239,7 +249,8 @@ class HpAgentModelCalculationSpec defaultSimulationEnd, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, + _ ) => inputModel shouldBe WithHeatInputContainer(hpInput, thermalGrid) modelConfig shouldBe modelConfig @@ -254,7 +265,10 @@ class HpAgentModelCalculationSpec } /* Refuse registration */ - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg( @@ -277,6 +291,8 @@ class HpAgentModelCalculationSpec voltageValueStore, resultValueStore, requestValueStore, + _, + _, _ ), awaitRegistrationResponsesFrom, @@ -292,13 +308,14 @@ class HpAgentModelCalculationSpec ) outputConfig shouldBe NotifierConfig( simulationResultInfo = true, - powerRequestReply = false + powerRequestReply = false, + flexResult = false ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - Map(0L -> Each(1d)) + SortedMap(0L -> Each(1.0)) ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPowerAndHeat]( @@ -315,7 +332,10 @@ class HpAgentModelCalculationSpec } /* Reply, that registration was successful */ - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(4711L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + ) /* Expect a completion message */ scheduler.expectMsg(Completion(hpAgent.toTyped, Some(4711L))) @@ -323,7 +343,7 @@ class HpAgentModelCalculationSpec /* ... as well as corresponding state and state data */ hpAgent.stateName shouldBe Idle hpAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map( weatherService.ref -> Some(4711L) @@ -348,13 +368,19 @@ class HpAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* Expect a registration message */ weatherService.expectMsg( RegisterForWeatherMessage(51.4843281, 7.4116482) ) - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(900L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -364,27 +390,27 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 0L, - Each(1d), - Each(0d) + Dimensionless.primaryUnit(1.0), + Dimensionless.primaryUnit(0.0) ) expectMsg( AssetPowerChangedMessage( - Megawatts(0d), - Megavars(0d) + Megawatts(0.0), + Megavars(0.0) ) ) inside(hpAgent.stateData) { - case modelBaseStateData: ParticipantModelBaseStateData[_, _, _] => + case modelBaseStateData: ParticipantModelBaseStateData[_, _, _, _] => modelBaseStateData.requestValueStore shouldBe ValueStore[ ApparentPowerAndHeat ]( resolution, - Map( + SortedMap( 0L -> ApparentPowerAndHeat( - Megawatts(0d), - Megavars(0d), - Megawatts(0d) + Megawatts(0.0), + Megavars(0.0), + Megawatts(0.0) ) ) ) @@ -408,11 +434,17 @@ class HpAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -421,22 +453,22 @@ class HpAgentModelCalculationSpec /* Send out new data */ val weatherData = WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ) weatherService.send( hpAgent, - ProvideWeatherMessage(0L, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) ) /* Find yourself in corresponding state and state data */ hpAgent.stateName shouldBe HandleInformation hpAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -467,48 +499,36 @@ class HpAgentModelCalculationSpec hpAgent.stateName shouldBe Idle hpAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => - /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { - case ValueStore(_, store) => - store.get(0L) match { - case Some( - HpRelevantData( - HpState( - isRunning, - lastTimeTick, - activePower, - qDot, - thermalGridState - ), - currentTimeTick, - ambientTemperature - ) - ) => - isRunning shouldBe false - lastTimeTick shouldBe 0L - (activePower =~ Kilowatts(0d)) shouldBe true - - (qDot =~ - Kilowatts(0d)) shouldBe true - - thermalGridState.houseState match { - case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature =~ - Celsius( - 20.9999769069444444444444444444444 - )) shouldBe true - case None => - fail( - s"Expected to get a result for thermal house '${inputModel.getUuid}'" - ) - } - - currentTimeTick shouldBe 0L - (ambientTemperature =~ Celsius(1.815d)) shouldBe true + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.stateDataStore.last(0L) match { + case Some( + ( + _, + HpState( + isRunning, + lastTimeTick, + _, + activePower, + qDot, + thermalGridState, + _ + ) + ) + ) => + isRunning shouldBe false + lastTimeTick shouldBe 0L + (activePower ~= Kilowatts(0.0)) shouldBe true + (qDot ~= Kilowatts(0.0)) shouldBe true + + thermalGridState.houseState match { + case Some(ThermalHouseState(_, innerTemperature, _)) => + (innerTemperature ~= Celsius(20.99998675925926)) shouldBe true case None => - fail("Did expect to get hp relevant data for tick 0L") + fail( + s"Expected to get a result for thermal house '${hpInputModel.getUuid}'" + ) } + case None => fail("Expected to get a model state") } /* The store for simulation results has been extended */ @@ -520,9 +540,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(0d)) shouldBe true - q =~ Megavars(0d) shouldBe true - qDot =~ Megawatts(0d) shouldBe true + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true + (qDot ~= Megawatts(0.0)) shouldBe true } } case _ => @@ -545,11 +565,17 @@ class HpAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -562,7 +588,7 @@ class HpAgentModelCalculationSpec hpAgent.stateName shouldBe HandleInformation hpAgent.stateData match { case DataCollectionStateData( - baseStateData: ParticipantModelBaseStateData[_, _, _], + baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, isYetTriggered ) => @@ -584,15 +610,15 @@ class HpAgentModelCalculationSpec /* Providing the awaited data will lead to the foreseen transitions */ val weatherData = WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ) weatherService.send( hpAgent, - ProvideWeatherMessage(0L, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) ) /* Expect confirmation */ @@ -601,47 +627,36 @@ class HpAgentModelCalculationSpec /* Expect the state change to idle with updated base state data */ hpAgent.stateName shouldBe Idle hpAgent.stateData match { - case baseStateData: ParticipantModelBaseStateData[_, _, _] => - /* The store for calculation relevant data has been extended */ - baseStateData.calcRelevantDateStore match { - case ValueStore(_, store) => - store.get(0L) match { - case Some( - HpRelevantData( - HpState( - isRunning, - lastTimeTick, - activePower, - qDot, - thermalGridState - ), - currentTimeTick, - ambientTemperature - ) - ) => - isRunning shouldBe false - lastTimeTick shouldBe 0L - (activePower =~ Kilowatts(0d)) shouldBe true - - (qDot =~ Kilowatts(0d)) shouldBe true - - thermalGridState.houseState match { - case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature =~ Celsius( - 20.9999769069444444444444444444444 - )) shouldBe true - case None => - fail( - s"Expected to get a result for thermal house '${inputModel.getUuid}'" - ) - } - - currentTimeTick shouldBe 0L - (ambientTemperature =~ - Celsius(1.815d)) shouldBe true + case baseStateData: ParticipantModelBaseStateData[_, _, _, _] => + baseStateData.stateDataStore.last(0L) match { + case Some( + ( + _, + HpState( + isRunning, + lastTimeTick, + _, + activePower, + qDot, + thermalGridState, + _ + ) + ) + ) => + isRunning shouldBe false + lastTimeTick shouldBe 0L + (activePower ~= Kilowatts(0.0)) shouldBe true + (qDot ~= Kilowatts(0.0)) shouldBe true + + thermalGridState.houseState match { + case Some(ThermalHouseState(_, innerTemperature, _)) => + (innerTemperature ~= Celsius(20.99998675925926)) shouldBe true case None => - fail("Did expect to get hp relevant data for tick 0L") + fail( + s"Expected to get a result for thermal house '${hpInputModel.getUuid}'" + ) } + case None => fail("Expected to get a model state.") } /* The store for simulation results has been extended */ @@ -653,11 +668,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 0.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - ( - qDot =~ Megawatts(0d) - ) shouldBe true + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true + (qDot ~= Megawatts(0.0)) shouldBe true } } case _ => @@ -681,11 +694,17 @@ class HpAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(3600L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -694,22 +713,27 @@ class HpAgentModelCalculationSpec /* Ask the agent for average power in tick 7200 */ hpAgent ! RequestAssetPowerMessage( 7200L, - Each(1d), - Each(0d) + Each(1.0), + Each(0.0) ) expectNoMessage(noReceiveTimeOut.duration) awaitAssert(hpAgent.stateName == Idle) /* Send out the expected data and wait for the reply */ val weatherData = WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ) weatherService.send( hpAgent, - ProvideWeatherMessage(3600L, weatherData, Some(7200L)) + ProvideWeatherMessage( + 3600L, + weatherService.ref, + weatherData, + Some(7200L) + ) ) /* Trigger the agent */ @@ -722,8 +746,8 @@ class HpAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true } } @@ -741,11 +765,17 @@ class HpAgentModelCalculationSpec /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] - primaryServiceProxy.send(hpAgent, RegistrationFailedMessage) + primaryServiceProxy.send( + hpAgent, + RegistrationFailedMessage(primaryServiceProxy.ref) + ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] - weatherService.send(hpAgent, RegistrationSuccessfulMessage(Some(0L))) + weatherService.send( + hpAgent, + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + ) /* I'm not interested in the content of the CompletionMessage */ scheduler.expectMsgType[Completion] @@ -757,11 +787,12 @@ class HpAgentModelCalculationSpec hpAgent, ProvideWeatherMessage( 0L, + weatherService.ref, WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ), Some(3600L) ) @@ -774,11 +805,12 @@ class HpAgentModelCalculationSpec hpAgent, ProvideWeatherMessage( 3600L, + weatherService.ref, WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ), Some(7200L) ) @@ -791,11 +823,12 @@ class HpAgentModelCalculationSpec hpAgent, ProvideWeatherMessage( 7200L, + weatherService.ref, WeatherData( - WattsPerSquareMeter(0d), - WattsPerSquareMeter(0d), - Celsius(1.815d), - MetersPerSecond(7.726576d) + WattsPerSquareMeter(0), + WattsPerSquareMeter(0), + Celsius(1.815), + MetersPerSecond(7.726576) ), None ) @@ -806,15 +839,14 @@ class HpAgentModelCalculationSpec /* Ask the agent for average power in tick 7500 */ hpAgent ! RequestAssetPowerMessage( 7500L, - Each(1d), - Each(0d) + Each(1.0), + Each(0.0) ) expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -825,14 +857,14 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 7500L, Each(1.000000000000001d), - Each(0d) + Each(0.0) ) /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true } } @@ -840,16 +872,15 @@ class HpAgentModelCalculationSpec /* Ask again with changed information */ hpAgent ! RequestAssetPowerMessage( 7500L, - Each(0.98d), - Each(0d) + Each(0.98), + Each(0.0) ) /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - + (p ~= Megawatts(0.0)) shouldBe true + (q ~= Megavars(0.0)) shouldBe true } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index b1723c3650..189844505f 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -8,22 +8,29 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.model.participant.HpModel.HpState import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState +import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState +import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ + HouseTemperatureLowerBoundaryReached, + HouseTemperatureUpperBoundaryReached +} +import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.util.scala.quantities.WattsPerKelvin import org.scalatest.prop.TableDrivenPropertyChecks -import squants.energy.{Kilowatts, Watts} +import squants.energy.{KilowattHours, Kilowatts, Watts} import squants.thermal.Celsius -import squants.{Power, Temperature} +import squants.{Kelvin, Power, Temperature} class HpModelSpec extends UnitSpec with TableDrivenPropertyChecks with HpModelTestData { - implicit val tempTolerance: Temperature = Celsius(1e-3) + implicit val tempTolerance: Temperature = Kelvin(1e-3) implicit val powerTolerance: Power = Watts(1e-3) "Testing the heat pump model" when { - "calculating the next state with different states" should { "deliver correct tick, power and running state" in { val cases = Table( @@ -31,127 +38,158 @@ class HpModelSpec "state", "expectedRunningState", "expectedActivePower", - "expectedInnerTemperature" + "expectedInnerTemperature", + "expectedNextThreshold" ), ( HpState( isRunning = false, 0, + hpData.ambientTemperature, Kilowatts(0d), Kilowatts(0d), - thermalState(Celsius(17d)) + thermalState(Celsius(17d)), + None ), true, 95, - 15.6 + 15.6, + Some(HouseTemperatureUpperBoundaryReached(31711L)) ), ( HpState( isRunning = false, 0, + hpData.ambientTemperature, Kilowatts(0d), Kilowatts(0d), - thermalState(Celsius(18)) + thermalState(Celsius(18)), + None ), true, 95, - 16.4 + 16.4, + Some(HouseTemperatureUpperBoundaryReached(30642L)) ), ( HpState( isRunning = false, 0, + hpData.ambientTemperature, Kilowatts(0d), Kilowatts(0d), - thermalState(Celsius(20)) + thermalState(Celsius(20)), + None ), true, 95, - 18.0 + 18.0, + Some(HouseTemperatureUpperBoundaryReached(27771L)) ), ( HpState( isRunning = false, 0, + hpData.ambientTemperature, Kilowatts(0d), Kilowatts(0d), - thermalState(Celsius(22)) + thermalState(Celsius(22)), + None ), false, 0, - 19.6 + 19.6, + Some(HouseTemperatureLowerBoundaryReached(13200L)) ), ( HpState( isRunning = false, 0, + hpData.ambientTemperature, Kilowatts(0d), Kilowatts(0d), - thermalState(Celsius(23)) + thermalState(Celsius(23)), + None ), false, 0, - 20.4 + 20.4, + Some(HouseTemperatureLowerBoundaryReached(15508L)) ), ( HpState( isRunning = true, 0, + hpData.ambientTemperature, Kilowatts(95d), Kilowatts(80d), - thermalState(Celsius(17)) + thermalState(Celsius(17)), + None ), true, 95, - 15.6 + 15.6, + Some(HouseTemperatureUpperBoundaryReached(31711L)) ), ( HpState( isRunning = true, 0, + hpData.ambientTemperature, Kilowatts(95d), Kilowatts(80d), - thermalState(Celsius(18)) + thermalState(Celsius(18)), + None ), true, 95, - 16.4 + 16.4, + Some(HouseTemperatureUpperBoundaryReached(30642L)) ), ( HpState( isRunning = true, 0, + hpData.ambientTemperature, Kilowatts(95d), Kilowatts(80d), - thermalState(Celsius(20)) + thermalState(Celsius(20)), + None ), true, 95, - 18.0 + 18.0, + Some(HouseTemperatureUpperBoundaryReached(27771L)) ), ( HpState( isRunning = true, 0, + hpData.ambientTemperature, Kilowatts(95d), Kilowatts(80d), - thermalState(Celsius(22)) + thermalState(Celsius(22)), + None ), true, 95, - 19.6 + 19.6, + Some(HouseTemperatureUpperBoundaryReached(23200L)) ), ( HpState( isRunning = true, 0, + hpData.ambientTemperature, Kilowatts(95d), Kilowatts(80d), - thermalState(Celsius(25)) + thermalState(Celsius(25)), + None ), false, 0, - 22.0 + 22.0, + Some(HouseTemperatureLowerBoundaryReached(19200L)) ) ) @@ -160,30 +198,86 @@ class HpModelSpec state, expectedRunningState, expectedActivePower, - expectedInnerTemperature + expectedInnerTemperature, + expectedNextThreshold ) => - val data = hpData(state) + val data = hpData val house = thermalHouse(18, 22) val grid = thermalGrid(house) val hp = hpModel(grid) - hp.calculateNextState(data) match { + hp.calculateNextState(state, data) match { case HpState( isRunning, - lastTimeTick, + _, + _, activePower, _, - ThermalGridState(Some(thermalHouseState), _) + ThermalGridState(Some(thermalHouseState), _), + maybeThreshold ) => isRunning shouldBe expectedRunningState - (activePower =~ Kilowatts(expectedActivePower)) shouldBe true + (activePower ~= Kilowatts(expectedActivePower)) shouldBe true - (thermalHouseState.innerTemperature =~ Celsius( + (thermalHouseState.innerTemperature ~= Celsius( expectedInnerTemperature )) shouldBe true + + maybeThreshold shouldBe expectedNextThreshold } } } } + + "determining the flexibility options" when { + "the house is heated up and storage has space" should { + "deliver positive flexibility" in { + val house = thermalHouse(18, 22) + .copy(ethLosses = WattsPerKelvin(200)) + val grid = thermalGrid(house, Some(thermalStorage)) + val hp = hpModel(grid) + // Tick, at which the house is heated up + val relevantData = hpData.copy(currentTimeTick = 2763L) + val thermalState = ThermalGridState( + Some( + ThermalHouseState( + 0L, + Celsius(21), + Kilowatts(80) + ) + ), + Some( + ThermalStorageState( + 0L, + KilowattHours(20), + Kilowatts(0) + ) + ) + ) + val lastState = HpState( + isRunning = true, + 0, + hpData.ambientTemperature, + Kilowatts(95.0), + Kilowatts(80.0), + thermalState, + Some(HouseTemperatureUpperBoundaryReached(7995L)) + ) + + hp.determineFlexOptions(relevantData, lastState) match { + case ProvideMinMaxFlexOptions( + modelUuid, + referencePower, + minPower, + maxPower + ) => + modelUuid shouldBe hp.uuid + (referencePower ~= Kilowatts(95.0)) shouldBe true + (minPower ~= Kilowatts(0.0)) shouldBe true + (maxPower ~= Kilowatts(95.0)) shouldBe true + } + } + } + } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala index 464e8f9653..fb0fa4c0a1 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.model.participant -import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.datamodel.models.input.system.`type`.HpTypeInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed @@ -14,9 +13,10 @@ import edu.ie3.datamodel.models.input.thermal.{ ThermalBusInput, ThermalHouseInput } +import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.datamodel.models.{OperationTime, StandardUnits} -import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} +import edu.ie3.simona.model.participant.HpModel.HpRelevantData import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState @@ -130,7 +130,7 @@ trait HpModelTestData { KilowattHours(0d) ) - def thermalState( + protected def thermalState( temperature: Temperature, qDot: Power = Kilowatts(0d) ): ThermalGridState = ThermalGridState( @@ -144,7 +144,7 @@ trait HpModelTestData { None ) - protected def hpData(hpState: HpState): HpRelevantData = - HpRelevantData(hpState, 7200, Celsius(10d)) + protected def hpData: HpRelevantData = + HpRelevantData(7200, Celsius(10d)) } diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala new file mode 100644 index 0000000000..0839479be4 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -0,0 +1,848 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs + +import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType +import edu.ie3.simona.model.participant.FlexChangeIndicator +import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsRelevantData, + EvcsState +} +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.model.MockEvModel +import edu.ie3.simona.test.common.model.participant.EvcsTestData +import edu.ie3.simona.test.helper.TableDrivenHelper +import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble +import org.scalatest.prop.TableDrivenPropertyChecks +import squants.Each +import squants.energy.{KilowattHours, Kilowatts} + +import java.util.UUID + +class EvcsModelSpec + extends UnitSpec + with TableDrivenPropertyChecks + with TableDrivenHelper + with EvcsTestData { + + private val simulationStart = evcsStandardModel.simulationStartDate + + private implicit val energyTolerance: squants.Energy = KilowattHours(1e-10) + private implicit val powerTolerance: squants.Power = Kilowatts(1e-10) + + // TODO some conditions/functions have not been tested yet + "An EVCS model" should { + + "calculate new schedules correctly" when { + + "configured as a charging hub" in { + val evcsModel = evcsStandardModel.copy( + strategy = ChargingStrategy.CONSTANT_POWER, + locationType = EvcsLocationType.CHARGING_HUB_TOWN + ) + + val evModel = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 20.0.asKiloWattHour, + 5.0.asKiloWattHour, + 10800L + ) + ) + + val actualSchedule = evcsModel.calculateNewScheduling( + EvcsRelevantData( + 3600L, + Seq.empty, + Map.empty // should be irrelevant + ), + Set(evModel) + ) + + actualSchedule shouldBe Map( + evModel -> Some( + // ending early at 9000 because of max power charging + ChargingSchedule(evModel, Seq(Entry(3600L, 9000L, Kilowatts(10.0)))) + ) + ) + } + + "configured as a home cs with constant power strategy" in { + val evcsModel = evcsStandardModel.copy( + strategy = ChargingStrategy.CONSTANT_POWER, + locationType = EvcsLocationType.HOME + ) + + val evModel = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 20.0.asKiloWattHour, + 15.0.asKiloWattHour, + 10800L + ) + ) + + val actualSchedule = evcsModel.calculateNewScheduling( + EvcsRelevantData( + 3600L, + Seq.empty, + Map.empty // should be irrelevant + ), + Set(evModel) + ) + + actualSchedule shouldBe Map( + evModel -> Some( + // using 2.5 kW with constant power charging + ChargingSchedule(evModel, Seq(Entry(3600L, 10800L, Kilowatts(2.5)))) + ) + ) + } + } + + "apply schedules correctly" when { + + "being provided with a ChargingSchedule consisting of one entry" in { + val evcsModel = evcsStandardModel + + val currentTick = 3600L + + val cases = Table( + ( + "storedEnergy", + "chargeStart", + "chargeEnd", + "lastCalcTick", + "power", + "expectedStored" + ), + // charging ends before currentTick + (0.0, 0L, 2700L, 0L, 5.0, 3.75), + (0.0, 0L, 1800L, 0L, 2.5, 1.25), + (0.0, 900L, 2700L, 0L, 5.0, 2.5), + (2.5, 0L, 2700L, 1800L, 5.0, 3.75), + (2.5, 0L, 2700L, 900L, 5.0, 5.0), + // charging ends at currentTick + (0.0, 0L, 3600L, 0L, 5.0, 5.0), + (0.0, 0L, 3600L, 0L, 2.5, 2.5), + (0.0, 900L, 3600L, 0L, 5.0, 3.75), + (2.5, 0L, 3600L, 1800L, 5.0, 5.0), + (2.5, 0L, 3600L, 2700L, 5.0, 3.75), + // charging ends after currentTick + (0.0, 0L, 7200L, 0L, 5.0, 5.0), + (0.0, 0L, 7200L, 0L, 2.5, 2.5), + (0.0, 900L, 7200L, 0L, 5.0, 3.75), + (2.5, 0L, 7200L, 1800L, 5.0, 5.0), + (2.5, 0L, 7200L, 2700L, 5.0, 3.75) + ) + + forAll(cases) { + ( + storedEnergy, + chargeStart, + chargeEnd, + lastCalcTick, + power, + expectedStored + ) => + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "TestEv1", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + storedEnergy.asKiloWattHour, + 7200L // is ignored here + ) + ) + + val schedule = ChargingSchedule( + ev, + Seq(Entry(chargeStart, chargeEnd, Kilowatts(power))) + ) + + val state = EvcsState( + Set(ev), + Map(ev -> Some(schedule)), + lastCalcTick + ) + + val actualOutput = evcsModel.applySchedule( + state, + currentTick + ) + + actualOutput should have size 1 + val actualEv = + actualOutput.headOption.getOrElse( + fail("No charging schedule provided.") + ) + + actualEv.uuid shouldBe ev.uuid + actualEv.id shouldBe ev.id + actualEv.sRatedAc shouldBe ev.sRatedAc + actualEv.sRatedDc shouldBe ev.sRatedDc + actualEv.eStorage shouldBe ev.eStorage + (actualEv.storedEnergy ~= KilowattHours( + expectedStored + )) shouldBe true + actualEv.departureTick shouldBe ev.departureTick + + } + + } + } + + "calculate results correctly" when { + + "one EV is parked and charging" in { + + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "TestEv1", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 0d.asKiloWattHour, + 10800L + ) + ) + + val schedule = ChargingSchedule( + ev, + Seq( + Entry(3600L, 5400L, Kilowatts(2d)), + Entry(7200L, 9000L, Kilowatts(4d)) + ) + ) + + // tick, p in kW + val generalEvResults = + Seq( + (0L, 0d), + (3600L, 2d), + (5400L, 0d), + (7200L, 4d), + (9000L, 0d) + ) + + val cases = Table( + ( + "lastTick", + "currentTick", + "firstResultIndex", + "lastResultIndex" + ), + (1800L, 10800L, 0, 5), + (3600L, 10000L, 1, 5), + (2700L, 9000L, 0, 4), + (3600L, 9000L, 1, 4), + (3660L, 9000L, 1, 4), + (5400L, 9001L, 2, 5), + (5400L, 8999L, 2, 4), + (8999L, 9000L, 3, 4), + (8999L, 9060L, 3, 5) + ) + + forAll(cases) { + ( + lastTick, + currentTick, + firstResultIndex, + lastResultIndex + ) => + val lastState = EvcsState( + Set(ev), + Map(ev -> Some(schedule)), + lastTick + ) + + val (actualEvResults, actualEvcsResults) = + evcsStandardModel.createResults( + lastState, + currentTick, + Each(1d) + ) + + val (_, firstPower) = generalEvResults(firstResultIndex) + + val expectedEvResults = generalEvResults + .slice(firstResultIndex + 1, lastResultIndex) + .prepended(lastTick, firstPower) + + actualEvResults should have size expectedEvResults.size + actualEvResults.zip(expectedEvResults).foreach { + case (actual, (startTick, p)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getInputModel shouldBe ev.uuid + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + } + + actualEvcsResults should have size expectedEvResults.size + actualEvcsResults.zip(expectedEvResults).foreach { + case (actual, (startTick, p)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getInputModel shouldBe evcsStandardModel.getUuid + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + } + } + + } + + "two EVs are parked and charging" in { + + val ev1 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "TestEv1", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 0d.asKiloWattHour, + 18000L + ) + ) + + val ev2 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "TestEv2", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 0d.asKiloWattHour, + 18000L + ) + ) + + val schedule1 = ChargingSchedule( + ev1, + Seq( + Entry(3600L, 7200L, Kilowatts(2d)), + Entry(9000L, 14400L, Kilowatts(3d)) + ) + ) + + val schedule2 = ChargingSchedule( + ev2, + Seq( + Entry(5400L, 9000L, Kilowatts(2d)) + ) + ) + + val lastTick = 1800L + val currentTick = 10800L + + val lastState = EvcsState( + Set(ev1, ev2), + Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + lastTick + ) + + val (actualEvResults, actualEvcsResults) = + evcsStandardModel.createResults( + lastState, + currentTick, + Each(1d) + ) + + // tick, p in kW, soc in % + val expectedEv1Results = + Seq( + (1800L, 0d, 0d), + (3600L, 2d, 0d), + (7200L, 0d, 20d), + (9000L, 3d, 20d) + ) + + // tick, p in kW, soc in % + val expectedEv2Results = + Seq( + (1800L, 0d, 0d), + (5400L, 2d, 0d), + (9000L, 0d, 20d) + ) + + // tick, p in kW + val expectedEvcsResults = + Seq( + (1800L, 0d), + (3600L, 2d), + (5400L, 4d), + (7200L, 2d), + (9000L, 3d) + ) + + actualEvResults should have size expectedEv1Results.size + expectedEv2Results.size + + val actualEv1Results = + actualEvResults.filter(_.getInputModel == ev1.uuid) + actualEv1Results should have size expectedEv1Results.size + actualEv1Results.zip(expectedEv1Results).foreach { + case (actual, (startTick, p, soc)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + actual.getSoc should beEquivalentTo(soc.asPercent) + } + + val actualEv2Results = + actualEvResults.filter(_.getInputModel == ev2.uuid) + actualEv2Results should have size expectedEv2Results.size + actualEv2Results.zip(expectedEv2Results).foreach { + case (actual, (startTick, p, soc)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + actual.getSoc should beEquivalentTo(soc.asPercent) + } + + actualEvcsResults should have size expectedEvcsResults.size + actualEvcsResults.zip(expectedEvcsResults).foreach { + case (actual, (startTick, p)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getInputModel shouldBe evcsStandardModel.getUuid + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + } + } + + "EV is departing at current tick" in { + + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "TestEv", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 0d.asKiloWattHour, + 7200L // equals the current tick + ) + ) + + val schedule = ChargingSchedule( + ev, + Seq( + Entry(3600L, 7200L, Kilowatts(2d)) + ) + ) + + val lastTick = 1800L + val currentTick = 7200L + + val lastState = EvcsState( + Set(ev), + Map(ev -> Some(schedule)), + lastTick + ) + + val (actualEvResults, actualEvcsResults) = + evcsStandardModel.createResults( + lastState, + currentTick, + Each(1d) + ) + + // tick, p in kW, soc in % + val expectedEvResults = + Seq( + (1800L, 0d, 0d), + (3600L, 2d, 0d), + // this result normally does not appear + // if EV does not depart at current tick + (7200L, 0d, 20d) + ) + + // tick, p in kW + val expectedEvcsResults = + Seq( + (1800L, 0d), + (3600L, 2d) + ) + + actualEvResults should have size expectedEvResults.size + + actualEvResults should have size expectedEvResults.size + actualEvResults.zip(expectedEvResults).foreach { + case (actual, (startTick, p, soc)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + actual.getSoc should beEquivalentTo(soc.asPercent) + } + + actualEvcsResults should have size expectedEvcsResults.size + actualEvcsResults.zip(expectedEvcsResults).foreach { + case (actual, (startTick, p)) => + actual.getTime shouldBe startTick.toDateTime(simulationStart) + actual.getInputModel shouldBe evcsStandardModel.getUuid + actual.getP should beEquivalentTo(p.asKiloWatt) + actual.getQ should beEquivalentTo(0d.asKiloVar) + } + } + + } + + "handle flexibility correctly" when { + val evcsModel = + evcsStandardModel.copy(strategy = ChargingStrategy.CONSTANT_POWER) + + "calculate flex options for two evs correctly" in { + val currentTick = 7200L + + val data = EvcsRelevantData( + currentTick, + Seq.empty, + Map.empty + ) + + val cases = Table( + ( + "lastStored1", + "lastStored2", + "lastPower2", + "expectedPRef", + "expectedPMin", + "expectedPMax" + ), + + /* 1: empty */ + // 2: empty + (0.0, 0.0, 0.0, 15.0, 15.0, 15.0), + // 2: at lower margin + (0.0, 3.0, 0.0, 15.0, 10.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh) + (0.0, 0.0, 5.0, 15.0, 10.0, 15.0), + // 2: mid-way full (set to 7.5 kWh) + (0.0, 7.5, 0.0, 15.0, 10.0, 15.0), + // 2: almost full (12.5 kWh) + (0.0, 5.0, 5.0, 12.5, 10.0, 15.0), + // 2: full (set) + (0.0, 15.0, 0.0, 10.0, 10.0, 10.0), + + /* 1: at lower margin (set to 2 kWh) */ + // 2: empty + (2.0, 0.0, 0.0, 13.0, 5.0, 15.0), + // 2: at lower margin + (2.0, 3.0, 0.0, 13.0, 0.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh) + (2.0, 0.0, 5.0, 13.0, -5.0, 15.0), + // 2: mid-way full (set to 7.5 kWh) + (2.0, 7.5, 0.0, 13.0, -5.0, 15.0), + // 2: almost full (12.5 kWh) + (2.0, 5.0, 5.0, 10.5, -5.0, 15.0), + // 2: full (set) + (2.0, 15.0, 0.0, 8.0, -5.0, 10.0), + + /* 1: mid-way full (set to 5 kWh) */ + // 2: empty + (5.0, 0.0, 0.0, 10.0, 5.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh) + (5.0, 0.0, 5.0, 10.0, -15.0, 15.0), + // 2: mid-way full (set to 7.5 kWh) + (5.0, 7.5, 0.0, 10.0, -15.0, 15.0), + // 2: almost full (12.5 kWh) + (5.0, 5.0, 5.0, 7.5, -15.0, 15.0), + // 2: full (set) + (5.0, 15.0, 0.0, 5.0, -15.0, 10.0), + + /* 1: full (set to 10 kWh) */ + // 2: empty + (10.0, 0.0, 0.0, 5.0, 5.0, 5.0), + // 2: mid-way full (charged to 7.5 kWh) + (10.0, 0.0, 5.0, 5.0, -15.0, 5.0), + // 2: mid-way full (set to 7.5 kWh) + (10.0, 7.5, 0.0, 5.0, -15.0, 5.0), + // 2: almost full (12.5 kWh) + (10.0, 5.0, 5.0, 2.5, -15.0, 5.0), + // 2: full (set) + (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) + ) + + forAll(cases) { + ( + lastStored1, + lastStored2, + lastPower2, + expectedPRef, + expectedPMin, + expectedPMax + ) => + val ev1 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 1", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 10.0.asKiloWattHour, + lastStored1.asKiloWattHour, + 10800L + ) + ) + + val schedule1 = ChargingSchedule( + ev1, + Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(0d))) + ) + + val ev2 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 2", + 5.0.asKiloWatt, // AC is relevant, + 10.0.asKiloWatt, // DC is not + 15.0.asKiloWattHour, + lastStored2.asKiloWattHour, + 10800L + ) + ) + + val schedule2 = ChargingSchedule( + ev1, + Seq(ChargingSchedule.Entry(0L, 5400L, Kilowatts(lastPower2))) + ) + + evcsModel.determineFlexOptions( + data, + EvcsState( + Set(ev1, ev2), + Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + 0L + ) + ) match { + case ProvideMinMaxFlexOptions( + modelUuid, + refPower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsModel.getUuid + (refPower ~= Kilowatts(expectedPRef)) shouldBe true + (minPower ~= Kilowatts(expectedPMin)) shouldBe true + (maxPower ~= Kilowatts(expectedPMax)) shouldBe true + } + } + + } + + "calculate flex options for an evcs without vehicle2grid correctly" in { + val evcsModel = evcsStandardModel.copy( + vehicle2grid = false, + strategy = ChargingStrategy.CONSTANT_POWER + ) + + val currentTick = 7200L + + val data = EvcsRelevantData( + currentTick, + Seq.empty, + Map.empty + ) + + val ev1 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 1", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 10.0.asKiloWattHour, + 0.0.asKiloWattHour, + 10800L + ) + ) + + val schedule1 = ChargingSchedule( + ev1, + Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(5.0))) + ) + + evcsModel.determineFlexOptions( + data, + EvcsState( + Set(ev1), + Map(ev1 -> Some(schedule1)), + 0L + ) + ) match { + case ProvideMinMaxFlexOptions( + modelUuid, + refPower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsModel.getUuid + (refPower ~= Kilowatts(5.0)) shouldBe true // one hour left + (minPower ~= Kilowatts(0d)) shouldBe true // no v2g allowed! + (maxPower ~= ev1.sRatedAc) shouldBe true + } + + } + + "handle controlled power change for two evs correctly" in { + val currentTick = 3600L + + val data = EvcsRelevantData( + currentTick, + Seq.empty, + Map.empty + ) + + val cases = Table( + ( + "stored1", + "stored2", + "setPower", + "expPowerAndTick1", + "expPowerAndTick2", + "expNextActivation", + "expNextTick" + ), + + /* setPower is 0 kWh */ + (0.0, 0.0, 0.0, N, N, false, N), + (10.0, 5.0, 0.0, N, N, false, N), + (5.0, 15.0, 0.0, N, N, false, N), + (10.0, 15.0, 0.0, N, N, false, N), + + /* setPower is positive (charging) */ + (0.0, 0.0, 4.0, S(2.0, 7200L), S(2.0, 9000L), true, S(7200L)), + (5.0, 0.0, 4.0, N, S(4.0, 6300L), true, S(6300L)), + (0.0, 7.5, 4.0, S(4.0, 5400L), N, true, S(5400L)), + (9.0, 0.0, 4.0, N, S(4.0, 6300L), true, S(6300L)), + (5.0, 14.0, 4.0, S(2.0, 7200L), S(2.0, 5400L), false, S(5400L)), + (9.0, 14.0, 4.0, S(2.0, 5400L), S(2.0, 5400L), false, S(5400L)), + (10.0, 14.0, 4.0, N, S(4.0, 4500L), false, S(4500L)), + (6.0, 15.0, 4.0, S(4.0, 7200L), N, false, S(7200L)), + + /* setPower is set to > (ev2 * 2) (charging) */ + (0.0, 0.0, 13.0, S(8.0, 4500L), S(5.0, 5760L), true, S(4500L)), + (7.0, 0.0, 11.0, S(6.0, 5400L), S(5.0, 5760L), true, S(5400L)), + (0.0, 5.0, 15.0, S(10.0, 4320L), S(5.0, 10800L), true, S(4320L)), + (0.0, 12.5, 15.0, S(10.0, 4320L), S(5.0, 5400L), true, S(4320L)), + (0.0, 0.0, 15.0, S(10.0, 4320L), S(5.0, 5760L), true, S(4320L)), + (5.0, 7.5, 15.0, S(10.0, 5400L), S(5.0, 9000L), false, S(5400L)), + + /* setPower is negative (discharging) */ + (10.0, 15.0, -4.0, S(-2.0, 7200L), S(-2.0, 10800L), true, S(7200L)), + (5.0, 15.0, -4.0, S(-2.0, 7200L), S(-2.0, 10800L), true, S(7200L)), + (10.0, 7.5, -4.0, S(-2.0, 7200L), S(-2.0, 10800L), true, S(7200L)), + (3.0, 15.0, -4.0, S(-2.0, 5400L), S(-2.0, 10800L), true, S(5400L)), + (5.0, 4.0, -4.0, S(-2.0, 7200L), S(-2.0, 5400L), false, S(5400L)), + (3.0, 4.0, -4.0, S(-2.0, 5400L), S(-2.0, 5400L), false, S(5400L)), + (0.0, 4.0, -4.0, N, S(-4.0, 4500L), false, S(4500L)), + (6.0, 0.0, -4.0, S(-4.0, 7200L), N, false, S(7200L)), + + /* setPower is set to > (ev2 * 2) (discharging) */ + (10.0, 15.0, -13.0, S(-8.0, 7200L), S(-5.0, 10800L), true, S(7200L)), + (5.0, 15.0, -11.0, S(-6.0, 5400L), S(-5.0, 10800L), true, S(5400L)), + (10.0, 8.0, -15.0, S(-10.0, 6480L), S(-5.0, 7200L), true, S(6480L)), + (10.0, 5.5, -15.0, S(-10.0, 6480L), S(-5.0, 5400L), true, S(5400L)), + (10.0, 15.0, -15.0, S(-10.0, 6480L), S(-5.0, 10800L), true, S(6480L)), + (7.0, 10.5, -15.0, S(-10.0, 5400L), S(-5.0, 9000L), false, S(5400L)) + ) + + forAll(cases) { + ( + stored1: Double, + stored2: Double, + setPower: Double, + expPowerAndTick1: Option[(Double, Long)], + expPowerAndTick2: Option[(Double, Long)], + expNextActivation: Boolean, + expNextTick: Option[Long] + ) => + val ev1 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 1", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 10.0.asKiloWattHour, + stored1.asKiloWattHour, + 7200L + ) + ) + + val ev2 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 2", + 5.0.asKiloWatt, // AC is relevant, + 10.0.asKiloWatt, // DC is not + 15.0.asKiloWattHour, + stored2.asKiloWattHour, + 10800L + ) + ) + + evcsModel.handleControlledPowerChange( + data, + EvcsState( + Set(ev1, ev2), + Map(ev1 -> None, ev2 -> None), + 0L + ), + Kilowatts(setPower) + ) match { + case ( + EvcsState(actualEvs, actualSchedules, actualTick), + FlexChangeIndicator(actualNextActivation, actualNextTick) + ) => + // evs have not changed here since no schedules were given as input + actualEvs shouldBe Set(ev1, ev2) + + actualSchedules.getOrElse(ev1, None).map { + case ChargingSchedule(_, entries) => + entries.size shouldBe 1 + val entry = entries.headOption + .getOrElse(fail("No charging schedule entry for ev1")) + entry.tickStart shouldBe currentTick + + ( + entry.chargingPower.toKilowatts, + entry.tickStop + ) + } shouldBe expPowerAndTick1 + actualSchedules.getOrElse(ev2, None).map { + case ChargingSchedule(_, entries) => + entries.size shouldBe 1 + val entry = entries.headOption + .getOrElse(fail("No charging schedule entry for ev2")) + entry.tickStart shouldBe currentTick + + ( + entry.chargingPower.toKilowatts, + entry.tickStop + ) + } shouldBe expPowerAndTick2 + + actualTick shouldBe currentTick + + actualNextActivation shouldBe expNextActivation + actualNextTick shouldBe expNextTick + } + } + + } + } + } + +} diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala new file mode 100644 index 0000000000..08817297b6 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala @@ -0,0 +1,181 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs.uncontrolled + +import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.model.MockEvModel +import edu.ie3.simona.test.common.model.participant.EvcsTestData +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble +import org.scalatest.prop.TableDrivenPropertyChecks +import squants.energy.Kilowatts + +import java.util.UUID + +class ConstantPowerChargingSpec + extends UnitSpec + with TableDrivenPropertyChecks + with EvcsTestData { + + "Calculating constant power charging schedules" should { + val evcsModel = evcsStandardModel + + "not charge evs if they are fully charged" in { + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, + 10.0.asKiloWatt, + 20.0.asKiloWattHour, + 20.0.asKiloWattHour, + 3600L + ) + ) + + val actualSchedule = evcsModel.chargeWithConstantPower( + 1800L, + Set(ev) + ) + + actualSchedule shouldBe Map( + ev -> None + ) + } + + "work correctly with one ev" in { + val offset = 1800L + + val cases = Table( + ("stayingTicks", "storedEnergy", "expectedPower"), + // empty battery + (3600L, 0.0, 5.0), // more than max power, limited + (7200L, 0.0, 5.0), // exactly max power + (14400L, 0.0, 2.5), // less than max power + (360000L, 0.0, 0.1), // long stay: 100 hours + // half full battery + (1800L, 5.0, 5.0), // more than max power, limited + (3600L, 5.0, 5.0), // exactly max power + (7200L, 5.0, 2.5), // less than max power + (180000L, 5.0, 0.1) // long stay: 100 hours + ) + + forAll(cases) { (stayingTicks, storedEnergy, expectedPower) => + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + storedEnergy.asKiloWattHour, + offset + stayingTicks + ) + ) + + val chargingMap = evcsModel.chargeWithConstantPower( + offset, + Set(ev) + ) + + chargingMap shouldBe Map( + ev -> Some( + ChargingSchedule( + ev, + Seq( + ChargingSchedule.Entry( + offset, + offset + stayingTicks, + Kilowatts(expectedPower) + ) + ) + ) + ) + ) + } + + } + + "work correctly with two evs" in { + val offset = 3600L + + val cases = Table( + ("stayingTicks", "storedEnergy", "expectedPower"), + // empty battery + (3600L, 0.0, 5.0), // more than max power, limited + (7200L, 0.0, 5.0), // exactly max power + (14400L, 0.0, 2.5), // less than max power + (360000L, 0.0, 0.1), // long stay: 100 hours + // half full battery + (1800L, 5.0, 5.0), // more than max power, limited + (3600L, 5.0, 5.0), // exactly max power + (7200L, 5.0, 2.5), // less than max power + (180000L, 5.0, 0.1) // long stay: 100 hours + ) + + forAll(cases) { (stayingTicks, storedEnergy, expectedPower) => + val givenEv = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "First EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 5.0.asKiloWattHour, + offset + 3600L + ) + ) + + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + storedEnergy.asKiloWattHour, + offset + stayingTicks + ) + ) + + val chargingMap = evcsModel.chargeWithConstantPower( + offset, + Set(givenEv, ev) + ) + + chargingMap shouldBe Map( + givenEv -> Some( + ChargingSchedule( + givenEv, + Seq( + ChargingSchedule.Entry( + offset, + offset + 3600L, + Kilowatts(5.0) + ) + ) + ) + ), + ev -> Some( + ChargingSchedule( + ev, + Seq( + ChargingSchedule.Entry( + offset, + offset + stayingTicks, + Kilowatts(expectedPower) + ) + ) + ) + ) + ) + } + + } + } + +} diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala new file mode 100644 index 0000000000..89da615b19 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala @@ -0,0 +1,176 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.participant.evcs.uncontrolled + +import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} +import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.model.MockEvModel +import edu.ie3.simona.test.common.model.participant.EvcsTestData +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble +import org.scalatest.prop.TableDrivenPropertyChecks +import squants.energy.Kilowatts + +import java.util.UUID + +class MaximumPowerChargingSpec + extends UnitSpec + with TableDrivenPropertyChecks + with EvcsTestData { + + "Calculating maximum power charging schedules" should { + val evcsModel = evcsStandardModel + + "not charge evs if they are fully charged" in { + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, + 10.0.asKiloWatt, + 20.0.asKiloWattHour, + 20.0.asKiloWattHour, + 3600 + ) + ) + + val actualSchedule = evcsModel.chargeWithMaximumPower( + 1800L, + Set(ev) + ) + + actualSchedule shouldBe Map( + ev -> None + ) + } + + "work correctly with one ev" in { + val offset = 1800L + + val cases = Table( + ("stayingTicks", "storedEnergy", "expectedDuration"), + // empty battery + (3600L, 0.0, 3600L), // stay shorter than full + (7200L, 0.0, 7200L), // exactly full + (14400L, 0.0, 7200L), // full before end of stay + // half full battery + (1800L, 5.0, 1800L), // stay shorter than full + (3600L, 5.0, 3600L), // exactly full + (14400L, 5.0, 3600L) // full before end of stay + ) + + forAll(cases) { (stayingTicks, storedEnergy, expectedDuration) => + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + storedEnergy.asKiloWattHour, + offset + stayingTicks + ) + ) + + val chargingMap = evcsModel.chargeWithMaximumPower( + offset, + Set(ev) + ) + + chargingMap shouldBe Map( + ev -> Some( + ChargingSchedule( + ev, + Seq( + ChargingSchedule.Entry( + offset, + offset + expectedDuration, + ev.sRatedAc + ) + ) + ) + ) + ) + } + + } + + "work correctly with two evs" in { + val offset = 3600L + + val cases = Table( + ("stayingTicks", "storedEnergy", "expectedDuration"), + // empty battery + (3600L, 0.0, 3600L), // stay shorter than full + (7200L, 0.0, 7200L), // exactly full + (14400L, 0.0, 7200L), // full before end of stay + // half full battery + (1800L, 5.0, 1800L), // stay shorter than full + (3600L, 5.0, 3600L), // exactly full + (14400L, 5.0, 3600L) // full before end of stay + ) + + forAll(cases) { (stayingTicks, storedEnergy, expectedDuration) => + val givenEv = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "First EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + 5.0.asKiloWattHour, + offset + 3600L + ) + ) + + val ev = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Test EV", + 5.0.asKiloWatt, // using AC charging here + 10.0.asKiloWatt, + 10.0.asKiloWattHour, + storedEnergy.asKiloWattHour, + offset + stayingTicks + ) + ) + + val chargingMap = evcsModel.chargeWithMaximumPower( + offset, + Set(givenEv, ev) + ) + + chargingMap shouldBe Map( + givenEv -> Some( + ChargingSchedule( + givenEv, + Seq( + ChargingSchedule.Entry( + offset, + offset + 3600L, + Kilowatts(5.0) + ) + ) + ) + ), + ev -> Some( + ChargingSchedule( + ev, + Seq( + ChargingSchedule.Entry( + offset, + offset + expectedDuration, + Kilowatts(5.0) + ) + ) + ) + ) + ) + } + + } + } +} diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala index 80a20585ce..974a76b30e 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala @@ -46,7 +46,6 @@ class ThermalGridSpec extends UnitSpec { val energyDemand = ThermalEnergyDemand.noDemand (energyDemand.required =~ MegawattHours(0d)) shouldBe true - (energyDemand.possible =~ MegawattHours(0d)) shouldBe true } } @@ -94,7 +93,6 @@ class ThermalGridSpec extends UnitSpec { val totalDemand = energyDemand1 + energyDemand2 (totalDemand.required =~ MegawattHours(68d)) shouldBe true - (totalDemand.possible =~ MegawattHours(75d)) shouldBe true } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala index 4ee4fbcf33..bbcaa52207 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala @@ -9,8 +9,8 @@ package edu.ie3.simona.model.thermal import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput -import squants.energy.Kilowatts -import squants.thermal.Celsius +import squants.energy.{Kilowatts, Power} +import squants.thermal.{Celsius, Temperature} import java.util.UUID @@ -21,8 +21,8 @@ trait ThermalGridTestData { OperatorInput.NO_OPERATOR_ASSIGNED, OperationTime.notLimited() ) - protected val testGridambientTemperature = Celsius(12d) - protected val testGridQDotInfeed = Kilowatts(15d) - protected val testGridQDotConsumption = Kilowatts(-42d) - protected val testGridQDotConsumptionHigh = Kilowatts(-200d) + protected val testGridambientTemperature: Temperature = Celsius(12d) + protected val testGridQDotInfeed: Power = Kilowatts(15d) + protected val testGridQDotConsumption: Power = Kilowatts(-42d) + protected val testGridQDotConsumptionHigh: Power = Kilowatts(-200d) } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala index 4baff53e4e..68a022c26e 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.{ import edu.ie3.simona.test.common.UnitSpec import squants.energy._ import squants.thermal.Celsius -import squants.{Energy, Power, Temperature} +import squants.{Energy, Kelvin, Power, Temperature} import tech.units.indriya.unit.Units import scala.jdk.CollectionConverters._ @@ -31,7 +31,7 @@ class ThermalGridWithHouseAndStorageSpec with ThermalHouseTestData with ThermalStorageTestData { - implicit val tempTolerance: Temperature = Celsius(1e-3) + implicit val tempTolerance: Temperature = Kelvin(1e-3) implicit val powerTolerance: Power = Watts(1e-3) implicit val energyTolerance: Energy = WattHours(1e-3) @@ -175,7 +175,7 @@ class ThermalGridWithHouseAndStorageSpec case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( - HouseTemperatureLowerBoundaryReached(154284L) + HouseTemperatureLowerBoundaryReached(154285L) ) } @@ -214,14 +214,14 @@ class ThermalGridWithHouseAndStorageSpec (qDotStorage =~ externalQDot) shouldBe true case _ => fail("Thermal grid state has been calculated wrong.") } - reachedThreshold shouldBe Some(StorageEmpty(17142L)) + reachedThreshold shouldBe Some(StorageEmpty(17143L)) } } "revising infeed from storage to house" should { val zeroInflux = Kilowatts(0d) val tick = 3600L - val testGridambientTemperature = Celsius(14d) + val ambientTemperature = Celsius(14d) "hand back unaltered information if needed information is missing" in { val maybeHouseState = Some( ( @@ -231,7 +231,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getTargetTemperature .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), zeroInflux ), @@ -264,7 +264,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getTargetTemperature .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), zeroInflux ), @@ -288,7 +288,7 @@ class ThermalGridWithHouseAndStorageSpec maybeStorageState, maybeHouseState.map(_._1), maybeStorageState.map(_._1), - testGridambientTemperature, + ambientTemperature, zeroInflux ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -306,7 +306,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getTargetTemperature .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), testGridQDotInfeed ), @@ -330,7 +330,7 @@ class ThermalGridWithHouseAndStorageSpec maybeStorageState, maybeHouseState.map(_._1), maybeStorageState.map(_._1), - testGridambientTemperature, + ambientTemperature, testGridQDotInfeed ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -348,7 +348,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getLowerTemperatureLimit .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), zeroInflux ), @@ -372,7 +372,7 @@ class ThermalGridWithHouseAndStorageSpec maybeStorageState, maybeHouseState.map(_._1), maybeStorageState.map(_._1), - testGridambientTemperature, + ambientTemperature, zeroInflux ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -390,7 +390,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getLowerTemperatureLimit .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), zeroInflux ), @@ -414,7 +414,7 @@ class ThermalGridWithHouseAndStorageSpec thermalHouseInput.getTargetTemperature .to(Units.CELSIUS) .getValue - .doubleValue() + .doubleValue ), zeroInflux ) @@ -433,7 +433,7 @@ class ThermalGridWithHouseAndStorageSpec maybeStorageState, formerHouseState, formerStorageState, - testGridambientTemperature, + ambientTemperature, zeroInflux ) match { case ( @@ -454,8 +454,7 @@ class ThermalGridWithHouseAndStorageSpec storageTick shouldBe tick (revisedQDotHouse =~ thermalStorage.chargingPower) shouldBe true - - (revisedQDotStorage =~ thermalStorage.chargingPower * (-1)) shouldBe true + (revisedQDotStorage =~ thermalStorage.chargingPower * -1) shouldBe true houseColdTick shouldBe 3718L storageEmptyTick shouldBe 3678L @@ -538,13 +537,9 @@ class ThermalGridWithHouseAndStorageSpec (qDotHouse =~ Kilowatts(0d)) shouldBe true storageTick shouldBe 0L - (storedEnergy =~ - gridState.storageState - .map(_.storedEnergy) - .getOrElse( - fail("No initial storage state found") - )) shouldBe true - + (storedEnergy =~ gridState.storageState + .map(_.storedEnergy) + .getOrElse(fail("No initial storage state found"))) shouldBe true (qDotStorage =~ externalQDot) shouldBe true case _ => fail("Thermal grid state has been calculated wrong.") } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala index edd2392208..df6b85409e 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -119,7 +119,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( - HouseTemperatureLowerBoundaryReached(154284L) + HouseTemperatureLowerBoundaryReached(154285L) ) } @@ -146,7 +146,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( - HouseTemperatureLowerBoundaryReached(154284L) + HouseTemperatureLowerBoundaryReached(154285L) ) } } @@ -225,7 +225,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { tick shouldBe 0L (innerTemperature =~ Celsius(18.9999d)) shouldBe true (qDot =~ Megawatts(0d)) shouldBe true - thresholdTick shouldBe 154284L + thresholdTick shouldBe 154285L case _ => fail("Thermal grid state updated failed") } } @@ -247,7 +247,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { tick shouldBe 0L (innerTemperature =~ Celsius(18.9999d)) shouldBe true (qDot =~ Kilowatts(0d)) shouldBe true - thresholdTick shouldBe 154284L + thresholdTick shouldBe 154285L case _ => fail("Thermal grid state updated failed") } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala index 43ccceb75a..769711004a 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -124,7 +124,6 @@ class ThermalGridWithStorageOnlySpec ) => tick shouldBe 0L (storedEnergy =~ KilowattHours(430d)) shouldBe true - (qDot =~ testGridQDotConsumptionHigh) shouldBe true case _ => fail("Thermal grid state has been calculated wrong.") } @@ -237,9 +236,7 @@ class ThermalGridWithStorageOnlySpec ) => tick shouldBe 0L (storedEnergy =~ KilowattHours(230d)) shouldBe true - (qDot =~ Megawatts(0d)) shouldBe true - case _ => fail("Thermal grid state updated failed") } } diff --git a/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala b/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala new file mode 100644 index 0000000000..6602614262 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala @@ -0,0 +1,66 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.ontology.messages.flex + +import edu.ie3.simona.exceptions.CriticalFailureException +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions +import edu.ie3.simona.test.common.UnitSpec +import squants.energy.Watts + +import java.util.UUID + +class MinMaxFlexibilityMessageTest extends UnitSpec { + + "Creating a ProvideMinMaxFlexibilityMessage" should { + + "succeed if there is no flexibility" in { + val res = ProvideMinMaxFlexOptions.noFlexOption( + modelUuid = UUID.randomUUID(), + power = Watts(1) + ) + + res.ref shouldBe Watts(1) + res.min shouldBe Watts(1) + res.max shouldBe Watts(1) + } + + "succeed if minimum, reference and maximum power are in order" in { + val res = ProvideMinMaxFlexOptions( + modelUuid = UUID.randomUUID(), + ref = Watts(1), + min = Watts(0), + max = Watts(2) + ) + + res.ref shouldBe Watts(1) + res.min shouldBe Watts(0) + res.max shouldBe Watts(2) + } + + "throw an exception if minimum power is greater then reference power" in { + intercept[CriticalFailureException] { + ProvideMinMaxFlexOptions( + modelUuid = UUID.randomUUID(), + ref = Watts(1), + min = Watts(2), + max = Watts(2) + ) + }.getMessage should include("is greater than reference power") + } + + "throw an exception if reference power is greater then maximum power" in { + intercept[CriticalFailureException] { + ProvideMinMaxFlexOptions( + modelUuid = UUID.randomUUID(), + ref = Watts(1), + min = Watts(1), + max = Watts(0) + ) + }.getMessage should include("is greater than maximum power") + } + } +} diff --git a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala index c08b4e827d..789666829e 100644 --- a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala @@ -15,6 +15,7 @@ import edu.ie3.simona.api.data.ev.model.EvModel import edu.ie3.simona.api.data.ev.ontology._ import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.exceptions.ServiceException +import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, @@ -396,7 +397,7 @@ class ExtEvDataServiceSpec evcs1.send( evService, - DepartingEvsResponse(evcs1UUID, Set(updatedEvA)) + DepartingEvsResponse(evcs1UUID, Set(EvModelWrapper(updatedEvA))) ) // nothing should happen yet, waiting for second departed ev @@ -408,7 +409,7 @@ class ExtEvDataServiceSpec evcs2.send( evService, - DepartingEvsResponse(evcs2UUID, Set(updatedEvB)) + DepartingEvsResponse(evcs2UUID, Set(EvModelWrapper(updatedEvB))) ) // ev service should recognize that all evs that are expected are returned, @@ -475,12 +476,12 @@ class ExtEvDataServiceSpec val evsMessage1 = evcs1.expectMsgType[ProvideEvDataMessage] evsMessage1.tick shouldBe tick - evsMessage1.data shouldBe ArrivingEvsData(Seq(evA)) + evsMessage1.data shouldBe ArrivingEvsData(Seq(EvModelWrapper(evA))) evsMessage1.unlockKey should not be empty val evsMessage2 = evcs2.expectMsgType[ProvideEvDataMessage] evsMessage2.tick shouldBe tick - evsMessage2.data shouldBe ArrivingEvsData(Seq(evB)) + evsMessage2.data shouldBe ArrivingEvsData(Seq(EvModelWrapper(evB))) evsMessage2.unlockKey should not be empty scheduler.expectMsg(Completion(evService.toTyped)) @@ -538,7 +539,7 @@ class ExtEvDataServiceSpec val evsMessage1 = evcs1.expectMsgType[ProvideEvDataMessage] evsMessage1.tick shouldBe tick - evsMessage1.data shouldBe ArrivingEvsData(Seq(evA)) + evsMessage1.data shouldBe ArrivingEvsData(Seq(EvModelWrapper(evA))) evsMessage1.unlockKey should not be empty scheduler.expectMsg(Completion(evService.toTyped)) diff --git a/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala b/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala index 93f2820010..a339890968 100644 --- a/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala @@ -17,12 +17,16 @@ trait EvTestData { UUID.fromString("73c041c7-68e9-470e-8ca2-21fd7dbd1797"), "evA", Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), - Quantities.getQuantity(58d, PowerSystemUnits.KILOWATTHOUR) + Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), + Quantities.getQuantity(58d, PowerSystemUnits.KILOWATTHOUR), + 200 ) protected val evB: MockEvModel = new MockEvModel( UUID.fromString("6d7d27a1-5cbb-4b73-aecb-dfcc5a6fb22e"), "evB", Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), - Quantities.getQuantity(80d, PowerSystemUnits.KILOWATTHOUR) + Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), + Quantities.getQuantity(80d, PowerSystemUnits.KILOWATTHOUR), + 200 ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala index e50e1f9c62..b819f552da 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala @@ -56,6 +56,13 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { simonaConfig.simona.output.participant.defaultConfig.flexResult ) + protected val simResultOutputConfig: NotifierConfig = + NotifierConfig( + simulationResultInfo = true, + powerRequestReply = false, + flexResult = false + ) + protected val modelConfig: SimonaConfig.EvcsRuntimeConfig = configUtil.getOrDefault[SimonaConfig.EvcsRuntimeConfig]( evcsInputModel.getUuid diff --git a/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala index f92c0cff86..431bb33135 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala @@ -6,19 +6,17 @@ package edu.ie3.simona.test.common.input -import java.time.ZonedDateTime -import java.util.UUID - import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.{OperationTime, StandardUnits} import edu.ie3.simona.test.common.DefaultTestData -import edu.ie3.util.TimeUtil import org.mockito.Mockito.when import org.scalatestplus.mockito.MockitoSugar import tech.units.indriya.quantity.Quantities +import java.util.UUID + /** Simple test data to be used in tests for PvModel. Should be extended as * needed. */ @@ -26,10 +24,6 @@ trait PvInputTestData extends DefaultTestData with NodeInputTestData with MockitoSugar { - protected implicit val simulationStartDate: ZonedDateTime = - TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00") - protected val simulationEndDate: ZonedDateTime = - TimeUtil.withDefaults.toZonedDateTime("2020-01-01 01:00:00") protected val pvInputMock: PvInput = mock[PvInput] when(pvInputMock.getUuid) @@ -42,7 +36,7 @@ trait PvInputTestData when(pvInputModel04Kv.getId).thenReturn("TestPvInputModel_0.4_kV") when(pvInputModel04Kv.getNode).thenReturn(nodeInputNoSlackNs04KvA) - protected val pvInputModel = new PvInput( + protected val pvInput = new PvInput( UUID.randomUUID(), "Dummy_PvModel", new OperatorInput(UUID.randomUUID(), "NO_OPERATOR"), diff --git a/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala new file mode 100644 index 0000000000..14ea648b41 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala @@ -0,0 +1,38 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.test.common.model.participant + +import edu.ie3.datamodel.models.ElectricCurrentType +import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType +import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed +import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.participant.evcs.{ChargingStrategy, EvcsModel} +import edu.ie3.util.TimeUtil +import edu.ie3.util.quantities.PowerSystemUnits +import edu.ie3.util.scala.OperationInterval +import tech.units.indriya.quantity.Quantities + +import java.util.UUID + +trait EvcsTestData { + protected val evcsStandardModel: EvcsModel = EvcsModel( + UUID.randomUUID(), + "Evcs Model Test", + OperationInterval(0L, 31536000L), + 1.0, + TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00"), + QControl.apply(new CosPhiFixed("cosPhiFixed:{(0.0,1.0)}")), + Quantities.getQuantity(100, PowerSystemUnits.KILOVOLTAMPERE), + ElectricCurrentType.AC, + 0.95d, + 4, + EvcsLocationType.HOME, + vehicle2grid = true, + ChargingStrategy.MAX_POWER, + lowestEvSoc = 0.2 + ) +} diff --git a/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala index 9dbed89e7b..39873e9ece 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala @@ -52,7 +52,7 @@ trait HpTestData extends DefaultTestData { Quantities.getQuantity(11.0, StandardUnits.ACTIVE_POWER_IN) ) - protected val inputModel = new HpInput( + protected val hpInputModel = new HpInput( UUID.fromString("7832dea4-8703-4b37-8752-e67b86e957df"), "test hp", OperatorInput.NO_OPERATOR_ASSIGNED, diff --git a/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala new file mode 100644 index 0000000000..ed1f9c3af7 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala @@ -0,0 +1,19 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.test.helper + +trait TableDrivenHelper { + + /** Shortcut for Some type to make case tables more concise */ + def S[T](value: T): Some[T] = Some(value) + + /** Shortcut for None type to make case tables more concise */ + def N: None.type = None + + /** Shortcut for Seq type to make case tables more concise */ + def L: Seq.type = Seq +} diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala index 1afb07811d..50c8d4776e 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala @@ -6,15 +6,36 @@ package edu.ie3.simona.test.matchers +import edu.ie3.simona.test.matchers.QuantityMatchers.{ + QuantityEqualityMatcher, + QuantityEquivalenceMatcher +} import edu.ie3.util.quantities.QuantityUtil + import javax.measure.Quantity import org.scalatest.matchers.{MatchResult, Matcher} /** Trait, to simplify test coding, that is reliant on [[Quantity]] s */ trait QuantityMatchers { - class QuantityMatcher[Q <: Quantity[Q]](right: Quantity[Q], tolerance: Double) - extends Matcher[Quantity[Q]] + def equalWithTolerance[Q <: Quantity[Q]]( + right: Quantity[Q], + tolerance: Double = 1e-10 + ) = new QuantityEqualityMatcher(right, tolerance) + + def beEquivalentTo[Q <: Quantity[Q]]( + right: Quantity[Q], + tolerance: Double = 1e-10 + ) = new QuantityEquivalenceMatcher(right, tolerance) + +} + +object QuantityMatchers { + + class QuantityEqualityMatcher[Q <: Quantity[Q]]( + right: Quantity[Q], + tolerance: Double + ) extends Matcher[Quantity[Q]] with QuantityMatchers { override def apply(left: Quantity[Q]): MatchResult = MatchResult( QuantityUtil.equals(left, right, tolerance), @@ -23,18 +44,24 @@ trait QuantityMatchers { ) } - def equalWithTolerance[Q <: Quantity[Q]]( + class QuantityEquivalenceMatcher[Q <: Quantity[Q]]( right: Quantity[Q], - tolerance: Double = 1e-10 - ) = new QuantityMatcher(right, tolerance) -} + tolerance: Double + ) extends Matcher[Quantity[Q]] + with QuantityMatchers { + override def apply(left: Quantity[Q]): MatchResult = MatchResult( + QuantityUtil.isEquivalentAbs(left, right, tolerance), + QuantityMatchers.assembleRawFailureMessage(left, right, tolerance), + QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance) + ) + } -case object QuantityMatchers extends QuantityMatchers { private def assembleRawFailureMessage[Q <: Quantity[Q]]( lhs: Quantity[Q], rhs: Quantity[Q], tolerance: Double ) = s"The quantities $lhs and $rhs differ more than $tolerance in value" + private def assembleNegatedFailureMessage[Q <: Quantity[Q]]( lhs: Quantity[Q], rhs: Quantity[Q], From 277cf0926e7b108e2f54f62dfbcd7796c21607e7 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 13:18:53 +0100 Subject: [PATCH 134/305] spotless --- .../edu/ie3/simona/config/SimonaConfig.scala | 3102 ++++++++++++----- 1 file changed, 2197 insertions(+), 905 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 3bc7b13b79..1079b2b932 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -1,1451 +1,2743 @@ -// generated by tscfg 1.0.0 on Thu Jan 25 13:15:53 CET 2024 -// source: src/main/resources/config/config-template.conf +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ package edu.ie3.simona.config final case class SimonaConfig( - simona : SimonaConfig.Simona + simona: SimonaConfig.Simona ) object SimonaConfig { final case class BaseCsvParams( - override val csvSep : java.lang.String, - override val directoryPath : java.lang.String, - override val isHierarchic : scala.Boolean - ) extends CsvParams(csvSep,directoryPath,isHierarchic) + override val csvSep: java.lang.String, + override val directoryPath: java.lang.String, + override val isHierarchic: scala.Boolean + ) extends CsvParams(csvSep, directoryPath, isHierarchic) object BaseCsvParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.BaseCsvParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.BaseCsvParams = { SimonaConfig.BaseCsvParams( csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + directoryPath = + $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - sealed abstract class BaseOutputConfig ( - val notifier : java.lang.String, - val simulationResult : scala.Boolean + + sealed abstract class BaseOutputConfig( + val notifier: java.lang.String, + val simulationResult: scala.Boolean ) - - sealed abstract class BaseRuntimeConfig ( - val calculateMissingReactivePowerWithModel : scala.Boolean, - val scaling : scala.Double, - val uuids : scala.List[java.lang.String] + + sealed abstract class BaseRuntimeConfig( + val calculateMissingReactivePowerWithModel: scala.Boolean, + val scaling: scala.Double, + val uuids: scala.List[java.lang.String] ) extends java.io.Serializable - - sealed abstract class CsvParams ( - val csvSep : java.lang.String, - val directoryPath : java.lang.String, - val isHierarchic : scala.Boolean + + sealed abstract class CsvParams( + val csvSep: java.lang.String, + val directoryPath: java.lang.String, + val isHierarchic: scala.Boolean ) - + final case class EvcsRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String], - chargingStrategy : java.lang.String, - lowestEvSoc : scala.Double - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String], + chargingStrategy: java.lang.String, + lowestEvSoc: scala.Double + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object EvcsRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.EvcsRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.EvcsRuntimeConfig = { SimonaConfig.EvcsRuntimeConfig( - chargingStrategy = if(c.hasPathOrNull("chargingStrategy")) c.getString("chargingStrategy") else "maxPower", - lowestEvSoc = if(c.hasPathOrNull("lowestEvSoc")) c.getDouble("lowestEvSoc") else 0.2, - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + chargingStrategy = + if (c.hasPathOrNull("chargingStrategy")) + c.getString("chargingStrategy") + else "maxPower", + lowestEvSoc = + if (c.hasPathOrNull("lowestEvSoc")) c.getDouble("lowestEvSoc") + else 0.2, + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class FixedFeedInRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object FixedFeedInRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.FixedFeedInRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.FixedFeedInRuntimeConfig = { SimonaConfig.FixedFeedInRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class GridOutputConfig( - lines : scala.Boolean, - nodes : scala.Boolean, - notifier : java.lang.String, - switches : scala.Boolean, - transformers2w : scala.Boolean, - transformers3w : scala.Boolean + lines: scala.Boolean, + nodes: scala.Boolean, + notifier: java.lang.String, + switches: scala.Boolean, + transformers2w: scala.Boolean, + transformers3w: scala.Boolean ) object GridOutputConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.GridOutputConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.GridOutputConfig = { SimonaConfig.GridOutputConfig( - lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), - nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), - transformers2w = c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), - transformers3w = c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") + lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), + nodes = c.hasPathOrNull("nodes") && c.getBoolean("nodes"), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + switches = c.hasPathOrNull("switches") && c.getBoolean("switches"), + transformers2w = + c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), + transformers3w = + c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class HpRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object HpRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.HpRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.HpRuntimeConfig = { SimonaConfig.HpRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - sealed abstract class KafkaParams ( - val bootstrapServers : java.lang.String, - val linger : scala.Int, - val runId : java.lang.String, - val schemaRegistryUrl : java.lang.String + + sealed abstract class KafkaParams( + val bootstrapServers: java.lang.String, + val linger: scala.Int, + val runId: java.lang.String, + val schemaRegistryUrl: java.lang.String ) - + final case class LoadRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String], - modelBehaviour : java.lang.String, - reference : java.lang.String - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String], + modelBehaviour: java.lang.String, + reference: java.lang.String + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object LoadRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.LoadRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.LoadRuntimeConfig = { SimonaConfig.LoadRuntimeConfig( - modelBehaviour = $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), - reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), - scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + modelBehaviour = + $_reqStr(parentPath, c, "modelBehaviour", $tsCfgValidator), + reference = $_reqStr(parentPath, c, "reference", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), + scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class ParticipantBaseOutputConfig( - override val notifier : java.lang.String, - override val simulationResult : scala.Boolean, - flexResult : scala.Boolean, - powerRequestReply : scala.Boolean - ) extends BaseOutputConfig(notifier,simulationResult) + override val notifier: java.lang.String, + override val simulationResult: scala.Boolean, + flexResult: scala.Boolean, + powerRequestReply: scala.Boolean + ) extends BaseOutputConfig(notifier, simulationResult) object ParticipantBaseOutputConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.ParticipantBaseOutputConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.ParticipantBaseOutputConfig = { SimonaConfig.ParticipantBaseOutputConfig( - flexResult = c.hasPathOrNull("flexResult") && c.getBoolean("flexResult"), - powerRequestReply = $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), - notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + flexResult = + c.hasPathOrNull("flexResult") && c.getBoolean("flexResult"), + powerRequestReply = + $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), + notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), + simulationResult = + $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PrimaryDataCsvParams( - override val csvSep : java.lang.String, - override val directoryPath : java.lang.String, - override val isHierarchic : scala.Boolean, - timePattern : java.lang.String - ) extends CsvParams(csvSep,directoryPath,isHierarchic) + override val csvSep: java.lang.String, + override val directoryPath: java.lang.String, + override val isHierarchic: scala.Boolean, + timePattern: java.lang.String + ) extends CsvParams(csvSep, directoryPath, isHierarchic) object PrimaryDataCsvParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PrimaryDataCsvParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.PrimaryDataCsvParams = { SimonaConfig.PrimaryDataCsvParams( - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), - directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), + directoryPath = + $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class PvRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object PvRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.PvRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.PvRuntimeConfig = { SimonaConfig.PvRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class RefSystemConfig( - gridIds : scala.Option[scala.List[java.lang.String]], - sNom : java.lang.String, - vNom : java.lang.String, - voltLvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + gridIds: scala.Option[scala.List[java.lang.String]], + sNom: java.lang.String, + vNom: java.lang.String, + voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object RefSystemConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RefSystemConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.RefSystemConfig = { SimonaConfig.RefSystemConfig( - gridIds = if(c.hasPathOrNull("gridIds")) scala.Some($_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator)) else None, - sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), - vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), - voltLvls = if(c.hasPathOrNull("voltLvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("voltLvls"), parentPath, $tsCfgValidator)) else None + gridIds = + if (c.hasPathOrNull("gridIds")) + scala.Some( + $_L$_str(c.getList("gridIds"), parentPath, $tsCfgValidator) + ) + else None, + sNom = $_reqStr(parentPath, c, "sNom", $tsCfgValidator), + vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), + voltLvls = + if (c.hasPathOrNull("voltLvls")) + scala.Some( + $_LSimonaConfig_VoltLvlConfig( + c.getList("voltLvls"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.VoltLvlConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class ResultKafkaParams( - override val bootstrapServers : java.lang.String, - override val linger : scala.Int, - override val runId : java.lang.String, - override val schemaRegistryUrl : java.lang.String, - topicNodeRes : java.lang.String - ) extends KafkaParams(bootstrapServers,linger,runId,schemaRegistryUrl) + override val bootstrapServers: java.lang.String, + override val linger: scala.Int, + override val runId: java.lang.String, + override val schemaRegistryUrl: java.lang.String, + topicNodeRes: java.lang.String + ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) object ResultKafkaParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.ResultKafkaParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.ResultKafkaParams = { SimonaConfig.ResultKafkaParams( topicNodeRes = $_reqStr(parentPath, c, "topicNodeRes", $tsCfgValidator), - bootstrapServers = $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), - linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), - runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), - schemaRegistryUrl = $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + bootstrapServers = + $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), + linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), + runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), + schemaRegistryUrl = + $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class RuntimeKafkaParams( - override val bootstrapServers : java.lang.String, - override val linger : scala.Int, - override val runId : java.lang.String, - override val schemaRegistryUrl : java.lang.String, - topic : java.lang.String - ) extends KafkaParams(bootstrapServers,linger,runId,schemaRegistryUrl) + override val bootstrapServers: java.lang.String, + override val linger: scala.Int, + override val runId: java.lang.String, + override val schemaRegistryUrl: java.lang.String, + topic: java.lang.String + ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) object RuntimeKafkaParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.RuntimeKafkaParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.RuntimeKafkaParams = { SimonaConfig.RuntimeKafkaParams( topic = $_reqStr(parentPath, c, "topic", $tsCfgValidator), - bootstrapServers = $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), + bootstrapServers = + $_reqStr(parentPath, c, "bootstrapServers", $tsCfgValidator), linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), - schemaRegistryUrl = $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + schemaRegistryUrl = + $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SimpleOutputConfig( - override val notifier : java.lang.String, - override val simulationResult : scala.Boolean - ) extends BaseOutputConfig(notifier,simulationResult) + override val notifier: java.lang.String, + override val simulationResult: scala.Boolean + ) extends BaseOutputConfig(notifier, simulationResult) object SimpleOutputConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.SimpleOutputConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.SimpleOutputConfig = { SimonaConfig.SimpleOutputConfig( notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), - simulationResult = $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + simulationResult = + $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class VoltLvlConfig( - id : java.lang.String, - vNom : java.lang.String + id: java.lang.String, + vNom: java.lang.String ) object VoltLvlConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.VoltLvlConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.VoltLvlConfig = { SimonaConfig.VoltLvlConfig( - id = $_reqStr(parentPath, c, "id", $tsCfgValidator), + id = $_reqStr(parentPath, c, "id", $tsCfgValidator), vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class WecRuntimeConfig( - override val calculateMissingReactivePowerWithModel : scala.Boolean, - override val scaling : scala.Double, - override val uuids : scala.List[java.lang.String] - ) extends BaseRuntimeConfig(calculateMissingReactivePowerWithModel,scaling,uuids) + override val calculateMissingReactivePowerWithModel: scala.Boolean, + override val scaling: scala.Double, + override val uuids: scala.List[java.lang.String] + ) extends BaseRuntimeConfig( + calculateMissingReactivePowerWithModel, + scaling, + uuids + ) object WecRuntimeConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.WecRuntimeConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.WecRuntimeConfig = { SimonaConfig.WecRuntimeConfig( - calculateMissingReactivePowerWithModel = $_reqBln(parentPath, c, "calculateMissingReactivePowerWithModel", $tsCfgValidator), + calculateMissingReactivePowerWithModel = $_reqBln( + parentPath, + c, + "calculateMissingReactivePowerWithModel", + $tsCfgValidator + ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) ) } - private def $_reqBln(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Boolean = { + private def $_reqBln( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Boolean = { if (c == null) false - else try c.getBoolean(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - false - } + else + try c.getBoolean(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + false + } } - - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Simona( - event : SimonaConfig.Simona.Event, - gridConfig : SimonaConfig.Simona.GridConfig, - input : SimonaConfig.Simona.Input, - output : SimonaConfig.Simona.Output, - powerflow : SimonaConfig.Simona.Powerflow, - runtime : SimonaConfig.Simona.Runtime, - simulationName : java.lang.String, - time : SimonaConfig.Simona.Time + event: SimonaConfig.Simona.Event, + gridConfig: SimonaConfig.Simona.GridConfig, + input: SimonaConfig.Simona.Input, + output: SimonaConfig.Simona.Output, + powerflow: SimonaConfig.Simona.Powerflow, + runtime: SimonaConfig.Simona.Runtime, + simulationName: java.lang.String, + time: SimonaConfig.Simona.Time ) object Simona { final case class Event( - listener : scala.Option[scala.List[SimonaConfig.Simona.Event.Listener$Elm]] + listener: scala.Option[ + scala.List[SimonaConfig.Simona.Event.Listener$Elm] + ] ) object Event { final case class Listener$Elm( - eventsToProcess : scala.Option[scala.List[java.lang.String]], - fullClassPath : java.lang.String + eventsToProcess: scala.Option[scala.List[java.lang.String]], + fullClassPath: java.lang.String ) object Listener$Elm { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event.Listener$Elm = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Event.Listener$Elm = { SimonaConfig.Simona.Event.Listener$Elm( - eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, - fullClassPath = $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) + eventsToProcess = + if (c.hasPathOrNull("eventsToProcess")) + scala.Some( + $_L$_str( + c.getList("eventsToProcess"), + parentPath, + $tsCfgValidator + ) + ) + else None, + fullClassPath = + $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Event = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Event = { SimonaConfig.Simona.Event( - listener = if(c.hasPathOrNull("listener")) scala.Some($_LSimonaConfig_Simona_Event_Listener$Elm(c.getList("listener"), parentPath, $tsCfgValidator)) else None + listener = + if (c.hasPathOrNull("listener")) + scala.Some( + $_LSimonaConfig_Simona_Event_Listener$Elm( + c.getList("listener"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_Simona_Event_Listener$Elm(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { + private def $_LSimonaConfig_Simona_Event_Listener$Elm( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.Simona.Event.Listener$Elm(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.Simona.Event.Listener$Elm( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class GridConfig( - refSystems : scala.List[SimonaConfig.RefSystemConfig] + refSystems: scala.List[SimonaConfig.RefSystemConfig] ) object GridConfig { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.GridConfig = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.GridConfig = { SimonaConfig.Simona.GridConfig( - refSystems = $_LSimonaConfig_RefSystemConfig(c.getList("refSystems"), parentPath, $tsCfgValidator) + refSystems = $_LSimonaConfig_RefSystemConfig( + c.getList("refSystems"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_RefSystemConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.RefSystemConfig] = { + private def $_LSimonaConfig_RefSystemConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.RefSystemConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.RefSystemConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.RefSystemConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Input( - grid : SimonaConfig.Simona.Input.Grid, - primary : SimonaConfig.Simona.Input.Primary, - weather : SimonaConfig.Simona.Input.Weather + grid: SimonaConfig.Simona.Input.Grid, + primary: SimonaConfig.Simona.Input.Primary, + weather: SimonaConfig.Simona.Input.Weather ) object Input { final case class Grid( - datasource : SimonaConfig.Simona.Input.Grid.Datasource + datasource: SimonaConfig.Simona.Input.Grid.Datasource ) object Grid { final case class Datasource( - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - id : java.lang.String + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + id: java.lang.String ) object Datasource { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid.Datasource = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Grid.Datasource = { SimonaConfig.Simona.Input.Grid.Datasource( - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - id = $_reqStr(parentPath, c, "id", $tsCfgValidator) + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + id = $_reqStr(parentPath, c, "id", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Grid = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Grid = { SimonaConfig.Simona.Input.Grid( - datasource = SimonaConfig.Simona.Input.Grid.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) + datasource = SimonaConfig.Simona.Input.Grid.Datasource( + if (c.hasPathOrNull("datasource")) c.getConfig("datasource") + else + com.typesafe.config.ConfigFactory.parseString("datasource{}"), + parentPath + "datasource.", + $tsCfgValidator + ) ) } } - + final case class Primary( - couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Primary.CouchbaseParams], - csvParams : scala.Option[SimonaConfig.PrimaryDataCsvParams], - influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Primary.InfluxDb1xParams], - sqlParams : scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] + couchbaseParams: scala.Option[ + SimonaConfig.Simona.Input.Primary.CouchbaseParams + ], + csvParams: scala.Option[SimonaConfig.PrimaryDataCsvParams], + influxDb1xParams: scala.Option[ + SimonaConfig.Simona.Input.Primary.InfluxDb1xParams + ], + sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] ) object Primary { final case class CouchbaseParams( - bucketName : java.lang.String, - coordinateColumnName : java.lang.String, - keyPrefix : java.lang.String, - password : java.lang.String, - timePattern : java.lang.String, - url : java.lang.String, - userName : java.lang.String + bucketName: java.lang.String, + coordinateColumnName: java.lang.String, + keyPrefix: java.lang.String, + password: java.lang.String, + timePattern: java.lang.String, + url: java.lang.String, + userName: java.lang.String ) object CouchbaseParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { SimonaConfig.Simona.Input.Primary.CouchbaseParams( - bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = + $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr( + parentPath, + c, + "coordinateColumnName", + $tsCfgValidator + ), + keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database : java.lang.String, - port : scala.Int, - timePattern : java.lang.String, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + timePattern: java.lang.String, + url: java.lang.String ) object InfluxDb1xParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( - database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + database = $_reqStr(parentPath, c, "database", $tsCfgValidator), + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SqlParams( - jdbcUrl : java.lang.String, - password : java.lang.String, - schemaName : java.lang.String, - timePattern : java.lang.String, - userName : java.lang.String + jdbcUrl: java.lang.String, + password: java.lang.String, + schemaName: java.lang.String, + timePattern: java.lang.String, + userName: java.lang.String ) object SqlParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary.SqlParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary.SqlParams = { SimonaConfig.Simona.Input.Primary.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", - timePattern = if(c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = + if (c.hasPathOrNull("schemaName")) c.getString("schemaName") + else "public", + timePattern = + if (c.hasPathOrNull("timePattern")) c.getString("timePattern") + else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Primary = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Primary = { SimonaConfig.Simona.Input.Primary( - couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Primary.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.PrimaryDataCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Primary.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, - sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Primary.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None + couchbaseParams = + if (c.hasPathOrNull("couchbaseParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.CouchbaseParams( + c.getConfig("couchbaseParams"), + parentPath + "couchbaseParams.", + $tsCfgValidator + ) + ) + else None, + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.PrimaryDataCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + influxDb1xParams = + if (c.hasPathOrNull("influxDb1xParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( + c.getConfig("influxDb1xParams"), + parentPath + "influxDb1xParams.", + $tsCfgValidator + ) + ) + else None, + sqlParams = + if (c.hasPathOrNull("sqlParams")) + scala.Some( + SimonaConfig.Simona.Input.Primary.SqlParams( + c.getConfig("sqlParams"), + parentPath + "sqlParams.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class Weather( - datasource : SimonaConfig.Simona.Input.Weather.Datasource + datasource: SimonaConfig.Simona.Input.Weather.Datasource ) object Weather { final case class Datasource( - coordinateSource : SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, - couchbaseParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams], - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - influxDb1xParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams], - maxCoordinateDistance : scala.Double, - resolution : scala.Option[scala.Long], - sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SampleParams], - scheme : java.lang.String, - sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.SqlParams], - timestampPattern : scala.Option[java.lang.String] + coordinateSource: SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource, + couchbaseParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams + ], + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + influxDb1xParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams + ], + maxCoordinateDistance: scala.Double, + resolution: scala.Option[scala.Long], + sampleParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.SampleParams + ], + scheme: java.lang.String, + sqlParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.SqlParams + ], + timestampPattern: scala.Option[java.lang.String] ) object Datasource { final case class CoordinateSource( - csvParams : scala.Option[SimonaConfig.BaseCsvParams], - gridModel : java.lang.String, - sampleParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams], - sqlParams : scala.Option[SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams] + csvParams: scala.Option[SimonaConfig.BaseCsvParams], + gridModel: java.lang.String, + sampleParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams + ], + sqlParams: scala.Option[ + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams + ] ) object CoordinateSource { final case class SampleParams( - use : scala.Boolean + use: scala.Boolean ) object SampleParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams( - use = !c.hasPathOrNull("use") || c.getBoolean("use") - ) + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SampleParams( + use = !c.hasPathOrNull("use") || c.getBoolean("use") + ) } } - + final case class SqlParams( - jdbcUrl : java.lang.String, - password : java.lang.String, - schemaName : java.lang.String, - tableName : java.lang.String, - userName : java.lang.String + jdbcUrl: java.lang.String, + password: java.lang.String, + schemaName: java.lang.String, + tableName: java.lang.String, + userName: java.lang.String ) object SqlParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams = { - SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", - tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) - ) + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams = { + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SqlParams( + jdbcUrl = + $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = + $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = + if (c.hasPathOrNull("schemaName")) + c.getString("schemaName") + else "public", + tableName = + $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = + $_reqStr(parentPath, c, "userName", $tsCfgValidator) + ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - gridModel = if(c.hasPathOrNull("gridModel")) c.getString("gridModel") else "icon", - sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, - sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + gridModel = + if (c.hasPathOrNull("gridModel")) c.getString("gridModel") + else "icon", + sampleParams = + if (c.hasPathOrNull("sampleParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SampleParams( + c.getConfig("sampleParams"), + parentPath + "sampleParams.", + $tsCfgValidator + ) + ) + else None, + sqlParams = + if (c.hasPathOrNull("sqlParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource + .SqlParams( + c.getConfig("sqlParams"), + parentPath + "sqlParams.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class CouchbaseParams( - bucketName : java.lang.String, - coordinateColumnName : java.lang.String, - keyPrefix : java.lang.String, - password : java.lang.String, - url : java.lang.String, - userName : java.lang.String + bucketName: java.lang.String, + coordinateColumnName: java.lang.String, + keyPrefix: java.lang.String, + password: java.lang.String, + url: java.lang.String, + userName: java.lang.String ) object CouchbaseParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams( - bucketName = $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), - coordinateColumnName = $_reqStr(parentPath, c, "coordinateColumnName", $tsCfgValidator), - keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + bucketName = + $_reqStr(parentPath, c, "bucketName", $tsCfgValidator), + coordinateColumnName = $_reqStr( + parentPath, + c, + "coordinateColumnName", + $tsCfgValidator + ), + keyPrefix = + $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class InfluxDb1xParams( - database : java.lang.String, - port : scala.Int, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + url: java.lang.String ) object InfluxDb1xParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class SampleParams( - use : scala.Boolean + use: scala.Boolean ) object SampleParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( use = !c.hasPathOrNull("use") || c.getBoolean("use") ) } } - + final case class SqlParams( - jdbcUrl : java.lang.String, - password : java.lang.String, - schemaName : java.lang.String, - tableName : java.lang.String, - userName : java.lang.String + jdbcUrl: java.lang.String, + password: java.lang.String, + schemaName: java.lang.String, + tableName: java.lang.String, + userName: java.lang.String ) object SqlParams { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( - jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), - password = $_reqStr(parentPath, c, "password", $tsCfgValidator), - schemaName = if(c.hasPathOrNull("schemaName")) c.getString("schemaName") else "public", - tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), + password = $_reqStr(parentPath, c, "password", $tsCfgValidator), + schemaName = + if (c.hasPathOrNull("schemaName")) c.getString("schemaName") + else "public", + tableName = + $_reqStr(parentPath, c, "tableName", $tsCfgValidator), + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather.Datasource = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather.Datasource = { SimonaConfig.Simona.Input.Weather.Datasource( - coordinateSource = SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource(if(c.hasPathOrNull("coordinateSource")) c.getConfig("coordinateSource") else com.typesafe.config.ConfigFactory.parseString("coordinateSource{}"), parentPath + "coordinateSource.", $tsCfgValidator), - couchbaseParams = if(c.hasPathOrNull("couchbaseParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams(c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", $tsCfgValidator)) else None, - csvParams = if(c.hasPathOrNull("csvParams")) scala.Some(SimonaConfig.BaseCsvParams(c.getConfig("csvParams"), parentPath + "csvParams.", $tsCfgValidator)) else None, - influxDb1xParams = if(c.hasPathOrNull("influxDb1xParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams(c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", $tsCfgValidator)) else None, - maxCoordinateDistance = if(c.hasPathOrNull("maxCoordinateDistance")) c.getDouble("maxCoordinateDistance") else 50000, - resolution = if(c.hasPathOrNull("resolution")) Some(c.getLong("resolution").longValue()) else None, - sampleParams = if(c.hasPathOrNull("sampleParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SampleParams(c.getConfig("sampleParams"), parentPath + "sampleParams.", $tsCfgValidator)) else None, - scheme = if(c.hasPathOrNull("scheme")) c.getString("scheme") else "icon", - sqlParams = if(c.hasPathOrNull("sqlParams")) scala.Some(SimonaConfig.Simona.Input.Weather.Datasource.SqlParams(c.getConfig("sqlParams"), parentPath + "sqlParams.", $tsCfgValidator)) else None, - timestampPattern = if(c.hasPathOrNull("timestampPattern")) Some(c.getString("timestampPattern")) else None + coordinateSource = + SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( + if (c.hasPathOrNull("coordinateSource")) + c.getConfig("coordinateSource") + else + com.typesafe.config.ConfigFactory + .parseString("coordinateSource{}"), + parentPath + "coordinateSource.", + $tsCfgValidator + ), + couchbaseParams = + if (c.hasPathOrNull("couchbaseParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource + .CouchbaseParams( + c.getConfig("couchbaseParams"), + parentPath + "couchbaseParams.", + $tsCfgValidator + ) + ) + else None, + csvParams = + if (c.hasPathOrNull("csvParams")) + scala.Some( + SimonaConfig.BaseCsvParams( + c.getConfig("csvParams"), + parentPath + "csvParams.", + $tsCfgValidator + ) + ) + else None, + influxDb1xParams = + if (c.hasPathOrNull("influxDb1xParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource + .InfluxDb1xParams( + c.getConfig("influxDb1xParams"), + parentPath + "influxDb1xParams.", + $tsCfgValidator + ) + ) + else None, + maxCoordinateDistance = + if (c.hasPathOrNull("maxCoordinateDistance")) + c.getDouble("maxCoordinateDistance") + else 50000, + resolution = + if (c.hasPathOrNull("resolution")) + Some(c.getLong("resolution").longValue()) + else None, + sampleParams = + if (c.hasPathOrNull("sampleParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( + c.getConfig("sampleParams"), + parentPath + "sampleParams.", + $tsCfgValidator + ) + ) + else None, + scheme = + if (c.hasPathOrNull("scheme")) c.getString("scheme") + else "icon", + sqlParams = + if (c.hasPathOrNull("sqlParams")) + scala.Some( + SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( + c.getConfig("sqlParams"), + parentPath + "sqlParams.", + $tsCfgValidator + ) + ) + else None, + timestampPattern = + if (c.hasPathOrNull("timestampPattern")) + Some(c.getString("timestampPattern")) + else None ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input.Weather = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input.Weather = { SimonaConfig.Simona.Input.Weather( - datasource = SimonaConfig.Simona.Input.Weather.Datasource(if(c.hasPathOrNull("datasource")) c.getConfig("datasource") else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", $tsCfgValidator) + datasource = SimonaConfig.Simona.Input.Weather.Datasource( + if (c.hasPathOrNull("datasource")) c.getConfig("datasource") + else + com.typesafe.config.ConfigFactory.parseString("datasource{}"), + parentPath + "datasource.", + $tsCfgValidator + ) ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Input = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Input = { SimonaConfig.Simona.Input( - grid = SimonaConfig.Simona.Input.Grid(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), - primary = SimonaConfig.Simona.Input.Primary(if(c.hasPathOrNull("primary")) c.getConfig("primary") else com.typesafe.config.ConfigFactory.parseString("primary{}"), parentPath + "primary.", $tsCfgValidator), - weather = SimonaConfig.Simona.Input.Weather(if(c.hasPathOrNull("weather")) c.getConfig("weather") else com.typesafe.config.ConfigFactory.parseString("weather{}"), parentPath + "weather.", $tsCfgValidator) + grid = SimonaConfig.Simona.Input.Grid( + if (c.hasPathOrNull("grid")) c.getConfig("grid") + else com.typesafe.config.ConfigFactory.parseString("grid{}"), + parentPath + "grid.", + $tsCfgValidator + ), + primary = SimonaConfig.Simona.Input.Primary( + if (c.hasPathOrNull("primary")) c.getConfig("primary") + else com.typesafe.config.ConfigFactory.parseString("primary{}"), + parentPath + "primary.", + $tsCfgValidator + ), + weather = SimonaConfig.Simona.Input.Weather( + if (c.hasPathOrNull("weather")) c.getConfig("weather") + else com.typesafe.config.ConfigFactory.parseString("weather{}"), + parentPath + "weather.", + $tsCfgValidator + ) ) } } - + final case class Output( - base : SimonaConfig.Simona.Output.Base, - flex : scala.Boolean, - grid : SimonaConfig.GridOutputConfig, - participant : SimonaConfig.Simona.Output.Participant, - sink : SimonaConfig.Simona.Output.Sink, - thermal : SimonaConfig.Simona.Output.Thermal + base: SimonaConfig.Simona.Output.Base, + flex: scala.Boolean, + grid: SimonaConfig.GridOutputConfig, + participant: SimonaConfig.Simona.Output.Participant, + sink: SimonaConfig.Simona.Output.Sink, + thermal: SimonaConfig.Simona.Output.Thermal ) object Output { final case class Base( - addTimestampToOutputDir : scala.Boolean, - dir : java.lang.String + addTimestampToOutputDir: scala.Boolean, + dir: java.lang.String ) object Base { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Base = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Base = { SimonaConfig.Simona.Output.Base( - addTimestampToOutputDir = !c.hasPathOrNull("addTimestampToOutputDir") || c.getBoolean("addTimestampToOutputDir"), - dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) + addTimestampToOutputDir = !c.hasPathOrNull( + "addTimestampToOutputDir" + ) || c.getBoolean("addTimestampToOutputDir"), + dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + final case class Participant( - defaultConfig : SimonaConfig.ParticipantBaseOutputConfig, - individualConfigs : scala.List[SimonaConfig.ParticipantBaseOutputConfig] + defaultConfig: SimonaConfig.ParticipantBaseOutputConfig, + individualConfigs: scala.List[ + SimonaConfig.ParticipantBaseOutputConfig + ] ) object Participant { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Participant = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Participant = { SimonaConfig.Simona.Output.Participant( - defaultConfig = SimonaConfig.ParticipantBaseOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_ParticipantBaseOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.ParticipantBaseOutputConfig( + if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_ParticipantBaseOutputConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_ParticipantBaseOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.ParticipantBaseOutputConfig] = { + private def $_LSimonaConfig_ParticipantBaseOutputConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.ParticipantBaseOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.ParticipantBaseOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.ParticipantBaseOutputConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Sink( - csv : scala.Option[SimonaConfig.Simona.Output.Sink.Csv], - influxDb1x : scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x], - kafka : scala.Option[SimonaConfig.ResultKafkaParams] + csv: scala.Option[SimonaConfig.Simona.Output.Sink.Csv], + influxDb1x: scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x], + kafka: scala.Option[SimonaConfig.ResultKafkaParams] ) object Sink { final case class Csv( - fileFormat : java.lang.String, - filePrefix : java.lang.String, - fileSuffix : java.lang.String, - isHierarchic : scala.Boolean + fileFormat: java.lang.String, + filePrefix: java.lang.String, + fileSuffix: java.lang.String, + isHierarchic: scala.Boolean ) object Csv { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.Csv = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink.Csv = { SimonaConfig.Simona.Output.Sink.Csv( - fileFormat = if(c.hasPathOrNull("fileFormat")) c.getString("fileFormat") else ".csv", - filePrefix = if(c.hasPathOrNull("filePrefix")) c.getString("filePrefix") else "", - fileSuffix = if(c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") else "", - isHierarchic = c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") + fileFormat = + if (c.hasPathOrNull("fileFormat")) c.getString("fileFormat") + else ".csv", + filePrefix = + if (c.hasPathOrNull("filePrefix")) c.getString("filePrefix") + else "", + fileSuffix = + if (c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") + else "", + isHierarchic = + c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") ) } } - + final case class InfluxDb1x( - database : java.lang.String, - port : scala.Int, - url : java.lang.String + database: java.lang.String, + port: scala.Int, + url: java.lang.String ) object InfluxDb1x { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), - port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + port = $_reqInt(parentPath, c, "port", $tsCfgValidator), + url = $_reqStr(parentPath, c, "url", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Sink = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Sink = { SimonaConfig.Simona.Output.Sink( - csv = if(c.hasPathOrNull("csv")) scala.Some(SimonaConfig.Simona.Output.Sink.Csv(c.getConfig("csv"), parentPath + "csv.", $tsCfgValidator)) else None, - influxDb1x = if(c.hasPathOrNull("influxDb1x")) scala.Some(SimonaConfig.Simona.Output.Sink.InfluxDb1x(c.getConfig("influxDb1x"), parentPath + "influxDb1x.", $tsCfgValidator)) else None, - kafka = if(c.hasPathOrNull("kafka")) scala.Some(SimonaConfig.ResultKafkaParams(c.getConfig("kafka"), parentPath + "kafka.", $tsCfgValidator)) else None + csv = + if (c.hasPathOrNull("csv")) + scala.Some( + SimonaConfig.Simona.Output.Sink.Csv( + c.getConfig("csv"), + parentPath + "csv.", + $tsCfgValidator + ) + ) + else None, + influxDb1x = + if (c.hasPathOrNull("influxDb1x")) + scala.Some( + SimonaConfig.Simona.Output.Sink.InfluxDb1x( + c.getConfig("influxDb1x"), + parentPath + "influxDb1x.", + $tsCfgValidator + ) + ) + else None, + kafka = + if (c.hasPathOrNull("kafka")) + scala.Some( + SimonaConfig.ResultKafkaParams( + c.getConfig("kafka"), + parentPath + "kafka.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class Thermal( - defaultConfig : SimonaConfig.SimpleOutputConfig, - individualConfigs : scala.List[SimonaConfig.SimpleOutputConfig] + defaultConfig: SimonaConfig.SimpleOutputConfig, + individualConfigs: scala.List[SimonaConfig.SimpleOutputConfig] ) object Thermal { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output.Thermal = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output.Thermal = { SimonaConfig.Simona.Output.Thermal( - defaultConfig = SimonaConfig.SimpleOutputConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_SimpleOutputConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.SimpleOutputConfig( + if (c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_SimpleOutputConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_SimpleOutputConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.SimpleOutputConfig] = { + private def $_LSimonaConfig_SimpleOutputConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.SimpleOutputConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.SimpleOutputConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.SimpleOutputConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Output = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Output = { SimonaConfig.Simona.Output( - base = SimonaConfig.Simona.Output.Base(if(c.hasPathOrNull("base")) c.getConfig("base") else com.typesafe.config.ConfigFactory.parseString("base{}"), parentPath + "base.", $tsCfgValidator), - flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), - grid = SimonaConfig.GridOutputConfig(if(c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", $tsCfgValidator), - participant = SimonaConfig.Simona.Output.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), - sink = SimonaConfig.Simona.Output.Sink(if(c.hasPathOrNull("sink")) c.getConfig("sink") else com.typesafe.config.ConfigFactory.parseString("sink{}"), parentPath + "sink.", $tsCfgValidator), - thermal = SimonaConfig.Simona.Output.Thermal(if(c.hasPathOrNull("thermal")) c.getConfig("thermal") else com.typesafe.config.ConfigFactory.parseString("thermal{}"), parentPath + "thermal.", $tsCfgValidator) + base = SimonaConfig.Simona.Output.Base( + if (c.hasPathOrNull("base")) c.getConfig("base") + else com.typesafe.config.ConfigFactory.parseString("base{}"), + parentPath + "base.", + $tsCfgValidator + ), + flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), + grid = SimonaConfig.GridOutputConfig( + if (c.hasPathOrNull("grid")) c.getConfig("grid") + else com.typesafe.config.ConfigFactory.parseString("grid{}"), + parentPath + "grid.", + $tsCfgValidator + ), + participant = SimonaConfig.Simona.Output.Participant( + if (c.hasPathOrNull("participant")) c.getConfig("participant") + else com.typesafe.config.ConfigFactory.parseString("participant{}"), + parentPath + "participant.", + $tsCfgValidator + ), + sink = SimonaConfig.Simona.Output.Sink( + if (c.hasPathOrNull("sink")) c.getConfig("sink") + else com.typesafe.config.ConfigFactory.parseString("sink{}"), + parentPath + "sink.", + $tsCfgValidator + ), + thermal = SimonaConfig.Simona.Output.Thermal( + if (c.hasPathOrNull("thermal")) c.getConfig("thermal") + else com.typesafe.config.ConfigFactory.parseString("thermal{}"), + parentPath + "thermal.", + $tsCfgValidator + ) ) } } - + final case class Powerflow( - maxSweepPowerDeviation : scala.Double, - newtonraphson : SimonaConfig.Simona.Powerflow.Newtonraphson, - resolution : java.time.Duration, - stopOnFailure : scala.Boolean, - sweepTimeout : java.time.Duration + maxSweepPowerDeviation: scala.Double, + newtonraphson: SimonaConfig.Simona.Powerflow.Newtonraphson, + resolution: java.time.Duration, + stopOnFailure: scala.Boolean, + sweepTimeout: java.time.Duration ) object Powerflow { final case class Newtonraphson( - epsilon : scala.List[scala.Double], - iterations : scala.Int + epsilon: scala.List[scala.Double], + iterations: scala.Int ) object Newtonraphson { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow.Newtonraphson = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Powerflow.Newtonraphson = { SimonaConfig.Simona.Powerflow.Newtonraphson( - epsilon = $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), + epsilon = + $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator) ) } - private def $_reqInt(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Int = { + private def $_reqInt( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Int = { if (c == null) 0 - else try c.getInt(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getInt(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Powerflow = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Powerflow = { SimonaConfig.Simona.Powerflow( - maxSweepPowerDeviation = $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), - newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson(if(c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") else com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), parentPath + "newtonraphson.", $tsCfgValidator), - resolution = if(c.hasPathOrNull("resolution")) c.getDuration("resolution") else java.time.Duration.parse("PT1H"), - stopOnFailure = c.hasPathOrNull("stopOnFailure") && c.getBoolean("stopOnFailure"), - sweepTimeout = if(c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") else java.time.Duration.parse("PT30S") + maxSweepPowerDeviation = + $_reqDbl(parentPath, c, "maxSweepPowerDeviation", $tsCfgValidator), + newtonraphson = SimonaConfig.Simona.Powerflow.Newtonraphson( + if (c.hasPathOrNull("newtonraphson")) c.getConfig("newtonraphson") + else + com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), + parentPath + "newtonraphson.", + $tsCfgValidator + ), + resolution = + if (c.hasPathOrNull("resolution")) c.getDuration("resolution") + else java.time.Duration.parse("PT1H"), + stopOnFailure = + c.hasPathOrNull("stopOnFailure") && c.getBoolean("stopOnFailure"), + sweepTimeout = + if (c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") + else java.time.Duration.parse("PT30S") ) } - private def $_reqDbl(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.Double = { + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.Double = { if (c == null) 0 - else try c.getDouble(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } } - + } - + final case class Runtime( - listener : SimonaConfig.Simona.Runtime.Listener, - participant : SimonaConfig.Simona.Runtime.Participant, - selected_subgrids : scala.Option[scala.List[scala.Int]], - selected_volt_lvls : scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + listener: SimonaConfig.Simona.Runtime.Listener, + participant: SimonaConfig.Simona.Runtime.Participant, + selected_subgrids: scala.Option[scala.List[scala.Int]], + selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] ) object Runtime { final case class Listener( - eventsToProcess : scala.Option[scala.List[java.lang.String]], - kafka : scala.Option[SimonaConfig.RuntimeKafkaParams] + eventsToProcess: scala.Option[scala.List[java.lang.String]], + kafka: scala.Option[SimonaConfig.RuntimeKafkaParams] ) object Listener { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Listener = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Listener = { SimonaConfig.Simona.Runtime.Listener( - eventsToProcess = if(c.hasPathOrNull("eventsToProcess")) scala.Some($_L$_str(c.getList("eventsToProcess"), parentPath, $tsCfgValidator)) else None, - kafka = if(c.hasPathOrNull("kafka")) scala.Some(SimonaConfig.RuntimeKafkaParams(c.getConfig("kafka"), parentPath + "kafka.", $tsCfgValidator)) else None + eventsToProcess = + if (c.hasPathOrNull("eventsToProcess")) + scala.Some( + $_L$_str( + c.getList("eventsToProcess"), + parentPath, + $tsCfgValidator + ) + ) + else None, + kafka = + if (c.hasPathOrNull("kafka")) + scala.Some( + SimonaConfig.RuntimeKafkaParams( + c.getConfig("kafka"), + parentPath + "kafka.", + $tsCfgValidator + ) + ) + else None ) } } - + final case class Participant( - evcs : SimonaConfig.Simona.Runtime.Participant.Evcs, - fixedFeedIn : SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, - hp : SimonaConfig.Simona.Runtime.Participant.Hp, - load : SimonaConfig.Simona.Runtime.Participant.Load, - pv : SimonaConfig.Simona.Runtime.Participant.Pv, - requestVoltageDeviationThreshold : scala.Double, - wec : SimonaConfig.Simona.Runtime.Participant.Wec + evcs: SimonaConfig.Simona.Runtime.Participant.Evcs, + fixedFeedIn: SimonaConfig.Simona.Runtime.Participant.FixedFeedIn, + hp: SimonaConfig.Simona.Runtime.Participant.Hp, + load: SimonaConfig.Simona.Runtime.Participant.Load, + pv: SimonaConfig.Simona.Runtime.Participant.Pv, + requestVoltageDeviationThreshold: scala.Double, + wec: SimonaConfig.Simona.Runtime.Participant.Wec ) object Participant { final case class Evcs( - defaultConfig : SimonaConfig.EvcsRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.EvcsRuntimeConfig] + defaultConfig: SimonaConfig.EvcsRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig] ) object Evcs { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Evcs = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Evcs = { SimonaConfig.Simona.Runtime.Participant.Evcs( - defaultConfig = SimonaConfig.EvcsRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.EvcsRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_EvcsRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.EvcsRuntimeConfig] = { + private def $_LSimonaConfig_EvcsRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.EvcsRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.EvcsRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.EvcsRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class FixedFeedIn( - defaultConfig : SimonaConfig.FixedFeedInRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.FixedFeedInRuntimeConfig] + defaultConfig: SimonaConfig.FixedFeedInRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig] ) object FixedFeedIn { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( - defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_FixedFeedInRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { + private def $_LSimonaConfig_FixedFeedInRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.FixedFeedInRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.FixedFeedInRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Hp( - defaultConfig : SimonaConfig.HpRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.HpRuntimeConfig] + defaultConfig: SimonaConfig.HpRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.HpRuntimeConfig] ) object Hp { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Hp = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Hp = { SimonaConfig.Simona.Runtime.Participant.Hp( - defaultConfig = SimonaConfig.HpRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_HpRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.HpRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_HpRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_HpRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.HpRuntimeConfig] = { + private def $_LSimonaConfig_HpRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.HpRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.HpRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.HpRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Load( - defaultConfig : SimonaConfig.LoadRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.LoadRuntimeConfig] + defaultConfig: SimonaConfig.LoadRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig] ) object Load { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Load = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Load = { SimonaConfig.Simona.Runtime.Participant.Load( - defaultConfig = SimonaConfig.LoadRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_LoadRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.LoadRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_LoadRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_LoadRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.LoadRuntimeConfig] = { + private def $_LSimonaConfig_LoadRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.LoadRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.LoadRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.LoadRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Pv( - defaultConfig : SimonaConfig.PvRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.PvRuntimeConfig] + defaultConfig: SimonaConfig.PvRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig] ) object Pv { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Pv = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Pv = { SimonaConfig.Simona.Runtime.Participant.Pv( - defaultConfig = SimonaConfig.PvRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_PvRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.PvRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_PvRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_PvRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.PvRuntimeConfig] = { + private def $_LSimonaConfig_PvRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.PvRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.PvRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.PvRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Wec( - defaultConfig : SimonaConfig.WecRuntimeConfig, - individualConfigs : scala.List[SimonaConfig.WecRuntimeConfig] + defaultConfig: SimonaConfig.WecRuntimeConfig, + individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig] ) object Wec { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant.Wec = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant.Wec = { SimonaConfig.Simona.Runtime.Participant.Wec( - defaultConfig = SimonaConfig.WecRuntimeConfig(if(c.hasPathOrNull("defaultConfig")) c.getConfig("defaultConfig") else com.typesafe.config.ConfigFactory.parseString("defaultConfig{}"), parentPath + "defaultConfig.", $tsCfgValidator), - individualConfigs = $_LSimonaConfig_WecRuntimeConfig(c.getList("individualConfigs"), parentPath, $tsCfgValidator) + defaultConfig = SimonaConfig.WecRuntimeConfig( + if (c.hasPathOrNull("defaultConfig")) + c.getConfig("defaultConfig") + else + com.typesafe.config.ConfigFactory + .parseString("defaultConfig{}"), + parentPath + "defaultConfig.", + $tsCfgValidator + ), + individualConfigs = $_LSimonaConfig_WecRuntimeConfig( + c.getList("individualConfigs"), + parentPath, + $tsCfgValidator + ) ) } - private def $_LSimonaConfig_WecRuntimeConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.WecRuntimeConfig] = { + private def $_LSimonaConfig_WecRuntimeConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.WecRuntimeConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.WecRuntimeConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.WecRuntimeConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime.Participant = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime.Participant = { SimonaConfig.Simona.Runtime.Participant( - evcs = SimonaConfig.Simona.Runtime.Participant.Evcs(if(c.hasPathOrNull("evcs")) c.getConfig("evcs") else com.typesafe.config.ConfigFactory.parseString("evcs{}"), parentPath + "evcs.", $tsCfgValidator), - fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn(if(c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") else com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), parentPath + "fixedFeedIn.", $tsCfgValidator), - hp = SimonaConfig.Simona.Runtime.Participant.Hp(if(c.hasPathOrNull("hp")) c.getConfig("hp") else com.typesafe.config.ConfigFactory.parseString("hp{}"), parentPath + "hp.", $tsCfgValidator), - load = SimonaConfig.Simona.Runtime.Participant.Load(if(c.hasPathOrNull("load")) c.getConfig("load") else com.typesafe.config.ConfigFactory.parseString("load{}"), parentPath + "load.", $tsCfgValidator), - pv = SimonaConfig.Simona.Runtime.Participant.Pv(if(c.hasPathOrNull("pv")) c.getConfig("pv") else com.typesafe.config.ConfigFactory.parseString("pv{}"), parentPath + "pv.", $tsCfgValidator), - requestVoltageDeviationThreshold = if(c.hasPathOrNull("requestVoltageDeviationThreshold")) c.getDouble("requestVoltageDeviationThreshold") else 1E-14, - wec = SimonaConfig.Simona.Runtime.Participant.Wec(if(c.hasPathOrNull("wec")) c.getConfig("wec") else com.typesafe.config.ConfigFactory.parseString("wec{}"), parentPath + "wec.", $tsCfgValidator) + evcs = SimonaConfig.Simona.Runtime.Participant.Evcs( + if (c.hasPathOrNull("evcs")) c.getConfig("evcs") + else com.typesafe.config.ConfigFactory.parseString("evcs{}"), + parentPath + "evcs.", + $tsCfgValidator + ), + fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( + if (c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") + else + com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), + parentPath + "fixedFeedIn.", + $tsCfgValidator + ), + hp = SimonaConfig.Simona.Runtime.Participant.Hp( + if (c.hasPathOrNull("hp")) c.getConfig("hp") + else com.typesafe.config.ConfigFactory.parseString("hp{}"), + parentPath + "hp.", + $tsCfgValidator + ), + load = SimonaConfig.Simona.Runtime.Participant.Load( + if (c.hasPathOrNull("load")) c.getConfig("load") + else com.typesafe.config.ConfigFactory.parseString("load{}"), + parentPath + "load.", + $tsCfgValidator + ), + pv = SimonaConfig.Simona.Runtime.Participant.Pv( + if (c.hasPathOrNull("pv")) c.getConfig("pv") + else com.typesafe.config.ConfigFactory.parseString("pv{}"), + parentPath + "pv.", + $tsCfgValidator + ), + requestVoltageDeviationThreshold = + if (c.hasPathOrNull("requestVoltageDeviationThreshold")) + c.getDouble("requestVoltageDeviationThreshold") + else 1e-14, + wec = SimonaConfig.Simona.Runtime.Participant.Wec( + if (c.hasPathOrNull("wec")) c.getConfig("wec") + else com.typesafe.config.ConfigFactory.parseString("wec{}"), + parentPath + "wec.", + $tsCfgValidator + ) ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Runtime = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Runtime = { SimonaConfig.Simona.Runtime( - listener = SimonaConfig.Simona.Runtime.Listener(if(c.hasPathOrNull("listener")) c.getConfig("listener") else com.typesafe.config.ConfigFactory.parseString("listener{}"), parentPath + "listener.", $tsCfgValidator), - participant = SimonaConfig.Simona.Runtime.Participant(if(c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", $tsCfgValidator), - selected_subgrids = if(c.hasPathOrNull("selected_subgrids")) scala.Some($_L$_int(c.getList("selected_subgrids"), parentPath, $tsCfgValidator)) else None, - selected_volt_lvls = if(c.hasPathOrNull("selected_volt_lvls")) scala.Some($_LSimonaConfig_VoltLvlConfig(c.getList("selected_volt_lvls"), parentPath, $tsCfgValidator)) else None + listener = SimonaConfig.Simona.Runtime.Listener( + if (c.hasPathOrNull("listener")) c.getConfig("listener") + else com.typesafe.config.ConfigFactory.parseString("listener{}"), + parentPath + "listener.", + $tsCfgValidator + ), + participant = SimonaConfig.Simona.Runtime.Participant( + if (c.hasPathOrNull("participant")) c.getConfig("participant") + else com.typesafe.config.ConfigFactory.parseString("participant{}"), + parentPath + "participant.", + $tsCfgValidator + ), + selected_subgrids = + if (c.hasPathOrNull("selected_subgrids")) + scala.Some( + $_L$_int( + c.getList("selected_subgrids"), + parentPath, + $tsCfgValidator + ) + ) + else None, + selected_volt_lvls = + if (c.hasPathOrNull("selected_volt_lvls")) + scala.Some( + $_LSimonaConfig_VoltLvlConfig( + c.getList("selected_volt_lvls"), + parentPath, + $tsCfgValidator + ) + ) + else None ) } - private def $_LSimonaConfig_VoltLvlConfig(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[SimonaConfig.VoltLvlConfig] = { + private def $_LSimonaConfig_VoltLvlConfig( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ - cl.asScala.map(cv => SimonaConfig.VoltLvlConfig(cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, $tsCfgValidator)).toList + cl.asScala + .map(cv => + SimonaConfig.VoltLvlConfig( + cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, + parentPath, + $tsCfgValidator + ) + ) + .toList } } - + final case class Time( - endDateTime : java.lang.String, - schedulerReadyCheckWindow : scala.Option[scala.Int], - startDateTime : java.lang.String + endDateTime: java.lang.String, + schedulerReadyCheckWindow: scala.Option[scala.Int], + startDateTime: java.lang.String ) object Time { - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona.Time = { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona.Time = { SimonaConfig.Simona.Time( - endDateTime = if(c.hasPathOrNull("endDateTime")) c.getString("endDateTime") else "2011-05-01 01:00:00", - schedulerReadyCheckWindow = if(c.hasPathOrNull("schedulerReadyCheckWindow")) Some(c.getInt("schedulerReadyCheckWindow")) else None, - startDateTime = if(c.hasPathOrNull("startDateTime")) c.getString("startDateTime") else "2011-05-01 00:00:00" + endDateTime = + if (c.hasPathOrNull("endDateTime")) c.getString("endDateTime") + else "2011-05-01 01:00:00", + schedulerReadyCheckWindow = + if (c.hasPathOrNull("schedulerReadyCheckWindow")) + Some(c.getInt("schedulerReadyCheckWindow")) + else None, + startDateTime = + if (c.hasPathOrNull("startDateTime")) c.getString("startDateTime") + else "2011-05-01 00:00:00" ) } } - - def apply(c: com.typesafe.config.Config, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): SimonaConfig.Simona = { + + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): SimonaConfig.Simona = { SimonaConfig.Simona( - event = SimonaConfig.Simona.Event(if(c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), parentPath + "event.", $tsCfgValidator), - gridConfig = SimonaConfig.Simona.GridConfig(if(c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), parentPath + "gridConfig.", $tsCfgValidator), - input = SimonaConfig.Simona.Input(if(c.hasPathOrNull("input")) c.getConfig("input") else com.typesafe.config.ConfigFactory.parseString("input{}"), parentPath + "input.", $tsCfgValidator), - output = SimonaConfig.Simona.Output(if(c.hasPathOrNull("output")) c.getConfig("output") else com.typesafe.config.ConfigFactory.parseString("output{}"), parentPath + "output.", $tsCfgValidator), - powerflow = SimonaConfig.Simona.Powerflow(if(c.hasPathOrNull("powerflow")) c.getConfig("powerflow") else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), parentPath + "powerflow.", $tsCfgValidator), - runtime = SimonaConfig.Simona.Runtime(if(c.hasPathOrNull("runtime")) c.getConfig("runtime") else com.typesafe.config.ConfigFactory.parseString("runtime{}"), parentPath + "runtime.", $tsCfgValidator), - simulationName = $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), - time = SimonaConfig.Simona.Time(if(c.hasPathOrNull("time")) c.getConfig("time") else com.typesafe.config.ConfigFactory.parseString("time{}"), parentPath + "time.", $tsCfgValidator) + event = SimonaConfig.Simona.Event( + if (c.hasPathOrNull("event")) c.getConfig("event") + else com.typesafe.config.ConfigFactory.parseString("event{}"), + parentPath + "event.", + $tsCfgValidator + ), + gridConfig = SimonaConfig.Simona.GridConfig( + if (c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") + else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), + parentPath + "gridConfig.", + $tsCfgValidator + ), + input = SimonaConfig.Simona.Input( + if (c.hasPathOrNull("input")) c.getConfig("input") + else com.typesafe.config.ConfigFactory.parseString("input{}"), + parentPath + "input.", + $tsCfgValidator + ), + output = SimonaConfig.Simona.Output( + if (c.hasPathOrNull("output")) c.getConfig("output") + else com.typesafe.config.ConfigFactory.parseString("output{}"), + parentPath + "output.", + $tsCfgValidator + ), + powerflow = SimonaConfig.Simona.Powerflow( + if (c.hasPathOrNull("powerflow")) c.getConfig("powerflow") + else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), + parentPath + "powerflow.", + $tsCfgValidator + ), + runtime = SimonaConfig.Simona.Runtime( + if (c.hasPathOrNull("runtime")) c.getConfig("runtime") + else com.typesafe.config.ConfigFactory.parseString("runtime{}"), + parentPath + "runtime.", + $tsCfgValidator + ), + simulationName = + $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), + time = SimonaConfig.Simona.Time( + if (c.hasPathOrNull("time")) c.getConfig("time") + else com.typesafe.config.ConfigFactory.parseString("time{}"), + parentPath + "time.", + $tsCfgValidator + ) ) } - private def $_reqStr(parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, $tsCfgValidator: $TsCfgValidator): java.lang.String = { + private def $_reqStr( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): java.lang.String = { if (c == null) null - else try c.getString(path) - catch { - case e:com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - null - } + else + try c.getString(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + null + } } - + } - + def apply(c: com.typesafe.config.Config): SimonaConfig = { val $tsCfgValidator: $TsCfgValidator = new $TsCfgValidator() val parentPath: java.lang.String = "" val $result = SimonaConfig( - simona = SimonaConfig.Simona(if(c.hasPathOrNull("simona")) c.getConfig("simona") else com.typesafe.config.ConfigFactory.parseString("simona{}"), parentPath + "simona.", $tsCfgValidator) + simona = SimonaConfig.Simona( + if (c.hasPathOrNull("simona")) c.getConfig("simona") + else com.typesafe.config.ConfigFactory.parseString("simona{}"), + parentPath + "simona.", + $tsCfgValidator + ) ) $tsCfgValidator.validate() $result } - private def $_L$_dbl(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Double] = { + private def $_L$_dbl( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[scala.Double] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_dbl(cv)).toList } - private def $_L$_int(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[scala.Int] = { + private def $_L$_int( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[scala.Int] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_int(cv)).toList } - private def $_L$_str(cl:com.typesafe.config.ConfigList, parentPath: java.lang.String, $tsCfgValidator: $TsCfgValidator): scala.List[java.lang.String] = { + private def $_L$_str( + cl: com.typesafe.config.ConfigList, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator + ): scala.List[java.lang.String] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_str(cv)).toList } - private def $_dbl(cv:com.typesafe.config.ConfigValue): scala.Double = { + private def $_dbl(cv: com.typesafe.config.ConfigValue): scala.Double = { val u: Any = cv.unwrapped - if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[java.lang.Number]) throw $_expE(cv, "double") + if ( + (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[java.lang.Number] + ) throw $_expE(cv, "double") u.asInstanceOf[java.lang.Number].doubleValue() } - private def $_expE(cv:com.typesafe.config.ConfigValue, exp:java.lang.String) = { + private def $_expE( + cv: com.typesafe.config.ConfigValue, + exp: java.lang.String + ) = { val u: Any = cv.unwrapped - new java.lang.RuntimeException(s"${cv.origin.lineNumber}: " + - "expecting: " + exp + " got: " + - (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u)) + new java.lang.RuntimeException( + s"${cv.origin.lineNumber}: " + + "expecting: " + exp + " got: " + + (if (u.isInstanceOf[java.lang.String]) "\"" + u + "\"" else u) + ) } - private def $_int(cv:com.typesafe.config.ConfigValue): scala.Int = { + private def $_int(cv: com.typesafe.config.ConfigValue): scala.Int = { val u: Any = cv.unwrapped - if ((cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || - !u.isInstanceOf[Integer]) throw $_expE(cv, "integer") + if ( + (cv.valueType != com.typesafe.config.ConfigValueType.NUMBER) || + !u.isInstanceOf[Integer] + ) throw $_expE(cv, "integer") u.asInstanceOf[Integer] } - private def $_str(cv:com.typesafe.config.ConfigValue): java.lang.String = { + private def $_str(cv: com.typesafe.config.ConfigValue): java.lang.String = { java.lang.String.valueOf(cv.unwrapped()) } final class $TsCfgValidator { - private val badPaths = scala.collection.mutable.ArrayBuffer[java.lang.String]() + private val badPaths = + scala.collection.mutable.ArrayBuffer[java.lang.String]() - def addBadPath(path: java.lang.String, e: com.typesafe.config.ConfigException): Unit = { + def addBadPath( + path: java.lang.String, + e: com.typesafe.config.ConfigException + ): Unit = { badPaths += s"'$path': ${e.getClass.getName}(${e.getMessage})" } - def addInvalidEnumValue(path: java.lang.String, value: java.lang.String, enumName: java.lang.String): Unit = { + def addInvalidEnumValue( + path: java.lang.String, + value: java.lang.String, + enumName: java.lang.String + ): Unit = { badPaths += s"'$path': invalid value $value for enumeration $enumName" } @@ -1453,7 +2745,7 @@ object SimonaConfig { if (badPaths.nonEmpty) { throw new com.typesafe.config.ConfigException( badPaths.mkString("Invalid configuration:\n ", "\n ", "") - ){} + ) {} } } } From 63cebd5d8e2548bf526d95c19ee898d2e6d67402 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 13:30:40 +0100 Subject: [PATCH 135/305] Providing needed file --- .../edu/ie3/simona/util/ReceiveDataMap.scala | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala diff --git a/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala b/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala new file mode 100644 index 0000000000..ba568a043b --- /dev/null +++ b/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala @@ -0,0 +1,62 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.util + +/** Map that holds data that an actor is expected to receive over time and + * efficiently determines if all expected data has been received. + * @param expectedKeys + * The keys for which data is expected + * @param receivedData + * The map holding all received data so far + * @tparam K + * The type of the key + * @tparam V + * The type of the value + */ +final case class ReceiveDataMap[K, V]( + private val expectedKeys: Set[K], + receivedData: Map[K, V] +) { + def isComplete: Boolean = expectedKeys.isEmpty + + def nonComplete: Boolean = expectedKeys.nonEmpty + + def addData( + key: K, + value: V + ): ReceiveDataMap[K, V] = { + + if (!expectedKeys.contains(key)) + throw new RuntimeException( + s"Received value $value for key $key, but no data has been expected for this key." + ) + + copy( + expectedKeys = expectedKeys.excl(key), + receivedData.updated(key, value) + ) + } + +} + +object ReceiveDataMap { + + def apply[K, V]( + expectedKeys: Set[K] + ): ReceiveDataMap[K, V] = + ReceiveDataMap( + expectedKeys = expectedKeys, + receivedData = Map.empty + ) + + def empty[K, V]: ReceiveDataMap[K, V] = + ReceiveDataMap( + expectedKeys = Set.empty, + receivedData = Map.empty + ) + +} From b4eedb6af6247af43553dd825b1ee8626f53fdee Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 13:31:03 +0100 Subject: [PATCH 136/305] Adding EVCS changes to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 608cc1582a..740122d4c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added JDK installation, Scala Plugin + SDK in usersguide [#324](https://github.com/ie3-institute/simona/issues/324) - Energy Management capabilities: - Added capability of SystemParticipants to handle flexibility [#308](https://github.com/ie3-institute/simona/issues/308) + - Added smart charging logic [#31](https://github.com/ie3-institute/simona/issues/31) and flex calculation in `EvcsAgent` [#332](https://github.com/ie3-institute/simona/issues/332) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) From 3f38563aa0a41942cc6ccbf557b3001aaa8b78f5 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 13:54:10 +0100 Subject: [PATCH 137/305] Using ConstantState for now --- .../simona/model/participant/BMModel.scala | 24 +++++++++++-------- .../model/participant/BMModelTest.groovy | 16 ++++++------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index 2283bfddb7..4d9a35c568 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -7,7 +7,8 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower -import edu.ie3.simona.model.participant.BMModel.{BMCalcRelevantData, BmState} +import edu.ie3.simona.model.participant.BMModel.BMCalcRelevantData +import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -35,7 +36,11 @@ final case class BMModel( private val opex: Money, private val feedInTariff: EnergyPrice, private val loadGradient: Double -) extends SystemParticipant[BMCalcRelevantData, ApparentPower, BmState]( +) extends SystemParticipant[ + BMCalcRelevantData, + ApparentPower, + ConstantState.type + ]( uuid, id, operationInterval, @@ -44,7 +49,7 @@ final case class BMModel( sRated, cosPhi ) - with ApparentPowerParticipant[BMCalcRelevantData, BmState] { + with ApparentPowerParticipant[BMCalcRelevantData, ConstantState.type] { /** Saves power output of last cycle. Needed for load gradient */ @@ -53,7 +58,7 @@ final case class BMModel( override def calculatePower( tick: Long, voltage: Dimensionless, - modelState: BmState, + modelState: ConstantState.type, data: BMCalcRelevantData ): ApparentPower = { val result = super.calculatePower(tick, voltage, modelState, data) @@ -70,7 +75,7 @@ final case class BMModel( * Active power */ override protected def calculateActivePower( - modelState: BmState, + modelState: ConstantState.type, data: BMCalcRelevantData ): Power = { // Calculate heat demand // @@ -223,7 +228,7 @@ final case class BMModel( override def determineFlexOptions( data: BMCalcRelevantData, - lastState: BmState + lastState: ConstantState.type ): ProvideFlexOptions = { val power = calculateActivePower(lastState, data) @@ -232,15 +237,14 @@ final case class BMModel( override def handleControlledPowerChange( data: BMCalcRelevantData, - lastState: BmState, + lastState: ConstantState.type, setPower: squants.Power - ): (BmState, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) + ): (ConstantState.type, FlexChangeIndicator) = + (lastState, FlexChangeIndicator()) } object BMModel { - case class BmState() extends ModelState - /** Data, that is needed for model calculations with the biomass model * * @param date diff --git a/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy index 612004ab7e..e77782307d 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/BMModelTest.groovy @@ -6,30 +6,28 @@ package edu.ie3.simona.model.participant -import squants.market.EUR$ -import edu.ie3.util.scala.quantities.EuroPerKilowatthour$ - import static edu.ie3.util.quantities.PowerSystemUnits.* import static tech.units.indriya.unit.Units.PERCENT import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.input.system.type.BmTypeInput -import squants.energy.Megawatts$ -import squants.thermal.Celsius$ +import edu.ie3.simona.model.participant.ModelState.ConstantState$ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.util.scala.OperationInterval +import edu.ie3.util.scala.quantities.EuroPerKilowatthour$ +import edu.ie3.util.scala.quantities.Sq import scala.Some import spock.lang.Shared import spock.lang.Specification import squants.energy.Kilowatts$ -import edu.ie3.util.scala.quantities.Sq +import squants.energy.Megawatts$ +import squants.market.EUR$ +import squants.thermal.Celsius$ import tech.units.indriya.quantity.Quantities import java.time.ZonedDateTime - - /** * Test class that tries to cover all special cases of the current implementation of the {@link BMModel} * @@ -240,7 +238,7 @@ class BMModelTest extends Specification { bmModel._lastPower = new Some(Sq.create(lastPower, Kilowatts$.MODULE$)) when: "the power from the grid is calculated" - def powerCalc = bmModel.calculateActivePower(new BMModel.BmState(), relevantData) + def powerCalc = bmModel.calculateActivePower(ConstantState$.MODULE$, relevantData) then: "compare in kilowatts" powerCalc - Sq.create(powerSol, Kilowatts$.MODULE$) < Sq.create(1e-12d, Kilowatts$.MODULE$) From 3328147df537de881f1c612cb2c2ec8505e74d09 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 14:04:39 +0100 Subject: [PATCH 138/305] Removing more unused stuff --- .../evcs/EvcsAgentFundamentals.scala | 8 +- .../model/participant/evcs/EvcsModel.scala | 15 +--- .../evcs/SchedulingTimeWindows.scala | 79 ------------------- .../simona/service/ev/ExtEvDataService.scala | 1 - .../participant/evcs/EvcsModelSpec.scala | 15 ++-- 5 files changed, 10 insertions(+), 108 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index a84b68353b..54123751fe 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -51,7 +51,7 @@ import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ } import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.util.SimonaConstants -import edu.ie3.simona.util.TickUtil.{RichZonedDateTime, TickLong} +import edu.ie3.simona.util.TickUtil.RichZonedDateTime import edu.ie3.util.quantities.PowerSystemUnits.{MEGAVAR, MEGAWATT, PU} import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.Megavars @@ -219,11 +219,7 @@ protected trait EvcsAgentFundamentals } .getOrElse(Seq.empty) - val voltages = baseStateData.voltageValueStore.asMap - .map { case (tick, voltage) => - tick.toDateTime(baseStateData.startDate) -> voltage - } - EvcsRelevantData(tick, movements, voltages) + EvcsRelevantData(tick, movements) } /** Handle an active power change by flex control. diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index e302537dc2..ec45ba23cf 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -123,9 +123,7 @@ final case class EvcsModel( scheduleByStrategy( strategy, data.tick, - simulationStartDate, - evs, - data.voltages + evs ) } @@ -135,21 +133,15 @@ final case class EvcsModel( * Chosen charging strategy * @param currentTick * Current simulation time - * @param simulationStartDate - * The simulation start time * @param evs * Collection of currently apparent evs - * @param voltages - * Mapping from simulation time to nodal voltage * @return * A set of [[ChargingSchedule]]s */ private def scheduleByStrategy( strategy: ChargingStrategy.Value, currentTick: Long, - simulationStartDate: ZonedDateTime, - evs: Set[EvModelWrapper], - voltages: Map[ZonedDateTime, squants.Dimensionless] + evs: Set[EvModelWrapper] ): Map[EvModelWrapper, Option[ChargingSchedule]] = strategy match { case ChargingStrategy.MAX_POWER => chargeWithMaximumPower( @@ -959,8 +951,7 @@ object EvcsModel { */ final case class EvcsRelevantData( tick: Long, - arrivals: Seq[EvModelWrapper], - voltages: Map[ZonedDateTime, squants.Dimensionless] + arrivals: Seq[EvModelWrapper] ) extends CalcRelevantData /** Class that represents the state of the charging station at a given point diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala deleted file mode 100644 index b0e21a468b..0000000000 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/SchedulingTimeWindows.scala +++ /dev/null @@ -1,79 +0,0 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.evcs - -import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.util.quantities.interfaces.EnergyPrice -import tech.units.indriya.ComparableQuantity - -import javax.measure.quantity.Dimensionless - -object SchedulingTimeWindows { - - /** Time window used for the scheduling of ev charging. */ - trait SchedulingTimeWindow { - val start: Long - val end: Long - - /** @return - * Length of the window in seconds - */ - def length: Long = end - start + 1 - } - - /** Time window used for the scheduling of ev charging. Additional information - * on the voltages in the time window. - * - * @param start - * start of time window - * @param end - * end of time window - * @param voltage - * predicted voltage in this time window - * @param voltageDeviation - * deviation from reference voltage in the schedule time - * @param size - * size of the time window expressed as voltage deviation * length - * @param parkedEvs - * still parked ev in this time window - */ - case class SchedulingTimeWindowWithVoltage( - override val start: Long, - override val end: Long, - voltage: ComparableQuantity[Dimensionless], - voltageDeviation: ComparableQuantity[Dimensionless], - size: Double, - parkedEvs: Set[EvModel] - ) extends SchedulingTimeWindow { - override def toString: String = - s"SchedulingTimeWindow(start=$start, end=$end, voltage=$voltage, voltageDeviation=$voltageDeviation, " + - s"timeBoxLength=$length, timeBoxSize=$size, parkedEvs=${parkedEvs - .foldLeft(Set.empty[String])((names: Set[String], ev: EvModel) => { - names + ev.getId - })})" - } - - /** Time window used for the scheduling of ev charging. Additional information - * on the voltages in the time window. - * - * @param start - * start of time window - * @param end - * end of time window - * @param price - * predicted price in this time window - */ - case class SchedulingSliceWithPrice( - start: Long, - end: Long, - price: ComparableQuantity[EnergyPrice] - ) extends SchedulingTimeWindow { - override def toString: String = - s"SchedulingTimeWindow(start=$start, end=$end, price=$price, timeBoxLength=$length)" - } - -} diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index 6bdba6e8c4..87063f1a18 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -46,7 +46,6 @@ object ExtEvDataService { uuidToActorRef: Map[UUID, ActorRef] = Map.empty[UUID, ActorRef], extEvMessage: Option[EvDataMessageFromExt] = None, freeLots: ReceiveDataMap[UUID, Int] = ReceiveDataMap.empty, - currentPrices: ReceiveDataMap[UUID, Double] = ReceiveDataMap.empty, departingEvResponses: ReceiveDataMap[UUID, Seq[EvModelWrapper]] = ReceiveDataMap.empty ) extends ServiceBaseStateData diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 0839479be4..b1eddfd271 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -63,8 +63,7 @@ class EvcsModelSpec val actualSchedule = evcsModel.calculateNewScheduling( EvcsRelevantData( 3600L, - Seq.empty, - Map.empty // should be irrelevant + Seq.empty ), Set(evModel) ) @@ -98,8 +97,7 @@ class EvcsModelSpec val actualSchedule = evcsModel.calculateNewScheduling( EvcsRelevantData( 3600L, - Seq.empty, - Map.empty // should be irrelevant + Seq.empty ), Set(evModel) ) @@ -510,8 +508,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty, - Map.empty + Seq.empty ) val cases = Table( @@ -653,8 +650,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty, - Map.empty + Seq.empty ) val ev1 = EvModelWrapper( @@ -701,8 +697,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty, - Map.empty + Seq.empty ) val cases = Table( From 671dd324480a997407435c5b77fb375ccae448b6 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 17:12:21 +0100 Subject: [PATCH 139/305] Little bit of cleanup --- .../simona/model/participant/evcs/ChargingSchedule.scala | 2 +- .../edu/ie3/simona/model/participant/evcs/EvcsModel.scala | 4 +--- .../model/thermal/CylindricalThermalStorageTest.groovy | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala index 33a645970c..fb930cf3df 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala @@ -18,7 +18,7 @@ import scala.collection.immutable.{SortedSet, TreeSet} * @param schedule * Actual schedule */ -final case class ChargingSchedule(ev: UUID, schedule: SortedSet[Entry]) {} +final case class ChargingSchedule(ev: UUID, schedule: SortedSet[Entry]) object ChargingSchedule { def apply(ev: EvModelWrapper, entries: Seq[Entry]) = diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index ec45ba23cf..38d87cde15 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -91,7 +91,7 @@ final case class EvcsModel( operationInterval, scalingFactor, qControl, - (sRated * chargingPoints), + sRated * chargingPoints, cosPhiRated ) with LazyLogging @@ -946,8 +946,6 @@ object EvcsModel { * The current tick * @param arrivals * The evs arriving at the current tick - * @param voltages - * Nodal voltage per known time instant */ final case class EvcsRelevantData( tick: Long, diff --git a/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy b/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy index b3c17eb4e0..af5ffef8e5 100644 --- a/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/thermal/CylindricalThermalStorageTest.groovy @@ -6,6 +6,9 @@ package edu.ie3.simona.model.thermal +import static edu.ie3.util.quantities.PowerSystemUnits.KILOWATTHOUR +import static tech.units.indriya.quantity.Quantities.getQuantity + import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.util.scala.quantities.KilowattHoursPerKelvinCubicMeters$ @@ -17,9 +20,6 @@ import squants.energy.Kilowatts$ import squants.space.CubicMeters$ import squants.thermal.Celsius$ -import static edu.ie3.util.quantities.PowerSystemUnits.KILOWATTHOUR -import static tech.units.indriya.quantity.Quantities.getQuantity - class CylindricalThermalStorageTest extends Specification { static final double TESTING_TOLERANCE = 1e-10 From 9b711652553126fe00f335555576d453258fc57b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 17:32:39 +0100 Subject: [PATCH 140/305] Solving todo: Preferred charging considered --- .../model/participant/evcs/EvcsModel.scala | 88 ++++++++++--------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 38d87cde15..9938e5e467 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -543,52 +543,54 @@ final case class EvcsModel( val preferredScheduling = calculateNewScheduling(data, currentEvs) - val preferredPower = - preferredScheduling.values.flatten.foldLeft(Kilowatts(0d)) { - case (sum, ChargingSchedule(_, schedule)) => - val power = - schedule - .find { case ChargingSchedule.Entry(tickStart, tickStop, _) => - tickStart <= data.tick && tickStop > data.tick - } - .map(_.chargingPower) - .getOrElse(Kilowatts(0d)) - sum + power - } - - val (maxCharging, forcedCharging, maxDischarging) = + val (maxCharging, preferredPower, forcedCharging, maxDischarging) = preferredScheduling.foldLeft( - (Kilowatts(0d), Kilowatts(0d), Kilowatts(0d)) - ) { case ((chargingSum, forcedSum, dischargingSum), (ev, _)) => - val maxPower = getMaxAvailableChargingPower(ev) - - val maxCharging = - if (!isFull(ev)) - maxPower - else - Kilowatts(0d) - - val forcedCharging = - if (isEmpty(ev) && !isInLowerMargin(ev)) - maxPower // TODO maybe use preferred power instead - else - Kilowatts(0d) - - val maxDischarging = - if (!isEmpty(ev) && vehicle2grid) - maxPower * -1 - else - Kilowatts(0d) - - ( - chargingSum + maxCharging, - forcedSum + forcedCharging, - dischargingSum + maxDischarging - ) + (Kilowatts(0d), Kilowatts(0d), Kilowatts(0d), Kilowatts(0d)) + ) { + case ( + (chargingSum, preferredSum, forcedSum, dischargingSum), + (ev, optChargingSchedule) + ) => + val maxPower = getMaxAvailableChargingPower(ev) + + val preferred = optChargingSchedule + .flatMap { case ChargingSchedule(_, schedule) => + schedule + .find { case ChargingSchedule.Entry(tickStart, tickStop, _) => + tickStart <= data.tick && tickStop > data.tick + } + .map(_.chargingPower) + } + .getOrElse(Kilowatts(0d)) + + val maxCharging = + if (!isFull(ev)) + maxPower + else + Kilowatts(0d) + + val forced = + if (isEmpty(ev) && !isInLowerMargin(ev)) + preferred + else + Kilowatts(0d) + + val maxDischarging = + if (!isEmpty(ev) && vehicle2grid) + maxPower * -1 + else + Kilowatts(0d) + + ( + chargingSum + maxCharging, + preferredSum + preferred, + forcedSum + forced, + dischargingSum + maxDischarging + ) } // if we need to charge at least one EV, we cannot discharge any other - val (adaptedMin, adaptedPreferred) = + val (adaptedMaxDischarging, adaptedPreferred) = if (forcedCharging > Kilowatts(0d)) (forcedCharging, preferredPower.max(forcedCharging)) else @@ -597,7 +599,7 @@ final case class EvcsModel( ProvideMinMaxFlexOptions( uuid, adaptedPreferred, - adaptedMin, + adaptedMaxDischarging, maxCharging ) } From fe2fd1953f970b41cac750f4a8da51a18ed684b3 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 17:32:58 +0100 Subject: [PATCH 141/305] Replaced ??? --- .../edu/ie3/simona/model/participant/evcs/EvcsModel.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 9938e5e467..71d346e37f 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -517,7 +517,8 @@ final case class EvcsModel( voltage: squants.Dimensionless, modelState: EvcsState, data: EvcsRelevantData - ): ApparentPower = ??? + ): ApparentPower = + throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") /** Calculate the active power behaviour of the model * From 4c537750c20133df567b0ff6164af31a01b23758 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 25 Jan 2024 17:37:10 +0100 Subject: [PATCH 142/305] Squants cleanup --- .../model/participant/evcs/EvcsModel.scala | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 71d346e37f..ca7529c078 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -34,14 +34,15 @@ import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.OperationInterval -import squants.energy +import squants.{Dimensionless, Power, Energy} +import squants.time.Seconds import squants.energy.{KilowattHours, Kilowatts} import tech.units.indriya.ComparableQuantity import tech.units.indriya.unit.Units.PERCENT import java.time.ZonedDateTime import java.util.UUID -import javax.measure.quantity.Power +import javax.measure import scala.collection.SortedMap import scala.collection.immutable.SortedSet @@ -77,7 +78,7 @@ final case class EvcsModel( scalingFactor: Double, simulationStartDate: ZonedDateTime, qControl: QControl, - sRated: energy.Power, + sRated: Power, currentType: ElectricCurrentType, cosPhiRated: Double, chargingPoints: Int, @@ -248,7 +249,7 @@ final case class EvcsModel( def createResults( lastState: EvcsState, currentTick: Long, - voltageMagnitude: squants.Dimensionless + voltageMagnitude: Dimensionless ): (Iterable[EvResult], Iterable[EvcsResult]) = { val lastTick = lastState.tick @@ -420,8 +421,8 @@ final case class EvcsModel( private def createEvResult( ev: EvModelWrapper, tick: Long, - p: squants.Power, - voltageMagnitude: squants.Dimensionless + p: Power, + voltageMagnitude: Dimensionless ) = { val q = calculateReactivePower( p, @@ -473,8 +474,8 @@ final case class EvcsModel( */ private def chargedEnergyInScheduleEntry( scheduleEntry: ChargingSchedule.Entry - ): squants.Energy = - scheduleEntry.chargingPower * squants.time.Seconds( + ): Energy = + scheduleEntry.chargingPower * Seconds( scheduleEntry.tickStop - scheduleEntry.tickStart ) @@ -488,7 +489,7 @@ final case class EvcsModel( */ def getMaxAvailableChargingPower( ev: EvModelWrapper - ): squants.Power = { + ): Power = { val evPower = currentType match { case ElectricCurrentType.AC => ev.sRatedAc @@ -514,7 +515,7 @@ final case class EvcsModel( */ override def calculatePower( tick: Long, - voltage: squants.Dimensionless, + voltage: Dimensionless, modelState: EvcsState, data: EvcsRelevantData ): ApparentPower = @@ -532,7 +533,7 @@ final case class EvcsModel( override protected def calculateActivePower( modelState: EvcsState, data: EvcsRelevantData - ): squants.Power = + ): Power = throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") override def determineFlexOptions( @@ -610,7 +611,7 @@ final case class EvcsModel( override def handleControlledPowerChange( data: EvcsRelevantData, lastState: EvcsState, - setPower: squants.Power + setPower: Power ): (EvcsState, FlexChangeIndicator) = { val currentEvs = determineCurrentState(data, lastState) @@ -695,10 +696,10 @@ final case class EvcsModel( private def createScheduleWithSetPower( currentTick: Long, evs: Set[EvModelWrapper], - setPower: squants.Power + setPower: Power ): ( Set[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])], - squants.Power + Power ) = { if (evs.isEmpty) return (Set.empty, setPower) @@ -793,7 +794,7 @@ final case class EvcsModel( private def calculateChargingDuration( ev: EvModelWrapper, - power: squants.Power + power: Power ): Long = { val timeUntilFullOrEmpty = if (power > Kilowatts(0d)) { @@ -849,8 +850,8 @@ final case class EvcsModel( ) } - private def calcToleranceMargin(ev: EvModelWrapper): squants.Energy = - getMaxAvailableChargingPower(ev) * squants.time.Seconds(1) + private def calcToleranceMargin(ev: EvModelWrapper): Energy = + getMaxAvailableChargingPower(ev) * Seconds(1) /** Determines the current state of staying and arriving EVs. * @@ -1042,7 +1043,7 @@ object EvcsModel { scalingFactor: Double, simulationStartDate: ZonedDateTime, qControl: QControl, - sRated: ComparableQuantity[Power], + sRated: ComparableQuantity[measure.quantity.Power], currentType: ElectricCurrentType, cosPhiRated: Double, chargingPoints: Int, @@ -1058,7 +1059,7 @@ object EvcsModel { scalingFactor, simulationStartDate, qControl, - energy.Kilowatts(sRated.to(KILOWATT).getValue.doubleValue), + Kilowatts(sRated.to(KILOWATT).getValue.doubleValue), currentType, cosPhiRated, chargingPoints, From 498b9537b288c0f8e53fde285f500f9adf70d7b1 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 11:05:06 +0100 Subject: [PATCH 143/305] Commentary for result creation --- .../model/participant/evcs/EvcsModel.scala | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index ca7529c078..b612bf3c57 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -246,6 +246,21 @@ final case class EvcsModel( ) } + /** Create [[EvResult]]s and [[EvcsResult]]s for all EVs that have been + * connected to this charging station for some time in the time interval from + * (and including) the last tick to (and excluding) the current tick. + * + * As an exception to the rule, for EVs that are departing at current tick, + * an [[EvResult]] with 0 kW starting at current tick is created. + * @param lastState + * The last EVCS state + * @param currentTick + * The current tick + * @param voltageMagnitude + * The voltage magnitude used for reactive power calulation + * @return + * EV and EVCS results + */ def createResults( lastState: EvcsState, currentTick: Long, @@ -277,7 +292,7 @@ final case class EvcsModel( val entriesByStartTick = prefilteredSchedules .flatMap { case ChargingSchedule(evUuid, schedule) => - schedule.unsorted + schedule.unsorted // unsorted for speedier execution .map { entry => // trim down entries to the currently considered window of the charging schedule evUuid -> trimScheduleEntry( @@ -322,14 +337,19 @@ final case class EvcsModel( ) { case ((evMap, lastActiveEntries, evResults, evcsResults), tick) => val time = tick.toDateTime(simulationStartDate) + // separate into those entries that are still active + // and those that have ended before or at tick val (stillActive, endedEntries) = lastActiveEntries.partition { case (_, entry) => entry.tickStop > tick } - + // entries that become active with tick val newActiveEntries = entriesByStartTick.getOrElse(tick, Iterable.empty).toMap + // for those entries that ended with tick and that + // do not have a directly connected entry after that, + // add 0 kW entries val noChargingEvResults = endedEntries .filterNot { case evUuid -> _ => @@ -346,6 +366,8 @@ final case class EvcsModel( ) } + // create result and update EVs with the + // newly active entries val (updatedEvMap, chargingEvResults) = newActiveEntries.foldLeft(evMap, Seq.empty[EvResult]) { case ((evMap, results), evUuid -> entry) => @@ -371,16 +393,15 @@ final case class EvcsModel( val currentActiveEntries = stillActive ++ newActiveEntries + // create the EVCS result with all currently active entries val evcsP = currentActiveEntries.foldLeft(Kilowatts(0d)) { case (powerSum, _ -> entry) => powerSum + entry.chargingPower } - val evcsQ = calculateReactivePower( evcsP, voltageMagnitude ) - val evcsResult = new EvcsResult( time, uuid, From d848869f83fc0f636a47b26c63dfda649fdcf894 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 16:41:32 +0100 Subject: [PATCH 144/305] Better implementation and enhanced tests for flex calculation --- .../model/participant/evcs/EvcsModel.scala | 5 +- .../participant/evcs/EvcsModelSpec.scala | 191 ++++++++++++++++-- 2 files changed, 173 insertions(+), 23 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index b612bf3c57..09f7cb0872 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -584,7 +584,6 @@ final case class EvcsModel( } .map(_.chargingPower) } - .getOrElse(Kilowatts(0d)) val maxCharging = if (!isFull(ev)) @@ -594,7 +593,7 @@ final case class EvcsModel( val forced = if (isEmpty(ev) && !isInLowerMargin(ev)) - preferred + preferred.getOrElse(maxPower) else Kilowatts(0d) @@ -606,7 +605,7 @@ final case class EvcsModel( ( chargingSum + maxCharging, - preferredSum + preferred, + preferredSum + preferred.getOrElse(Kilowatts(0d)), forcedSum + forced, dischargingSum + maxDischarging ) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index b1eddfd271..0943ec8a9a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -499,11 +499,12 @@ class EvcsModelSpec } - "handle flexibility correctly" when { - val evcsModel = - evcsStandardModel.copy(strategy = ChargingStrategy.CONSTANT_POWER) + "calculate flex options correctly" when { + + "charging with constant power and allowing v2g" in { + val evcsModel = + evcsStandardModel.copy(strategy = ChargingStrategy.CONSTANT_POWER) - "calculate flex options for two evs correctly" in { val currentTick = 7200L val data = EvcsRelevantData( @@ -526,13 +527,13 @@ class EvcsModelSpec (0.0, 0.0, 0.0, 15.0, 15.0, 15.0), // 2: at lower margin (0.0, 3.0, 0.0, 15.0, 10.0, 15.0), - // 2: mid-way full (charged to 7.5 kWh) - (0.0, 0.0, 5.0, 15.0, 10.0, 15.0), - // 2: mid-way full (set to 7.5 kWh) - (0.0, 7.5, 0.0, 15.0, 10.0, 15.0), - // 2: almost full (12.5 kWh) - (0.0, 5.0, 5.0, 12.5, 10.0, 15.0), - // 2: full (set) + // 2: mid-way full (charged to 7.5 kWh), forced charging + (0.0, 0.0, 5.0, 13.75, 10.0, 15.0), + // 2: mid-way full (set to 7.5 kWh), forced charging + (0.0, 7.5, 0.0, 13.75, 10.0, 15.0), + // 2: almost full (12.5 kWh), forced charging + (0.0, 5.0, 5.0, 11.25, 10.0, 15.0), + // 2: full (set), forced charging (0.0, 15.0, 0.0, 10.0, 10.0, 10.0), /* 1: at lower margin (set to 2 kWh) */ @@ -541,35 +542,179 @@ class EvcsModelSpec // 2: at lower margin (2.0, 3.0, 0.0, 13.0, 0.0, 15.0), // 2: mid-way full (charged to 7.5 kWh) - (2.0, 0.0, 5.0, 13.0, -5.0, 15.0), + (2.0, 0.0, 5.0, 11.75, -5.0, 15.0), // 2: mid-way full (set to 7.5 kWh) - (2.0, 7.5, 0.0, 13.0, -5.0, 15.0), + (2.0, 7.5, 0.0, 11.75, -5.0, 15.0), // 2: almost full (12.5 kWh) - (2.0, 5.0, 5.0, 10.5, -5.0, 15.0), + (2.0, 5.0, 5.0, 9.25, -5.0, 15.0), // 2: full (set) (2.0, 15.0, 0.0, 8.0, -5.0, 10.0), /* 1: mid-way full (set to 5 kWh) */ - // 2: empty + // 2: empty, forced charging (5.0, 0.0, 0.0, 10.0, 5.0, 15.0), // 2: mid-way full (charged to 7.5 kWh) - (5.0, 0.0, 5.0, 10.0, -15.0, 15.0), + (5.0, 0.0, 5.0, 8.75, -15.0, 15.0), // 2: mid-way full (set to 7.5 kWh) - (5.0, 7.5, 0.0, 10.0, -15.0, 15.0), + (5.0, 7.5, 0.0, 8.75, -15.0, 15.0), // 2: almost full (12.5 kWh) - (5.0, 5.0, 5.0, 7.5, -15.0, 15.0), + (5.0, 5.0, 5.0, 6.25, -15.0, 15.0), // 2: full (set) (5.0, 15.0, 0.0, 5.0, -15.0, 10.0), /* 1: full (set to 10 kWh) */ + // 2: empty, forced charging + (10.0, 0.0, 0.0, 5.0, 5.0, 5.0), + // 2: mid-way full (charged to 7.5 kWh) + (10.0, 0.0, 5.0, 3.75, -15.0, 5.0), + // 2: mid-way full (set to 7.5 kWh) + (10.0, 7.5, 0.0, 3.75, -15.0, 5.0), + // 2: almost full (12.5 kWh) + (10.0, 5.0, 5.0, 1.25, -15.0, 5.0), + // 2: full (set) + (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) + ) + + forAll(cases) { + ( + lastStored1, + lastStored2, + lastPower2, + expectedPRef, + expectedPMin, + expectedPMax + ) => + // stays one more hour + val ev1 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 1", + 10.0.asKiloWatt, // AC is relevant, + 20.0.asKiloWatt, // DC is not + 10.0.asKiloWattHour, + lastStored1.asKiloWattHour, + 10800L + ) + ) + + // has not been charging before + val schedule1 = ChargingSchedule( + ev1, + Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(0d))) + ) + + // stays two more hours + val ev2 = EvModelWrapper( + new MockEvModel( + UUID.randomUUID(), + "Mock EV 2", + 5.0.asKiloWatt, // AC is relevant, + 10.0.asKiloWatt, // DC is not + 15.0.asKiloWattHour, + lastStored2.asKiloWattHour, + 14400L + ) + ) + + // has been charging for 1.5 hours with given power + val schedule2 = ChargingSchedule( + ev1, + Seq(ChargingSchedule.Entry(0L, 5400L, Kilowatts(lastPower2))) + ) + + evcsModel.determineFlexOptions( + data, + EvcsState( + Set(ev1, ev2), + Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + 0L + ) + ) match { + case ProvideMinMaxFlexOptions( + modelUuid, + refPower, + minPower, + maxPower + ) => + modelUuid shouldBe evcsModel.getUuid + (refPower ~= Kilowatts(expectedPRef)) shouldBe true + (minPower ~= Kilowatts(expectedPMin)) shouldBe true + (maxPower ~= Kilowatts(expectedPMax)) shouldBe true + } + } + + } + + "charging with maximum power and allowing v2g" in { + val evcsModel = + evcsStandardModel.copy(strategy = ChargingStrategy.MAX_POWER) + + val currentTick = 7200L + + val data = EvcsRelevantData( + currentTick, + Seq.empty + ) + + val cases = Table( + ( + "lastStored1", + "lastStored2", + "lastPower2", + "expectedPRef", + "expectedPMin", + "expectedPMax" + ), + + /* 1: empty */ // 2: empty + (0.0, 0.0, 0.0, 15.0, 15.0, 15.0), + // 2: at lower margin + (0.0, 3.0, 0.0, 15.0, 10.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh), forced charging + (0.0, 0.0, 5.0, 15.0, 10.0, 15.0), + // 2: mid-way full (set to 7.5 kWh), forced charging + (0.0, 7.5, 0.0, 15.0, 10.0, 15.0), + // 2: almost full (12.5 kWh), forced charging + (0.0, 5.0, 5.0, 15.0, 10.0, 15.0), + // 2: full (set) + (0.0, 15.0, 0.0, 10.0, 10.0, 10.0), + + /* 1: at lower margin (set to 2 kWh) */ + // 2: empty + (2.0, 0.0, 0.0, 15.0, 5.0, 15.0), + // 2: at lower margin + (2.0, 3.0, 0.0, 15.0, 0.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh) + (2.0, 0.0, 5.0, 15.0, -5.0, 15.0), + // 2: mid-way full (set to 7.5 kWh) + (2.0, 7.5, 0.0, 15.0, -5.0, 15.0), + // 2: almost full (12.5 kWh) + (2.0, 5.0, 5.0, 15.0, -5.0, 15.0), + // 2: full (set) + (2.0, 15.0, 0.0, 10.0, -5.0, 10.0), + + /* 1: mid-way full (set to 5 kWh) */ + // 2: empty, forced charging + (5.0, 0.0, 0.0, 15.0, 5.0, 15.0), + // 2: mid-way full (charged to 7.5 kWh) + (5.0, 0.0, 5.0, 15.0, -15.0, 15.0), + // 2: mid-way full (set to 7.5 kWh) + (5.0, 7.5, 0.0, 15.0, -15.0, 15.0), + // 2: almost full (12.5 kWh) + (5.0, 5.0, 5.0, 15.0, -15.0, 15.0), + // 2: full (set) + (5.0, 15.0, 0.0, 10.0, -15.0, 10.0), + + /* 1: full (set to 10 kWh) */ + // 2: empty, forced charging (10.0, 0.0, 0.0, 5.0, 5.0, 5.0), // 2: mid-way full (charged to 7.5 kWh) (10.0, 0.0, 5.0, 5.0, -15.0, 5.0), // 2: mid-way full (set to 7.5 kWh) (10.0, 7.5, 0.0, 5.0, -15.0, 5.0), // 2: almost full (12.5 kWh) - (10.0, 5.0, 5.0, 2.5, -15.0, 5.0), + (10.0, 5.0, 5.0, 5.0, -15.0, 5.0), // 2: full (set) (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) ) @@ -640,7 +785,7 @@ class EvcsModelSpec } - "calculate flex options for an evcs without vehicle2grid correctly" in { + "disallowing v2g" in { val evcsModel = evcsStandardModel.copy( vehicle2grid = false, strategy = ChargingStrategy.CONSTANT_POWER @@ -692,6 +837,12 @@ class EvcsModelSpec } + } + + "handle flexibility correctly" when { + val evcsModel = + evcsStandardModel.copy(strategy = ChargingStrategy.CONSTANT_POWER) + "handle controlled power change for two evs correctly" in { val currentTick = 3600L From d10837fb485f63607210a23315ab090b0fef3280 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 17:18:32 +0100 Subject: [PATCH 145/305] Replacing sets with sequences for speedier execution --- .../evcs/EvcsAgentFundamentals.scala | 2 +- .../model/participant/evcs/EvcsModel.scala | 27 +++++++++---------- .../uncontrolled/ConstantPowerCharging.scala | 2 +- .../uncontrolled/MaximumPowerCharging.scala | 5 ++-- .../messages/services/EvMessage.scala | 2 +- .../simona/service/ev/ExtEvDataService.scala | 2 +- .../participant/evcs/EvcsModelSpec.scala | 20 +++++++------- .../ConstantPowerChargingSpec.scala | 6 ++--- .../MaximumPowerChargingSpec.scala | 6 ++--- .../service/ev/ExtEvDataServiceSpec.scala | 4 +-- 10 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 54123751fe..8adca6bf76 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -194,7 +194,7 @@ protected trait EvcsAgentFundamentals ] ): EvcsState = EvcsState( - Set.empty, + Seq.empty, Map.empty, SimonaConstants.FIRST_TICK_IN_SIMULATION ) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 09f7cb0872..373a99f452 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -110,7 +110,7 @@ final case class EvcsModel( */ def calculateNewScheduling( data: EvcsRelevantData, - evs: Set[EvModelWrapper] + evs: Seq[EvModelWrapper] ): Map[EvModelWrapper, Option[ChargingSchedule]] = { if ( locationType == EvcsLocationType.CHARGING_HUB_TOWN || locationType == EvcsLocationType.CHARGING_HUB_HIGHWAY @@ -142,7 +142,7 @@ final case class EvcsModel( private def scheduleByStrategy( strategy: ChargingStrategy.Value, currentTick: Long, - evs: Set[EvModelWrapper] + evs: Seq[EvModelWrapper] ): Map[EvModelWrapper, Option[ChargingSchedule]] = strategy match { case ChargingStrategy.MAX_POWER => chargeWithMaximumPower( @@ -177,7 +177,7 @@ final case class EvcsModel( def applySchedule( state: EvcsState, currentTick: Long - ): Set[EvModelWrapper] = if (state.schedule.nonEmpty) { + ): Seq[EvModelWrapper] = if (state.schedule.nonEmpty) { state.evs .map(ev => state @@ -660,7 +660,7 @@ final case class EvcsModel( isEmpty(ev) && !isInLowerMargin(ev) } else - (Set.empty[EvModelWrapper], applicableEvs) + (Seq.empty[EvModelWrapper], applicableEvs) val (forcedSchedules, remainingPower) = createScheduleWithSetPower(data.tick, forcedChargingEvs, setPower) @@ -691,7 +691,7 @@ final case class EvcsModel( ( EvcsState( - evs = allSchedules.keys.toSet, + evs = allSchedules.keys.toSeq, schedule = allSchedules, tick = data.tick ), @@ -715,14 +715,14 @@ final case class EvcsModel( */ private def createScheduleWithSetPower( currentTick: Long, - evs: Set[EvModelWrapper], + evs: Seq[EvModelWrapper], setPower: Power ): ( - Set[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])], + Seq[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])], Power ) = { - if (evs.isEmpty) return (Set.empty, setPower) + if (evs.isEmpty) return (Seq.empty, setPower) if (setPower.~=(Kilowatts(0d))(Kilowatts(1e-6))) { // No power left. Rest is not charging @@ -756,7 +756,7 @@ final case class EvcsModel( isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) ) ) - }: Set[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])] + }: Seq[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])] (results, Kilowatts(0d)) } else { @@ -886,8 +886,7 @@ final case class EvcsModel( def determineCurrentState( data: EvcsRelevantData, lastState: EvcsState - ): Set[EvModelWrapper] = { - // TODO use Seq instead of Set as return value + ): Seq[EvModelWrapper] = { // if last state is from before current tick, determine current state val currentEVs = @@ -914,7 +913,7 @@ final case class EvcsModel( * Departing EVs at the current tick */ def validateDepartures( - lastEvs: Set[EvModelWrapper], + lastEvs: Seq[EvModelWrapper], departures: Seq[UUID] ): Unit = { departures.foreach { ev => @@ -938,7 +937,7 @@ final case class EvcsModel( * max number of charging points available at this CS */ def validateArrivals( - lastEvs: Set[EvModelWrapper], + lastEvs: Seq[EvModelWrapper], arrivals: Seq[EvModelWrapper], chargingPoints: Int ): Unit = { @@ -987,7 +986,7 @@ object EvcsModel { * The tick that the data has been calculated for */ final case class EvcsState( - evs: Set[EvModelWrapper], + evs: Seq[EvModelWrapper], schedule: Map[EvModelWrapper, Option[ChargingSchedule]], tick: Long ) extends ModelState { diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala index 82fa7d6249..def36fbbcc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala @@ -31,7 +31,7 @@ trait ConstantPowerCharging { */ def chargeWithConstantPower( currentTick: Long, - evs: Set[EvModelWrapper] + evs: Seq[EvModelWrapper] ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => ev -> Option.when(ev.storedEnergy < ev.eStorage) { val maxChargingPower = getMaxAvailableChargingPower(ev) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala index d068f0b7ba..372f2658bf 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala @@ -12,6 +12,7 @@ import edu.ie3.simona.model.participant.evcs.{ EvModelWrapper, EvcsModel } +import squants.Seconds trait MaximumPowerCharging { this: EvcsModel => @@ -30,12 +31,12 @@ trait MaximumPowerCharging { */ def chargeWithMaximumPower( currentTick: Long, - evs: Set[EvModelWrapper] + evs: Seq[EvModelWrapper] ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => ev -> Option.when(ev.storedEnergy < ev.eStorage) { val chargingPower = getMaxAvailableChargingPower(ev) val remainingParkingTime = - squants.Seconds(ev.departureTick - currentTick) + Seconds(ev.departureTick - currentTick) val possibleChargeableEnergyUntilDeparture = chargingPower * remainingParkingTime diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala index ff485e5f99..404cf9e8aa 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala @@ -87,7 +87,7 @@ object EvMessage { final case class DepartingEvsResponse( evcs: UUID, - evModels: Set[EvModelWrapper] + evModels: Seq[EvModelWrapper] ) extends EvResponseMessage } diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index 87063f1a18..2ccb45197a 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -316,7 +316,7 @@ class ExtEvDataService(override val scheduler: ActorRef) extResponseMsg match { case DepartingEvsResponse(evcs, evModels) => val updatedResponses = - serviceStateData.departingEvResponses.addData(evcs, evModels.toList) + serviceStateData.departingEvResponses.addData(evcs, evModels) if (updatedResponses.nonComplete) { // responses are still incomplete diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 0943ec8a9a..7be1a97562 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -65,7 +65,7 @@ class EvcsModelSpec 3600L, Seq.empty ), - Set(evModel) + Seq(evModel) ) actualSchedule shouldBe Map( @@ -99,7 +99,7 @@ class EvcsModelSpec 3600L, Seq.empty ), - Set(evModel) + Seq(evModel) ) actualSchedule shouldBe Map( @@ -174,7 +174,7 @@ class EvcsModelSpec ) val state = EvcsState( - Set(ev), + Seq(ev), Map(ev -> Some(schedule)), lastCalcTick ) @@ -265,7 +265,7 @@ class EvcsModelSpec lastResultIndex ) => val lastState = EvcsState( - Set(ev), + Seq(ev), Map(ev -> Some(schedule)), lastTick ) @@ -349,7 +349,7 @@ class EvcsModelSpec val currentTick = 10800L val lastState = EvcsState( - Set(ev1, ev2), + Seq(ev1, ev2), Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), lastTick ) @@ -447,7 +447,7 @@ class EvcsModelSpec val currentTick = 7200L val lastState = EvcsState( - Set(ev), + Seq(ev), Map(ev -> Some(schedule)), lastTick ) @@ -625,7 +625,7 @@ class EvcsModelSpec evcsModel.determineFlexOptions( data, EvcsState( - Set(ev1, ev2), + Seq(ev1, ev2), Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), 0L ) @@ -765,7 +765,7 @@ class EvcsModelSpec evcsModel.determineFlexOptions( data, EvcsState( - Set(ev1, ev2), + Seq(ev1, ev2), Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), 0L ) @@ -818,7 +818,7 @@ class EvcsModelSpec evcsModel.determineFlexOptions( data, EvcsState( - Set(ev1), + Seq(ev1), Map(ev1 -> Some(schedule1)), 0L ) @@ -942,7 +942,7 @@ class EvcsModelSpec evcsModel.handleControlledPowerChange( data, EvcsState( - Set(ev1, ev2), + Seq(ev1, ev2), Map(ev1 -> None, ev2 -> None), 0L ), diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala index 08817297b6..5b87eb6566 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala @@ -39,7 +39,7 @@ class ConstantPowerChargingSpec val actualSchedule = evcsModel.chargeWithConstantPower( 1800L, - Set(ev) + Seq(ev) ) actualSchedule shouldBe Map( @@ -79,7 +79,7 @@ class ConstantPowerChargingSpec val chargingMap = evcsModel.chargeWithConstantPower( offset, - Set(ev) + Seq(ev) ) chargingMap shouldBe Map( @@ -144,7 +144,7 @@ class ConstantPowerChargingSpec val chargingMap = evcsModel.chargeWithConstantPower( offset, - Set(givenEv, ev) + Seq(givenEv, ev) ) chargingMap shouldBe Map( diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala index 89da615b19..5813056d41 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala @@ -39,7 +39,7 @@ class MaximumPowerChargingSpec val actualSchedule = evcsModel.chargeWithMaximumPower( 1800L, - Set(ev) + Seq(ev) ) actualSchedule shouldBe Map( @@ -77,7 +77,7 @@ class MaximumPowerChargingSpec val chargingMap = evcsModel.chargeWithMaximumPower( offset, - Set(ev) + Seq(ev) ) chargingMap shouldBe Map( @@ -140,7 +140,7 @@ class MaximumPowerChargingSpec val chargingMap = evcsModel.chargeWithMaximumPower( offset, - Set(givenEv, ev) + Seq(givenEv, ev) ) chargingMap shouldBe Map( diff --git a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala index 789666829e..5d91b272e0 100644 --- a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala @@ -397,7 +397,7 @@ class ExtEvDataServiceSpec evcs1.send( evService, - DepartingEvsResponse(evcs1UUID, Set(EvModelWrapper(updatedEvA))) + DepartingEvsResponse(evcs1UUID, Seq(EvModelWrapper(updatedEvA))) ) // nothing should happen yet, waiting for second departed ev @@ -409,7 +409,7 @@ class ExtEvDataServiceSpec evcs2.send( evService, - DepartingEvsResponse(evcs2UUID, Set(EvModelWrapper(updatedEvB))) + DepartingEvsResponse(evcs2UUID, Seq(EvModelWrapper(updatedEvB))) ) // ev service should recognize that all evs that are expected are returned, From 5ab305d97467ea93de0f873f9b3aa8bdfe36d11b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 17:22:25 +0100 Subject: [PATCH 146/305] Removing redundant todo --- .../simona/agent/participant/evcs/EvcsAgentFundamentals.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 8adca6bf76..4e2bd5379f 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -154,7 +154,7 @@ protected trait EvcsAgentFundamentals Map.empty, requestVoltageDeviationThreshold, ValueStore.forVoltage( - resolution, // FIXME probably need to increase this for grid oriented scheduling + resolution, Each( inputModel.electricalInputModel.getNode .getvTarget() From 258831e2da57523f4421f6beed4665712b211b96 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 17:32:02 +0100 Subject: [PATCH 147/305] Fixing EvcsModelSpec --- .../edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 7be1a97562..2ea7992ea8 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -953,7 +953,8 @@ class EvcsModelSpec FlexChangeIndicator(actualNextActivation, actualNextTick) ) => // evs have not changed here since no schedules were given as input - actualEvs shouldBe Set(ev1, ev2) + actualEvs should have size 2 + actualEvs should contain allOf (ev1, ev2) actualSchedules.getOrElse(ev1, None).map { case ChargingSchedule(_, entries) => From f1067dd6b65f587e6199d9b88984db2ee72a3a91 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 26 Jan 2024 17:50:45 +0100 Subject: [PATCH 148/305] Additional ExtEvDataService test --- .../service/ev/ExtEvDataServiceSpec.scala | 105 ++++++++++-------- 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala index 5d91b272e0..10a1be82c7 100644 --- a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala @@ -71,11 +71,7 @@ class ExtEvDataServiceSpec "An uninitialized ev movement service" must { "send correct completion message after initialisation" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val key = ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) @@ -94,11 +90,7 @@ class ExtEvDataServiceSpec } "stash registration request and handle it correctly once initialized" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val evcs1 = TestProbe("evcs1") @@ -128,13 +120,9 @@ class ExtEvDataServiceSpec } "An idle ev movements service" must { - // TODO enhance with tests for cases where no EVCS are applicable and answer is sent right away + "handle duplicate registrations correctly" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val key = ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) @@ -165,11 +153,7 @@ class ExtEvDataServiceSpec } "fail when activated without having received ExtEvMessage" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val key = ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) @@ -198,11 +182,7 @@ class ExtEvDataServiceSpec } "handle free lots requests correctly and forward them to the correct evcs" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val extData = extEvData(evService) @@ -274,7 +254,7 @@ class ExtEvDataServiceSpec ) // ev service should recognize that all evcs that are expected are returned, - // thus should send ProvidePublicEvcs + // thus should send ProvideEvcsFreeLots awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, @@ -288,11 +268,7 @@ class ExtEvDataServiceSpec } "return free lots requests right away if there are no evcs registered" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val extData = extEvData(evService) @@ -322,7 +298,7 @@ class ExtEvDataServiceSpec scheduler.expectMsg(Completion(evService.toTyped)) - // ev service should send ProvidePublicEvcs right away + // ev service should send ProvideEvcsFreeLots right away awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, @@ -333,11 +309,7 @@ class ExtEvDataServiceSpec } "handle ev departure requests correctly and return departed evs" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val extData = extEvData(evService) @@ -413,7 +385,7 @@ class ExtEvDataServiceSpec ) // ev service should recognize that all evs that are expected are returned, - // thus should send AllDepartedEvsResponse + // thus should send ProvideDepartingEvs awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, @@ -425,10 +397,53 @@ class ExtEvDataServiceSpec ) } - "handle ev arrivals correctly and forward them to the correct evcs" in { - val evService = TestActorRef( - new ExtEvDataService(scheduler.ref) + "return ev departure requests right away if request list is empty" in { + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) + + val extData = extEvData(evService) + + val key = + ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) + scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled + + scheduler.send( + evService, + SimonaService.Create(InitExtEvData(extData), key) ) + scheduler.expectMsgType[ScheduleActivation] + + scheduler.send(evService, Activation(INIT_SIM_TICK)) + scheduler.expectMsg(Completion(evService.toTyped)) + + extData.sendExtMsg( + new RequestDepartingEvs(Map.empty[UUID, java.util.List[UUID]].asJava) + ) + + // ev service should receive departure msg at this moment + // scheduler should receive schedule msg + extSimAdapter.expectMsg(new ScheduleDataServiceMessage(evService)) + + val tick = 0L + + // we trigger ev service + scheduler.send(evService, Activation(tick)) + + scheduler.expectMsg(Completion(evService.toTyped)) + + // ev service should send ProvideDepartingEvs right away + awaitCond( + !extData.receiveTriggerQueue.isEmpty, + max = 3.seconds, + message = "No message received" + ) + extData.receiveTriggerQueue.size() shouldBe 1 + extData.receiveTriggerQueue.take() shouldBe new ProvideDepartingEvs( + List.empty[EvModel].asJava + ) + } + + "handle ev arrivals correctly and forward them to the correct evcs" in { + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val extData = extEvData(evService) @@ -491,11 +506,7 @@ class ExtEvDataServiceSpec } "skip a movements provision from an evcs that is not registered" in { - val evService = TestActorRef( - new ExtEvDataService( - scheduler.ref - ) - ) + val evService = TestActorRef(new ExtEvDataService(scheduler.ref)) val extData = extEvData(evService) From 82e108cfd1b171e45e6996bfaabc95b0ae93ca37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 09:11:21 +0000 Subject: [PATCH 149/305] Bump pekkoVersion from 1.0.1 to 1.0.2 (#716) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 157c5d3dd5..8790cd28bf 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ ext { scalaVersion = '2.13' scalaBinaryVersion = '2.13.12' - pekkoVersion = '1.0.1' + pekkoVersion = '1.0.2' jtsVersion = '1.19.0' confluentKafkaVersion = '7.4.0' tscfgVersion = '1.0.2' From aa7e648dacfecf4f0dc14a75feb689a8d7f91ecc Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 29 Jan 2024 11:59:50 +0100 Subject: [PATCH 150/305] Renamed schedule entries field Added more explanatory commentary --- .../evcs/EvcsAgentFundamentals.scala | 9 ++++---- .../participant/evcs/ChargingSchedule.scala | 6 ++--- .../model/participant/evcs/EvcsModel.scala | 22 +++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 4e2bd5379f..9724da98d4 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -447,10 +447,11 @@ protected trait EvcsAgentFundamentals case (ev, maybeSchedule) if !requestedDepartingEvs.contains(ev.uuid) => Some( ev -> maybeSchedule.map(scheduleContainer => - scheduleContainer.copy(schedule = - scheduleContainer.schedule.filter(_.tickStop >= tick) - // filter(_.tickStop > currentTick) - // TODO is it possible to remove also the schedules that ended at currentTick? -> probably yes, test required + scheduleContainer.copy(entries = + // Remove schedules that ended before or at current tick. + // Schedule entries ending at current tick do not have any + // impact on the schedule from the current tick on + scheduleContainer.entries.filter(_.tickStop > tick) ) ) ) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala index fb930cf3df..74b25cdc9b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala @@ -15,10 +15,10 @@ import scala.collection.immutable.{SortedSet, TreeSet} * * @param ev * Unique identifier of the car - * @param schedule - * Actual schedule + * @param entries + * Actual charging schedule entries */ -final case class ChargingSchedule(ev: UUID, schedule: SortedSet[Entry]) +final case class ChargingSchedule(ev: UUID, entries: SortedSet[Entry]) object ChargingSchedule { def apply(ev: EvModelWrapper, entries: Seq[Entry]) = diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 373a99f452..d5ecd8fbb8 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -221,7 +221,7 @@ final case class EvcsModel( ): EvModelWrapper = { /* Determine charged energy in the charging interval */ val chargedEnergySinceLastScheduling = - schedule.schedule.toSeq + schedule.entries.toSeq .filter { case ChargingSchedule.Entry(tickStart, tickStop, _) => /* Filter for entries, that end after the last schedule application (that slice is not yet fully applied) * and that start before the current tick */ @@ -248,7 +248,9 @@ final case class EvcsModel( /** Create [[EvResult]]s and [[EvcsResult]]s for all EVs that have been * connected to this charging station for some time in the time interval from - * (and including) the last tick to (and excluding) the current tick. + * (and including) the last tick to (but excluding) the current tick. + * Schedule entries that start at current tick are excluded, but will be + * considered in the next interval. * * As an exception to the rule, for EVs that are departing at current tick, * an [[EvResult]] with 0 kW starting at current tick is created. @@ -285,14 +287,12 @@ final case class EvcsModel( tickStop > lastTick && tickStart < currentTick } - schedule.copy( - schedule = filteredEntries - ) + schedule.copy(entries = filteredEntries) } val entriesByStartTick = prefilteredSchedules - .flatMap { case ChargingSchedule(evUuid, schedule) => - schedule.unsorted // unsorted for speedier execution + .flatMap { case ChargingSchedule(evUuid, entries) => + entries.unsorted // unsorted for speedier execution .map { entry => // trim down entries to the currently considered window of the charging schedule evUuid -> trimScheduleEntry( @@ -308,8 +308,8 @@ final case class EvcsModel( .to(SortedMap) val startAndStopTicks = prefilteredSchedules - .flatMap { case ChargingSchedule(_, schedule) => - schedule.unsorted.flatMap { + .flatMap { case ChargingSchedule(_, entries) => + entries.unsorted.flatMap { case ChargingSchedule.Entry(start, stop, _) => Iterable(start, stop) } @@ -577,8 +577,8 @@ final case class EvcsModel( val maxPower = getMaxAvailableChargingPower(ev) val preferred = optChargingSchedule - .flatMap { case ChargingSchedule(_, schedule) => - schedule + .flatMap { case ChargingSchedule(_, entries) => + entries .find { case ChargingSchedule.Entry(tickStart, tickStop, _) => tickStart <= data.tick && tickStop > data.tick } From 3708d13ccd6c9533602abfd567ad96f08244e148 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 29 Jan 2024 13:32:41 +0100 Subject: [PATCH 151/305] Some refactorings and ScalaDoc --- .../ParticipantAgentFundamentals.scala | 2 +- .../evcs/EvcsAgentFundamentals.scala | 56 +++++++++---------- .../model/participant/evcs/EvcsModel.scala | 9 +-- .../EvcsAgentModelCalculationSpec.scala | 3 + 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala index 5627047aea..8afd11c7a8 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala @@ -1097,7 +1097,7 @@ protected trait ParticipantAgentFundamentals[ false } - // Only after init: + // Only for completing initialization: // if we are EM-managed, there is no new tick for the // scheduler, since we are activated by the EmAgent from now on scheduler ! Completion( diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 9724da98d4..f28a971c88 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -214,8 +214,8 @@ protected trait EvcsAgentFundamentals .getOrElse(tick, Map.empty) .collectFirst { // filter secondary data for arriving EVs data - case (_, evcsData: ArrivingEvsData) => - evcsData.arrivals + case (_, arrivingEvsData: ArrivingEvsData) => + arrivingEvsData.arrivals } .getOrElse(Seq.empty) @@ -470,14 +470,13 @@ protected trait EvcsAgentFundamentals ) } - /** Handles a evcs movements message that contains information on arriving and - * departing vehicles. After applying the movements to the last known set of - * parked evs, returns departing evs and calculates new scheduling. Sends - * completion message to scheduler without scheduling new activations. FIXME - * scaladoc + /** Handles data message that contains information on arriving EVs. Updates + * already parked EVs (if applicable) and adds new arrivals. Also calculates + * new schedules for all staying and arriving EVs. Sends completion message + * to scheduler without scheduling new activations. * - * @param currentTick - * The current tick that has been triggered + * @param tick + * The current tick that data has arrived for * @param scheduler * The scheduler ref * @param modelBaseStateData @@ -486,7 +485,7 @@ protected trait EvcsAgentFundamentals * [[Idle]] with updated relevant data store */ private def handleArrivingEvsAndGoIdle( - currentTick: Long, + tick: Long, scheduler: ActorRef, modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, @@ -497,39 +496,36 @@ protected trait EvcsAgentFundamentals ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { val relevantData = - createCalcRelevantData(modelBaseStateData, currentTick) + createCalcRelevantData(modelBaseStateData, tick) - val lastState = getLastOrInitialStateData(modelBaseStateData, currentTick) + val lastState = getLastOrInitialStateData(modelBaseStateData, tick) - val currentEvs = modelBaseStateData.model.determineCurrentState( + val currentEvs = modelBaseStateData.model.determineCurrentEvs( relevantData, lastState ) // if new EVs arrived, a new scheduling must be calculated. - val newSchedule = modelBaseStateData.model - .calculateNewScheduling( - relevantData, - currentEvs - ) + val newSchedule = modelBaseStateData.model.calculateNewScheduling( + relevantData, + currentEvs + ) // create new current state - val newState = EvcsState(currentEvs, newSchedule, currentTick) + val newState = EvcsState(currentEvs, newSchedule, tick) - val updatedStateDataStore = - ValueStore.updateValueStore( - modelBaseStateData.stateDataStore, - currentTick, - newState - ) + val updatedStateDataStore = ValueStore.updateValueStore( + modelBaseStateData.stateDataStore, + tick, + newState + ) /* Update the base state data with the updated result value store and relevant data store */ - val updatedBaseStateData = - modelBaseStateData.copy( - stateDataStore = updatedStateDataStore - ) + val updatedBaseStateData = modelBaseStateData.copy( + stateDataStore = updatedStateDataStore + ) - // FIXME no completion anymore with flex + // We're only here if we're not flex-controlled, thus sending a Completion is always right goToIdleReplyCompletionAndScheduleTriggerForNextAction( updatedBaseStateData, scheduler diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index d5ecd8fbb8..8cbf70a3a5 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -562,7 +562,7 @@ final case class EvcsModel( lastState: EvcsState ): FlexibilityMessage.ProvideFlexOptions = { - val currentEvs = determineCurrentState(data, lastState) + val currentEvs = determineCurrentEvs(data, lastState) val preferredScheduling = calculateNewScheduling(data, currentEvs) @@ -633,7 +633,7 @@ final case class EvcsModel( lastState: EvcsState, setPower: Power ): (EvcsState, FlexChangeIndicator) = { - val currentEvs = determineCurrentState(data, lastState) + val currentEvs = determineCurrentEvs(data, lastState) if (setPower == Kilowatts(0d)) return ( @@ -883,12 +883,13 @@ final case class EvcsModel( * @return * The EVs currently parked at the EVCS, including the arriving EVs */ - def determineCurrentState( + def determineCurrentEvs( data: EvcsRelevantData, lastState: EvcsState ): Seq[EvModelWrapper] = { - // if last state is from before current tick, determine current state + // If last state is outdated, determine + // current state for already parked EVs val currentEVs = if (lastState.tick < data.tick) applySchedule(lastState, data.tick) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 65009a72e2..3bca1b8b1c 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -1921,6 +1921,9 @@ class EvcsAgentModelCalculationSpec requestAtTick shouldBe Some(72000) } + // expect no more messages after completion of initialization + scheduler.expectNoMessage() + } } From 37a34711dd73ba2f8a5dbce450307fdbfdf90284 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 29 Jan 2024 13:41:10 +0100 Subject: [PATCH 152/305] Minor cleanup --- .../participant/evcs/EvcsAgentFundamentals.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index f28a971c88..493c0f5bd6 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -210,7 +210,7 @@ protected trait EvcsAgentFundamentals ): EvcsRelevantData = { // always only take arrivals for the current tick // or empty sequence if none arrived - val movements = baseStateData.receivedSecondaryDataStore + val arrivingEvs = baseStateData.receivedSecondaryDataStore .getOrElse(tick, Map.empty) .collectFirst { // filter secondary data for arriving EVs data @@ -219,10 +219,11 @@ protected trait EvcsAgentFundamentals } .getOrElse(Seq.empty) - EvcsRelevantData(tick, movements) + EvcsRelevantData(tick, arrivingEvs) } /** Handle an active power change by flex control. + * * @param tick * Tick, in which control is issued * @param baseStateData @@ -297,7 +298,7 @@ protected trait EvcsAgentFundamentals * The base state data with collected secondary data * @param lastModelState * Last model state - * @param currentTick + * @param tick * Tick, the trigger belongs to * @param scheduler * [[ActorRef]] to the scheduler in the simulation @@ -312,18 +313,18 @@ protected trait EvcsAgentFundamentals EvcsModel ], lastModelState: EvcsState, - currentTick: Long, + tick: Long, scheduler: ActorRef ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { /* extract EV data from secondary data, which should have been requested and received before */ baseStateData.receivedSecondaryDataStore - .getOrElse(currentTick, Map.empty) + .getOrElse(tick, Map.empty) .values .collectFirst { // filter secondary data for arriving EVs data case _: ArrivingEvsData => handleArrivingEvsAndGoIdle( - currentTick, + tick, scheduler, baseStateData ) @@ -338,6 +339,7 @@ protected trait EvcsAgentFundamentals /** Returns the number of free parking lots based on the last available state * data. + * * @param tick * The tick that free lots have been requested for * @param modelBaseStateData From 8dcccf3dc5cb0184bc94bca91fb3e1b59f7278f9 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 29 Jan 2024 13:48:21 +0100 Subject: [PATCH 153/305] ScalaDoc --- .../participant/evcs/EvModelWrapper.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala index ee8a4b58c5..071a321557 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala @@ -13,6 +13,18 @@ import squants.energy.{KilowattHours, Kilowatts} import java.util.UUID +/** Wrapper for objects that extend [[EvModel]], which uses + * [[javax.measure.Quantity]]. Since operations on javax/indriya quantities are + * a bit slow, we lazily convert them to [[squants.Quantity]]. When + * "unwrapping", we store back the only value that can have changed (while + * considering immutability, i.e. when using [[copy]]), which is + * [[storedEnergy]]. + * + * @param storedEnergy + * Currently stored energy in the EV battery + * @param original + * The wrapped [[EvModel]] + */ case class EvModelWrapper( storedEnergy: squants.Energy, private val original: EvModel @@ -29,6 +41,12 @@ case class EvModelWrapper( ) def departureTick: Long = original.getDepartureTick + /** Unwrapping the original [[EvModel]] while also updating the + * [[storedEnergy]], which could have changed. + * + * @return + * The original [[EvModel]] with updated stored energy. + */ def unwrap(): EvModel = { original.copyWith( storedEnergy.toKilowattHours.asKiloWattHour From 11532660f0eae1e2305df7faaf37575bd4563f37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:28:22 +0000 Subject: [PATCH 154/305] Bump testContainerVersion from 0.41.0 to 0.41.2 (#717) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8790cd28bf..acac04204f 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ ext { tscfgVersion = '1.0.2' scapegoatVersion = '2.1.3' - testContainerVersion = '0.41.0' + testContainerVersion = '0.41.2' scriptsLocation = 'gradle' + File.separator + 'scripts' + File.separator // location of script plugins } From 43e06d099f1788374954e1dd10dd7ecb0b55b271 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 12:20:17 +0100 Subject: [PATCH 155/305] Improvements to how charging schedules are stored in EVCS state Also Refactorings, ScalaDoc --- .../evcs/EvcsAgentFundamentals.scala | 25 +- .../participant/evcs/ChargingSchedule.scala | 56 ---- .../model/participant/evcs/EvcsModel.scala | 291 ++++++++++-------- .../uncontrolled/ConstantPowerCharging.scala | 23 +- .../uncontrolled/MaximumPowerCharging.scala | 21 +- .../EvcsAgentModelCalculationSpec.scala | 56 ++-- .../participant/evcs/EvcsModelSpec.scala | 137 ++++----- .../ConstantPowerChargingSpec.scala | 53 ++-- .../MaximumPowerChargingSpec.scala | 53 ++-- 9 files changed, 318 insertions(+), 397 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 493c0f5bd6..de39424338 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -445,20 +445,17 @@ protected trait EvcsAgentFundamentals baseStateData ) - val stayingSchedules = lastState.schedule.flatMap { - case (ev, maybeSchedule) if !requestedDepartingEvs.contains(ev.uuid) => - Some( - ev -> maybeSchedule.map(scheduleContainer => - scheduleContainer.copy(entries = - // Remove schedules that ended before or at current tick. - // Schedule entries ending at current tick do not have any - // impact on the schedule from the current tick on - scheduleContainer.entries.filter(_.tickStop > tick) - ) - ) - ) - case _ => None - } + val stayingSchedules = + lastState.schedule + .filterNot(requestedDepartingEvs.contains) + .view + .mapValues { + // Remove schedules that ended before or at current tick. + // Schedule entries ending at current tick do not have any + // impact on the schedule from the current tick on + _.filter(_.tickStop > tick) + } + .toMap val newState = EvcsState(stayingEvs, stayingSchedules, tick) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala deleted file mode 100644 index 74b25cdc9b..0000000000 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/ChargingSchedule.scala +++ /dev/null @@ -1,56 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.evcs - -import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry - -import java.util.UUID -import scala.collection.immutable.{SortedSet, TreeSet} - -/** Charging schedule for an EV for several time intervals - * - * @param ev - * Unique identifier of the car - * @param entries - * Actual charging schedule entries - */ -final case class ChargingSchedule(ev: UUID, entries: SortedSet[Entry]) - -object ChargingSchedule { - def apply(ev: EvModelWrapper, entries: Seq[Entry]) = - new ChargingSchedule(ev.uuid, TreeSet.from(entries)) - - /** Schedule entry specifying a time interval in which the EV should be - * charged with some given power - * - * @param tickStart - * start of charging interval - * @param tickStop - * end of charging interval - * @param chargingPower - * charging power for the charging interval - */ - final case class Entry( - tickStart: Long, - tickStop: Long, - chargingPower: squants.Power - ) extends Ordered[Entry] { - override def compare(that: Entry): Int = { - val startComp = tickStart.compare(that.tickStart) - if (startComp != 0) - startComp - else { - // important for checking equality: consider other fields as well - val stopComp = tickStop.compare(that.tickStop) - if (stopComp != 0) - stopComp - else - chargingPower.compareTo(that.chargingPower) - } - } - } -} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 8cbf70a3a5..90450f9695 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -15,8 +15,11 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + ChargingSchedule, EvcsRelevantData, - EvcsState + EvcsState, + ScheduleEntry, + ScheduleMap } import edu.ie3.simona.model.participant.evcs.uncontrolled.{ ConstantPowerCharging, @@ -34,7 +37,7 @@ import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.OperationInterval -import squants.{Dimensionless, Power, Energy} +import squants.{Dimensionless, Energy, Power} import squants.time.Seconds import squants.energy.{KilowattHours, Kilowatts} import tech.units.indriya.ComparableQuantity @@ -106,12 +109,12 @@ final case class EvcsModel( * @param data * data including the current EVs parked at the charging station * @return - * scheduling for charging the EVs + * Charging schedule for charging given EVs */ def calculateNewScheduling( data: EvcsRelevantData, evs: Seq[EvModelWrapper] - ): Map[EvModelWrapper, Option[ChargingSchedule]] = { + ): ScheduleMap = { if ( locationType == EvcsLocationType.CHARGING_HUB_TOWN || locationType == EvcsLocationType.CHARGING_HUB_HIGHWAY ) { @@ -135,15 +138,15 @@ final case class EvcsModel( * @param currentTick * Current simulation time * @param evs - * Collection of currently apparent evs + * Collection of currently parked evs * @return - * A set of [[ChargingSchedule]]s + * Charging schedule for charging given EVs */ private def scheduleByStrategy( strategy: ChargingStrategy.Value, currentTick: Long, evs: Seq[EvModelWrapper] - ): Map[EvModelWrapper, Option[ChargingSchedule]] = strategy match { + ): ScheduleMap = strategy match { case ChargingStrategy.MAX_POWER => chargeWithMaximumPower( currentTick, @@ -180,8 +183,8 @@ final case class EvcsModel( ): Seq[EvModelWrapper] = if (state.schedule.nonEmpty) { state.evs .map(ev => - state - .getSchedule(ev) + state.schedule + .get(ev.uuid) .map { chargeEv( ev, @@ -221,8 +224,8 @@ final case class EvcsModel( ): EvModelWrapper = { /* Determine charged energy in the charging interval */ val chargedEnergySinceLastScheduling = - schedule.entries.toSeq - .filter { case ChargingSchedule.Entry(tickStart, tickStop, _) => + schedule.toSeq + .filter { case ScheduleEntry(tickStart, tickStop, _) => /* Filter for entries, that end after the last schedule application (that slice is not yet fully applied) * and that start before the current tick */ tickStop > lastSchedulingTick && tickStart < currentTick @@ -238,7 +241,7 @@ final case class EvcsModel( ) /* Determine the energy charged within this slice of the schedule and accumulate it */ - accumulatedEnergy + chargedEnergyInScheduleEntry(trimmedEntry) + accumulatedEnergy + calcChargedEnergy(trimmedEntry) } /* Update EV with the charged energy during the charging interval */ ev.copy( @@ -259,7 +262,7 @@ final case class EvcsModel( * @param currentTick * The current tick * @param voltageMagnitude - * The voltage magnitude used for reactive power calulation + * The voltage magnitude used for reactive power calculation * @return * EV and EVCS results */ @@ -273,59 +276,53 @@ final case class EvcsModel( val lastEvMap = lastState.evs.map(ev => ev.uuid -> ev).toMap - val prefilteredSchedules = lastState.schedule.values.flatten - .map { case schedule @ ChargingSchedule(_, entries) => - val filteredEntries = entries - .filter { case ChargingSchedule.Entry(tickStart, tickStop, _) => - /* Filter for entries, that end after the last schedule application + val prefilteredSchedules = lastState.schedule.view.mapValues { + _.filter { case ScheduleEntry(tickStart, tickStop, _) => + /* Filter for entries, that end after the last schedule application and that start before the current tick. Entries that end at lastTick are not included because schedule intervals are open at the right hand side. Entries that start at currentTick are not included because these will be calculated with the next state. - */ - tickStop > lastTick && tickStart < currentTick - } - - schedule.copy(entries = filteredEntries) + */ + tickStop > lastTick && tickStart < currentTick } + } - val entriesByStartTick = prefilteredSchedules - .flatMap { case ChargingSchedule(evUuid, entries) => - entries.unsorted // unsorted for speedier execution - .map { entry => - // trim down entries to the currently considered window of the charging schedule - evUuid -> trimScheduleEntry( - entry, - lastTick, - currentTick - ) - } + val entriesByStartTick = prefilteredSchedules.toSeq + .flatMap { case (evUuid, entries) => + // unsorted for speedier execution + entries.unsorted.map { entry => + // trim down entries to the currently + // considered window of the charging schedule + evUuid -> trimScheduleEntry( + entry, + lastTick, + currentTick + ) + } } - .groupBy { case _ -> entry => + .groupBy { case (_, entry) => entry.tickStart } .to(SortedMap) - val startAndStopTicks = prefilteredSchedules - .flatMap { case ChargingSchedule(_, entries) => - entries.unsorted.flatMap { - case ChargingSchedule.Entry(start, stop, _) => - Iterable(start, stop) + val startAndStopTicks = prefilteredSchedules.values + .flatMap { + _.unsorted.flatMap { case ScheduleEntry(start, stop, _) => + Iterable(start, stop) } } .filter(tick => tick >= lastTick && tick < currentTick) .to(SortedSet) - // the last tick needs to be included, - // the current tick excluded + // the last tick needs to be present .incl(lastTick) - .excl(currentTick) // in order to create 0kW entries for EVs that do not // start charging right away at lastTick, create mock // schedule entries that end before lastTick val startingSchedules = lastEvMap.keys.map { - _ -> ChargingSchedule.Entry(lastTick, lastTick, Kilowatts(0d)) + _ -> ScheduleEntry(lastTick, lastTick, Kilowatts(0d)) } val (currentEvs, currentSchedules, evResults, evcsResults) = @@ -382,7 +379,7 @@ final case class EvcsModel( // update EV val newEvStoredEnergy = ev.storedEnergy + - chargedEnergyInScheduleEntry(entry) + calcChargedEnergy(entry) val newEv = ev.copy(storedEnergy = newEvStoredEnergy) ( @@ -476,10 +473,10 @@ final case class EvcsModel( * A trimmed version of given scheduleEntry */ private def trimScheduleEntry( - scheduleEntry: ChargingSchedule.Entry, + scheduleEntry: ScheduleEntry, lastSchedulingTick: Long, currentTick: Long - ): ChargingSchedule.Entry = + ): ScheduleEntry = scheduleEntry.copy( tickStart = math.max(scheduleEntry.tickStart, lastSchedulingTick), tickStop = math.min(scheduleEntry.tickStop, currentTick) @@ -493,8 +490,8 @@ final case class EvcsModel( * @return * The energy charged during the time interval of the schedule entry */ - private def chargedEnergyInScheduleEntry( - scheduleEntry: ChargingSchedule.Entry + private def calcChargedEnergy( + scheduleEntry: ScheduleEntry ): Energy = scheduleEntry.chargingPower * Seconds( scheduleEntry.tickStop - scheduleEntry.tickStart @@ -521,19 +518,6 @@ final case class EvcsModel( evPower.min(sRated) } - /** Calculate the power behaviour based on the given data. - * - * @param tick - * Regarded instant in simulation - * @param voltage - * Nodal voltage magnitude - * @param modelState - * Current state of the model - * @param data - * Further needed, secondary data - * @return - * A tuple of active and reactive power - */ override def calculatePower( tick: Long, voltage: Dimensionless, @@ -542,15 +526,6 @@ final case class EvcsModel( ): ApparentPower = throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") - /** Calculate the active power behaviour of the model - * - * @param modelState - * Current state of the model - * @param data - * Further needed, secondary data - * @return - * Active power - */ override protected def calculateActivePower( modelState: EvcsState, data: EvcsRelevantData @@ -567,22 +542,21 @@ final case class EvcsModel( val preferredScheduling = calculateNewScheduling(data, currentEvs) val (maxCharging, preferredPower, forcedCharging, maxDischarging) = - preferredScheduling.foldLeft( + currentEvs.foldLeft( (Kilowatts(0d), Kilowatts(0d), Kilowatts(0d), Kilowatts(0d)) ) { case ( (chargingSum, preferredSum, forcedSum, dischargingSum), - (ev, optChargingSchedule) + ev ) => val maxPower = getMaxAvailableChargingPower(ev) - val preferred = optChargingSchedule - .flatMap { case ChargingSchedule(_, entries) => - entries - .find { case ChargingSchedule.Entry(tickStart, tickStop, _) => - tickStart <= data.tick && tickStop > data.tick - } - .map(_.chargingPower) + val preferred = preferredScheduling + .get(ev.uuid) + .flatMap { + _.find { case ScheduleEntry(tickStart, tickStop, _) => + tickStart <= data.tick && tickStop > data.tick + }.map(_.chargingPower) } val maxCharging = @@ -639,14 +613,14 @@ final case class EvcsModel( return ( EvcsState( evs = currentEvs, - schedule = currentEvs.map(_ -> None).toMap, + schedule = Map.empty, tick = data.tick ), FlexChangeIndicator() ) // applicable evs can be charged/discharged, other evs cannot - val (applicableEvs, otherEvs) = currentEvs.partition { ev => + val applicableEvs = currentEvs.filter { ev => if (setPower > Kilowatts(0d)) !isFull(ev) else @@ -660,7 +634,7 @@ final case class EvcsModel( isEmpty(ev) && !isInLowerMargin(ev) } else - (Seq.empty[EvModelWrapper], applicableEvs) + (Seq.empty, applicableEvs) val (forcedSchedules, remainingPower) = createScheduleWithSetPower(data.tick, forcedChargingEvs, setPower) @@ -670,9 +644,33 @@ final case class EvcsModel( val combinedSchedules = forcedSchedules ++ regularSchedules - val schedulesOnly = combinedSchedules.flatMap { case (_, scheduleOpt) => - scheduleOpt - } + val allSchedules = combinedSchedules.map { case (ev, (schedule, _, _)) => + ev -> schedule + }.toMap + + ( + EvcsState( + evs = currentEvs, + schedule = allSchedules, + tick = data.tick + ), + aggregateFlexChange(combinedSchedules) + ) + } + + /** Aggregates a flex change indicator from controlled schedule calcuation + * result + * + * @param combinedSchedules + * The schedule calculation results + * @return + * The aggregated flex change indicator + */ + private def aggregateFlexChange( + combinedSchedules: Seq[(UUID, (ChargingSchedule, Long, Boolean))] + ): FlexChangeIndicator = { + val schedulesOnly = + combinedSchedules.map { case (_, schedule) => schedule } val scheduleAtNextActivation = schedulesOnly .map { case (_, _, scheduleAtNext) => scheduleAtNext } @@ -683,26 +681,16 @@ final case class EvcsModel( endTick }.minOption - val allSchedules = combinedSchedules.map { - case (ev, Some((schedule, _, _))) => - ev -> Some(schedule) - case (ev, None) => ev -> None - }.toMap ++ otherEvs.map(_ -> None).toMap - - ( - EvcsState( - evs = allSchedules.keys.toSeq, - schedule = allSchedules, - tick = data.tick - ), - FlexChangeIndicator( - scheduleAtNextActivation, - nextScheduledTick - ) + FlexChangeIndicator( + scheduleAtNextActivation, + nextScheduledTick ) } - /** @param currentTick + /** Distributes some set power value across given EVs, taking into + * consideration the maximum charging power of EVs and the charging station + * + * @param currentTick * The current tick * @param evs * The collection of EVs to assign charging power to @@ -718,7 +706,7 @@ final case class EvcsModel( evs: Seq[EvModelWrapper], setPower: Power ): ( - Seq[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])], + Seq[(UUID, (ChargingSchedule, Long, Boolean))], Power ) = { @@ -726,7 +714,7 @@ final case class EvcsModel( if (setPower.~=(Kilowatts(0d))(Kilowatts(1e-6))) { // No power left. Rest is not charging - return (evs.map { _ -> None }, Kilowatts(0d)) + return (Seq.empty, Kilowatts(0d)) } val proposedPower = setPower.divide(evs.size) @@ -742,21 +730,20 @@ final case class EvcsModel( // end of recursion, rest of charging power fits to all val results = fittingPowerEvs.map { ev => - val chargingTicks = calculateChargingDuration(ev, proposedPower) + val chargingTicks = calcFlexOptionsChange(ev, proposedPower) val endTick = Math.min(currentTick + chargingTicks, ev.departureTick) ( - ev, - Some( - ChargingSchedule( - ev, - Seq(ChargingSchedule.Entry(currentTick, endTick, proposedPower)) + ev.uuid, + ( + SortedSet( + ScheduleEntry(currentTick, endTick, proposedPower) ), endTick, isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) ) ) - }: Seq[(EvModelWrapper, Option[(ChargingSchedule, Long, Boolean)])] + } (results, Kilowatts(0d)) } else { @@ -771,7 +758,7 @@ final case class EvcsModel( else maxPower * (-1) - val chargingTicks = calculateChargingDuration(ev, power) + val chargingTicks = calcFlexOptionsChange(ev, power) val endTick = Math.min(currentTick + chargingTicks, ev.departureTick) (ev, power, endTick) @@ -795,12 +782,9 @@ final case class EvcsModel( val combinedResults = maxCharged.map { case (ev, power, endTick) => ( - ev, - Some( - ChargingSchedule( - ev, - Seq(ChargingSchedule.Entry(currentTick, endTick, power)) - ), + ev.uuid, + ( + SortedSet(ScheduleEntry(currentTick, endTick, power)), endTick, isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) ) @@ -812,7 +796,18 @@ final case class EvcsModel( } - private def calculateChargingDuration( + /** Calculates the duration (in ticks) until the flex options will change + * next, which could be the battery being fully charged or discharged or the + * minimum SOC requirement being reached + * + * @param ev + * The EV to charge/discharge + * @param power + * The charging/discharging power + * @return + * The tick at which flex options will change + */ + private def calcFlexOptionsChange( ev: EvModelWrapper, power: Power ): Long = { @@ -964,7 +959,17 @@ final case class EvcsModel( object EvcsModel { - /** Class that holds all relevant data for an Evcs model calculation + /** A charging schedule for a single EV, consisting of multiple schedule + * entries that are (primarily) sorted by start tick + */ + type ChargingSchedule = SortedSet[ScheduleEntry] + + /** A schedule map consisting of charging schedules for multiple EVs, + * referenced by their model UUID + */ + type ScheduleMap = Map[UUID, ChargingSchedule] + + /** Class that holds all relevant data for an EVCS model calculation * * @param tick * The current tick @@ -976,23 +981,51 @@ object EvcsModel { arrivals: Seq[EvModelWrapper] ) extends CalcRelevantData - /** Class that represents the state of the charging station at a given point - * in time + /** Class that represents the state of the charging station (including + * schedules for future charging) at a given point in time * * @param evs - * EVs that are staying at the charging station + * EVs that are parked at the charging station * @param schedule - * the schedule determining when to load which EVs with which power + * The schedule determining when to load which EVs with which power, as a + * map EV model UUID -> charging schedule * @param tick * The tick that the data has been calculated for */ final case class EvcsState( evs: Seq[EvModelWrapper], - schedule: Map[EvModelWrapper, Option[ChargingSchedule]], + schedule: ScheduleMap, tick: Long - ) extends ModelState { - def getSchedule(ev: EvModelWrapper): Option[ChargingSchedule] = - schedule.getOrElse(ev, None) + ) extends ModelState + + /** Schedule entry specifying a time interval in which the EV should be + * charged/discharged with some given power + * + * @param tickStart + * start of charging interval + * @param tickStop + * end of charging interval + * @param chargingPower + * charging power for the charging interval + */ + final case class ScheduleEntry( + tickStart: Long, + tickStop: Long, + chargingPower: squants.Power + ) extends Ordered[ScheduleEntry] { + override def compare(that: ScheduleEntry): Int = { + val startComp = tickStart.compare(that.tickStart) + if (startComp != 0) + startComp + else { + // important for checking equality: consider other fields as well + val stopComp = tickStop.compare(that.tickStop) + if (stopComp != 0) + stopComp + else + chargingPower.compareTo(that.chargingPower) + } + } } def apply( diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala index def36fbbcc..cab4b756b7 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala @@ -6,14 +6,15 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled -import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry -import edu.ie3.simona.model.participant.evcs.{ - ChargingSchedule, - EvModelWrapper, - EvcsModel +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + ScheduleMap, + ScheduleEntry } +import edu.ie3.simona.model.participant.evcs.{EvModelWrapper, EvcsModel} import squants.time.Seconds +import scala.collection.immutable.SortedSet + trait ConstantPowerCharging { this: EvcsModel => @@ -32,8 +33,9 @@ trait ConstantPowerCharging { def chargeWithConstantPower( currentTick: Long, evs: Seq[EvModelWrapper] - ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => - ev -> Option.when(ev.storedEnergy < ev.eStorage) { + ): ScheduleMap = evs + .filter(ev => ev.storedEnergy < ev.eStorage) + .map { ev => val maxChargingPower = getMaxAvailableChargingPower(ev) val remainingParkingTime = Seconds(ev.departureTick - currentTick) @@ -45,10 +47,9 @@ trait ConstantPowerCharging { val chargingPower = actualChargedEnergy / remainingParkingTime - ChargingSchedule( - ev, - Seq(Entry(currentTick, ev.departureTick, chargingPower)) + ev.uuid -> SortedSet( + ScheduleEntry(currentTick, ev.departureTick, chargingPower) ) } - }.toMap + .toMap } diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala index 372f2658bf..babbc580ac 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala @@ -6,14 +6,15 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled -import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry -import edu.ie3.simona.model.participant.evcs.{ - ChargingSchedule, - EvModelWrapper, - EvcsModel +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + ScheduleMap, + ScheduleEntry } +import edu.ie3.simona.model.participant.evcs.{EvModelWrapper, EvcsModel} import squants.Seconds +import scala.collection.immutable.SortedSet + trait MaximumPowerCharging { this: EvcsModel => @@ -32,8 +33,9 @@ trait MaximumPowerCharging { def chargeWithMaximumPower( currentTick: Long, evs: Seq[EvModelWrapper] - ): Map[EvModelWrapper, Option[ChargingSchedule]] = evs.map { ev => - ev -> Option.when(ev.storedEnergy < ev.eStorage) { + ): ScheduleMap = evs + .filter(ev => ev.storedEnergy < ev.eStorage) + .map { ev => val chargingPower = getMaxAvailableChargingPower(ev) val remainingParkingTime = Seconds(ev.departureTick - currentTick) @@ -52,7 +54,8 @@ trait MaximumPowerCharging { ((ev.eStorage - ev.storedEnergy) / chargingPower).toSeconds.toLong + currentTick } - ChargingSchedule(ev, Seq(Entry(currentTick, endTick, chargingPower))) + ev.uuid -> + SortedSet(ScheduleEntry(currentTick, endTick, chargingPower)) } - }.toMap + .toMap } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 3bca1b8b1c..3c50b895f4 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -25,8 +25,11 @@ import edu.ie3.simona.event.ResultEvent.{ ParticipantResultEvent } import edu.ie3.simona.event.notifier.NotifierConfig -import edu.ie3.simona.model.participant.evcs.EvcsModel.EvcsState -import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} +import edu.ie3.simona.model.participant.evcs.EvcsModel.{ + EvcsState, + ScheduleEntry +} +import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -62,6 +65,7 @@ import squants.{Each, Energy, Power} import java.util.UUID import scala.collection.SortedMap +import scala.collection.immutable.SortedSet class EvcsAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -490,25 +494,19 @@ class EvcsAgentModelCalculationSpec EvModelWrapper(evB) ) - schedule.values.flatten should contain allOf ( - ChargingSchedule( - EvModelWrapper(evA), - Seq( - ChargingSchedule.Entry( - 0, - 200, - Kilowatts(11.0) - ) + schedule shouldBe Map( + evA.getUuid -> SortedSet( + ScheduleEntry( + 0, + 200, + Kilowatts(11.0) ) ), - ChargingSchedule( - EvModelWrapper(evB), - Seq( - ChargingSchedule.Entry( - 0, - 200, - Kilowatts(11.0) - ) + evB.getUuid -> SortedSet( + ScheduleEntry( + 0, + 200, + Kilowatts(11.0) ) ) ) @@ -628,27 +626,23 @@ class EvcsAgentModelCalculationSpec EvModelWrapper(evA), EvModelWrapper(evB) ) - schedule.values.flatten should contain allOf ( - ChargingSchedule( - EvModelWrapper(evA), - Seq( - ChargingSchedule.Entry( + schedule shouldBe Map( + evA.getUuid -> + SortedSet( + ScheduleEntry( 0, 200, Kilowatts(11.0) ) - ) - ), - ChargingSchedule( - EvModelWrapper(evB), - Seq( - ChargingSchedule.Entry( + ), + evB.getUuid -> + SortedSet( + ScheduleEntry( 0, 200, Kilowatts(11.0) ) ) - ) ) tick shouldBe 0L diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 2ea7992ea8..afc0755bb4 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -8,10 +8,10 @@ package edu.ie3.simona.model.participant.evcs import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType import edu.ie3.simona.model.participant.FlexChangeIndicator -import edu.ie3.simona.model.participant.evcs.ChargingSchedule.Entry import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsRelevantData, - EvcsState + EvcsState, + ScheduleEntry } import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.test.common.UnitSpec @@ -25,6 +25,7 @@ import squants.Each import squants.energy.{KilowattHours, Kilowatts} import java.util.UUID +import scala.collection.immutable.SortedSet class EvcsModelSpec extends UnitSpec @@ -69,10 +70,9 @@ class EvcsModelSpec ) actualSchedule shouldBe Map( - evModel -> Some( + evModel.uuid -> // ending early at 9000 because of max power charging - ChargingSchedule(evModel, Seq(Entry(3600L, 9000L, Kilowatts(10.0)))) - ) + SortedSet(ScheduleEntry(3600L, 9000L, Kilowatts(10.0))) ) } @@ -103,10 +103,9 @@ class EvcsModelSpec ) actualSchedule shouldBe Map( - evModel -> Some( + evModel.uuid -> // using 2.5 kW with constant power charging - ChargingSchedule(evModel, Seq(Entry(3600L, 10800L, Kilowatts(2.5)))) - ) + SortedSet(ScheduleEntry(3600L, 10800L, Kilowatts(2.5))) ) } } @@ -168,14 +167,12 @@ class EvcsModelSpec ) ) - val schedule = ChargingSchedule( - ev, - Seq(Entry(chargeStart, chargeEnd, Kilowatts(power))) - ) + val entry = + SortedSet(ScheduleEntry(chargeStart, chargeEnd, Kilowatts(power))) val state = EvcsState( Seq(ev), - Map(ev -> Some(schedule)), + Map(ev.uuid -> entry), lastCalcTick ) @@ -221,12 +218,9 @@ class EvcsModelSpec ) ) - val schedule = ChargingSchedule( - ev, - Seq( - Entry(3600L, 5400L, Kilowatts(2d)), - Entry(7200L, 9000L, Kilowatts(4d)) - ) + val schedule = SortedSet( + ScheduleEntry(3600L, 5400L, Kilowatts(2d)), + ScheduleEntry(7200L, 9000L, Kilowatts(4d)) ) // tick, p in kW @@ -266,7 +260,7 @@ class EvcsModelSpec ) => val lastState = EvcsState( Seq(ev), - Map(ev -> Some(schedule)), + Map(ev.uuid -> schedule), lastTick ) @@ -330,19 +324,14 @@ class EvcsModelSpec ) ) - val schedule1 = ChargingSchedule( - ev1, - Seq( - Entry(3600L, 7200L, Kilowatts(2d)), - Entry(9000L, 14400L, Kilowatts(3d)) + val schedule1 = + SortedSet( + ScheduleEntry(3600L, 7200L, Kilowatts(2d)), + ScheduleEntry(9000L, 14400L, Kilowatts(3d)) ) - ) - val schedule2 = ChargingSchedule( - ev2, - Seq( - Entry(5400L, 9000L, Kilowatts(2d)) - ) + val schedule2 = SortedSet( + ScheduleEntry(5400L, 9000L, Kilowatts(2d)) ) val lastTick = 1800L @@ -350,7 +339,7 @@ class EvcsModelSpec val lastState = EvcsState( Seq(ev1, ev2), - Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), lastTick ) @@ -436,11 +425,8 @@ class EvcsModelSpec ) ) - val schedule = ChargingSchedule( - ev, - Seq( - Entry(3600L, 7200L, Kilowatts(2d)) - ) + val schedule = SortedSet( + ScheduleEntry(3600L, 7200L, Kilowatts(2d)) ) val lastTick = 1800L @@ -448,7 +434,7 @@ class EvcsModelSpec val lastState = EvcsState( Seq(ev), - Map(ev -> Some(schedule)), + Map(ev.uuid -> schedule), lastTick ) @@ -598,9 +584,8 @@ class EvcsModelSpec ) // has not been charging before - val schedule1 = ChargingSchedule( - ev1, - Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(0d))) + val schedule1 = SortedSet( + ScheduleEntry(3600L, 7200L, Kilowatts(0d)) ) // stays two more hours @@ -617,16 +602,15 @@ class EvcsModelSpec ) // has been charging for 1.5 hours with given power - val schedule2 = ChargingSchedule( - ev1, - Seq(ChargingSchedule.Entry(0L, 5400L, Kilowatts(lastPower2))) + val schedule2 = SortedSet( + ScheduleEntry(0L, 5400L, Kilowatts(lastPower2)) ) evcsModel.determineFlexOptions( data, EvcsState( Seq(ev1, ev2), - Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), 0L ) ) match { @@ -740,9 +724,8 @@ class EvcsModelSpec ) ) - val schedule1 = ChargingSchedule( - ev1, - Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(0d))) + val schedule1 = SortedSet( + ScheduleEntry(3600L, 7200L, Kilowatts(0d)) ) val ev2 = EvModelWrapper( @@ -757,16 +740,15 @@ class EvcsModelSpec ) ) - val schedule2 = ChargingSchedule( - ev1, - Seq(ChargingSchedule.Entry(0L, 5400L, Kilowatts(lastPower2))) + val schedule2 = SortedSet( + ScheduleEntry(0L, 5400L, Kilowatts(lastPower2)) ) evcsModel.determineFlexOptions( data, EvcsState( Seq(ev1, ev2), - Map(ev1 -> Some(schedule1), ev2 -> Some(schedule2)), + Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), 0L ) ) match { @@ -810,16 +792,15 @@ class EvcsModelSpec ) ) - val schedule1 = ChargingSchedule( - ev1, - Seq(ChargingSchedule.Entry(3600L, 7200L, Kilowatts(5.0))) + val schedule1 = SortedSet( + ScheduleEntry(3600L, 7200L, Kilowatts(5.0)) ) evcsModel.determineFlexOptions( data, EvcsState( Seq(ev1), - Map(ev1 -> Some(schedule1)), + Map(ev1.uuid -> schedule1), 0L ) ) match { @@ -943,7 +924,7 @@ class EvcsModelSpec data, EvcsState( Seq(ev1, ev2), - Map(ev1 -> None, ev2 -> None), + Map.empty, 0L ), Kilowatts(setPower) @@ -956,29 +937,27 @@ class EvcsModelSpec actualEvs should have size 2 actualEvs should contain allOf (ev1, ev2) - actualSchedules.getOrElse(ev1, None).map { - case ChargingSchedule(_, entries) => - entries.size shouldBe 1 - val entry = entries.headOption - .getOrElse(fail("No charging schedule entry for ev1")) - entry.tickStart shouldBe currentTick - - ( - entry.chargingPower.toKilowatts, - entry.tickStop - ) + actualSchedules.get(ev1.uuid).map { entries => + entries.size shouldBe 1 + val entry = entries.headOption + .getOrElse(fail("No charging schedule entry for ev1")) + entry.tickStart shouldBe currentTick + + ( + entry.chargingPower.toKilowatts, + entry.tickStop + ) } shouldBe expPowerAndTick1 - actualSchedules.getOrElse(ev2, None).map { - case ChargingSchedule(_, entries) => - entries.size shouldBe 1 - val entry = entries.headOption - .getOrElse(fail("No charging schedule entry for ev2")) - entry.tickStart shouldBe currentTick - - ( - entry.chargingPower.toKilowatts, - entry.tickStop - ) + actualSchedules.get(ev2.uuid).map { entries => + entries.size shouldBe 1 + val entry = entries.headOption + .getOrElse(fail("No charging schedule entry for ev2")) + entry.tickStart shouldBe currentTick + + ( + entry.chargingPower.toKilowatts, + entry.tickStop + ) } shouldBe expPowerAndTick2 actualTick shouldBe currentTick diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala index 5b87eb6566..726b7a4ae7 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala @@ -6,7 +6,8 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled -import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} +import edu.ie3.simona.model.participant.evcs.EvModelWrapper +import edu.ie3.simona.model.participant.evcs.EvcsModel.ScheduleEntry import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.MockEvModel import edu.ie3.simona.test.common.model.participant.EvcsTestData @@ -15,6 +16,7 @@ import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.Kilowatts import java.util.UUID +import scala.collection.immutable.SortedSet class ConstantPowerChargingSpec extends UnitSpec @@ -42,9 +44,7 @@ class ConstantPowerChargingSpec Seq(ev) ) - actualSchedule shouldBe Map( - ev -> None - ) + actualSchedule shouldBe Map.empty } "work correctly with one ev" in { @@ -83,16 +83,11 @@ class ConstantPowerChargingSpec ) chargingMap shouldBe Map( - ev -> Some( - ChargingSchedule( - ev, - Seq( - ChargingSchedule.Entry( - offset, - offset + stayingTicks, - Kilowatts(expectedPower) - ) - ) + ev.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + stayingTicks, + Kilowatts(expectedPower) ) ) ) @@ -148,28 +143,18 @@ class ConstantPowerChargingSpec ) chargingMap shouldBe Map( - givenEv -> Some( - ChargingSchedule( - givenEv, - Seq( - ChargingSchedule.Entry( - offset, - offset + 3600L, - Kilowatts(5.0) - ) - ) + givenEv.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + 3600L, + Kilowatts(5.0) ) ), - ev -> Some( - ChargingSchedule( - ev, - Seq( - ChargingSchedule.Entry( - offset, - offset + stayingTicks, - Kilowatts(expectedPower) - ) - ) + ev.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + stayingTicks, + Kilowatts(expectedPower) ) ) ) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala index 5813056d41..62a1cbff48 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala @@ -6,7 +6,8 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled -import edu.ie3.simona.model.participant.evcs.{ChargingSchedule, EvModelWrapper} +import edu.ie3.simona.model.participant.evcs.EvModelWrapper +import edu.ie3.simona.model.participant.evcs.EvcsModel.ScheduleEntry import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.MockEvModel import edu.ie3.simona.test.common.model.participant.EvcsTestData @@ -15,6 +16,7 @@ import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.Kilowatts import java.util.UUID +import scala.collection.immutable.SortedSet class MaximumPowerChargingSpec extends UnitSpec @@ -42,9 +44,7 @@ class MaximumPowerChargingSpec Seq(ev) ) - actualSchedule shouldBe Map( - ev -> None - ) + actualSchedule shouldBe Map.empty } "work correctly with one ev" in { @@ -81,16 +81,11 @@ class MaximumPowerChargingSpec ) chargingMap shouldBe Map( - ev -> Some( - ChargingSchedule( - ev, - Seq( - ChargingSchedule.Entry( - offset, - offset + expectedDuration, - ev.sRatedAc - ) - ) + ev.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + expectedDuration, + ev.sRatedAc ) ) ) @@ -144,28 +139,18 @@ class MaximumPowerChargingSpec ) chargingMap shouldBe Map( - givenEv -> Some( - ChargingSchedule( - givenEv, - Seq( - ChargingSchedule.Entry( - offset, - offset + 3600L, - Kilowatts(5.0) - ) - ) + givenEv.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + 3600L, + Kilowatts(5.0) ) ), - ev -> Some( - ChargingSchedule( - ev, - Seq( - ChargingSchedule.Entry( - offset, - offset + expectedDuration, - Kilowatts(5.0) - ) - ) + ev.uuid -> SortedSet( + ScheduleEntry( + offset, + offset + expectedDuration, + Kilowatts(5.0) ) ) ) From 4f22c2e152d5a2593f7706cb18331b0ab82636f3 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 13:44:15 +0100 Subject: [PATCH 156/305] Restructuring for clarity --- .../model/participant/evcs/EvcsModel.scala | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 90450f9695..9e2a1fdd1c 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -764,6 +764,17 @@ final case class EvcsModel( (ev, power, endTick) } + val maxChargedResults = maxCharged.map { case (ev, power, endTick) => + ( + ev.uuid, + ( + SortedSet(ScheduleEntry(currentTick, endTick, power)), + endTick, + isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) + ) + ) + } + // sum up allocated power val chargingPowerSum = maxCharged.foldLeft(Kilowatts(0d)) { case (powerSum, (_, chargingPower, _)) => @@ -780,16 +791,7 @@ final case class EvcsModel( remainingAfterAllocation ) - val combinedResults = maxCharged.map { case (ev, power, endTick) => - ( - ev.uuid, - ( - SortedSet(ScheduleEntry(currentTick, endTick, power)), - endTick, - isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) - ) - ) - } ++ nextIterationResults + val combinedResults = maxChargedResults ++ nextIterationResults (combinedResults, remainingAfterRecursion) } From 3c306e27be789950f6fb27f27b4727f883cc0350 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 14:25:50 +0100 Subject: [PATCH 157/305] Simplification --- .../evcs/EvcsAgentFundamentals.scala | 40 ++++--------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index de39424338..9818f25524 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -429,19 +429,11 @@ protected trait EvcsAgentFundamentals ) } - val voltage = baseStateData.voltageValueStore - .last(tick) - .map { case (_, voltage) => - voltage - } - .getOrElse(Each(1d)) - /* Calculate evcs power for interval since last update, save for updating value store, and inform listeners */ val updatedResultValueStore = determineResultsAnnounceUpdateValueStore( lastState, tick, - voltage, baseStateData ) @@ -619,25 +611,13 @@ protected trait EvcsAgentFundamentals EvcsState, EvcsModel ] => - // FIXME this is still incomplete ? - val lastState = getLastOrInitialStateData(modelBaseStateData, requestTick) - val voltage = modelBaseStateData.voltageValueStore - .last(requestTick) - .map { case (_, voltage) => - voltage - } - .getOrElse( - Each(1d) - ) - val updatedResultValueStore = determineResultsAnnounceUpdateValueStore( lastState, requestTick, - voltage, modelBaseStateData ) @@ -718,20 +698,10 @@ protected trait EvcsAgentFundamentals // Thus, skip recalculating and sending out results. baseStateData case None => - val voltage = baseStateData.voltageValueStore - .last(currentTick - 1) - .map { case (_, voltage) => - voltage - } - .getOrElse( - Each(1d) - ) - val updatedResultValueStore = determineResultsAnnounceUpdateValueStore( lastState, currentTick, - voltage, baseStateData ) @@ -756,8 +726,6 @@ protected trait EvcsAgentFundamentals * The state (including schedule) to calculate results for * @param currentTick * The tick up to which results should be calculated for - * @param voltage - * The voltage magnitude used for reactive power calculation * @param modelBaseStateData * Model base state data * @return @@ -766,7 +734,6 @@ protected trait EvcsAgentFundamentals private def determineResultsAnnounceUpdateValueStore( lastState: EvcsState, currentTick: Long, - voltage: squants.Dimensionless, modelBaseStateData: ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, @@ -775,6 +742,13 @@ protected trait EvcsAgentFundamentals ] ): ValueStore[ApparentPower] = { + val voltage = modelBaseStateData.voltageValueStore + .last(currentTick) + .map { case (_, voltage) => + voltage + } + .getOrElse(Each(1d)) + val (evResults, evcsResults) = modelBaseStateData.model.createResults( lastState, currentTick, From e2b51f2f849dac39bbfae4a0683e30cd37293ac1 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 15:12:16 +0100 Subject: [PATCH 158/305] Fixing code smell: non-indexed seq --- .../edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index afc0755bb4..490add56c5 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -225,7 +225,7 @@ class EvcsModelSpec // tick, p in kW val generalEvResults = - Seq( + IndexedSeq( (0L, 0d), (3600L, 2d), (5400L, 0d), From ca10e59d44fda4ba258f2afe638a8abd58ef2fb6 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 15:22:41 +0100 Subject: [PATCH 159/305] Suppressing method nane scapegoat issue --- .../scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala index ed1f9c3af7..f466689677 100644 --- a/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala +++ b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala @@ -6,6 +6,9 @@ package edu.ie3.simona.test.helper +// Methods are supposed to be shorthand notations for +// class constructors, thus uppercase naming is intuitive +@SuppressWarnings(Array("MethodNames")) trait TableDrivenHelper { /** Shortcut for Some type to make case tables more concise */ From c337ef953177781cd92331d92b3429e77dde4180 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 15:41:18 +0100 Subject: [PATCH 160/305] Clarified result handling --- .../agent/participant/EvcsAgentModelCalculationSpec.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 3c50b895f4..4c8348873f 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -519,7 +519,8 @@ class EvcsAgentModelCalculationSpec /* The store for simulation results has been extended */ baseStateData.resultValueStore match { case ValueStore(_, store) => - // FIXME: Please double-check if an empty result store is actually correct here! + // Since departures and arrivals are considered separately, + // EvcsAgent calculates results only with the next activation store.keys shouldBe empty } case _ => @@ -653,7 +654,8 @@ class EvcsAgentModelCalculationSpec /* The store for simulation results has been extended */ baseStateData.resultValueStore match { case ValueStore(_, store) => - // FIXME: Please double-check if an empty result store is actually correct here! + // Since departures and arrivals are considered separately, + // EvcsAgent calculates results only with the next activation store shouldBe empty } case _ => From cb8e521968d7a2345ffa702b4cc57b93f4643e4a Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 15:43:47 +0100 Subject: [PATCH 161/305] Removed duplicate EvModelWrapper --- .../model/participant/EvModelWrapper.scala | 50 ------------------- .../participant/evcs/EvModelWrapper.scala | 2 +- 2 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/model/participant/EvModelWrapper.scala diff --git a/src/main/scala/edu/ie3/simona/model/participant/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/EvModelWrapper.scala deleted file mode 100644 index 7b9019aede..0000000000 --- a/src/main/scala/edu/ie3/simona/model/participant/EvModelWrapper.scala +++ /dev/null @@ -1,50 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant - -import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.util.quantities.PowerSystemUnits._ -import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble -import squants.energy.{KilowattHours, Kilowatts} - -import java.util.UUID - -final case class EvModelWrapper( - storedEnergy: squants.Energy, - private val original: EvModel -) { - - def uuid: UUID = original.getUuid - def id: String = original.getId - lazy val sRatedAc: squants.Power = - Kilowatts(original.getSRatedAC.to(KILOWATT).getValue.doubleValue) - lazy val sRatedDc: squants.Power = - Kilowatts(original.getSRatedDC.to(KILOWATT).getValue.doubleValue) - lazy val eStorage: squants.Energy = KilowattHours( - original.getEStorage.to(KILOWATTHOUR).getValue.doubleValue - ) - def departureTick: Long = original.getDepartureTick - - def unwrap(): EvModel = { - original.copyWith( - storedEnergy.toKilowattHours.asKiloWattHour - ) - } - -} - -object EvModelWrapper { - - def apply(evModel: EvModel): EvModelWrapper = { - new EvModelWrapper( - KilowattHours( - evModel.getStoredEnergy.to(KILOWATTHOUR).getValue.doubleValue - ), - evModel - ) - } -} diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala index 071a321557..f9d6e5cce7 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala @@ -25,7 +25,7 @@ import java.util.UUID * @param original * The wrapped [[EvModel]] */ -case class EvModelWrapper( +final case class EvModelWrapper( storedEnergy: squants.Energy, private val original: EvModel ) { From abe9f1378e4c3e537a1695ab1623c4c09e7abb25 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 15:59:51 +0100 Subject: [PATCH 162/305] Improved TODO phrasing --- .../scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 9e2a1fdd1c..4aff673679 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -600,7 +600,7 @@ final case class EvcsModel( ) } - // TODO sometimes we issue too early nextTicks, since remaining power might be added to remaining non-full vehicles + // TODO less activations could be possible if after departure of vehicles, the additional power might be added to remaining non-full vehicles // (minor) TODO? if IssueNoControl is sent, there might be a different result than anticipated when calculating flex options (strat is not used) override def handleControlledPowerChange( data: EvcsRelevantData, From be7e71c09adc75bc8576fad6f9fd4532c5e008a5 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 16:00:18 +0100 Subject: [PATCH 163/305] Improved TableDrivenHelper --- .../evcs/uncontrolled/ConstantPowerCharging.scala | 2 +- .../edu/ie3/simona/test/helper/TableDrivenHelper.scala | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala index cab4b756b7..4e2a56135e 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.model.participant.evcs.EvcsModel.{ ScheduleEntry } import edu.ie3.simona.model.participant.evcs.{EvModelWrapper, EvcsModel} -import squants.time.Seconds +import squants.Seconds import scala.collection.immutable.SortedSet diff --git a/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala index f466689677..f618b9106e 100644 --- a/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala +++ b/src/test/scala/edu/ie3/simona/test/helper/TableDrivenHelper.scala @@ -6,17 +6,14 @@ package edu.ie3.simona.test.helper -// Methods are supposed to be shorthand notations for -// class constructors, thus uppercase naming is intuitive -@SuppressWarnings(Array("MethodNames")) trait TableDrivenHelper { /** Shortcut for Some type to make case tables more concise */ - def S[T](value: T): Some[T] = Some(value) + val S: Some.type = Some /** Shortcut for None type to make case tables more concise */ - def N: None.type = None + val N: None.type = None /** Shortcut for Seq type to make case tables more concise */ - def L: Seq.type = Seq + val L: Seq.type = Seq } From 4b7295b855e4e40df73d9dfa5263c0a098019eb4 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 19:43:12 +0100 Subject: [PATCH 164/305] Unifying EvcsModel constructors Cleaning up EVCS test data --- .../participant/evcs/EvModelWrapper.scala | 7 +- .../model/participant/evcs/EvcsModel.scala | 99 ++++---------- .../ie3/util/scala/OperationInterval.scala | 2 +- .../EvcsAgentModelCalculationSpec.scala | 126 ++++++++++++------ .../participant/evcs/EvcsModelSpec.scala | 4 +- .../ConstantPowerChargingSpec.scala | 4 +- .../MaximumPowerChargingSpec.scala | 4 +- .../test/common/input/EvcsInputTestData.scala | 48 ++----- .../model/participant/EvcsTestData.scala | 38 ------ 9 files changed, 130 insertions(+), 202 deletions(-) delete mode 100644 src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala index f9d6e5cce7..80cdcf8a9a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala @@ -47,22 +47,21 @@ final case class EvModelWrapper( * @return * The original [[EvModel]] with updated stored energy. */ - def unwrap(): EvModel = { + def unwrap(): EvModel = original.copyWith( storedEnergy.toKilowattHours.asKiloWattHour ) - } } object EvModelWrapper { - def apply(evModel: EvModel): EvModelWrapper = { + def apply(evModel: EvModel): EvModelWrapper = new EvModelWrapper( KilowattHours( evModel.getStoredEnergy.to(KILOWATTHOUR).getValue.doubleValue ), evModel ) - } + } diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 4aff673679..04f7fb3077 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -14,13 +14,7 @@ import edu.ie3.datamodel.models.result.system.{EvResult, EvcsResult} import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.evcs.EvcsModel.{ - ChargingSchedule, - EvcsRelevantData, - EvcsState, - ScheduleEntry, - ScheduleMap -} +import edu.ie3.simona.model.participant.evcs.EvcsModel._ import edu.ie3.simona.model.participant.evcs.uncontrolled.{ ConstantPowerCharging, MaximumPowerCharging @@ -37,15 +31,13 @@ import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.OperationInterval -import squants.{Dimensionless, Energy, Power} -import squants.time.Seconds import squants.energy.{KilowattHours, Kilowatts} -import tech.units.indriya.ComparableQuantity +import squants.time.Seconds +import squants.{Dimensionless, Energy, Power} import tech.units.indriya.unit.Units.PERCENT import java.time.ZonedDateTime import java.util.UUID -import javax.measure import scala.collection.SortedMap import scala.collection.immutable.SortedSet @@ -73,6 +65,8 @@ import scala.collection.immutable.SortedSet * The location type * @param strategy * Strategy to follow in oder to determine the charging habits + * @param lowestEvSoc + * The lowest SOC possible for EV batteries (inverse of max dod) */ final case class EvcsModel( uuid: UUID, @@ -1030,6 +1024,23 @@ object EvcsModel { } } + /** Default factory method to create an EvcsModel instance. + * + * @param inputModel + * The EVCS input model providing parameters + * @param scalingFactor + * The scaling factor of the power output + * @param simulationStartDate + * The start date of the simulation + * @param simulationEndDate + * The end date of the simulation + * @param chargingStrategy + * The charging strategy to use + * @param lowestEvSoc + * The lowest SOC possible for EV batteries (inverse of max dod) + * @return + * The enabled EvcsModel + */ def apply( inputModel: EvcsInput, scalingFactor: Double, @@ -1046,14 +1057,14 @@ object EvcsModel { inputModel.getOperationTime ) - apply( + val model = EvcsModel( inputModel.getUuid, inputModel.getId, operationInterval, scalingFactor, simulationStartDate, QControl(inputModel.getqCharacteristics), - inputModel.getType.getsRated, + Kilowatts(inputModel.getType.getsRated.to(KILOWATT).getValue.doubleValue), inputModel.getType.getElectricCurrentType, inputModel.getCosPhiRated, inputModel.getChargingPoints, @@ -1062,70 +1073,10 @@ object EvcsModel { ChargingStrategy(chargingStrategy), lowestEvSoc ) - } - - /** Default factory method to create an EvcsModel instance. - * - * @param uuid - * the unique id of the model - * @param id - * the human readable id - * @param operationInterval - * the operation interval of the model - * @param scalingFactor - * the scaling factor of the power output - * @param simulationStartDate - * The start date of the simulation - * @param qControl - * the q control this model is using - * @param sRated - * the rated apparent power of the model - * @param cosPhiRated - * the rated cosine phi of the model - * @param chargingPoints - * Number of charging points available at this charging station - * @param locationType - * The location type - * @param chargingStrategy - * The charging strategy to use - * @return - * the enabled EvcsModel - */ - def apply( - uuid: UUID, - id: String, - operationInterval: OperationInterval, - scalingFactor: Double, - simulationStartDate: ZonedDateTime, - qControl: QControl, - sRated: ComparableQuantity[measure.quantity.Power], - currentType: ElectricCurrentType, - cosPhiRated: Double, - chargingPoints: Int, - locationType: EvcsLocationType, - vehicle2grid: Boolean, - chargingStrategy: ChargingStrategy.Value, - lowestEvSoc: Double - ): EvcsModel = { - val model = new EvcsModel( - uuid, - id, - operationInterval, - scalingFactor, - simulationStartDate, - qControl, - Kilowatts(sRated.to(KILOWATT).getValue.doubleValue), - currentType, - cosPhiRated, - chargingPoints, - locationType, - vehicle2grid, - chargingStrategy, - lowestEvSoc - ) model.enable() model } + } diff --git a/src/main/scala/edu/ie3/util/scala/OperationInterval.scala b/src/main/scala/edu/ie3/util/scala/OperationInterval.scala index fd786bae26..880f441460 100644 --- a/src/main/scala/edu/ie3/util/scala/OperationInterval.scala +++ b/src/main/scala/edu/ie3/util/scala/OperationInterval.scala @@ -34,6 +34,6 @@ final case class OperationInterval(start: java.lang.Long, end: java.lang.Long) def getEnd: Long = getUpper } -case object OperationInterval { +object OperationInterval { def apply(start: Long, end: Long) = new OperationInterval(start, end) } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 4c8348873f..c671e5dec8 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -25,14 +25,12 @@ import edu.ie3.simona.event.ResultEvent.{ ParticipantResultEvent } import edu.ie3.simona.event.notifier.NotifierConfig +import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsState, ScheduleEntry } -import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.Activation -import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ -import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, @@ -42,6 +40,8 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation } +import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ @@ -54,6 +54,7 @@ import edu.ie3.simona.test.common.input.EvcsInputTestData import edu.ie3.simona.test.common.{EvTestData, TestSpawnerClassic} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.{Megavars, ReactivePower, Vars} @@ -63,9 +64,9 @@ import org.apache.pekko.testkit.{TestFSMRef, TestProbe} import squants.energy._ import squants.{Each, Energy, Power} +import java.time.ZonedDateTime import java.util.UUID -import scala.collection.SortedMap -import scala.collection.immutable.SortedSet +import scala.collection.immutable.{SortedMap, SortedSet} class EvcsAgentModelCalculationSpec extends ParticipantAgentSpec( @@ -82,9 +83,28 @@ class EvcsAgentModelCalculationSpec with EvTestData with TestSpawnerClassic { - private implicit val powerTolerance: Power = Watts(0.1) - private implicit val energyTolerance: Energy = WattHours(0.1) - private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) + private val requestVoltageDeviationThreshold = 1e-14d + + private val defaultOutputConfig = + NotifierConfig( + simulationResultInfo = false, + powerRequestReply = false, + flexResult = false + ) + + private val modelConfig = + EvcsRuntimeConfig.apply( + calculateMissingReactivePowerWithModel = false, + scaling = 1.0, + uuids = List("default"), + chargingStrategy = "maxPower", + lowestEvSoc = 0.2 + ) + + protected implicit val simulationStartDate: ZonedDateTime = + TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00") + protected val simulationEndDate: ZonedDateTime = + TimeUtil.withDefaults.toZonedDateTime("2020-01-01 02:00:00") /* Alter the input model to have a voltage sensitive reactive power calculation */ private val evcsInputModelQv = evcsInputModel @@ -92,16 +112,11 @@ class EvcsAgentModelCalculationSpec .qCharacteristics(new QV("qV:{(0.95,-0.625),(1.05,0.625)}")) .build() - private val evService = TestProbe("evService") - - private val noServices = None - private val withServices = Some( - Vector( - ActorEvMovementsService(evService.ref) - ) - ) + private val resolution = 3600L - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private implicit val powerTolerance: Power = Watts(0.1) + private implicit val energyTolerance: Energy = WattHours(0.1) + private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) "An evcs agent with model calculation depending on no secondary data service" should { val initStateData = ParticipantInitializeStateData[ @@ -111,12 +126,11 @@ class EvcsAgentModelCalculationSpec ]( inputModel = evcsInputModel, modelConfig = modelConfig, - secondaryDataServices = noServices, + secondaryDataServices = None, simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, resolution = resolution, - requestVoltageDeviationThreshold = - simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref ) @@ -167,6 +181,8 @@ class EvcsAgentModelCalculationSpec } "An evcs agent with model calculation depending on one secondary data service" should { + val evService = TestProbe("evService") + val initStateData = ParticipantInitializeStateData[ EvcsInput, EvcsRuntimeConfig, @@ -174,12 +190,15 @@ class EvcsAgentModelCalculationSpec ]( inputModel = evcsInputModel, modelConfig = modelConfig, - secondaryDataServices = withServices, + secondaryDataServices = Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, resolution = resolution, - requestVoltageDeviationThreshold = - simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref ) @@ -235,11 +254,15 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModel) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe withServices + secondaryDataServices shouldBe Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate timeBin shouldBe resolution - requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold + requestVoltageDeviationThreshold shouldBe requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig maybeEmAgent shouldBe None case unsuitableStateData => @@ -801,12 +824,15 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = evcsInputModelQv, modelConfig = modelConfig, - secondaryDataServices = withServices, + secondaryDataServices = Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, - resolution = simonaConfig.simona.powerflow.resolution.getSeconds, - requestVoltageDeviationThreshold = - simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + resolution = resolution, + requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref ), @@ -975,6 +1001,7 @@ class EvcsAgentModelCalculationSpec "An evcs agent with model calculation controlled by an EmAgent" should { "be initialized correctly" in { + val evService = TestProbe("evService") val emAgent = TestProbe("EmAgentProbe") val evcsAgent = TestFSMRef( @@ -983,12 +1010,15 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = evcsInputModelQv, modelConfig = modelConfig, - secondaryDataServices = withServices, + secondaryDataServices = Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, resolution = resolution, - requestVoltageDeviationThreshold = - simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref, maybeEmAgent = Some(emAgent.ref.toTyped) @@ -1019,11 +1049,15 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe withServices + secondaryDataServices shouldBe Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate resolution shouldBe resolution - requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold + requestVoltageDeviationThreshold shouldBe requestVoltageDeviationThreshold outputConfig shouldBe defaultOutputConfig maybeEmAgent shouldBe Some(emAgent.ref.toTyped) case unsuitableStateData => @@ -1080,7 +1114,11 @@ class EvcsAgentModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe withServices + services shouldBe Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ) outputConfig shouldBe defaultOutputConfig additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map(evService.ref -> None) @@ -1102,6 +1140,7 @@ class EvcsAgentModelCalculationSpec } "provide correct flex options when in Idle" in { + val evService = TestProbe("evService") val emAgent = TestProbe("EmAgentProbe") val resultListener = TestProbe("ResultListener") @@ -1111,12 +1150,15 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = SimpleInputContainer(evcsInputModelQv), modelConfig = modelConfig, - secondaryDataServices = withServices, + secondaryDataServices = Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, resolution = resolution, - requestVoltageDeviationThreshold = - simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, + requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = NotifierConfig( simulationResultInfo = true, powerRequestReply = false, @@ -1151,11 +1193,15 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe withServices + secondaryDataServices shouldBe Some( + Vector( + ActorEvMovementsService(evService.ref) + ) + ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate resolution shouldBe resolution - requestVoltageDeviationThreshold shouldBe simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold + requestVoltageDeviationThreshold shouldBe requestVoltageDeviationThreshold outputConfig shouldBe NotifierConfig( simulationResultInfo = true, powerRequestReply = false, diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 490add56c5..2dce1b5317 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -15,8 +15,8 @@ import edu.ie3.simona.model.participant.evcs.EvcsModel.{ } import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.input.EvcsInputTestData import edu.ie3.simona.test.common.model.MockEvModel -import edu.ie3.simona.test.common.model.participant.EvcsTestData import edu.ie3.simona.test.helper.TableDrivenHelper import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble @@ -31,7 +31,7 @@ class EvcsModelSpec extends UnitSpec with TableDrivenPropertyChecks with TableDrivenHelper - with EvcsTestData { + with EvcsInputTestData { private val simulationStart = evcsStandardModel.simulationStartDate diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala index 726b7a4ae7..6b8612ae00 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala @@ -9,8 +9,8 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.model.participant.evcs.EvcsModel.ScheduleEntry import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.input.EvcsInputTestData import edu.ie3.simona.test.common.model.MockEvModel -import edu.ie3.simona.test.common.model.participant.EvcsTestData import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.Kilowatts @@ -21,7 +21,7 @@ import scala.collection.immutable.SortedSet class ConstantPowerChargingSpec extends UnitSpec with TableDrivenPropertyChecks - with EvcsTestData { + with EvcsInputTestData { "Calculating constant power charging schedules" should { val evcsModel = evcsStandardModel diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala index 62a1cbff48..af1dbf6000 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala @@ -9,8 +9,8 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.model.participant.evcs.EvcsModel.ScheduleEntry import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.input.EvcsInputTestData import edu.ie3.simona.test.common.model.MockEvModel -import edu.ie3.simona.test.common.model.participant.EvcsTestData import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.Kilowatts @@ -21,7 +21,7 @@ import scala.collection.immutable.SortedSet class MaximumPowerChargingSpec extends UnitSpec with TableDrivenPropertyChecks - with EvcsTestData { + with EvcsInputTestData { "Calculating maximum power charging schedules" should { val evcsModel = evcsStandardModel diff --git a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala index b819f552da..4100d2041d 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala @@ -12,15 +12,9 @@ import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.datamodel.models.input.system.`type`.chargingpoint.ChargingPointTypeUtils import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.event.notifier.NotifierConfig -import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference} +import edu.ie3.simona.model.participant.evcs.EvcsModel import edu.ie3.simona.test.common.DefaultTestData -import edu.ie3.simona.util.ConfigUtil -import edu.ie3.util.TimeUtil -import squants.energy.Kilowatts -import java.time.ZonedDateTime import java.util.UUID trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { @@ -28,7 +22,7 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { protected val evcsInputModel = new EvcsInput( UUID.randomUUID(), "Dummy_EvcsModel", - new OperatorInput(UUID.randomUUID(), "NO_OPERATOR"), + OperatorInput.NO_OPERATOR_ASSIGNED, OperationTime.notLimited(), nodeInputNoSlackNs04KvA, CosPhiFixed.CONSTANT_CHARACTERISTIC, @@ -39,37 +33,13 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { true ) - protected val simonaConfig: SimonaConfig = - createSimonaConfig( - LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0.0)) - ) - - private val configUtil = ConfigUtil.ParticipantConfigUtil( - simonaConfig.simona.runtime.participant + protected val evcsStandardModel: EvcsModel = EvcsModel( + evcsInputModel, + 1.0, + defaultSimulationStart, + defaultSimulationEnd, + "maxPower", + lowestEvSoc = 0.2 ) - protected val defaultOutputConfig: NotifierConfig = - NotifierConfig( - simonaConfig.simona.output.participant.defaultConfig.simulationResult, - simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult - ) - - protected val simResultOutputConfig: NotifierConfig = - NotifierConfig( - simulationResultInfo = true, - powerRequestReply = false, - flexResult = false - ) - - protected val modelConfig: SimonaConfig.EvcsRuntimeConfig = - configUtil.getOrDefault[SimonaConfig.EvcsRuntimeConfig]( - evcsInputModel.getUuid - ) - - protected implicit val simulationStartDate: ZonedDateTime = - TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00") - protected val simulationEndDate: ZonedDateTime = - TimeUtil.withDefaults.toZonedDateTime("2020-01-01 02:00:00") } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala deleted file mode 100644 index 14ea648b41..0000000000 --- a/src/test/scala/edu/ie3/simona/test/common/model/participant/EvcsTestData.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.test.common.model.participant - -import edu.ie3.datamodel.models.ElectricCurrentType -import edu.ie3.datamodel.models.input.system.`type`.evcslocation.EvcsLocationType -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.evcs.{ChargingStrategy, EvcsModel} -import edu.ie3.util.TimeUtil -import edu.ie3.util.quantities.PowerSystemUnits -import edu.ie3.util.scala.OperationInterval -import tech.units.indriya.quantity.Quantities - -import java.util.UUID - -trait EvcsTestData { - protected val evcsStandardModel: EvcsModel = EvcsModel( - UUID.randomUUID(), - "Evcs Model Test", - OperationInterval(0L, 31536000L), - 1.0, - TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00"), - QControl.apply(new CosPhiFixed("cosPhiFixed:{(0.0,1.0)}")), - Quantities.getQuantity(100, PowerSystemUnits.KILOVOLTAMPERE), - ElectricCurrentType.AC, - 0.95d, - 4, - EvcsLocationType.HOME, - vehicle2grid = true, - ChargingStrategy.MAX_POWER, - lowestEvSoc = 0.2 - ) -} From 293389fd81e023775b726e18c38fe4a97c3c5108 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 30 Jan 2024 19:59:33 +0100 Subject: [PATCH 165/305] TODO is done --- .../edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 2dce1b5317..492e4498be 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -38,7 +38,6 @@ class EvcsModelSpec private implicit val energyTolerance: squants.Energy = KilowattHours(1e-10) private implicit val powerTolerance: squants.Power = Kilowatts(1e-10) - // TODO some conditions/functions have not been tested yet "An EVCS model" should { "calculate new schedules correctly" when { From f5e712534140d4cbc36062484df3a9780158aa2f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 09:56:46 +0100 Subject: [PATCH 166/305] Unified flex calculation in model --- .../edu/ie3/simona/model/participant/BMModel.scala | 4 ++-- .../edu/ie3/simona/model/participant/ChpModel.scala | 10 ++++++++-- .../simona/model/participant/FixedFeedInModel.scala | 2 +- .../edu/ie3/simona/model/participant/PvModel.scala | 2 +- .../edu/ie3/simona/model/participant/WecModel.scala | 4 ++-- .../ie3/simona/model/participant/load/LoadModel.scala | 11 +++++------ .../messages/flex/MinMaxFlexibilityMessage.scala | 1 + 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index 4d9a35c568..60598ded28 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -14,7 +14,7 @@ import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptio import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.EnergyPrice -import squants.energy.Megawatts +import squants.energy.{Kilowatts, Megawatts} import squants.{Dimensionless, Money, Power, Temperature} import java.time.ZonedDateTime @@ -232,7 +232,7 @@ final case class BMModel( ): ProvideFlexOptions = { val power = calculateActivePower(lastState, data) - ProvideMinMaxFlexOptions(uuid, power, power, Megawatts(0d)) + ProvideMinMaxFlexOptions(uuid, power, power, Kilowatts(0d)) } override def handleControlledPowerChange( diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 0f03864853..6aac937ac0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -13,6 +13,7 @@ import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.thermal.{MutableStorage, ThermalStorage} import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions +import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities @@ -291,14 +292,19 @@ final case class ChpModel( override def determineFlexOptions( data: ChpRelevantData, lastState: ConstantState.type - ): ProvideFlexOptions = ??? // TODO actual implementation + ): ProvideFlexOptions = + ProvideMinMaxFlexOptions.noFlexOption( + uuid, + calculateActivePower(lastState, data) + ) override def handleControlledPowerChange( data: ChpRelevantData, lastState: ConstantState.type, setPower: squants.Power ): (ConstantState.type, FlexChangeIndicator) = - ??? // TODO actual implementation + (lastState, FlexChangeIndicator()) + } /** Create valid ChpModel by calling the apply function. diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index 04e3a9b7e3..ba23987f8b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -84,7 +84,7 @@ final case class FixedFeedInModel( ): ProvideFlexOptions = ProvideMinMaxFlexOptions.noFlexOption( uuid, - calculateActivePower(ConstantState, data) + calculateActivePower(lastState, data) ) override def handleControlledPowerChange( diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index 94ce736644..de634712be 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -718,7 +718,7 @@ final case class PvModel private ( ): ProvideFlexOptions = { val power = calculateActivePower(ConstantState, data) - ProvideMinMaxFlexOptions(uuid, power, power, DefaultQuantities.zeroMW) + ProvideMinMaxFlexOptions(uuid, power, power, DefaultQuantities.zeroKW) } override def handleControlledPowerChange( diff --git a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala index d063479c67..b2d1ff8458 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala @@ -23,7 +23,7 @@ import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMin import edu.ie3.util.quantities.PowerSystemUnits._ import edu.ie3.util.scala.OperationInterval import squants._ -import squants.energy.{Kilowatts, Megawatts, Watts} +import squants.energy.{Kilowatts, Watts} import squants.mass.{Kilograms, KilogramsPerCubicMeter} import squants.motion.{MetersPerSecond, Pressure} import squants.space.SquareMeters @@ -199,7 +199,7 @@ final case class WecModel( ): ProvideFlexOptions = { val power = calculateActivePower(ConstantState, data) - ProvideMinMaxFlexOptions(uuid, power, power, Megawatts(0d)) + ProvideMinMaxFlexOptions(uuid, power, power, Kilowatts(0d)) } override def handleControlledPowerChange( diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala index 72fd9f79d6..6557f8cd9b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala @@ -53,12 +53,11 @@ abstract class LoadModel[D <: LoadRelevantData]( override def determineFlexOptions( data: D, lastState: ConstantState.type - ): ProvideFlexOptions = { - val power = calculateActivePower(lastState, data) - - // no flexibility - ProvideMinMaxFlexOptions(uuid, power, power, power) - } + ): ProvideFlexOptions = + ProvideMinMaxFlexOptions.noFlexOption( + uuid, + calculateActivePower(lastState, data) + ) override def handleControlledPowerChange( data: D, diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala index d498fc18c0..760575571e 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala @@ -92,6 +92,7 @@ object MinMaxFlexibilityMessage { /** Creates a [[ProvideMinMaxFlexOptions]] message that does not allow any * flexibility, meaning that min = ref = max power. + * * @param modelUuid * The UUID of the flex provider asset model * @param power From 401cf55a5dd41bf326b3383ceb882b86161fd483 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:15:47 +0100 Subject: [PATCH 167/305] Solving state/ambient temp issue, refactorings --- .../participant/hp/HpAgentFundamentals.scala | 4 +- .../simona/model/participant/HpModel.scala | 74 +++++++++---------- .../simona/model/thermal/ThermalGrid.scala | 26 ++++--- .../simona/model/thermal/ThermalHouse.scala | 3 +- .../model/participant/HpModelSpec.scala | 26 +++---- 5 files changed, 65 insertions(+), 68 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 159b2555d2..4330b8ebd8 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -116,7 +116,7 @@ trait HpAgentFundamentals ): HpState = HpState( isRunning = false, -1, - Celsius(10d), // TODO + None, Megawatts(0d), Megawatts(0d), ThermalGrid.startingState(thermalGrid), @@ -285,7 +285,7 @@ trait HpAgentFundamentals calcRelevantData: HpRelevantData, nodalVoltage: squants.Dimensionless, model: HpModel - ): HpState = model.calculateNextState(modelState, calcRelevantData) + ): HpState = model.determineState(modelState, calcRelevantData) /** Abstract definition, individual implementations found in individual agent * fundamental classes diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index af97ac1ed5..69f5bbb720 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -80,8 +80,8 @@ final case class HpModel( /** As this is a state-full model (with respect to the current operation * condition and inner temperature), the power calculation operates on the * current state of the model, which has to be calculated beforehand by - * [[HpModel.calculateNextState]]. This state then is fed into the power - * calculation logic by hpData. + * [[HpModel.determineState]]. This state then is fed into the power + * calculation logic by [[HpState]]. * * @param modelState * Current state of the heat pump @@ -99,6 +99,7 @@ final case class HpModel( * updated, because the calculation of apparent power in * [[ApparentPowerAndHeatParticipant]] did trigger it. So we only need to * extract the information + * * @param tick * Current simulation time for the calculation * @param modelState @@ -112,8 +113,7 @@ final case class HpModel( tick: Long, modelState: HpState, data: HpRelevantData - ): Power = - modelState.qDot + ): Power = modelState.qDot /** Given a [[HpRelevantData]] object and the current [[HpState]], this * function calculates the heat pump's next state To get the actual active @@ -126,7 +126,7 @@ final case class HpModel( * @return * next [[HpState]] */ - def calculateNextState( + def determineState( state: HpState, relevantData: HpRelevantData ): HpState = { @@ -147,19 +147,17 @@ final case class HpModel( * @return * boolean defining if heat pump runs in next time step */ - def operatesInNextState( + private def operatesInNextState( state: HpState, relevantData: HpRelevantData - ): Boolean = - relevantData match { - case HpRelevantData(currentTimeTick, ambientTemperature) => - val demand = thermalGrid.energyDemand( - currentTimeTick, - ambientTemperature, - state.thermalGridState - ) - demand.hasRequiredDemand || (state.isRunning && demand.hasAdditionalDemand) - } + ): Boolean = { + val demand = thermalGrid.energyDemand( + relevantData.currentTick, + relevantData.ambientTemperature, + state.thermalGridState + ) + demand.hasRequiredDemand || (state.isRunning && demand.hasAdditionalDemand) + } /** Calculate state depending on whether heat pump is needed or not. Also * calculate inner temperature change of thermal house and update its inner @@ -184,21 +182,19 @@ final case class HpModel( (pRated, pThermal * scalingFactor) else (DefaultQuantities.zeroKW, DefaultQuantities.zeroKW) - /* Push thermal energy to the thermal grid and get it's updated state in return */ - val (thermalGridState, maybeThreshold) = relevantData match { - case HpRelevantData(currentTimeTick, _) => - thermalGrid.updateState( - currentTimeTick, - state.thermalGridState, - state.ambientTemperature, - newThermalPower - ) - } + /* Push thermal energy to the thermal grid and get its updated state in return */ + val (thermalGridState, maybeThreshold) = + thermalGrid.updateState( + relevantData.currentTick, + state.thermalGridState, + state.ambientTemperature.getOrElse(relevantData.ambientTemperature), + newThermalPower + ) HpState( isRunning, - relevantData.currentTimeTick, - relevantData.ambientTemperature, + relevantData.currentTick, + Some(relevantData.ambientTemperature), newActivePower, newThermalPower, thermalGridState, @@ -211,11 +207,11 @@ final case class HpModel( lastState: HpState ): ProvideFlexOptions = { /* Determine the operating state in the given tick */ - val updatedState = calculateNextState(lastState, data) + val updatedState = determineState(lastState, data) /* Determine the options we have */ val thermalEnergyDemand = thermalGrid.energyDemand( - data.currentTimeTick, + data.currentTick, data.ambientTemperature, lastState.thermalGridState ) @@ -262,7 +258,7 @@ final case class HpModel( override def handleControlledPowerChange( data: HpRelevantData, lastState: HpState, - setPower: squants.Power + setPower: Power ): (HpState, FlexChangeIndicator) = { /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ val turnOn = setPower > (sRated * cosPhiRated * 0.5) @@ -334,7 +330,7 @@ object HpModel { * @param lastTimeTick * contains last time tick * @param ambientTemperature - * Ambient temperature + * Optional ambient temperature, if available * @param activePower * result active power * @param qDot @@ -348,7 +344,7 @@ object HpModel { final case class HpState( isRunning: Boolean, lastTimeTick: Long, - ambientTemperature: Temperature, + ambientTemperature: Option[Temperature], activePower: Power, qDot: Power, thermalGridState: ThermalGridState, @@ -356,18 +352,16 @@ object HpModel { ) extends ModelState /** Main data required for simulation/calculation, containing a [[HpState]] - * and the current time tick.

[[HpRelevantData.currentTimeTick]] and - * [[HpState.lastTimeTick]] form a time interval for the current state - * calculation. One time tick represents one second (3600 time ticks = 1 - * hour). + * and the current time tick. One time tick represents one second (3600 time + * ticks = 1 hour). * - * @param currentTimeTick + * @param currentTick * contains current time tick * @param ambientTemperature - * Ambient temperature + * Ambient temperature at current tick */ final case class HpRelevantData( - currentTimeTick: Long, + currentTick: Long, ambientTemperature: Temperature ) extends CalcRelevantData diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala index fc56536e97..e213a902ed 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -158,12 +158,13 @@ final case class ThermalGrid( case _ => state.storageState } - val (updatedHouseState, maybeHouseThreshold) = thermalHouse.updateState( - tick, - lastHouseState, - ambientTemperature, - qDot - ) + val (updatedHouseState, maybeHouseThreshold) = + thermalHouse.determineState( + tick, + lastHouseState, + ambientTemperature, + qDot + ) if ( thermalHouse.isInnerTemperatureTooHigh( @@ -172,7 +173,7 @@ final case class ThermalGrid( ) { /* The house is already heated up fully, set back the infeed and put it into storage, if available */ val (fullHouseState, maybeFullHouseThreshold) = - thermalHouse.updateState( + thermalHouse.determineState( tick, lastHouseState, ambientTemperature, @@ -243,6 +244,7 @@ final case class ThermalGrid( } /** Handle consumption (or no infeed) from thermal grid + * * @param tick * Current tick * @param ambientTemperature @@ -263,7 +265,7 @@ final case class ThermalGrid( /* House will be left with no influx in all cases. Determine if and when a threshold is reached */ val maybeUpdatedHouseState = house.zip(state.houseState).map { case (house, houseState) => - house.updateState( + house.determineState( tick, houseState, ambientTemperature, @@ -303,9 +305,9 @@ final case class ThermalGrid( } /** Check, if the storage can heat the house. This is only done, if

    - *
  • The house has reached it's lower temperature boundary
  • There - * is no infeed from external
  • The storage is not empty itself
  • - *
+ *
  • the house has reached it's lower temperature boundary,
  • there + * is no infeed from external and
  • the storage is not empty + * itself
  • * @param tick * The current tick * @param maybeHouseState @@ -357,7 +359,7 @@ final case class ThermalGrid( ) ) ) - val revisedHouseState = thermalHouse.updateState( + val revisedHouseState = thermalHouse.determineState( tick, formerHouseState.getOrElse( throw new InconsistentStateException( diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala index 263ded3683..bc5708d5a6 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -290,6 +290,7 @@ final case class ThermalHouse( } /** Update the current state of the house + * * @param tick * current instance in time * @param state @@ -301,7 +302,7 @@ final case class ThermalHouse( * @return * Updated state and the tick in which the next threshold is reached */ - def updateState( + def determineState( tick: Long, state: ThermalHouseState, ambientTemperature: Temperature, diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index 189844505f..8fc80e1b7d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -45,7 +45,7 @@ class HpModelSpec HpState( isRunning = false, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(17d)), @@ -60,7 +60,7 @@ class HpModelSpec HpState( isRunning = false, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(18)), @@ -75,7 +75,7 @@ class HpModelSpec HpState( isRunning = false, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(20)), @@ -90,7 +90,7 @@ class HpModelSpec HpState( isRunning = false, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(22)), @@ -105,7 +105,7 @@ class HpModelSpec HpState( isRunning = false, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(23)), @@ -120,7 +120,7 @@ class HpModelSpec HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(17)), @@ -135,7 +135,7 @@ class HpModelSpec HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(18)), @@ -150,7 +150,7 @@ class HpModelSpec HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(20)), @@ -165,7 +165,7 @@ class HpModelSpec HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(22)), @@ -180,7 +180,7 @@ class HpModelSpec HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(25)), @@ -206,7 +206,7 @@ class HpModelSpec val grid = thermalGrid(house) val hp = hpModel(grid) - hp.calculateNextState(state, data) match { + hp.determineState(state, data) match { case HpState( isRunning, _, @@ -237,7 +237,7 @@ class HpModelSpec val grid = thermalGrid(house, Some(thermalStorage)) val hp = hpModel(grid) // Tick, at which the house is heated up - val relevantData = hpData.copy(currentTimeTick = 2763L) + val relevantData = hpData.copy(currentTick = 2763L) val thermalState = ThermalGridState( Some( ThermalHouseState( @@ -257,7 +257,7 @@ class HpModelSpec val lastState = HpState( isRunning = true, 0, - hpData.ambientTemperature, + Some(hpData.ambientTemperature), Kilowatts(95.0), Kilowatts(80.0), thermalState, From e2387fecfbd911dab231e93c1c7da7b778139f68 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:16:11 +0100 Subject: [PATCH 168/305] Marking methods as deprecated, cleanup --- .../participant/hp/HpAgentFundamentals.scala | 1 - .../thermal/CylindricalThermalStorage.scala | 20 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 4330b8ebd8..e59fdac1d0 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -55,7 +55,6 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef} import org.apache.pekko.actor.{ActorRef, FSM} import squants.energy.Megawatts -import squants.thermal.Celsius import squants.{Dimensionless, Each, Power} import java.time.ZonedDateTime diff --git a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala index 1d750cae6f..c3f7ee83b4 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala @@ -129,9 +129,17 @@ final case class CylindricalThermalStorage( (ThermalStorageState(tick, updatedEnergy, qDot), nextThreshold) } + override def startingState: ThermalStorageState = ThermalStorageState( + -1L, + getMinEnergyThreshold, + Kilowatts(0d) + ) + + @deprecated("Use thermal storage state instead") override def usableThermalEnergy: Energy = _storedEnergy - minEnergyThreshold + @deprecated("Use thermal storage state instead") override def tryToStoreAndReturnRemainder( addedEnergy: Energy ): Option[Energy] = { @@ -146,6 +154,7 @@ final case class CylindricalThermalStorage( Option.empty } + @deprecated("Use thermal storage state instead") override def tryToTakeAndReturnLack( takenEnergy: Energy ): Option[Energy] = { @@ -154,20 +163,15 @@ final case class CylindricalThermalStorage( if (_storedEnergy < minEnergyThreshold) { val lack = minEnergyThreshold - _storedEnergy _storedEnergy = minEnergyThreshold - return Option(lack) + return Some(lack) } } - Option.empty + None } - override def startingState: ThermalStorageState = ThermalStorageState( - -1L, - getMinEnergyThreshold, - Kilowatts(0d) - ) } -case object CylindricalThermalStorage { +object CylindricalThermalStorage { /** Function to construct a new [[CylindricalThermalStorage]] based on a * provided [[CylindricalStorageInput]] From 6498655c33a7d19a5b46fdb89b67855c519dd9e2 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:21:50 +0100 Subject: [PATCH 169/305] Removing unnecessary trait --- .../ie3/simona/model/thermal/ThermalHouse.scala | 4 ++-- .../simona/model/thermal/ThermalModelState.scala | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/model/thermal/ThermalModelState.scala diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala index bc5708d5a6..ad20981b72 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -446,10 +446,10 @@ object ThermalHouse { * Continuous infeed of thermal energy since the given tick */ final case class ThermalHouseState( - override val tick: Long, + tick: Long, innerTemperature: Temperature, qDot: Power - ) extends ThermalModelState + ) def startingState(house: ThermalHouse): ThermalHouseState = ThermalHouseState( diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalModelState.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalModelState.scala deleted file mode 100644 index 209c58ff8a..0000000000 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalModelState.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.thermal - -/** Trait to group all states, that belong to a thermal model - */ -trait ThermalModelState { - - /** Simulation instance, since that state is valid - */ - val tick: Long -} From 1da75f96f8e3359a7edc0b6af3f8176a0e39340e Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:26:47 +0100 Subject: [PATCH 170/305] Removing dependency constraint --- build.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build.gradle b/build.gradle index acac04204f..d707adb0c6 100644 --- a/build.gradle +++ b/build.gradle @@ -67,11 +67,6 @@ repositories { } dependencies { - constraints { - implementation( 'com.fasterxml.jackson.core:jackson-databind:2.16.0+' ){ - because "[CVE-2020-25649] CWE-611: Improper Restriction of XML External Entity Reference ('XXE')" - } - } // ie³ internal repository implementation('com.github.ie3-institute:PowerSystemUtils:2.0') { From 16fdf8fc2547576be8c2af647632ea29f5c95900 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:30:46 +0100 Subject: [PATCH 171/305] Fixing tests after changing initial ambient temp --- .../agent/participant/HpAgentModelCalculationSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 077736af2b..e1360df7c5 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -522,7 +522,7 @@ class HpAgentModelCalculationSpec thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature ~= Celsius(20.99998675925926)) shouldBe true + (innerTemperature ~= Celsius(20.999976906944)) shouldBe true case None => fail( s"Expected to get a result for thermal house '${hpInputModel.getUuid}'" @@ -650,7 +650,7 @@ class HpAgentModelCalculationSpec thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature ~= Celsius(20.99998675925926)) shouldBe true + (innerTemperature ~= Celsius(20.999976906944)) shouldBe true case None => fail( s"Expected to get a result for thermal house '${hpInputModel.getUuid}'" From 60ec361c789625eacb06e46efb68dd6098340943 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 11:40:06 +0100 Subject: [PATCH 172/305] Removing todo --- .../ie3/simona/agent/participant/hp/HpAgentFundamentals.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index e59fdac1d0..8cea8f51c5 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -380,8 +380,6 @@ trait HpAgentFundamentals baseStateData.receivedSecondaryDataStore .last(tick) .flatMap { case (receivedTick, receivedValues) => - // FIXME: This fallback should check if the activation comes from an internal event. Only then it's valid to - // take previously received values if (receivedTick != tick) log.debug( s"The model ${baseStateData.model.getUuid} needs to do calculations with values received " + From beadafa916d3c61900a5a287d47445e3ef73f8ac Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 31 Jan 2024 17:42:21 +0100 Subject: [PATCH 173/305] Fixing codacy issue --- .../fixedfeedin/FixedFeedInAgentFundamentals.scala | 4 ++-- .../simona/agent/participant/load/LoadAgentFundamentals.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala index 5f4b34dd3a..22e6f1dd0d 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala @@ -265,7 +265,7 @@ protected trait FixedFeedInAgentFundamentals ConstantState.type, FixedFeedInModel ], - ConstantState, + state: ConstantState.type, voltage: Dimensionless ) => baseStateData.model match { @@ -273,7 +273,7 @@ protected trait FixedFeedInAgentFundamentals fixedModel.calculatePower( currentTick, voltage, - ConstantState, + state, FixedRelevantData ) case unsupportedModel => diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index 6dc3d70211..31df2fa55e 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -419,13 +419,13 @@ object LoadAgentFundamentals { ConstantState.type, FixedLoadModel ], - ConstantState, + state: ConstantState.type, voltage: Dimensionless ) => baseStateData.model.calculatePower( tick, voltage, - ConstantState, + state, FixedLoadRelevantData ) } From 6ed99df249d1082f2adda92d1b30884f3c3c187b Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Thu, 1 Feb 2024 13:07:42 +0100 Subject: [PATCH 174/305] Create squants scalatest matchers --- .../agent/grid/DBFSMockGridAgents.scala | 8 +- .../agent/grid/GridResultsSupportSpec.scala | 22 ++---- .../EvcsAgentModelCalculationSpec.scala | 24 +++--- ...FixedFeedInAgentModelCalculationSpec.scala | 20 ++--- .../HpAgentModelCalculationSpec.scala | 60 +++++++-------- .../LoadAgentFixedModelCalculationSpec.scala | 20 ++--- ...LoadAgentProfileModelCalculationSpec.scala | 16 ++-- .../ParticipantAgentExternalSourceSpec.scala | 24 +++--- .../ParticipantAgentFundamentalsSpec.scala | 24 +++--- .../PvAgentModelCalculationSpec.scala | 24 +++--- .../WecAgentModelCalculationSpec.scala | 24 +++--- .../model/assets/control/QControlSpec.scala | 15 ++-- .../edu/ie3/simona/model/grid/LineSpec.scala | 34 ++++----- .../model/grid/NodeInputModelSpec.scala | 7 +- .../model/grid/Transformer3wModelSpec.scala | 24 +++--- .../model/grid/TransformerModelSpec.scala | 12 +-- .../ApparentPowerAndHeatSpec.scala | 12 +-- .../participant/CharacteristicSpec.scala | 20 ++--- .../participant/FixedFeedInModelSpec.scala | 9 ++- .../model/participant/HpModelSpec.scala | 12 +-- .../participant/load/LoadModelSpec.scala | 4 +- .../load/LoadProfileStoreSpec.scala | 2 +- .../model/thermal/ThermalGridSpec.scala | 18 ++--- .../ThermalGridWithHouseAndStorageSpec.scala | 76 +++++++++++-------- .../ThermalGridWithHouseOnlySpec.scala | 35 +++++---- .../ThermalGridWithStorageOnlySpec.scala | 34 ++++----- .../primary/PrimaryServiceWorkerSpec.scala | 2 +- .../weather/SampleWeatherSourceSpec.scala | 19 ++--- .../weather/WeatherSourceWrapperSpec.scala | 51 ++++++------- .../edu/ie3/simona/test/common/UnitSpec.scala | 3 +- .../test/matchers/SquantsMatchers.scala | 27 +++++++ .../util/quantities/QuantityUtilSpec.scala | 11 ++- 32 files changed, 366 insertions(+), 327 deletions(-) create mode 100644 src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index 0f19e2055d..310e1522e6 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -73,8 +73,8 @@ trait DBFSMockGridAgents extends UnitSpec { _.nodeUuid == expectedVoltage.nodeUuid ) match { case Some(ExchangeVoltage(_, actualE, actualF)) => - actualE ~= Volts(3d) - actualF ~= expectedVoltage.f + equalWithTolerance(actualE, expectedVoltage.e) + equalWithTolerance(actualF, expectedVoltage.f) case None => fail( s"Expected ExchangeVoltage with node UUID ${expectedVoltage.nodeUuid} " + @@ -122,8 +122,8 @@ trait DBFSMockGridAgents extends UnitSpec { expectedExchangedPowers.foreach { expectedPower => exchangedPower.find(_.nodeUuid == expectedPower.nodeUuid) match { case Some(ExchangePower(_, actualP, actualQ)) => - (actualP ~= expectedPower.p) shouldBe true - (actualQ ~= expectedPower.q) shouldBe true + equalWithTolerance(actualP, expectedPower.p) + equalWithTolerance(actualQ, expectedPower.q) case None => fail( s"Expected ExchangePower with node UUID ${expectedPower.nodeUuid} " + diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala index c9d17d2379..e69efca8b3 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala @@ -489,10 +489,8 @@ class GridResultsSupportSpec time shouldBe timeStamp input shouldBe transformerA.uuid tapPos shouldBe transformerA.currentTapPos - (currentMagnitude ~= Amperes( - 13.15547500d - )) shouldBe true - (currentAngle ~= Degrees(-45.0000000d)) shouldBe true + equalWithTolerance(currentMagnitude, Amperes(13.15547500d)) + equalWithTolerance(currentAngle, Degrees(-45.0000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -517,8 +515,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformerB.uuid - (currentMagnitude ~= Amperes(14.14213562d)) shouldBe true - (currentAngle ~= Degrees(135.000000d)) shouldBe true + equalWithTolerance(currentMagnitude, Amperes(14.14213562d)) + equalWithTolerance(currentAngle, Degrees(135.000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -543,10 +541,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformerC.uuid - (currentMagnitude ~= Amperes( - 14.14213562d - )) shouldBe true - (currentAngle ~= Degrees(135.0000000d)) shouldBe true + equalWithTolerance(currentMagnitude, Amperes(14.14213562d)) + equalWithTolerance(currentAngle, Degrees(135.0000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -573,10 +569,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformer3wInput.getUuid - (currentMagnitude ~= Amperes( - 11.4542161d - )) shouldBe true - (currentAngle ~= Degrees(-89.4475391d)) shouldBe true + equalWithTolerance(currentMagnitude, Amperes(11.4542161d)) + equalWithTolerance(currentAngle, Degrees(-89.4475391d)) case wrong => fail(s"Got wrong result: '$wrong'") } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 5f53c56304..f53cfe9d73 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -461,8 +461,8 @@ class EvcsAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0d)) shouldBe true - (q ~= Megavars(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) } } case _ => @@ -568,8 +568,8 @@ class EvcsAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0d)) shouldBe true - (q ~= Megavars(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) } } case _ => @@ -613,8 +613,8 @@ class EvcsAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -825,8 +825,8 @@ class EvcsAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.00572)) + equalWithTolerance(q, Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -843,8 +843,8 @@ class EvcsAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.00572)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -859,8 +859,8 @@ class EvcsAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.00572)) shouldBe true - (q ~= Megavars(-0.00335669)) shouldBe true + equalWithTolerance(p, Megawatts(0.00572)) + equalWithTolerance(q, Megavars(-0.00335669)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index 1b3046f6f4..66945de876 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -317,8 +317,8 @@ class FixedFeedInAgentModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - (p ~= Megawatts(-268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(-268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 900.") @@ -364,8 +364,8 @@ class FixedFeedInAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(-268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(-268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -402,8 +402,8 @@ class FixedFeedInAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(-268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(-268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -420,8 +420,8 @@ class FixedFeedInAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(-268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(-268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -436,8 +436,8 @@ class FixedFeedInAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(-0.000268603)) shouldBe true - (q ~= Megavars(-22.07138418e-6)) shouldBe true + equalWithTolerance(p, Megawatts(-0.000268603)) + equalWithTolerance(q, Megavars(-22.07138418e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 9ac4aac473..d025c025a1 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -487,17 +487,16 @@ class HpAgentModelCalculationSpec ) => isRunning shouldBe false lastTimeTick shouldBe 0L - (activePower =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(activePower, Kilowatts(0d)) - (qDot =~ - Kilowatts(0d)) shouldBe true + equalWithTolerance(qDot, Kilowatts(0d)) thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature =~ - Celsius( - 20.9999769069444444444444444444444 - )) shouldBe true + equalWithTolerance( + innerTemperature, + Celsius(20.9999769069444444444444444444444) + ) case None => fail( s"Expected to get a result for thermal house '${inputModel.getUuid}'" @@ -505,7 +504,7 @@ class HpAgentModelCalculationSpec } currentTimeTick shouldBe 0L - (ambientTemperature =~ Celsius(1.815d)) shouldBe true + equalWithTolerance(ambientTemperature, Celsius(1.815d)) case None => fail("Did expect to get hp relevant data for tick 0L") } @@ -520,9 +519,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(0d)) shouldBe true - q =~ Megavars(0d) shouldBe true - qDot =~ Megawatts(0d) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) + equalWithTolerance(qDot, Megawatts(0d)) } } case _ => @@ -621,15 +620,16 @@ class HpAgentModelCalculationSpec ) => isRunning shouldBe false lastTimeTick shouldBe 0L - (activePower =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(activePower, Kilowatts(0d)) - (qDot =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(qDot, Kilowatts(0d)) thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - (innerTemperature =~ Celsius( - 20.9999769069444444444444444444444 - )) shouldBe true + equalWithTolerance( + innerTemperature, + Celsius(20.9999769069444444444444444444444) + ) case None => fail( s"Expected to get a result for thermal house '${inputModel.getUuid}'" @@ -637,8 +637,7 @@ class HpAgentModelCalculationSpec } currentTimeTick shouldBe 0L - (ambientTemperature =~ - Celsius(1.815d)) shouldBe true + equalWithTolerance(ambientTemperature, Celsius(1.815d)) case None => fail("Did expect to get hp relevant data for tick 0L") } @@ -653,11 +652,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 0.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - ( - qDot =~ Megawatts(0d) - ) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) + equalWithTolerance(qDot, Megawatts(0d)) } } case _ => @@ -722,8 +719,8 @@ class HpAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) } } @@ -812,8 +809,8 @@ class HpAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) case answer => fail(s"Did not expect to get that answer: $answer") } @@ -831,8 +828,8 @@ class HpAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) } } @@ -847,9 +844,8 @@ class HpAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index d7252f1dab..6637e8186d 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -311,8 +311,8 @@ class LoadAgentFixedModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - (p ~= Megawatts(268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 0.") @@ -358,8 +358,8 @@ class LoadAgentFixedModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -396,8 +396,8 @@ class LoadAgentFixedModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -414,8 +414,8 @@ class LoadAgentFixedModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(268.603e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(268.603e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -430,8 +430,8 @@ class LoadAgentFixedModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(268.603e-6)) shouldBe true - (q ~= Megavars(-22.07138e-6)) shouldBe true + equalWithTolerance(p, Megawatts(268.603e-6)) + equalWithTolerance(q, Megavars(-22.07138e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index ee17a58989..49c942708a 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -311,8 +311,8 @@ class LoadAgentProfileModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - (p ~= Megawatts(84.000938e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(84.000938e-6)) + equalWithTolerance(q, Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 0.") @@ -360,8 +360,8 @@ class LoadAgentProfileModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(79.750890e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(79.750890e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -377,8 +377,8 @@ class LoadAgentProfileModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(79.750890e-6)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(79.750890e-6)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -393,8 +393,8 @@ class LoadAgentProfileModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(79.750890e-6)) shouldBe true - (q ~= Megavars(-22.0714e-6)) shouldBe true + equalWithTolerance(p, Megawatts(79.750890e-6)) + equalWithTolerance(q, Megavars(-22.0714e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index bff18f7a87..3959e62587 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -563,7 +563,7 @@ class ParticipantAgentExternalSourceSpec val actualFunction = mockAgent.underlyingActor.getReactivePowerFunction(0L, baseStateData) - (actualFunction(Kilowatts(100.0)) ~= Kilovars(0.0)) shouldBe true + equalWithTolerance(actualFunction(Kilowatts(100.0)), Kilovars(0.0)) } "correctly determine the reactive power function from model when requested" in { @@ -592,7 +592,7 @@ class ParticipantAgentExternalSourceSpec val actualFunction = mockAgent.underlyingActor.getReactivePowerFunction(0L, baseStateData) - (actualFunction(Kilowatts(100.0)) ~= Kilovars(48.43221)) shouldBe true + equalWithTolerance(actualFunction(Kilowatts(100.0)), Kilovars(48.43221)) } "provide correct average power after three data ticks are available" in { @@ -667,8 +667,8 @@ class ParticipantAgentExternalSourceSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.095)) shouldBe true - (q ~= Megavars(0.0312)) shouldBe true + equalWithTolerance(p, Megawatts(0.095)) + equalWithTolerance(q, Megavars(0.0312)) } } @@ -684,8 +684,8 @@ class ParticipantAgentExternalSourceSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.095)) shouldBe true - (q ~= Megavars(0.0312)) shouldBe true + equalWithTolerance(p, Megawatts(0.095)) + equalWithTolerance(q, Megavars(0.0312)) } } @@ -701,8 +701,8 @@ class ParticipantAgentExternalSourceSpec /* Expect, that nothing has changed, as this model is meant to forward information from outside */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.095)) shouldBe true - (q ~= Megavars(0.0312)) shouldBe true + equalWithTolerance(p, Megawatts(0.095)) + equalWithTolerance(q, Megavars(0.0312)) } } @@ -764,8 +764,8 @@ class ParticipantAgentExternalSourceSpec participantAgent.prepareData(data, reactivePowerFunction) match { case Success(ApparentPower(p, q)) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) case Success(value) => fail(s"Succeeded, but with wrong data: '$value'.") case Failure(exception) => @@ -788,8 +788,8 @@ class ParticipantAgentExternalSourceSpec (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) ) match { case Success(ApparentPower(p, q)) => - (p ~= Kilowatts(100.0)) shouldBe true - (q ~= Kilovars(48.43221)) shouldBe true + equalWithTolerance(p, Kilowatts(100.0)) + equalWithTolerance(q, Kilovars(48.43221)) case Success(value) => fail(s"Succeeded, but with wrong data: '$value'.") case Failure(exception) => diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala index 3d87971bca..0c944e6a9e 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala @@ -320,8 +320,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(0.8666666666666667)) shouldBe true - (q ~= Megavars(0.5333333333333334)) shouldBe true + equalWithTolerance(p, Megawatts(0.8666666666666667)) + equalWithTolerance(q, Megavars(0.5333333333333334)) } } @@ -335,8 +335,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(4.571428571428573)) shouldBe true - (q ~= Megavars(3.571428571428571)) shouldBe true + equalWithTolerance(p, Megawatts(4.571428571428573)) + equalWithTolerance(q, Megavars(3.571428571428571)) } } @@ -350,8 +350,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(4.571428571428573)) shouldBe true - (q ~= Megavars(3.571428571428571)) shouldBe true + equalWithTolerance(p, Megawatts(4.571428571428573)) + equalWithTolerance(q, Megavars(3.571428571428571)) } } @@ -365,8 +365,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(0.8666666666666667)) shouldBe true - (q ~= Megavars(2.8666666666666667)) shouldBe true + equalWithTolerance(p, Megawatts(0.8666666666666667)) + equalWithTolerance(q, Megavars(2.8666666666666667)) } } @@ -380,8 +380,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(4.571428571428573)) shouldBe true - (q ~= Megavars(21.71428571428571)) shouldBe true + equalWithTolerance(p, Megawatts(4.571428571428573)) + equalWithTolerance(q, Megavars(21.71428571428571)) } } @@ -395,8 +395,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - (p ~= Megawatts(4.571428571428573)) shouldBe true - (q ~= Megavars(21.71428571428571)) shouldBe true + equalWithTolerance(p, Megawatts(4.571428571428573)) + equalWithTolerance(q, Megavars(21.71428571428571)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index 3a0882ed1c..a2e5be7fec 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -487,8 +487,8 @@ class PvAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } case _ => @@ -590,8 +590,8 @@ class PvAgentModelCalculationSpec fail("Expected a simulation result for tick 0.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } case _ => @@ -656,8 +656,8 @@ class PvAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -746,8 +746,8 @@ class PvAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -764,8 +764,8 @@ class PvAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -780,8 +780,8 @@ class PvAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(-780.6e-6)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(-780.6e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index 24ccac5f34..0422140a36 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -479,8 +479,8 @@ class WecAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } case _ => @@ -589,8 +589,8 @@ class WecAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } case _ => @@ -655,8 +655,8 @@ class WecAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -745,8 +745,8 @@ class WecAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -763,8 +763,8 @@ class WecAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(0.0)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(0.0)) } } @@ -779,8 +779,8 @@ class WecAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - (p ~= Megawatts(0.0)) shouldBe true - (q ~= Megavars(-156.1249e-3)) shouldBe true + equalWithTolerance(p, Megawatts(0.0)) + equalWithTolerance(q, Megavars(-156.1249e-3)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala index 23676e71ca..2951f5c376 100644 --- a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala @@ -118,20 +118,19 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { "provide correct values when the requested value is part of the containing xy coordinates" in { val requestedValue = Each(0.5) - (validCosPhiP.cosPhi(requestedValue) ~= Each(-0.8)) shouldBe true + + equalWithTolerance(validCosPhiP.cosPhi(requestedValue), Each(-0.8)) } "provide an interpolated value when the requested value is not part of the containing xy coordinates" in { val requestedValue = Each(0.75) - (validCosPhiP.cosPhi(requestedValue) ~= Each(-0.5)) shouldBe true + equalWithTolerance(validCosPhiP.cosPhi(requestedValue), Each(-0.5)) } "provide the last known value when the requested value is outside of the containing xy coordinates" in { - - (validCosPhiP.cosPhi(Each(2.0)) ~= Each(-0.2)) shouldBe true - - (validCosPhiP.cosPhi(Each(-1.0)) ~= Each(-1.0)) shouldBe true + equalWithTolerance(validCosPhiP.cosPhi(Each(2.0)), Each(-0.2)) + equalWithTolerance(validCosPhiP.cosPhi(Each(-1.0)), Each(-1.0)) } } @@ -163,7 +162,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => - (validQV.q(Each(v), qMax) ~= qMax * scaleExpected) shouldBe true + equalWithTolerance(validQV.q(Each(v), qMax), qMax * scaleExpected) } } @@ -201,7 +200,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => - (validQV.q(Each(v), qMax) ~= qMax * scaleExpected) shouldBe true + equalWithTolerance(validQV.q(Each(v), qMax), qMax * scaleExpected) } } } diff --git a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala index baebd2efe3..124001bf22 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala @@ -86,21 +86,21 @@ class LineSpec extends UnitSpec with LineInputTestData { nodeAUuid shouldBe lineInputMs10Kv.getNodeA.getUuid nodeBUuid shouldBe lineInputMs10Kv.getNodeB.getUuid amount shouldBe lineInputMs10Kv.getParallelDevices - (iMax ~= Amperes( - lineInputMs10Kv.getType.getiMax().getValue.doubleValue() - )) shouldBe true - - (r ~= Each(0.0013109999999999999d)) shouldBe true - (x ~= Each(0.0010680000000000002d)) shouldBe true - (g ~= Each(0d)) shouldBe true - (b ~= Each(0.00000060375d)) shouldBe true + equalWithTolerance( + iMax, + Amperes(lineInputMs10Kv.getType.getiMax().getValue.doubleValue()) + ) + + equalWithTolerance(r, Each(0.0013109999999999999d)) + equalWithTolerance(x, Each(0.0010680000000000002d)) + equalWithTolerance(g, Each(0d)) + equalWithTolerance(b, Each(0.00000060375d)) } - (validLineModel.b0() ~= Each(0.000000301875d)) shouldBe true - (validLineModel.bij() ~= Each(-373.5121155369499d)) shouldBe true - (validLineModel.g0() ~= Each(0d)) shouldBe true - (validLineModel.gij() ~= Each(458.4966137349637d)) shouldBe true - + equalWithTolerance(validLineModel.b0(), Each(0.000000301875d)) + equalWithTolerance(validLineModel.bij(), Each(-373.5121155369499d)) + equalWithTolerance(validLineModel.g0(), Each(0d)) + equalWithTolerance(validLineModel.gij(), Each(458.4966137349637d)) } } @@ -152,10 +152,10 @@ class LineSpec extends UnitSpec with LineInputTestData { val iNodeB: squants.electro.ElectricCurrent = Amperes(145d) - (LineModel.utilisation(validLineModel, iNodeA, iNodeB) ~= Each( - 22.222222222222218 - )) shouldBe true - + equalWithTolerance( + LineModel.utilisation(validLineModel, iNodeA, iNodeB), + Each(22.222222222222218) + ) } "be able to be enabled and disabled on request" in new FiveLinesWithNodes { diff --git a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala index 4f6f89a0a8..db70889638 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala @@ -43,9 +43,10 @@ class NodeInputModelSpec extends UnitSpec with NodeInputTestData { id shouldBe nodeInputNoSlackNs04KvA.getId operationInterval shouldBe defaultOperationInterval isSlack shouldBe nodeInputNoSlackNs04KvA.isSlack - (vTarget ~= Each( - nodeInputNoSlackNs04KvA.getvTarget.getValue.doubleValue() - )) shouldBe true + equalWithTolerance( + vTarget, + Each(nodeInputNoSlackNs04KvA.getvTarget.getValue.doubleValue()) + ) voltLvl shouldBe nodeInputNoSlackNs04KvA.getVoltLvl } diff --git a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala index e5082e6a3b..c1570a8b24 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala @@ -85,10 +85,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseA - (r ~= Each(1.03878e-3)) shouldBe true - (x ~= Each(166.34349e-3)) shouldBe true - (g ~= Each(1.874312e-6)) shouldBe true - (b ~= Each(-75.012912e-6)) shouldBe true + equalWithTolerance(r, Each(1.03878e-3)) + equalWithTolerance(x, Each(166.34349e-3)) + equalWithTolerance(g, Each(1.874312e-6)) + equalWithTolerance(b, Each(-75.012912e-6)) } val yii: Complex = Transformer3wModel.y0( @@ -160,10 +160,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseB - (r ~= Each(240.9972299e-6)) shouldBe true - (x ~= Each(24.99307479224e-3)) shouldBe true - (g ~= Each(0d)) shouldBe true - (b ~= Each(0d)) shouldBe true + equalWithTolerance(r, Each(240.9972299e-6)) + equalWithTolerance(x, Each(24.99307479224e-3)) + equalWithTolerance(g, Each(0d)) + equalWithTolerance(b, Each(0d)) } val yii: Complex = Transformer3wModel.y0( @@ -235,10 +235,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseC - (r ~= Each(3.185595567e-6)) shouldBe true - (x ~= Each(556.0941828e-6)) shouldBe true - (g ~= Each(0d)) shouldBe true - (b ~= Each(0d)) shouldBe true + equalWithTolerance(r, Each(3.185595567e-6)) + equalWithTolerance(x, Each(556.0941828e-6)) + equalWithTolerance(g, Each(0d)) + equalWithTolerance(b, Each(0d)) } val yii: Complex = Transformer3wModel.y0( diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index f69c0e4fb3..789f3aa8d6 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -129,12 +129,12 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { amount shouldBe inputModel.getParallelDevices voltRatioNominal shouldBe BigDecimal("25") - (iNomHv ~= Amperes(36.373066958946424d)) shouldBe true - (iNomLv ~= Amperes(909.3266739736606d)) shouldBe true - (r ~= Each(7.357e-3)) shouldBe true - (x ~= Each(24.30792e-3)) shouldBe true - (g ~= Each(0.0)) shouldBe true - (b ~= Each(-3.75e-3)) shouldBe true + equalWithTolerance(iNomHv, Amperes(36.373066958946424d)) + equalWithTolerance(iNomLv, Amperes(909.3266739736606d)) + equalWithTolerance(r, Each(7.357e-3)) + equalWithTolerance(x, Each(24.30792e-3)) + equalWithTolerance(g, Each(0.0)) + equalWithTolerance(b, Each(-3.75e-3)) } /* The following tests are with regard to the tap position = 0 */ diff --git a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala index b77e2a8ed9..ee5f6662fc 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala @@ -30,9 +30,9 @@ class ApparentPowerAndHeatSpec extends UnitSpec { FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(0d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - (qDot =~ Megawatts(0d)) shouldBe true + equalWithTolerance(p, Megawatts(0d)) + equalWithTolerance(q, Megavars(0d)) + equalWithTolerance(qDot, Megawatts(0d)) } } @@ -45,9 +45,9 @@ class ApparentPowerAndHeatSpec extends UnitSpec { FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => - (p =~ Megawatts(43d)) shouldBe true - (q =~ Megavars(0d)) shouldBe true - (qDot =~ Megawatts(42d)) shouldBe true + equalWithTolerance(p, Megawatts(43d)) + equalWithTolerance(q, Megavars(0d)) + equalWithTolerance(qDot, Megawatts(42d)) } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala index 0a5aa02595..f96eeeb02d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala @@ -45,28 +45,28 @@ class CharacteristicSpec extends UnitSpec with CharacteristicTestData { interpolation1 match { case (x, y) => - (x ~= Each(1)) shouldBe true - (y ~= Each(2)) shouldBe true + equalWithTolerance(x, Each(1)) + equalWithTolerance(y, Each(2)) } interpolation2 match { case (x, y) => - (x ~= Each(2)) shouldBe true - (y ~= Each(4)) shouldBe true + equalWithTolerance(x, Each(2)) + equalWithTolerance(y, Each(4)) } interpolation3 match { case (x, y) => - (x ~= Each(3)) shouldBe true - (y ~= Each(8)) shouldBe true + equalWithTolerance(x, Each(3)) + equalWithTolerance(y, Each(8)) } interpolation4 match { case (x, y) => - (x ~= Each(1.5)) shouldBe true - (y ~= Each(3)) shouldBe true + equalWithTolerance(x, Each(1.5)) + equalWithTolerance(y, Each(3)) } interpolation5 match { case (x, y) => - (x ~= Each(2.5)) shouldBe true - (y ~= Each(6)) shouldBe true + equalWithTolerance(x, Each(2.5)) + equalWithTolerance(y, Each(6)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala index 8f1698f7be..00fe6e6eb3 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala @@ -65,9 +65,12 @@ class FixedFeedInModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(fixedFeedInput.getqCharacteristics) - (sRated ~= Megawatts( - fixedFeedInput.getsRated().to(MEGAVOLTAMPERE).getValue.doubleValue - )) shouldBe true + equalWithTolerance( + sRated, + Megawatts( + fixedFeedInput.getsRated().to(MEGAVOLTAMPERE).getValue.doubleValue + ) + ) cosPhiRated shouldBe fixedFeedInput.getCosPhiRated } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index b1723c3650..9d9f26bc7f 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -176,11 +176,13 @@ class HpModelSpec ThermalGridState(Some(thermalHouseState), _) ) => isRunning shouldBe expectedRunningState - (activePower =~ Kilowatts(expectedActivePower)) shouldBe true - - (thermalHouseState.innerTemperature =~ Celsius( - expectedInnerTemperature - )) shouldBe true + equalWithTolerance(activePower, Kilowatts(expectedActivePower)) + equalWithTolerance( + thermalHouseState.innerTemperature, + Celsius( + expectedInnerTemperature + ) + ) } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala index b5317a8b71..912f22a3a2 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala @@ -67,7 +67,7 @@ class LoadModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(loadInput.getqCharacteristics) - (sRated ~= expsRated) shouldBe true + equalWithTolerance(sRated, expsRated) cosPhiRated shouldBe loadInput.getCosPhiRated loadProfile shouldBe loadInput.getLoadProfile reference shouldBe foreSeenReference @@ -115,7 +115,7 @@ class LoadModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(loadInput.getqCharacteristics) - (sRated ~= expsRated) shouldBe true + equalWithTolerance(sRated, expsRated) cosPhiRated shouldBe loadInput.getCosPhiRated reference shouldBe foreSeenReference } diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala index dd66916cb1..11c225e430 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala @@ -143,7 +143,7 @@ class LoadProfileStoreSpec implicit val powerTolerance: squants.Energy = KilowattHours(1.0) /* Check the deviation against the expected value (deviation should be smaller than 1 kWh) */ - (annualEnergy ~= expected) shouldBe true + equalWithTolerance(annualEnergy, expected) }) } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala index 80a20585ce..b273467b91 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala @@ -26,8 +26,8 @@ class ThermalGridSpec extends UnitSpec { val energyDemand = ThermalEnergyDemand(required, possible) - (energyDemand.required =~ possible) shouldBe true - (energyDemand.possible =~ possible) shouldBe true + equalWithTolerance(energyDemand.required, possible) + equalWithTolerance(energyDemand.possible, possible) } "set the correct values, if they are sensible" in { @@ -36,8 +36,8 @@ class ThermalGridSpec extends UnitSpec { val energyDemand = ThermalEnergyDemand(required, possible) - (energyDemand.required =~ required) shouldBe true - (energyDemand.possible =~ possible) shouldBe true + equalWithTolerance(energyDemand.required, required) + equalWithTolerance(energyDemand.possible, possible) } } @@ -45,9 +45,8 @@ class ThermalGridSpec extends UnitSpec { "actually have no demand" in { val energyDemand = ThermalEnergyDemand.noDemand - (energyDemand.required =~ MegawattHours(0d)) shouldBe true - - (energyDemand.possible =~ MegawattHours(0d)) shouldBe true + equalWithTolerance(energyDemand.required, MegawattHours(0d)) + equalWithTolerance(energyDemand.possible, MegawattHours(0d)) } } @@ -93,9 +92,8 @@ class ThermalGridSpec extends UnitSpec { val totalDemand = energyDemand1 + energyDemand2 - (totalDemand.required =~ MegawattHours(68d)) shouldBe true - - (totalDemand.possible =~ MegawattHours(75d)) shouldBe true + equalWithTolerance(totalDemand.required, MegawattHours(68d)) + equalWithTolerance(totalDemand.possible, MegawattHours(75d)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala index 4baff53e4e..2c683ca790 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -77,10 +77,16 @@ class ThermalGridWithHouseAndStorageSpec ) => houseTick shouldBe expectedHouseStartingState.tick storageTick shouldBe expectedHouseStartingState.tick - (innerTemperature =~ expectedHouseStartingState.innerTemperature) shouldBe true - (storedEnergy =~ expectedStorageStartingState.storedEnergy) shouldBe true - (qDotHouse =~ expectedHouseStartingState.qDot) shouldBe true - (qDotStorage =~ expectedStorageStartingState.qDot) shouldBe true + equalWithTolerance( + innerTemperature, + expectedHouseStartingState.innerTemperature + ) + equalWithTolerance( + storedEnergy, + expectedStorageStartingState.storedEnergy + ) + equalWithTolerance(qDotHouse, expectedHouseStartingState.qDot) + equalWithTolerance(qDotStorage, expectedStorageStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -97,8 +103,11 @@ class ThermalGridWithHouseAndStorageSpec ThermalGrid.startingState(thermalGrid) ) - (gridDemand.required =~ KilowattHours(0d)) shouldBe true - (gridDemand.possible =~ KilowattHours(31.05009722 + 920)) shouldBe true + equalWithTolerance(gridDemand.required, KilowattHours(0d)) + equalWithTolerance( + gridDemand.possible, + KilowattHours(31.05009722 + 920) + ) } "consider stored energy to reduce house demand" in { @@ -115,8 +124,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) - (gridDemand.required =~ KilowattHours(0d)) shouldBe true - (gridDemand.possible =~ KilowattHours(1041.200111111)) shouldBe true + equalWithTolerance(gridDemand.required, KilowattHours(0d)) + equalWithTolerance(gridDemand.possible, KilowattHours(1041.200111111)) } "consider stored energy to reduce house demand if stored energy is not enough" in { @@ -132,8 +141,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) ) - (gridDemand.required =~ KilowattHours(8.64987499999)) shouldBe true - (gridDemand.possible =~ KilowattHours(1418.64987499999)) shouldBe true + equalWithTolerance(gridDemand.required, KilowattHours(8.64987499999)) + equalWithTolerance(gridDemand.possible, KilowattHours(1418.64987499999)) } } @@ -170,8 +179,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) => storageTick shouldBe 0L - (storedEnergy =~ initialLoading) shouldBe true - (qDotStorage =~ externalQDot) shouldBe true + equalWithTolerance(storedEnergy, initialLoading) + equalWithTolerance(qDotStorage, externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -206,12 +215,12 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDotHouse =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDotHouse, Kilowatts(0d)) storageTick shouldBe 0L - (storedEnergy =~ initialLoading) shouldBe true - (qDotStorage =~ externalQDot) shouldBe true + equalWithTolerance(storedEnergy, initialLoading) + equalWithTolerance(qDotStorage, externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageEmpty(17142L)) @@ -453,9 +462,11 @@ class ThermalGridWithHouseAndStorageSpec houseTick shouldBe tick storageTick shouldBe tick - (revisedQDotHouse =~ thermalStorage.chargingPower) shouldBe true - - (revisedQDotStorage =~ thermalStorage.chargingPower * (-1)) shouldBe true + equalWithTolerance(revisedQDotHouse, thermalStorage.chargingPower) + equalWithTolerance( + revisedQDotStorage, + thermalStorage.chargingPower * (-1) + ) houseColdTick shouldBe 3718L storageEmptyTick shouldBe 3678L @@ -491,15 +502,18 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDotHouse =~ externalQDot) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDotHouse, externalQDot) storageTick shouldBe -1L - (storedEnergy =~ initialGridState.storageState - .map(_.storedEnergy) - .getOrElse(fail("No initial storage state found"))) shouldBe true + equalWithTolerance( + storedEnergy, + initialGridState.storageState + .map(_.storedEnergy) + .getOrElse(fail("No initial storage state found")) + ) - (qDotStorage =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(qDotStorage, Kilowatts(0d)) case _ => fail("Thermal grid state has been calculated wrong.") } @@ -534,18 +548,20 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - (innerTemperature =~ Celsius(20.99999167d)) shouldBe true - (qDotHouse =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(innerTemperature, Celsius(20.99999167d)) + equalWithTolerance(qDotHouse, Kilowatts(0d)) storageTick shouldBe 0L - (storedEnergy =~ + equalWithTolerance( + storedEnergy, gridState.storageState .map(_.storedEnergy) .getOrElse( fail("No initial storage state found") - )) shouldBe true + ) + ) - (qDotStorage =~ externalQDot) shouldBe true + equalWithTolerance(qDotStorage, externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala index edd2392208..58970c91a7 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -61,8 +61,11 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe expectedHouseStartingState.tick - (innerTemperature =~ expectedHouseStartingState.innerTemperature) shouldBe true - (thermalInfeed =~ expectedHouseStartingState.qDot) shouldBe true + equalWithTolerance( + innerTemperature, + expectedHouseStartingState.innerTemperature + ) + equalWithTolerance(thermalInfeed, expectedHouseStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -84,8 +87,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { ThermalGrid.startingState(thermalGrid) ) - (gridDemand.required =~ houseDemand.required) shouldBe true - (gridDemand.possible =~ houseDemand.possible) shouldBe true + equalWithTolerance(gridDemand.required, houseDemand.required) + equalWithTolerance(gridDemand.possible, houseDemand.possible) } } @@ -114,8 +117,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ externalQDot) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -141,8 +144,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ Megawatts(0d)) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, Megawatts(0d)) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -175,8 +178,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ testGridQDotInfeed) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, testGridQDotInfeed) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -201,8 +204,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureUpperBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ testGridQDotInfeed) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, testGridQDotInfeed) thresholdTick shouldBe 7372L case _ => fail("Thermal grid state updated failed") } @@ -223,8 +226,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ Megawatts(0d)) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, Megawatts(0d)) thresholdTick shouldBe 154284L case _ => fail("Thermal grid state updated failed") } @@ -245,8 +248,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - (innerTemperature =~ Celsius(18.9999d)) shouldBe true - (qDot =~ Kilowatts(0d)) shouldBe true + equalWithTolerance(innerTemperature, Celsius(18.9999d)) + equalWithTolerance(qDot, Kilowatts(0d)) thresholdTick shouldBe 154284L case _ => fail("Thermal grid state updated failed") } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala index 43ccceb75a..3ae623baf1 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -66,8 +66,11 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe expectedStorageStartingState.tick - (storedEnergy =~ expectedStorageStartingState.storedEnergy) shouldBe true - (qDot =~ expectedStorageStartingState.qDot) shouldBe true + equalWithTolerance( + storedEnergy, + expectedStorageStartingState.storedEnergy + ) + equalWithTolerance(qDot, expectedStorageStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -84,8 +87,8 @@ class ThermalGridWithStorageOnlySpec ThermalGrid.startingState(thermalGrid) ) - (gridDemand.required =~ MegawattHours(0d)) shouldBe true - (gridDemand.possible =~ MegawattHours(0.92d)) shouldBe true + equalWithTolerance(gridDemand.required, MegawattHours(0d)) + equalWithTolerance(gridDemand.possible, MegawattHours(0.92d)) } } @@ -123,9 +126,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - (storedEnergy =~ KilowattHours(430d)) shouldBe true - - (qDot =~ testGridQDotConsumptionHigh) shouldBe true + equalWithTolerance(storedEnergy, KilowattHours(430d)) + equalWithTolerance(qDot, testGridQDotConsumptionHigh) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageEmpty(3600L)) @@ -156,8 +158,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - (storedEnergy =~ KilowattHours(230d)) shouldBe true - (qDot =~ testGridQDotInfeed) shouldBe true + equalWithTolerance(storedEnergy, KilowattHours(230d)) + equalWithTolerance(qDot, testGridQDotInfeed) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageFull(220800L)) @@ -181,8 +183,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - (storedEnergy =~ KilowattHours(230d)) shouldBe true - (qDot =~ testGridQDotInfeed) shouldBe true + equalWithTolerance(storedEnergy, KilowattHours(230d)) + equalWithTolerance(qDot, testGridQDotInfeed) case _ => fail("Thermal grid state updated failed") } } @@ -212,9 +214,8 @@ class ThermalGridWithStorageOnlySpec Some(StorageEmpty(thresholdTick)) ) => tick shouldBe 0L - (storedEnergy =~ KilowattHours(430d)) shouldBe true - - (qDot =~ testGridQDotConsumptionHigh) shouldBe true + equalWithTolerance(storedEnergy, KilowattHours(430d)) + equalWithTolerance(qDot, testGridQDotConsumptionHigh) thresholdTick shouldBe 3600L case _ => fail("Thermal grid state updated failed") } @@ -236,9 +237,8 @@ class ThermalGridWithStorageOnlySpec None ) => tick shouldBe 0L - (storedEnergy =~ KilowattHours(230d)) shouldBe true - - (qDot =~ Megawatts(0d)) shouldBe true + equalWithTolerance(storedEnergy, KilowattHours(230d)) + equalWithTolerance(qDot, Megawatts(0d)) case _ => fail("Thermal grid state updated failed") } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala index 6f1aa171a6..e69b111a35 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala @@ -346,7 +346,7 @@ class PrimaryServiceWorkerSpec tick shouldBe 900L inside(data) { case ActivePower(p) => - (p ~= Kilowatts(1250.0)) shouldBe true + equalWithTolerance(p, Kilowatts(1250.0)) case _ => fail("Expected to get active power only.") } nextDataTick shouldBe None diff --git a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala index e94aaf6a1c..bbc66667e9 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala @@ -92,13 +92,10 @@ class SampleWeatherSourceSpec actual.windVel.unit shouldBe MetersPerSecond /* Values meet expectations */ - (actual.diffIrr ~= WattsPerSquareMeter(72.7656)) shouldBe true - - (actual.dirIrr ~= WattsPerSquareMeter(80.1172)) shouldBe true - - (actual.windVel ~= MetersPerSecond(11.11602)) shouldBe true - - (actual.temp ~= Celsius(6.459)) shouldBe true + equalWithTolerance(actual.diffIrr, WattsPerSquareMeter(72.7656)) + equalWithTolerance(actual.dirIrr, WattsPerSquareMeter(80.1172)) + equalWithTolerance(actual.windVel, MetersPerSecond(11.11602)) + equalWithTolerance(actual.temp, Celsius(6.459)) } @@ -109,16 +106,16 @@ class SampleWeatherSourceSpec source.getWeather(tick, weightedCoordinates) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => diffIrr.unit shouldBe WattsPerSquareMeter - (diffIrr ~= WattsPerSquareMeter(72.7656)) shouldBe true + equalWithTolerance(diffIrr, WattsPerSquareMeter(72.7656)) dirIrr.unit shouldBe WattsPerSquareMeter - (dirIrr ~= WattsPerSquareMeter(80.1172)) shouldBe true + equalWithTolerance(dirIrr, WattsPerSquareMeter(80.1172)) temp.unit shouldBe Celsius - (temp ~= Celsius(6.459d)) shouldBe true + equalWithTolerance(temp, Celsius(6.459d)) windVel.unit shouldBe MetersPerSecond - (windVel ~= MetersPerSecond(11.11602d)) shouldBe true + equalWithTolerance(windVel, MetersPerSecond(11.11602d)) } } diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala index 5d76f0b3e3..1c1788bad8 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala @@ -78,10 +78,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 + 13 - (result.dirIrr ~= WattsPerSquareMeter(sumOfAll / 4)) shouldBe true - (result.diffIrr ~= WattsPerSquareMeter(sumOfAll / 4)) shouldBe true - (result.temp ~= Celsius(sumOfAll / 4)) shouldBe true - (result.windVel ~= MetersPerSecond(sumOfAll / 4)) shouldBe true + equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 4)) + equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 4)) + equalWithTolerance(result.temp, Celsius(sumOfAll / 4)) + equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 4)) } @@ -96,10 +96,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 + 13 - (result.dirIrr ~= WattsPerSquareMeter(sumOfAll / 4)) shouldBe true - (result.diffIrr ~= WattsPerSquareMeter(sumOfAll / 4)) shouldBe true - (result.temp ~= Celsius((1 + 1 + 1) / 3)) shouldBe true - (result.windVel ~= MetersPerSecond(sumOfAll / 4)) shouldBe true + equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 4)) + equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 4)) + equalWithTolerance(result.temp, Celsius((1 + 1 + 1) / 3)) + equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 4)) } "Calculate the correct weighted value for 4 coordinates with 0.25 weight each, where one is empty" in { @@ -113,20 +113,20 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 - (result.dirIrr ~= WattsPerSquareMeter(sumOfAll / 3)) shouldBe true - (result.diffIrr ~= WattsPerSquareMeter(sumOfAll / 3)) shouldBe true - (result.temp ~= Celsius(sumOfAll / 3)) shouldBe true - (result.windVel ~= MetersPerSecond(sumOfAll / 3)) shouldBe true + equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 3)) + equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 3)) + equalWithTolerance(result.temp, Celsius(sumOfAll / 3)) + equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 3)) } "calculate the correct weighted value for 1 coordinate with a weight of 1" in { val weightedCoordinates = WeightedCoordinates(Map(coordinate13 -> 1d)) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) - (result.dirIrr ~= WattsPerSquareMeter(13d)) shouldBe true - (result.diffIrr ~= WattsPerSquareMeter(13d)) shouldBe true - (result.temp ~= Celsius(13d)) shouldBe true - (result.windVel ~= MetersPerSecond(13d)) shouldBe true + equalWithTolerance(result.dirIrr, WattsPerSquareMeter(13d)) + equalWithTolerance(result.diffIrr, WattsPerSquareMeter(13d)) + equalWithTolerance(result.temp, Celsius(13d)) + equalWithTolerance(result.windVel, MetersPerSecond(13d)) } "return temperature quantity on absolute scale" in { @@ -169,10 +169,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weightedWeather) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => - (diffIrr ~= WattsPerSquareMeter(19.83)) shouldBe true - (dirIrr ~= WattsPerSquareMeter(3.01)) shouldBe true - (temp ~= Kelvin(290.75)) shouldBe true - (windVel ~= MetersPerSecond(10.6)) shouldBe true + equalWithTolerance(diffIrr, WattsPerSquareMeter(19.83)) + equalWithTolerance(dirIrr, WattsPerSquareMeter(3.01)) + equalWithTolerance(temp, Kelvin(290.75)) + equalWithTolerance(windVel, MetersPerSecond(10.6)) } } } @@ -219,7 +219,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weightedWeather) match { case WeatherData(_, _, temp, _) => - (temp ~= Kelvin(290d)) shouldBe true + equalWithTolerance(temp, Kelvin(290d)) } } @@ -234,11 +234,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weatherData) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => - (diffIrr ~= WattsPerSquareMeter(4.0)) shouldBe true - (dirIrr ~= WattsPerSquareMeter(2.0)) shouldBe true - (temp ~= Kelvin(1.25d)) shouldBe true - (windVel ~= MetersPerSecond(1.0d)) shouldBe true - + equalWithTolerance(diffIrr, WattsPerSquareMeter(4.0)) + equalWithTolerance(dirIrr, WattsPerSquareMeter(2.0)) + equalWithTolerance(temp, Kelvin(1.25d)) + equalWithTolerance(windVel, MetersPerSecond(1.0d)) } } } diff --git a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala index ab6b1752bf..a61f4b7879 100644 --- a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.test.common import java.util.Locale import com.typesafe.scalalogging.LazyLogging -import edu.ie3.simona.test.matchers.QuantityMatchers +import edu.ie3.simona.test.matchers.{QuantityMatchers, SquantsMatchers} import edu.ie3.util.scala.quantities.{QuantityUtil => PSQuantityUtil} import org.scalatest._ import org.scalatest.matchers.should @@ -26,6 +26,7 @@ import org.scalatest.wordspec.AnyWordSpecLike trait UnitSpec extends should.Matchers with QuantityMatchers + with SquantsMatchers with AnyWordSpecLike with OptionValues with Inside diff --git a/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala new file mode 100644 index 0000000000..6f1ea53813 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala @@ -0,0 +1,27 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.test.matchers + +import edu.ie3.simona.exceptions.QuantityException +import squants.Quantity + +/** Trait, to simplify test coding, that is reliant on squants */ +trait SquantsMatchers { + def equalWithTolerance[T <: Quantity[T]](actual: T, expected: T)(implicit + tolerance: T + ): Boolean = { + val bool = actual =~ expected + + if (!bool) { + throw new QuantityException( + s"The actual quantity $actual and the expected quantity $expected differ more than $tolerance in value" + ) + } + bool + } + +} diff --git a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala index 549b76a826..d727df6beb 100644 --- a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala @@ -8,6 +8,7 @@ package edu.ie3.util.quantities import edu.ie3.simona.exceptions.QuantityException import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.matchers.SquantsMatchers import edu.ie3.util.scala.quantities.QuantityUtil import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.{Kilojoules, Kilowatts, WattHours, Watts} @@ -74,7 +75,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { QuantityUtil invokePrivate endingValue(values, 2L) match { case (tick, value) => tick shouldBe 2L - (value =~ unit(5d)) shouldBe true + equalWithTolerance(value, unit(5d)) } } } @@ -90,11 +91,13 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(cases) { (windowStart, windowEnd, expectedResult) => - QuantityUtil.integrate[Power, Energy]( + val actualResult = QuantityUtil.integrate[Power, Energy]( values, windowStart, windowEnd - ) =~ expectedResult + ) + + equalWithTolerance(actualResult, expectedResult) } } } @@ -156,7 +159,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { windowEnd ) match { case Success(result) => - result =~ expectedResult + equalWithTolerance(result, expectedResult) case Failure(exception) => fail( "Averaging with fine input should pass, but failed.", From 2621cf9579f265ab484bbab8ad2667bc7b901e9c Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Thu, 1 Feb 2024 13:08:54 +0100 Subject: [PATCH 175/305] Updating `CHANGELOG`. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 475c746d92..46a4879970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Instantiation of Heat Pump Agents [#253](https://github.com/ie3-institute/simona/issues/253) - Output of accompanying thermal result models - Added JDK installation, Scala Plugin + SDK in usersguide [#324](https://github.com/ie3-institute/simona/issues/324) +- Squants scalatest matchers [#715](https://github.com/ie3-institute/simona/issues/715) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) From b3f04f1d6c359e4bb6768f5a755cf3fb4ec5ffc4 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Thu, 1 Feb 2024 13:12:51 +0100 Subject: [PATCH 176/305] Convert `GridAgent` & `DBFSAlgorithm` to pekko typed --- CHANGELOG.md | 1 + .../ie3/simona/actor/SimonaActorNaming.scala | 24 +- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 1709 +++++++++-------- .../edu/ie3/simona/agent/grid/GridAgent.scala | 286 ++- .../agent/grid/GridAgentController.scala | 294 +-- .../ie3/simona/agent/grid/GridAgentData.scala | 25 +- .../simona/agent/grid/GridAgentMessage.scala | 110 ++ .../simona/agent/grid/GridEnvironment.scala | 11 +- .../agent/grid/GridResultsSupport.scala | 21 +- .../simona/agent/grid/PowerFlowSupport.scala | 6 +- .../simona/agent/grid/ReceivedValues.scala | 28 +- .../agent/grid/ReceivedValuesStore.scala | 29 +- .../agent/participant/ParticipantAgent.scala | 8 +- .../simona/agent/state/GridAgentState.scala | 21 - .../ie3/simona/event/notifier/Notifier.scala | 4 +- .../ontology/messages/PowerMessage.scala | 5 +- .../ontology/messages/VoltageMessage.scala | 5 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 35 +- .../ie3/simona/sim/setup/SetupHelper.scala | 13 +- .../ie3/simona/sim/setup/SimonaSetup.scala | 53 +- .../sim/setup/SimonaStandaloneSetup.scala | 78 +- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 143 +- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 120 +- .../grid/DBFSAlgorithmParticipantSpec.scala | 175 +- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 163 +- .../agent/grid/DBFSMockGridAgents.scala | 99 +- .../agent/grid/GridAgentSetup2WSpec.scala | 126 +- .../agent/grid/GridAgentSetup3WSpec.scala | 134 +- .../agent/grid/GridResultsSupportSpec.scala | 2 - .../agent/grid/PowerFlowSupportSpec.scala | 27 +- .../agent/grid/ReceivedValuesStoreSpec.scala | 65 +- .../ParticipantAgent2ListenerSpec.scala | 2 +- .../edu/ie3/simona/event/NotifierSpec.scala | 9 +- .../ie3/simona/sim/SimonaSimFailSpec.scala | 30 +- .../simona/sim/setup/SetupHelperSpec.scala | 18 +- .../simona/sim/setup/SimonaSetupSpec.scala | 38 +- 36 files changed, 2103 insertions(+), 1814 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala delete mode 100644 src/main/scala/edu/ie3/simona/agent/state/GridAgentState.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index 475c746d92..c4dccff0e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Replaced akka with pekko [#641](https://github.com/ie3-institute/simona/issues/641) - Use `ThermalGrid` to calculate thermal environment of a heat pump [#315](https://github.com/ie3-institute/simona/issues/315) - Enable windows path as config parameters [#549](https://github.com/ie3-institute/simona/issues/549) +- Converting the `GridAgent` and the `DBFSAlgorithm` to `pekko typed` [#666](https://github.com/ie3-institute/simona/issues/666) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) diff --git a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala index bc5b548f2f..04a2dbff60 100644 --- a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala +++ b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala @@ -6,7 +6,8 @@ package edu.ie3.simona.actor -import org.apache.pekko.actor.{ActorRef, ActorRefFactory, Props} +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.{ActorRefFactory, Props, ActorRef => classicRef} import java.util.UUID @@ -15,10 +16,10 @@ object SimonaActorNaming { implicit class RichActorRefFactory(private val refFactory: ActorRefFactory) extends AnyVal { - def simonaActorOf(props: Props, actorId: String): ActorRef = + def simonaActorOf(props: Props, actorId: String): classicRef = refFactory.actorOf(props, actorName(props, actorId)) - def simonaActorOf(props: Props): ActorRef = + def simonaActorOf(props: Props): classicRef = refFactory.actorOf(props, actorName(props, simonaActorUuid)) } @@ -62,13 +63,28 @@ object SimonaActorNaming { def actorName(typeName: String, actorId: String): String = s"${typeName}_${cleanActorIdForPekko(actorId)}" + /** Extracts the actor name from given [[classicRef]]. Cluster singletons are + * taken care of separately. + * + * @return + * the actor name extract from the ActorRef + */ + def actorName(actorRef: classicRef): String = + actorRef.path.name match { + case "singleton" => + // singletons end in /${actorName}/singleton + actorRef.path.parent.name + case other => + other + } + /** Extracts the actor name from given [[ActorRef]]. Cluster singletons are * taken care of separately. * * @return * the actor name extract from the ActorRef */ - def actorName(actorRef: ActorRef): String = + def actorName(actorRef: ActorRef[_]): String = actorRef.path.name match { case "singleton" => // singletons end in /${actorName}/singleton diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index 309fb1b7ef..a6e3177ab7 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -6,10 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorRef, FSM, PoisonPill} -import org.apache.pekko.pattern.{ask, pipe} -import org.apache.pekko.util.{Timeout => PekkoTimeout} import breeze.linalg.{DenseMatrix, DenseVector} import breeze.math.Complex import edu.ie3.datamodel.graph.SubGridGate @@ -19,19 +15,13 @@ import edu.ie3.powerflow.model.PowerFlowResult import edu.ie3.powerflow.model.PowerFlowResult.FailedPowerFlowResult.FailedNewtonRaphsonPFResult import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.powerflow.model.enums.NodeType -import edu.ie3.simona.agent.grid.GridAgent._ import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, PowerFlowDoneData } +import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.agent.grid.ReceivedValues._ -import edu.ie3.simona.agent.state.AgentState -import edu.ie3.simona.agent.state.AgentState.Idle -import edu.ie3.simona.agent.state.GridAgentState.{ - CheckPowerDifferences, - HandlePowerFlowCalculations, - SimulateGrid -} +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException import edu.ie3.simona.model.grid.{NodeModel, RefSystem} @@ -46,12 +36,21 @@ import edu.ie3.simona.ontology.messages.VoltageMessage.{ import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.scala.quantities.Megavars import edu.ie3.util.scala.quantities.SquantsUtils.RichElectricPotential +import org.apache.pekko.actor.typed.scaladsl.AskPattern._ +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps +import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} +import org.apache.pekko.actor.typed.{ActorRef, Behavior, Scheduler} +import org.apache.pekko.actor.{ActorRef => classicRef} +import org.apache.pekko.pattern.ask +import org.apache.pekko.util.{Timeout => PekkoTimeout} +import org.slf4j.Logger import squants.Each import squants.energy.Megawatts import java.time.{Duration, ZonedDateTime} import java.util.UUID import scala.concurrent.{ExecutionContext, Future} +import scala.util.{Failure, Success} /** Trait that is normally mixed into every [[GridAgent]] to enable distributed * forward backward sweep (DBFS) algorithm execution. It is considered to be @@ -59,693 +58,785 @@ import scala.concurrent.{ExecutionContext, Future} */ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { this: GridAgent => - // implicit ExecutionContext should be in scope - // see https://pekko.apache.org/docs/pekko/current/futures.html - implicit val ec: ExecutionContext = context.dispatcher - - when(SimulateGrid) { - - // first part of the grid simulation, same for all gridAgents on all levels - // we start with a forward-sweep by requesting the data from our child assets and grids (if any) - case Event( - Activation(currentTick), - gridAgentBaseData: GridAgentBaseData - ) => - log.debug("Start sweep number: {}", gridAgentBaseData.currentSweepNo) - // hold tick and trigger for the whole time the dbfs is executed or - // at least until the the first full sweep is done (for superior grid agent only) - holdTick(currentTick) - - // we start the grid simulation by requesting the p/q values of all the nodes we are responsible for - // as well as the slack voltage power from our superior grid - // 1. assets p/q values - askForAssetPowers( - currentTick, - gridAgentBaseData.sweepValueStores - .get(gridAgentBaseData.currentSweepNo), - gridAgentBaseData.gridEnv.nodeToAssetAgents, - gridAgentBaseData.gridEnv.gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout - ) - // 2. inferior grids p/q values - askInferiorGridsForPowers( - gridAgentBaseData.currentSweepNo, - gridAgentBaseData.gridEnv.subgridGateToActorRef, - gridAgentBaseData.inferiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout - ) + /** Method that defines the [[Behavior]] for simulating the grid. + * @param gridAgentData + * state data of the actor + * @param currentTick + * current simulation tick + * @return + * a [[Behavior]] + */ + protected def simulateGrid( + gridAgentData: GridAgentData, + currentTick: Long + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + (ctx, message) => + (message, gridAgentData) match { + // first part of the grid simulation, same for all gridAgents on all levels + // we start with a forward-sweep by requesting the data from our child assets and grids (if any) + case ( + ActivationAdapter(activation: Activation), + gridAgentBaseData: GridAgentBaseData + ) => + ctx.log.debug( + "Start sweep number: {}", + gridAgentBaseData.currentSweepNo + ) - // 3. superior grids slack voltage - askSuperiorGridsForSlackVoltages( - gridAgentBaseData.currentSweepNo, - gridAgentBaseData.gridEnv.subgridGateToActorRef, - gridAgentBaseData.superiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout - ) + // we start the grid simulation by requesting the p/q values of all the nodes we are responsible for + // as well as the slack voltage power from our superior grid + // 1. assets p/q values + askForAssetPowers( + currentTick, + gridAgentBaseData.sweepValueStores + .get(gridAgentBaseData.currentSweepNo), + gridAgentBaseData.gridEnv.nodeToAssetAgents, + gridAgentBaseData.gridEnv.gridModel.mainRefSystem, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) - stay() - - // if we receive power values as response on our request, we process them here - case Event( - receivedValues: ReceivedValues, - gridAgentBaseData: GridAgentBaseData - ) => - // we just received either all provided slack voltage values or all provided power values - val updatedGridAgentBaseData: GridAgentBaseData = receivedValues match { - case receivedPowers: ReceivedPowerValues => - /* Can be a message from an asset or a message from an inferior grid */ - gridAgentBaseData.updateWithReceivedPowerValues(receivedPowers) - case receivedSlacks: ReceivedSlackVoltageValues => - gridAgentBaseData.updateWithReceivedSlackVoltages(receivedSlacks) - case unknownReceivedValues => - throw new DBFSAlgorithmException( - s"Received unknown values: $unknownReceivedValues" + // 2. inferior grids p/q values + askInferiorGridsForPowers( + gridAgentBaseData.currentSweepNo, + gridAgentBaseData.gridEnv.subgridGateToActorRef, + gridAgentBaseData.inferiorGridGates, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) + + // 3. superior grids slack voltage + askSuperiorGridsForSlackVoltages( + gridAgentBaseData.currentSweepNo, + gridAgentBaseData.gridEnv.subgridGateToActorRef, + gridAgentBaseData.superiorGridGates, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) + + simulateGrid(gridAgentBaseData, activation.tick) + + // if we receive power values as response on our request, we process them here + case ( + ValuesAdapter(receivedValues: ReceivedValues), + gridAgentBaseData: GridAgentBaseData + ) => + // we just received either all provided slack voltage values or all provided power values + val updatedGridAgentBaseData: GridAgentBaseData = + receivedValues match { + case receivedPowers: ReceivedPowerValues => + /* Can be a message from an asset or a message from an inferior grid */ + gridAgentBaseData.updateWithReceivedPowerValues(receivedPowers) + case receivedSlacks: ReceivedSlackVoltageValues => + gridAgentBaseData.updateWithReceivedSlackVoltages( + receivedSlacks + ) + case unknownReceivedValues => + throw new DBFSAlgorithmException( + s"Received unknown values: $unknownReceivedValues" + ) + } + + // check if we have enough data for a power flow calculation or a + // power differences check (if the grid agent is a superior agent) + // if yes, check if we have failing power flow in at least one of the inferior grids + // if there are failing ones, escalate the failure to the superior grid (if any), + // if not go to power flow or power differences check + // if we haven't received everything yet, stay and wait + val allValuesReceived = + updatedGridAgentBaseData.allRequestedDataReceived + + ctx.log.debug( + "{}", + if (allValuesReceived) + "Got answers for all my requests for Slack Voltages and Power Values." + else + "Still waiting for answers my requests for Slack Voltages and Power Values." ) - } - // check if we have enough data for a power flow calculation or a - // power differences check (if the grid agent is a superior agent) - // if yes, check if we have failing power flow in at least one of the inferior grids - // if there are failing ones, escalate the failure to the superior grid (if any), - // if not go to power flow or power differences check - // if we haven't received everything yet, stay and wait - val allValuesReceived = updatedGridAgentBaseData.allRequestedDataReceived - - log.debug( - "{}", - if (allValuesReceived) - "Got answers for all my requests for Slack Voltages and Power Values." - else - "Still waiting for answers my requests for Slack Voltages and Power Values." - ) + if (gridAgentBaseData.isSuperior) { + goToCheckPowerDifferencesOrStay( + allValuesReceived, + updatedGridAgentBaseData, + currentTick, + simulateGrid + )(ctx) + } else { + goToPowerFlowCalculationOrStay( + allValuesReceived, + updatedGridAgentBaseData, + currentTick, + simulateGrid + )(ctx) + } - if (gridAgentBaseData.isSuperior) { - goToCheckPowerDifferencesOrStay( - allValuesReceived, - updatedGridAgentBaseData - ) - } else { - goToPowerFlowCalculationOrStay( - allValuesReceived, - updatedGridAgentBaseData - ) - } + // if we receive a request for slack voltages from our inferior grids we want to answer it + case ( + VMAdapter( + RequestSlackVoltageMessage( + currentSweepNo, + nodeUuids, + sender: ActorRef[GridAgentMessage] + ) + ), + gridAgentBaseData: GridAgentBaseData + ) => + ctx.log.debug( + s"Received Slack Voltages request from {} for nodes {} and sweepNo: {}", + sender, + nodeUuids, + gridAgentBaseData.currentSweepNo + ) - // if we receive a request for slack voltages from our inferior grids we want to answer it - case Event( - RequestSlackVoltageMessage(currentSweepNo, nodeUuids), - gridAgentBaseData: GridAgentBaseData - ) => - log.debug( - s"Received Slack Voltages request from {} for nodes {} and sweepNo: {}", - sender(), - nodeUuids, - gridAgentBaseData.currentSweepNo - ) + nodeUuids.map { nodeUuid => + // we either have voltages ready calculated (not the first sweep) or we don't have them here + // -> return calculated value or target voltage as physical value + (gridAgentBaseData.sweepValueStores.get(currentSweepNo) match { + case Some(result) => + Some(result, currentSweepNo) + case None => + // this happens if this agent is either a) the superior grid agent, because it will always get a request for + // the next sweep, as it triggers calculations for the next sweep or b) at all other + // (non last downstream grid agents) in sweep 0 + ctx.log.debug( + "Unable to find slack voltage for nodes '{}' in sweep '{}'. Try to get voltage of previous sweep.", + nodeUuids, + currentSweepNo + ) + gridAgentBaseData.sweepValueStores + .get(currentSweepNo - 1) + .map((_, currentSweepNo - 1)) + }).map { case (result, sweepNo) => + // get nodeUUID + result.sweepData.find(_.nodeUuid == nodeUuid) match { + case Some(sweepValueStoreData) => + val slackVoltageInPu = sweepValueStoreData.stateData.voltage + val mainRefSystem = + gridAgentBaseData.gridEnv.gridModel.mainRefSystem + ( + mainRefSystem.vInSi(slackVoltageInPu.real), + mainRefSystem.vInSi(slackVoltageInPu.imag) + ) + case None => + throw new DBFSAlgorithmException( + s"Requested nodeUuid $nodeUuid " + + s"not found in sweep value store data for sweepNo: $sweepNo. This indicates" + + s"either a wrong processing of a previous sweep result or inconsistencies in grid model data!" + ) + } + }.getOrElse { + ctx.log.debug( + "Unable to get slack voltage for node '{}' in sweeps '{}' and '{}'. Returning target voltage.", + nodeUuid, + currentSweepNo, + currentSweepNo - 1 + ) - nodeUuids.map { nodeUuid => - // we either have voltages ready calculated (not the first sweep) or we don't have them here - // -> return calculated value or target voltage as physical value - (gridAgentBaseData.sweepValueStores.get(currentSweepNo) match { - case Some(result) => - Some(result, currentSweepNo) - case None => - // this happens if this agent is either a) the superior grid agent, because it will always get a request for - // the next sweep, as it triggers calculations for the next sweep or b) at all other - // (non last downstream grid agents) in sweep 0 - log.debug( - "Unable to find slack voltage for nodes '{}' in sweep '{}'. Try to get voltage of previous sweep.", - nodeUuids, - currentSweepNo - ) - gridAgentBaseData.sweepValueStores - .get(currentSweepNo - 1) - .map((_, currentSweepNo - 1)) - }).map { case (result, sweepNo) => - // get nodeUUID - result.sweepData.find(_.nodeUuid == nodeUuid) match { - case Some(sweepValueStoreData) => - val slackVoltageInPu = sweepValueStoreData.stateData.voltage - val mainRefSystem = + val refSystem = gridAgentBaseData.gridEnv.gridModel.mainRefSystem + + /* Determine the slack node voltage under consideration of the target voltage set point */ + val vTarget = + gridAgentBaseData.gridEnv.gridModel.gridComponents.nodes + .find { case NodeModel(uuid, _, _, isSlack, _, _) => + uuid == nodeUuid && isSlack + } + .map(_.vTarget) + .getOrElse(Each(1d)) + val vSlack = + refSystem.nominalVoltage.multiplyWithDimensionles(vTarget) + ( - mainRefSystem.vInSi(slackVoltageInPu.real), - mainRefSystem.vInSi(slackVoltageInPu.imag) + vSlack, + refSystem.vInSi(0d) ) - case None => - throw new DBFSAlgorithmException( - s"Requested nodeUuid $nodeUuid " + - s"not found in sweep value store data for sweepNo: $sweepNo. This indicates" + - s"either a wrong processing of a previous sweep result or inconsistencies in grid model data!" + } match { + case (slackE, slackF) => + ctx.log.debug( + s"Provide {} to {} for node {} and sweepNo: {}", + s"$slackE, $slackF", + sender, + nodeUuid, + gridAgentBaseData.currentSweepNo + ) + + ExchangeVoltage(nodeUuid, slackE, slackF) + } + } match { + case exchangeVoltages => + sender ! VMAdapter( + ProvideSlackVoltageMessage(currentSweepNo, exchangeVoltages) ) + Behaviors.same } - }.getOrElse { - log.debug( - "Unable to get slack voltage for node '{}' in sweeps '{}' and '{}'. Returning target voltage.", - nodeUuid, - currentSweepNo, - currentSweepNo - 1 - ) - val refSystem = - gridAgentBaseData.gridEnv.gridModel.mainRefSystem + // receive grid power values message request from superior grids + // before power flow calc for this sweep we either have to stash() the message to answer it later (in current sweep) + // or trigger a new run for the next sweepNo + case ( + PMAdapter( + RequestGridPowerMessage( + requestSweepNo, + nodeUuids, + sender: ActorRef[GridAgentMessage] + ) + ), + gridAgentBaseData: GridAgentBaseData + ) => + if (gridAgentBaseData.currentSweepNo == requestSweepNo) { + ctx.log.debug( + s"Received request for grid power values for sweepNo {} before my first power flow calc. Stashing away.", + requestSweepNo + ) - /* Determine the slack node voltage under consideration of the target voltage set point */ - val vTarget = - gridAgentBaseData.gridEnv.gridModel.gridComponents.nodes - .find { case NodeModel(uuid, _, _, isSlack, _, _) => - uuid == nodeUuid && isSlack - } - .map(_.vTarget) - .getOrElse(Each(1d)) - val vSlack = - refSystem.nominalVoltage.multiplyWithDimensionles(vTarget) - - ( - vSlack, - refSystem.vInSi(0d) - ) - } match { - case (slackE, slackF) => - log.debug( - s"Provide {} to {} for node {} and sweepNo: {}", - s"$slackE, $slackF", - sender(), - nodeUuid, - gridAgentBaseData.currentSweepNo + buffer.stash( + PMAdapter( + RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) + ) ) - ExchangeVoltage(nodeUuid, slackE, slackF) - } - } match { - case exchangeVoltages => - stay() replying ProvideSlackVoltageMessage( - currentSweepNo, - exchangeVoltages - ) - } + Behaviors.same + } else { + ctx.log.debug( + s"Received request for grid power values for a NEW sweep (request: {}, my: {})", + requestSweepNo, + gridAgentBaseData.currentSweepNo + ) + ctx.self ! PrepareNextSweepTrigger(currentTick) - // receive grid power values message request from superior grids - // / before power flow calc for this sweep we either have to stash() the message to answer it later (in current sweep) - // / or trigger a new run for the next sweepNo - case Event( - RequestGridPowerMessage(requestSweepNo, _), - gridAgentBaseData: GridAgentBaseData - ) => - if (gridAgentBaseData.currentSweepNo == requestSweepNo) { - log.debug( - s"Received request for grid power values for sweepNo {} before my first power flow calc. Stashing away.", - requestSweepNo - ) - stash() - stay() - } else { - log.debug( - s"Received request for grid power values for a NEW sweep (request: {}, my: {})", - requestSweepNo, - gridAgentBaseData.currentSweepNo - ) - self ! PrepareNextSweepTrigger(currentTick) + buffer.stash( + PMAdapter( + RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) + ) + ) - stash() - stay() using gridAgentBaseData.copy(currentSweepNo = requestSweepNo) - } + simulateGrid( + gridAgentBaseData.copy(currentSweepNo = requestSweepNo), + currentTick + ) + } - // / after power flow calc for this sweepNo - case Event( - RequestGridPowerMessage(_, requestedNodeUuids), - powerFlowDoneData @ PowerFlowDoneData( - gridAgentBaseData, - powerFlowResult, - pendingRequestAnswers + // after power flow calc for this sweepNo + case ( + PMAdapter(RequestGridPowerMessage(_, requestedNodeUuids, sender)), + powerFlowDoneData @ PowerFlowDoneData( + gridAgentBaseData, + powerFlowResult, + pendingRequestAnswers + ) + ) => + /* Determine the subgrid number of the grid agent, that has sent the request */ + val firstRequestedNodeUuid = requestedNodeUuids.headOption.getOrElse( + throw new DBFSAlgorithmException( + "Did receive a grid power request but without specified nodes" + ) ) - ) => - /* Determine the subgrid number of the grid agent, that has sent the request */ - val firstRequestedNodeUuid = requestedNodeUuids.headOption.getOrElse( - throw new DBFSAlgorithmException( - "Did receive a grid power request but without specified nodes" - ) - ) - gridAgentBaseData.gridEnv.subgridGateToActorRef - .map { case (subGridGate, _) => subGridGate.superiorNode } - .find(_.getUuid == firstRequestedNodeUuid) - .map(_.getSubnet) match { - case Some(requestingSubgridNumber) => - powerFlowResult match { - case validNewtonRaphsonPFResult: ValidNewtonRaphsonPFResult => - val exchangePowers = requestedNodeUuids - .map { nodeUuid => - /* Figure out the node index for each requested node */ - nodeUuid -> gridAgentBaseData.gridEnv.gridModel.nodeUuidToIndexMap - .get(nodeUuid) - .flatMap { nodeIndex => - /* Find matching node result */ - validNewtonRaphsonPFResult.nodeData.find(stateData => - stateData.index == nodeIndex - ) + + gridAgentBaseData.gridEnv.subgridGateToActorRef + .map { case (subGridGate, _) => subGridGate.superiorNode } + .find(_.getUuid == firstRequestedNodeUuid) + .map(_.getSubnet) match { + case Some(requestingSubgridNumber) => + powerFlowResult match { + case validNewtonRaphsonPFResult: ValidNewtonRaphsonPFResult => + val exchangePowers = requestedNodeUuids + .map { nodeUuid => + /* Figure out the node index for each requested node */ + nodeUuid -> gridAgentBaseData.gridEnv.gridModel.nodeUuidToIndexMap + .get(nodeUuid) + .flatMap { nodeIndex => + /* Find matching node result */ + validNewtonRaphsonPFResult.nodeData.find(stateData => + stateData.index == nodeIndex + ) + } + .map { + case StateData(_, nodeType, _, power) + if nodeType == NodeType.SL => + val refSystem = + gridAgentBaseData.gridEnv.gridModel.mainRefSystem + val (pInPu, qInPu) = + (power.real, power.imag) + // The power flow result data provides the nodal residual power at the slack node. + // A feed-in case from the inferior grid TO the superior grid leads to positive residual power at the + // inferior grid's *slack node* (superior grid seems to be a load to the inferior grid). + // To model the exchanged power from the superior grid's point of view, -1 has to be multiplied. + // (Inferior grid is a feed in facility to superior grid, which is negative then). Analogously for load case. + ( + refSystem.pInSi(pInPu) * (-1), + refSystem.qInSi(qInPu) * (-1) + ) + case _ => + /* TODO: As long as there are no multiple slack nodes, provide "real" power only for the slack node */ + ( + Megawatts(0d), + Megavars(0d) + ) + } + .getOrElse { + throw new DBFSAlgorithmException( + s"Got a request for power @ node with uuid $requestedNodeUuids but cannot find it in my result data!" + ) + } } - .map { - case StateData(_, nodeType, _, power) - if nodeType == NodeType.SL => - val refSystem = - gridAgentBaseData.gridEnv.gridModel.mainRefSystem - val (pInPu, qInPu) = - (power.real, power.imag) - // The power flow result data provides the nodal residual power at the slack node. - // A feed-in case from the inferior grid TO the superior grid leads to positive residual power at the - // inferior grid's *slack node* (superior grid seems to be a load to the inferior grid). - // To model the exchanged power from the superior grid's point of view, -1 has to be multiplied. - // (Inferior grid is a feed in facility to superior grid, which is negative then). Analogously for load case. - ( - refSystem.pInSi(pInPu) * (-1), - refSystem.qInSi(qInPu) * (-1) - ) - case _ => - /* TODO: As long as there are no multiple slack nodes, provide "real" power only for the slack node */ - ( - Megawatts(0d), - Megavars(0d) - ) + .map { case (nodeUuid, (p, q)) => + ProvideGridPowerMessage.ExchangePower( + nodeUuid, + p, + q + ) } - .getOrElse { - throw new DBFSAlgorithmException( - s"Got a request for power @ node with uuid $requestedNodeUuids but cannot find it in my result data!" + + /* Determine the remaining replies */ + val stillPendingRequestAnswers = + pendingRequestAnswers.filterNot( + _ == requestingSubgridNumber + ) + + // update the sweep value store and clear all received maps + // note: normally it is expected that this has to be done after power flow calculations but for the sake + // of having it only once in the code we put this here. Otherwise it would have to been put before EVERY + // return with a valid power flow result (currently happens already in two situations) + val updatedGridAgentBaseData = + if (stillPendingRequestAnswers.isEmpty) { + gridAgentBaseData.storeSweepDataAndClearReceiveMaps( + validNewtonRaphsonPFResult, + gridAgentBaseData.superiorGridNodeUuids, + gridAgentBaseData.inferiorGridGates + ) + } else { + powerFlowDoneData.copy(pendingRequestAnswers = + stillPendingRequestAnswers ) } - } - .map { case (nodeUuid, (p, q)) => - ProvideGridPowerMessage.ExchangePower( - nodeUuid, - p, - q - ) - } - /* Determine the remaining replies */ - val stillPendingRequestAnswers = - pendingRequestAnswers.filterNot(_ == requestingSubgridNumber) - - // update the sweep value store and clear all received maps - // note: normally it is expected that this has to be done after power flow calculations but for the sake - // of having it only once in the code we put this here. Otherwise it would have to been put before EVERY - // return with a valid power flow result (currently happens already in two situations) - val updatedGridAgentBaseData = - if (stillPendingRequestAnswers.isEmpty) { - gridAgentBaseData.storeSweepDataAndClearReceiveMaps( - validNewtonRaphsonPFResult, - gridAgentBaseData.superiorGridNodeUuids, - gridAgentBaseData.inferiorGridGates - ) - } else { - powerFlowDoneData.copy(pendingRequestAnswers = - stillPendingRequestAnswers - ) - } + sender ! PMAdapter(ProvideGridPowerMessage(exchangePowers)) + simulateGrid(updatedGridAgentBaseData, currentTick) - stay() replying - ProvideGridPowerMessage( - exchangePowers - ) using updatedGridAgentBaseData + case _: FailedNewtonRaphsonPFResult => + sender ! PMAdapter(FailedPowerFlow) + simulateGrid(gridAgentBaseData, currentTick) + } + case None => + /* It is not possible to determine, who has asked */ + ctx.log.error( + "I got a grid power request from a subgrid I don't know. Can't answer it properly." + ) - case _: FailedNewtonRaphsonPFResult => - stay() replying FailedPowerFlow using gridAgentBaseData + sender ! PMAdapter(FailedPowerFlow) + Behaviors.same } - case None => - /* It is not possible to determine, who has asked */ - log.error( - "I got a grid power request from a subgrid I don't know. Can't answer it properly." - ) - stay() replying FailedPowerFlow using gridAgentBaseData - } - // called when a grid power values request from a superior grid is received - // which is similar to a new sweep and causes a) a power flow with updated slack voltage values and - // b) afterwards a request for updated power values from inferior grids and assets with updated voltage values - // based on the just carried out power flow - case Event( - PrepareNextSweepTrigger(_), - gridAgentBaseData: GridAgentBaseData - ) => - // request the updated slack voltages from the superior grid - askSuperiorGridsForSlackVoltages( - gridAgentBaseData.currentSweepNo, - gridAgentBaseData.gridEnv.subgridGateToActorRef, - gridAgentBaseData.superiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout - ) + // called when a grid power values request from a superior grid is received + // which is similar to a new sweep and causes a) a power flow with updated slack voltage values and + // b) afterwards a request for updated power values from inferior grids and assets with updated voltage values + // based on the just carried out power flow + case ( + PrepareNextSweepTrigger(_), + gridAgentBaseData: GridAgentBaseData + ) => + // request the updated slack voltages from the superior grid + askSuperiorGridsForSlackVoltages( + gridAgentBaseData.currentSweepNo, + gridAgentBaseData.gridEnv.subgridGateToActorRef, + gridAgentBaseData.superiorGridGates, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) + + ctx.log.debug(s"Going to HandlePowerFlowCalculation") + + handlePowerFlowCalculations(gridAgentBaseData, currentTick) + + // last step which should includes a) information on inferior grids about finish and + // b) cleanup of receiveMaps and sweepStore + case ( + FinishGridSimulationTrigger(currentTick), + gridAgentBaseData: GridAgentBaseData + ) => + // inform my child grids about the end of this grid simulation + gridAgentBaseData.inferiorGridGates + .map { + gridAgentBaseData.gridEnv.subgridGateToActorRef(_) + } + .distinct + .foreach( + _ ! FinishGridSimulationTrigger(currentTick) + ) - log.debug(s"Going to {}", HandlePowerFlowCalculations) - - goto(HandlePowerFlowCalculations) using gridAgentBaseData - - // last step which should includes a) information on inferior grids about finish and - // b) cleanup of receiveMaps and sweepStore - case Event( - FinishGridSimulationTrigger(currentTick), - gridAgentBaseData: GridAgentBaseData - ) => - // inform my child grids about the end of this grid simulation - gridAgentBaseData.inferiorGridGates - .map { - gridAgentBaseData.gridEnv.subgridGateToActorRef(_) - } - .distinct - .foreach(_ ! FinishGridSimulationTrigger(currentTick)) - - // inform every system participant about the end of this grid simulation - gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => - actors.foreach(actor => { - actor ! FinishGridSimulationTrigger( - currentTick - ) - }) - } + // inform every system participant about the end of this grid simulation + gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { + case (_, actors) => + actors.foreach { actor => + actor.toClassic ! FinishGridSimulationTrigger(currentTick) + } + } - // notify listener about the results - log.debug("Calculate results and sending the results to the listener ...") - createAndSendPowerFlowResults( - gridAgentBaseData, - currentTick.toDateTime(simStartTime) - ) + // notify listener about the results + ctx.log.debug( + "Calculate results and sending the results to the listener ..." + ) + createAndSendPowerFlowResults( + gridAgentBaseData, + currentTick.toDateTime(simStartTime) + )(ctx.log) - // do my cleanup stuff - log.debug("Doing my cleanup stuff") + // do my cleanup stuff + ctx.log.debug("Doing my cleanup stuff") - // / clean copy of the gridAgentBaseData - val cleanedGridAgentBaseData = GridAgentBaseData.clean( - gridAgentBaseData, - gridAgentBaseData.superiorGridNodeUuids, - gridAgentBaseData.inferiorGridGates - ) + // / clean copy of the gridAgentBaseData + val cleanedGridAgentBaseData = GridAgentBaseData.clean( + gridAgentBaseData, + gridAgentBaseData.superiorGridNodeUuids, + gridAgentBaseData.inferiorGridGates + ) - // / release tick for the whole simulation (StartGridSimulationTrigger) - releaseTick() + // / inform scheduler that we are done with the whole simulation and request new trigger for next time step + environmentRefs.scheduler ! Completion( + activationAdapter, + Some(currentTick + resolution) + ) - // / inform scheduler that we are done with the whole simulation and request new trigger for next time step - environmentRefs.scheduler ! Completion( - self.toTyped, - Some(currentTick + resolution) - ) + // return to Idle + idle(cleanedGridAgentBaseData) - // return to Idle - goto(Idle) using cleanedGridAgentBaseData + case (StopGridAgent, _) => + Behaviors.stopped + case (_, _) => + Behaviors.unhandled + } } - /** Every power flow calculation should take place here. Generally used for - * power flow calculations only and only if all data required are already - * received as requested. + /** Method that defines the [[Behavior]] for handling the power flow + * calculations. Generally used for power flow calculations only and only if + * all data required are already received as requested. + * + * @param gridAgentData + * state data of the actor + * @param currentTick + * current simulation tick + * @return + * a [[Behavior]] */ - when(HandlePowerFlowCalculations) { - - // main method for power flow calculations - case Event( - DoPowerFlowTrigger(currentTick, _), - gridAgentBaseData: GridAgentBaseData - ) => - log.debug( - "Received the following power values to the corresponding nodes: {}", - gridAgentBaseData.receivedValueStore.nodeToReceivedPower - ) - - val gridModel = gridAgentBaseData.gridEnv.gridModel - - val (operatingPoint, slackNodeVoltages) = composeOperatingPoint( - gridModel.gridComponents.nodes, - gridModel.gridComponents.transformers, - gridModel.gridComponents.transformers3w, - gridModel.nodeUuidToIndexMap, - gridAgentBaseData.receivedValueStore, - gridModel.mainRefSystem - ) - - newtonRaphsonPF( - gridModel, - gridAgentBaseData.powerFlowParams.maxIterations, - operatingPoint, - slackNodeVoltages - )(gridAgentBaseData.powerFlowParams.epsilon) match { - // if res is valid, ask our assets (if any) for updated power values based on the newly determined nodal voltages - case validPowerFlowResult: ValidNewtonRaphsonPFResult => - log.debug( - "{}", - composeValidNewtonRaphsonPFResultVoltagesDebugString( - validPowerFlowResult, - gridModel - ) + private def handlePowerFlowCalculations( + gridAgentData: GridAgentData, + currentTick: Long + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + (ctx, message) => + (message, gridAgentData) match { + + // main method for power flow calculations + case ( + DoPowerFlowTrigger(currentTick, _), + gridAgentBaseData: GridAgentBaseData + ) => + ctx.log.debug( + "Received the following power values to the corresponding nodes: {}", + gridAgentBaseData.receivedValueStore.nodeToReceivedPower ) - val powerFlowDoneData = - PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) + val gridModel = gridAgentBaseData.gridEnv.gridModel - val sweepValueStoreOpt = Some( - SweepValueStore( - validPowerFlowResult, - gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap - ) + val (operatingPoint, slackNodeVoltages) = composeOperatingPoint( + gridModel.gridComponents.nodes, + gridModel.gridComponents.transformers, + gridModel.gridComponents.transformers3w, + gridModel.nodeUuidToIndexMap, + gridAgentBaseData.receivedValueStore, + gridModel.mainRefSystem ) - askForAssetPowers( - currentTick, - sweepValueStoreOpt, - gridAgentBaseData.gridEnv.nodeToAssetAgents, - gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout - ) match { - case None => - // when we don't have assets we can skip another request for different asset behaviour due to changed - // voltage values and go back to SimulateGrid directly - log.debug( - s"No generation or load assets in the grid. Going back to {}.", - SimulateGrid - ) - unstashAll() // we can answer the stashed grid power requests now - goto(SimulateGrid) using powerFlowDoneData - case Some(_) => - // will return a future based on the `ask-pattern` which will be processed below - stay() using powerFlowDoneData - } - case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => - val powerFlowDoneData = - PowerFlowDoneData(gridAgentBaseData, failedNewtonRaphsonPFResult) - log.warning( - "Power flow calculation before asking for updated powers did finally not converge!" - ) - unstashAll() // we can answer the stashed grid power requests now and report a failed power flow back - goto(SimulateGrid) using powerFlowDoneData - } + newtonRaphsonPF( + gridModel, + gridAgentBaseData.powerFlowParams.maxIterations, + operatingPoint, + slackNodeVoltages + )(gridAgentBaseData.powerFlowParams.epsilon)(ctx.log) match { + // if res is valid, ask our assets (if any) for updated power values based on the newly determined nodal voltages + case validPowerFlowResult: ValidNewtonRaphsonPFResult => + ctx.log.debug( + "{}", + composeValidNewtonRaphsonPFResultVoltagesDebugString( + validPowerFlowResult, + gridModel + ) + ) - // handler for the future provided by `askForAssetPowers` to check if there are any changes in generation/load - // of assets based on updated nodal voltages - case Event( - receivedPowerValues: ReceivedPowerValues, - powerFlowDoneData: PowerFlowDoneData - ) => - val gridAgentBaseData = powerFlowDoneData.gridAgentBaseData - - // check if we have changed values from our assets - // if yes, we do another PF with adapted values - // if no, we are done with the pf and ready to report to our parent grid - val changed = receivedPowerValues.values.exists { - case (_, _: AssetPowerChangedMessage) => true - case _ => false - } + val powerFlowDoneData = + PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) - if (changed) { - log.debug( - "Assets have changed their exchanged power with the grid. Update nodal powers and prepare new power flow." - ) - val updatedGridAgentBaseData: GridAgentBaseData = - receivedPowerValues match { - case receivedPowers: ReceivedPowerValues => - gridAgentBaseData.updateWithReceivedPowerValues( - receivedPowers, - replace = true - ) - case unknownValuesReceived => - throw new DBFSAlgorithmException( - s"Received unsuitable values: $unknownValuesReceived" + val sweepValueStoreOpt = Some( + SweepValueStore( + validPowerFlowResult, + gridModel.gridComponents.nodes, + gridModel.nodeUuidToIndexMap + ) ) - } + askForAssetPowers( + currentTick, + sweepValueStoreOpt, + gridAgentBaseData.gridEnv.nodeToAssetAgents, + gridModel.mainRefSystem, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) match { + case None => + // when we don't have assets we can skip another request for different asset behaviour due to changed + // voltage values and go back to SimulateGrid directly + ctx.log.debug( + s"No generation or load assets in the grid. Going back to SimulateGrid." + ) - // check if we have enough data for a power flow calculation - // if yes, go to the powerflow - // if no, stay and wait - val readyForPowerFlow = - updatedGridAgentBaseData.allRequestedDataReceived - log.debug( - "{}", - if (readyForPowerFlow) - "Got answers for all my requests for Slack Voltages and Power Values." - else - "Still waiting for answers my requests for Slack Voltages and Power Values." - ) + // we can answer the stashed grid power requests now + buffer.unstashAll( + simulateGrid(powerFlowDoneData, currentTick) + ) - goToPowerFlowCalculationOrStay( - readyForPowerFlow, - updatedGridAgentBaseData - ) + case Some(_) => + // will return a future based on the `ask-pattern` which will be processed below + handlePowerFlowCalculations(powerFlowDoneData, currentTick) + } - } else { - // no changes from assets, we want to go back to SimulateGrid and report the LF results to our parent grids if any requests - log.debug( - s"Assets have not changed their exchanged power or no voltage dependent behaviour. Going back to {}.", - SimulateGrid - ) - unstashAll() // we can answer the stashed grid power requests now - goto(SimulateGrid) using powerFlowDoneData + case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => + val powerFlowDoneData = + PowerFlowDoneData( + gridAgentBaseData, + failedNewtonRaphsonPFResult + ) + ctx.log.warn( + "Power flow calculation before asking for updated powers did finally not converge!" + ) + // we can answer the stashed grid power requests now and report a failed power flow back + buffer.unstashAll(simulateGrid(powerFlowDoneData, currentTick)) + } - } + // handler for the future provided by `askForAssetPowers` to check if there are any changes in generation/load + // of assets based on updated nodal voltages + case ( + ValuesAdapter(receivedPowerValues: ReceivedPowerValues), + powerFlowDoneData: PowerFlowDoneData + ) => + val gridAgentBaseData = powerFlowDoneData.gridAgentBaseData + + // check if we have changed values from our assets + // if yes, we do another PF with adapted values + // if no, we are done with the pf and ready to report to our parent grid + val changed = receivedPowerValues.values.exists { + case (_, _: AssetPowerChangedMessage) => true + case _ => false + } - // executed after request from the superior grid to execute a new sweep (forward sweep state) - // this means we requested an update of the slack voltage values, but for now don't request (and hence don't expect) - // updated power values for our power flow calculations - case Event( - receivedSlackValues: ReceivedSlackVoltageValues, - gridAgentBaseData: GridAgentBaseData - ) => - log.debug( - "Received Slack values for new forward sweep with same power but updated voltage values" - ) + if (changed) { + ctx.log.debug( + "Assets have changed their exchanged power with the grid. Update nodal powers and prepare new power flow." + ) + val updatedGridAgentBaseData: GridAgentBaseData = + receivedPowerValues match { + case receivedPowers: ReceivedPowerValues => + gridAgentBaseData.updateWithReceivedPowerValues( + receivedPowers, + replace = true + ) + case unknownValuesReceived => + throw new DBFSAlgorithmException( + s"Received unsuitable values: $unknownValuesReceived" + ) + } - // power flow - val gridModel = gridAgentBaseData.gridEnv.gridModel - val previousSweepData = gridAgentBaseData.sweepValueStores.getOrElse( - gridAgentBaseData.currentSweepNo - 1, - throw new DBFSAlgorithmException( - s"$actorName Unable to get results from previous sweep ${gridAgentBaseData.currentSweepNo - 1}!" - ) - ) + // check if we have enough data for a power flow calculation + // if yes, go to the powerflow + // if no, stay and wait + val readyForPowerFlow = + updatedGridAgentBaseData.allRequestedDataReceived + ctx.log.debug( + "{}", + if (readyForPowerFlow) + "Got answers for all my requests for Slack Voltages and Power Values." + else + "Still waiting for answers my requests for Slack Voltages and Power Values." + ) - val (operatingPoint, slackNodeVoltages) = - composeOperatingPointWithUpdatedSlackVoltages( - receivedSlackValues, - previousSweepData.sweepData, - gridModel.gridComponents.transformers, - gridModel.gridComponents.transformers3w, - gridModel.mainRefSystem - ) + goToPowerFlowCalculationOrStay( + readyForPowerFlow, + updatedGridAgentBaseData, + currentTick, + handlePowerFlowCalculations + )(ctx) - newtonRaphsonPF( - gridModel, - gridAgentBaseData.powerFlowParams.maxIterations, - operatingPoint, - slackNodeVoltages - )(gridAgentBaseData.powerFlowParams.epsilon) match { - case validPowerFlowResult: ValidNewtonRaphsonPFResult => - log.debug( - "{}", - composeValidNewtonRaphsonPFResultVoltagesDebugString( - validPowerFlowResult, - gridModel + } else { + // no changes from assets, we want to go back to SimulateGrid and report the LF results to our parent grids if any requests + ctx.log.debug( + s"Assets have not changed their exchanged power or no voltage dependent behaviour. Going back to SimulateGrid." ) - ) + // we can answer the stashed grid power requests now + buffer.unstashAll(simulateGrid(powerFlowDoneData, currentTick)) + } - // update the data - val sweepValueStore = SweepValueStore( - validPowerFlowResult, - gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap + // executed after request from the superior grid to execute a new sweep (forward sweep state) + // this means we requested an update of the slack voltage values, but for now don't request (and hence don't expect) + // updated power values for our power flow calculations + case ( + ValuesAdapter(receivedSlackValues: ReceivedSlackVoltageValues), + gridAgentBaseData: GridAgentBaseData + ) => + ctx.log.debug( + "Received Slack values for new forward sweep with same power but updated voltage values" ) - val updatedSweepValueStore = - gridAgentBaseData.sweepValueStores + (gridAgentBaseData.currentSweepNo -> sweepValueStore) - // send request to child grids and assets for updated p/q values - // we start the grid simulation by requesting the p/q values of all the nodes we are responsible for - // as well as the slack voltage power from our superior grid - // 1. assets p/q values - val askForAssetPowersOpt = - askForAssetPowers( - currentTick, - Some(sweepValueStore), - gridAgentBaseData.gridEnv.nodeToAssetAgents, - gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout + // power flow + val gridModel = gridAgentBaseData.gridEnv.gridModel + val previousSweepData = gridAgentBaseData.sweepValueStores.getOrElse( + gridAgentBaseData.currentSweepNo - 1, + throw new DBFSAlgorithmException( + s"$actorName Unable to get results from previous sweep ${gridAgentBaseData.currentSweepNo - 1}!" ) + ) - // 2. inferior grids p/q values - val askForInferiorGridPowersOpt = - askInferiorGridsForPowers( - gridAgentBaseData.currentSweepNo, - gridAgentBaseData.gridEnv.subgridGateToActorRef, - gridAgentBaseData.inferiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout + val (operatingPoint, slackNodeVoltages) = + composeOperatingPointWithUpdatedSlackVoltages( + receivedSlackValues, + previousSweepData.sweepData, + gridModel.gridComponents.transformers, + gridModel.gridComponents.transformers3w, + gridModel.mainRefSystem ) - // when we don't have inferior grids and no assets both methods return None and we can skip doing another power - // flow calculation otherwise we go back to simulate grid and wait for the answers - (askForAssetPowersOpt, askForInferiorGridPowersOpt) match { - case (None, None) => - log.debug( - "I don't have assets or child grids. " + - "Going back to SimulateGrid and provide the power flow result if there is any request left." + newtonRaphsonPF( + gridModel, + gridAgentBaseData.powerFlowParams.maxIterations, + operatingPoint, + slackNodeVoltages + )(gridAgentBaseData.powerFlowParams.epsilon)(ctx.log) match { + case validPowerFlowResult: ValidNewtonRaphsonPFResult => + ctx.log.debug( + "{}", + composeValidNewtonRaphsonPFResultVoltagesDebugString( + validPowerFlowResult, + gridModel + ) ) - val powerFlowDoneData = - PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) + // update the data + val sweepValueStore = SweepValueStore( + validPowerFlowResult, + gridModel.gridComponents.nodes, + gridModel.nodeUuidToIndexMap + ) + val updatedSweepValueStore = + gridAgentBaseData.sweepValueStores + (gridAgentBaseData.currentSweepNo -> sweepValueStore) + + // send request to child grids and assets for updated p/q values + // we start the grid simulation by requesting the p/q values of all the nodes we are responsible for + // as well as the slack voltage power from our superior grid + // 1. assets p/q values + val askForAssetPowersOpt = + askForAssetPowers( + currentTick, + Some(sweepValueStore), + gridAgentBaseData.gridEnv.nodeToAssetAgents, + gridModel.mainRefSystem, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) + + // 2. inferior grids p/q values + val askForInferiorGridPowersOpt = + askInferiorGridsForPowers( + gridAgentBaseData.currentSweepNo, + gridAgentBaseData.gridEnv.subgridGateToActorRef, + gridAgentBaseData.inferiorGridGates, + gridAgentBaseData.powerFlowParams.sweepTimeout + )(ctx) + + // when we don't have inferior grids and no assets both methods return None and we can skip doing another power + // flow calculation otherwise we go back to simulate grid and wait for the answers + (askForAssetPowersOpt, askForInferiorGridPowersOpt) match { + case (None, None) => + ctx.log.debug( + "I don't have assets or child grids. " + + "Going back to SimulateGrid and provide the power flow result if there is any request left." + ) - unstashAll() // we can answer the stashed grid power requests now - goto(SimulateGrid) using powerFlowDoneData + val powerFlowDoneData = + PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) - case _ => - log.debug( - "Going back to SimulateGrid and wait for my assets or inferior grids to return." - ) + // we can answer the stashed grid power requests now + buffer.unstashAll( + simulateGrid(powerFlowDoneData, currentTick) + ) + + case _ => + ctx.log.debug( + "Going back to SimulateGrid and wait for my assets or inferior grids to return." + ) - // go back to simulate grid - goto(SimulateGrid) using gridAgentBaseData - .updateWithReceivedSlackVoltages(receivedSlackValues) - .copy(sweepValueStores = updatedSweepValueStore) + // go back to simulate grid + simulateGrid( + gridAgentBaseData + .updateWithReceivedSlackVoltages(receivedSlackValues) + .copy(sweepValueStores = updatedSweepValueStore), + currentTick + ) + } + + case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => + val powerFlowDoneData = + PowerFlowDoneData( + gridAgentBaseData, + failedNewtonRaphsonPFResult + ) + ctx.log.warn( + "Power flow with updated slack voltage did finally not converge!" + ) + // we can answer the stashed grid power requests now and report a failed power flow back + buffer.unstashAll(simulateGrid(powerFlowDoneData, currentTick)) } - case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => - val powerFlowDoneData = - PowerFlowDoneData( - gridAgentBaseData, - failedNewtonRaphsonPFResult - ) - log.warning( - "Power flow with updated slack voltage did finally not converge!" + // happens only when we received slack data and power values before we received a request to provide grid data + // (only possible when first simulation triggered and this agent is faster in this state as the request + // by a superior grid arrives) + case ( + PMAdapter(requestGridPowerMessage: RequestGridPowerMessage), + _: GridAgentBaseData + ) => + ctx.log.debug( + "Received Request for Grid Power too early. Stashing away" ) - unstashAll() // we can answer the stashed grid power requests now and report a failed power flow back - goto(SimulateGrid) using powerFlowDoneData - } + buffer.stash(PMAdapter(requestGridPowerMessage)) + Behaviors.same + + // happens only when we received slack data and power values before we received a request to provide grid + // (only possible when first simulation triggered and this agent is faster + // with its power flow calculation in this state as the request by a superior grid arrives) + case ( + PMAdapter(requestGridPowerMessage: RequestGridPowerMessage), + _: PowerFlowDoneData + ) => + ctx.log.debug( + "Received Request for Grid Power too early. Stashing away" + ) + + buffer.stash(PMAdapter(requestGridPowerMessage)) + Behaviors.same - // happens only when we received slack data and power values before we received a request to provide grid data - // (only possible when first simulation triggered and this agent is faster in this state as the request - // by a superior grid arrives) - case Event( - _: RequestGridPowerMessage, - _: GridAgentBaseData - ) => - log.debug("Received Request for Grid Power too early. Stashing away") - stash() - stay() - - // happens only when we received slack data and power values before we received a request to provide gride - // (only possible when first simulation triggered and this agent is faster - // with its power flow calculation in this state as the request by a superior grid arrives) - case Event( - _: RequestGridPowerMessage, - _: PowerFlowDoneData - ) => - log.debug("Received Request for Grid Power too early. Stashing away") - stash() - stay() + case (StopGridAgent, _) => + Behaviors.stopped + case (_, _) => + Behaviors.unhandled + } } - // should be reached by the superior (dummy) grid agent only - when(CheckPowerDifferences) { + /** Method used for checking the power difference.

    This method should only + * be reached by the superior (dummy) grid agent. + * @param gridAgentBaseData + * state data of the actor + * @return + * a [[Behavior]] + */ + private def checkPowerDifferences( + gridAgentBaseData: GridAgentBaseData + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - case Event( - CheckPowerDifferencesTrigger(currentTick), - gridAgentBaseData: GridAgentBaseData - ) => - log.debug("Starting the power differences check ...") + case (ctx, CheckPowerDifferencesTrigger(currentTick)) => + ctx.log.debug("Starting the power differences check ...") val currentSweepNo = gridAgentBaseData.currentSweepNo val gridModel = gridAgentBaseData.gridEnv.gridModel @@ -770,7 +861,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { val nodeData = operationPoint.map(StateData(_)) ValidNewtonRaphsonPFResult(-1, nodeData, DenseMatrix(0d, 0d)) } else { - log.debug( + ctx.log.debug( "This grid contains a three winding transformer. Perform power flow calculations before assessing the power deviations." ) newtonRaphsonPF( @@ -778,9 +869,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.powerFlowParams.maxIterations, operationPoint, slackNodeVoltages - )(gridAgentBaseData.powerFlowParams.epsilon) match { + )(gridAgentBaseData.powerFlowParams.epsilon)(ctx.log) match { case validPowerFlowResult: ValidNewtonRaphsonPFResult => - log.debug( + ctx.log.debug( "{}", composeValidNewtonRaphsonPFResultVoltagesDebugString( validPowerFlowResult, @@ -805,13 +896,17 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // the difference is checked @ the higher nodes of our transformers => the slack nodes // if we are either in the first backward sweep OR if the deviation is bigger as allowed, we need a second sweep if (gridAgentBaseData.sweepValueStores.isEmpty) { - log.debug("Sweep value store is empty. Starting a second sweep ...") + ctx.log.debug( + "Sweep value store is empty. Starting a second sweep ..." + ) goToSimulateGridForNextSweepWith( updatedGridAgentBaseData, currentTick ) } else { - log.debug("Sweep value store is not empty. Check for deviation ...") + ctx.log.debug( + "Sweep value store is not empty. Check for deviation ..." + ) // calculate deviation vector for all nodes val previousSweepNodePower: DenseVector[Complex] = @@ -850,7 +945,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { Math.abs(complex.imag) >= allowedDeviation }) match { case Some(deviation) => // next sweep - log.debug( + ctx.log.debug( "Deviation between the last two sweeps: {}", deviation ) @@ -859,56 +954,62 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentTick ) case None => // we're done - log.debug("We found a result! :-)") + ctx.log.debug("We found a result! :-)") - log.debug( + ctx.log.debug( "Final deviation: {}", (previousSweepNodePower - currentSweepNodePower).toScalaVector ) // go back to SimulateGrid and trigger a finish - self ! FinishGridSimulationTrigger(currentTick) - goto(SimulateGrid) - + ctx.self ! FinishGridSimulationTrigger(currentTick) + simulateGrid(gridAgentBaseData, currentTick) } } case failedResult: PowerFlowResult.FailedPowerFlowResult => - log.warning( + ctx.log.warn( "Power flow for high voltage branch of three winding transformer failed after {} iterations. Cause: {}", failedResult.iteration, failedResult.cause ) - self ! FinishGridSimulationTrigger(currentTick) - handlePowerFlowFailure(gridAgentBaseData) - goto(SimulateGrid) using gridAgentBaseData + ctx.self ! FinishGridSimulationTrigger(currentTick) + handlePowerFlowFailure(gridAgentBaseData)(ctx) + simulateGrid(gridAgentBaseData, currentTick) } + + case (_, StopGridAgent) => + Behaviors.stopped + + case (_, _) => + Behaviors.unhandled } /** Checks if all data has been received and if yes checks if the there are * any failed power flow indications from inferior grids. If both == true, - * then no state change is triggered but the sweep value store is updated - * with a [[FailedPowerFlow]] information as well, the now used data is set - * to [[PowerFlowDoneData]] and this is escalated to the superior grid(s). If - * there is no [[FailedPowerFlow]] in the [[GridAgentBaseData]] a state - * transition to [[HandlePowerFlowCalculations]] is triggered. + * then no [[Behavior]] change is triggered but the sweep value store is + * updated with a [[FailedPowerFlow]] information as well, the now used data + * is set to [[PowerFlowDoneData]] and this is escalated to the superior + * grid(s). If there is no [[FailedPowerFlow]] in the [[GridAgentBaseData]] a + * behavior transition to [[handlePowerFlowCalculations]] is triggered. * - * If allReceived == false, no state transition is triggered + * If allReceived == false, no [[Behavior]] transition is triggered * * @param allReceived * indicates if all requested data has been received * @param gridAgentBaseData * the current or updated data of the [[GridAgent]] * @return - * either the same state the agent is currently in or a transition to - * [[HandlePowerFlowCalculations]] + * either the same behavior the agent is currently in or a transition to + * [[handlePowerFlowCalculations]] */ private def goToPowerFlowCalculationOrStay( allReceived: Boolean, - gridAgentBaseData: GridAgentBaseData - ): FSM.State[AgentState, GridAgentData] = { - + gridAgentBaseData: GridAgentBaseData, + currentTick: Long, + behavior: (GridAgentData, Long) => Behavior[GridAgentMessage] + )(implicit ctx: ActorContext[GridAgentMessage]): Behavior[GridAgentMessage] = if (allReceived) { - log.debug( + ctx.log.debug( "All power values of inferior grids, assets + voltage superior grid slack voltages received." ) @@ -918,26 +1019,33 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .exists(v => v.exists(k => k._2.contains(FailedPowerFlow))) if (powerFlowFailedSomewhereInInferior) { - log.warning("Received Failed Power Flow Result. Escalate to my parent.") - unstashAll() // we want to answer the requests from our parent - stay() using PowerFlowDoneData( + ctx.log.warn( + "Received Failed Power Flow Result. Escalate to my parent." + ) + + // we want to answer the requests from our parent + val powerFlowDoneData = PowerFlowDoneData( gridAgentBaseData, FailedNewtonRaphsonPFResult(-1, CalculationFailed) ) + + buffer.unstashAll(behavior(powerFlowDoneData, currentTick)) } else { - self ! DoPowerFlowTrigger(currentTick, gridAgentBaseData.currentSweepNo) - goto(HandlePowerFlowCalculations) using gridAgentBaseData + ctx.self ! DoPowerFlowTrigger( + currentTick, + gridAgentBaseData.currentSweepNo + ) + handlePowerFlowCalculations(gridAgentBaseData, currentTick) } } else { - log.debug( + ctx.log.debug( "Still waiting for asset or grid power values or slack voltage information of inferior grids" ) - stay() using gridAgentBaseData - } - } + buffer.unstashAll(behavior(gridAgentBaseData, currentTick)) + } /** Normally only reached by the superior (dummy) agent! * @@ -947,8 +1055,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * this step is skipped and the simulation goes on or this leads to a * termination of the simulation due to a failed power flow calculation. * - * If there is no [[FailedPowerFlow]] in the [[GridAgentBaseData]] a state - * transition to [[CheckPowerDifferences]] is triggered. + * If there is no [[FailedPowerFlow]] in the [[GridAgentBaseData]] a + * [[Behavior]] transition to [[checkPowerDifferences]] is triggered. * * If allReceived == false, no state transition is triggered * @@ -959,15 +1067,21 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * @param gridAgentBaseData * the current or updated data of the [[GridAgent]] * @return - * either the same state the agent is currently in or a transition to - * [[CheckPowerDifferences]] + * either the same behavior the agent is currently in or a transition to + * [[checkPowerDifferences]] */ private def goToCheckPowerDifferencesOrStay( allReceived: Boolean, - gridAgentBaseData: GridAgentBaseData - ): FSM.State[AgentState, GridAgentData] = { + gridAgentBaseData: GridAgentBaseData, + currentTick: Long, + behavior: (GridAgentData, Long) => Behavior[GridAgentMessage] + )(implicit + ctx: ActorContext[GridAgentMessage] + ): Behavior[GridAgentMessage] = { if (allReceived) { - log.debug("All power values of child assets + inferior grids received.") + ctx.log.debug( + "All power values of child assets + inferior grids received." + ) // if our superior grid received a FailedPowerFlow from the inferior grids it has to trigger a finish // of the simulation which will either result in a skip of this time step OR a termination of the simulation run @@ -979,60 +1093,63 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) ) if (powerFlowFailedSomewhere) { - log.warning("Power flow failed! This incident will be reported!") - self ! FinishGridSimulationTrigger(currentTick) + ctx.log.warn("Power flow failed! This incident will be reported!") + ctx.self ! FinishGridSimulationTrigger(currentTick) + handlePowerFlowFailure(gridAgentBaseData) - goto(SimulateGrid) using gridAgentBaseData + simulateGrid(gridAgentBaseData, currentTick) } else { - self ! CheckPowerDifferencesTrigger(currentTick) - goto(CheckPowerDifferences) using gridAgentBaseData + ctx.self ! CheckPowerDifferencesTrigger(currentTick) + checkPowerDifferences(gridAgentBaseData) } } else { - log.debug( + ctx.log.debug( "Still waiting for asset or grid power values or slack voltage information of inferior grids" ) - stay() using gridAgentBaseData + + buffer.unstashAll(behavior(gridAgentBaseData, currentTick)) } } + /** Method for handling failed power flows. + * @param gridAgentBaseData + * state data of the actor + */ private def handlePowerFlowFailure( gridAgentBaseData: GridAgentBaseData - ): Unit = { + )(implicit ctx: ActorContext[GridAgentMessage]): Unit = { environmentRefs.runtimeEventListener ! PowerFlowFailed if (gridAgentBaseData.powerFlowParams.stopOnFailure) { - log.error("Stopping because of failed power flow.") - self ! PoisonPill + ctx.log.error("Stopping because of failed power flow.") + Behaviors.stopped } } /** Normally only reached by the superior (dummy) agent! * - * Triggers a state transition to [[SimulateGrid]], informs the + * Triggers a [[Behavior]] transition to [[simulateGrid]], informs the * [[edu.ie3.simona.scheduler.Scheduler]] about the finish of this sweep and * requests a new trigger for itself for a new sweep * * @param gridAgentBaseData * the [[GridAgentBaseData]] that should be used in the next sweep in - * [[SimulateGrid]] + * [[simulateGrid]] * @param currentTick * current tick the agent is in * @return - * a state transition to [[SimulateGrid]] + * a behavior transition to [[simulateGrid]] */ private def goToSimulateGridForNextSweepWith( gridAgentBaseData: GridAgentBaseData, currentTick: Long - ): FSM.State[AgentState, GridAgentData] = { - - releaseTick() + ): Behavior[GridAgentMessage] = { environmentRefs.scheduler ! Completion( - self.toTyped, + activationAdapter, Some(currentTick) ) - goto(SimulateGrid) using gridAgentBaseData - + simulateGrid(gridAgentBaseData, currentTick) } /** Triggers an execution of the pekko `ask` pattern for all power values of @@ -1044,79 +1161,77 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * the current sweep value store containing the current node voltage for * the assets * @param nodeToAssetAgents - * a map contains a mapping between nodes and the [[ActorRef]] s located @ - * those nodes + * a map contains a mapping between nodes and the [[classicRef]] s located + * \@ those nodes * @param refSystem * the reference system of the [[edu.ie3.simona.model.grid.GridModel]] of * this [[GridAgent]] * @param askTimeout * a timeout for the request - * @return - * Some(Future[ReceivedPowerValues]) if this grids contains assets or None - * if no request has been send due to non-existence of assets */ private def askForAssetPowers( currentTick: Long, sweepValueStore: Option[SweepValueStore], - nodeToAssetAgents: Map[UUID, Set[ActorRef]], + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], refSystem: RefSystem, askTimeout: Duration - ): Option[Future[ReceivedPowerValues]] = { - + )(implicit + ctx: ActorContext[GridAgentMessage] + ): Option[Future[ValuesAdapter]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) + implicit val ec: ExecutionContext = ctx.executionContext - log.debug(s"asking assets for power values: {}", nodeToAssetAgents) - - if (nodeToAssetAgents.values.flatten.nonEmpty) - Some( - Future - .sequence( - nodeToAssetAgents.flatten { case (nodeUuid, assetActorRefs) => - assetActorRefs.map(assetAgent => { - - val (eInPu, fInPU) = - sweepValueStore match { - case Some(sweepValueStore) => - val (eInSi, fInSi) = refSystem.vInSi( - sweepValueStore.sweepData - .find(_.nodeUuid == nodeUuid) - .getOrElse( - throw new DBFSAlgorithmException( - s"Provided Sweep value store contains no data for node with id $nodeUuid" - ) - ) - .stateData - .voltage - ) - ( - refSystem.vInPu(eInSi), - refSystem.vInPu(fInSi) - ) - case None => - ( - Each(1d), - Each(0d) - ) - } + ctx.log.debug(s"asking assets for power values: {}", nodeToAssetAgents) - (assetAgent ? RequestAssetPowerMessage( - currentTick, - eInPu, - fInPU - )).map { - case providedPowerValuesMessage: AssetPowerChangedMessage => - (assetAgent, providedPowerValuesMessage) - case assetPowerUnchangedMessage: AssetPowerUnchangedMessage => - (assetAgent, assetPowerUnchangedMessage) + if (nodeToAssetAgents.values.flatten.nonEmpty) { + val future = Future + .sequence( + nodeToAssetAgents.flatten { case (nodeUuid, assetActorRefs) => + assetActorRefs.map(assetAgent => { + + val (eInPu, fInPU) = + sweepValueStore match { + case Some(sweepValueStore) => + val (eInSi, fInSi) = refSystem.vInSi( + sweepValueStore.sweepData + .find(_.nodeUuid == nodeUuid) + .getOrElse( + throw new DBFSAlgorithmException( + s"Provided Sweep value store contains no data for node with id $nodeUuid" + ) + ) + .stateData + .voltage + ) + ( + refSystem.vInPu(eInSi), + refSystem.vInPu(fInSi) + ) + case None => + ( + Each(1d), + Each(0d) + ) } - }) - }.toVector - ) - .map(ReceivedAssetPowerValues) - .pipeTo(self) - ) - else - None + + (assetAgent.toClassic ? RequestAssetPowerMessage( + currentTick, + eInPu, + fInPU + )).map { + case providedPowerValuesMessage: AssetPowerChangedMessage => + (assetAgent, providedPowerValuesMessage) + case assetPowerUnchangedMessage: AssetPowerUnchangedMessage => + (assetAgent, assetPowerUnchangedMessage) + } + }) + }.toVector + ) + .map(res => ValuesAdapter(ReceivedAssetPowerValues(res))) + + pipeToSelf(future, ctx) + Some(future) + } else None } /** Triggers an execution of the pekko `ask` pattern for all power values @ @@ -1129,23 +1244,26 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * [[ActorRef]] s of [[GridAgent]] s @ these nodes * @param askTimeout * a timeout for the request - * @return - * Some(Future[ReceivedPowerValues]) if this grids has connected inferior - * grids or None if this no inferior grids */ private def askInferiorGridsForPowers( currentSweepNo: Int, - subGridGateToActorRef: Map[SubGridGate, ActorRef], + subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]], inferiorGridGates: Seq[SubGridGate], askTimeout: Duration - ): Option[Future[ReceivedPowerValues]] = { + )(implicit + ctx: ActorContext[GridAgentMessage] + ): Option[Future[ValuesAdapter]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) - log.debug( + implicit val ec: ExecutionContext = ctx.executionContext + implicit val scheduler: Scheduler = ctx.system.scheduler + + ctx.log.debug( s"asking inferior grids for power values: {}", inferiorGridGates ) + Option.when(inferiorGridGates.nonEmpty) { - Future + val future = Future .sequence( inferiorGridGates .map { inferiorGridGate => @@ -1161,20 +1279,30 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { inferiorGridGates } .map { case (inferiorGridAgentRef, inferiorGridGateNodes) => - (inferiorGridAgentRef ? RequestGridPowerMessage( - currentSweepNo, - inferiorGridGateNodes.distinct - )).map { - case provideGridPowerMessage: ProvideGridPowerMessage => - (inferiorGridAgentRef, provideGridPowerMessage) - case FailedPowerFlow => - (inferiorGridAgentRef, FailedPowerFlow) - } + inferiorGridAgentRef + .ask[GridAgentMessage](ref => + PMAdapter( + RequestGridPowerMessage( + currentSweepNo, + inferiorGridGateNodes.distinct, + ref + ) + ) + ) + .map { + case PMAdapter( + provideGridPowerMessage: ProvideGridPowerMessage + ) => + (inferiorGridAgentRef, provideGridPowerMessage) + case PMAdapter(FailedPowerFlow) => + (inferiorGridAgentRef, FailedPowerFlow) + } } .toVector ) - .map(ReceivedGridPowerValues) - .pipeTo(self) + .map(res => ValuesAdapter(ReceivedGridPowerValues(res))) + pipeToSelf(future, ctx) + future } } @@ -1188,39 +1316,52 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * [[ActorRef]] s of [[GridAgent]] s @ these nodes * @param askTimeout * a timeout for the request - * @return - * Some(Future[ReceivedSlackValues]) if this grids has connected superior - * grids or None if this no superior grids */ private def askSuperiorGridsForSlackVoltages( currentSweepNo: Int, - subGridGateToActorRef: Map[SubGridGate, ActorRef], + subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]], superiorGridGates: Vector[SubGridGate], askTimeout: Duration - ): Option[Future[ReceivedSlackVoltageValues]] = { + )(implicit + ctx: ActorContext[GridAgentMessage] + ): Option[Future[ValuesAdapter]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) - log.debug( + implicit val ec: ExecutionContext = ctx.executionContext + implicit val scheduler: Scheduler = ctx.system.scheduler + + ctx.log.debug( s"asking superior grids for slack voltage values: {}", superiorGridGates ) Option.when(superiorGridGates.nonEmpty) { - Future + val future = Future .sequence( superiorGridGates .groupBy(subGridGateToActorRef(_)) .map { case (superiorGridAgent, gridGates) => - (superiorGridAgent ? RequestSlackVoltageMessage( - currentSweepNo, - gridGates.map(_.superiorNode.getUuid) - )).map { case providedSlackValues: ProvideSlackVoltageMessage => - (superiorGridAgent, providedSlackValues) - } + superiorGridAgent + .ask[GridAgentMessage](ref => + VMAdapter( + RequestSlackVoltageMessage( + currentSweepNo, + gridGates.map(_.superiorNode.getUuid), + ref + ) + ) + ) + .map { + case VMAdapter( + providedSlackValues: ProvideSlackVoltageMessage + ) => + (superiorGridAgent, providedSlackValues) + } } .toVector ) - .map(ReceivedSlackVoltageValues) - .pipeTo(self) + .map(res => ValuesAdapter(ReceivedSlackVoltageValues(res))) + pipeToSelf(future, ctx) + future } } @@ -1236,10 +1377,10 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * @param currentTimestamp * the current time stamp */ - def createAndSendPowerFlowResults( + private def createAndSendPowerFlowResults( gridAgentBaseData: GridAgentBaseData, currentTimestamp: ZonedDateTime - ): Unit = { + )(implicit log: Logger): Unit = { gridAgentBaseData.sweepValueStores.lastOption.foreach { case (_, valueStore) => notifyListener( @@ -1247,10 +1388,26 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.gridEnv.gridModel, valueStore )( - currentTimestamp + currentTimestamp, + log ) ) } } + /** Simple method to pipe a future to itself. + * @param future + * value + * @param ctx + * context + */ + private def pipeToSelf( + future: Future[ValuesAdapter], + ctx: ActorContext[GridAgentMessage] + ): Unit = { + ctx.pipeToSelf[ValuesAdapter](future) { + case Success(value) => value + case Failure(exception) => ValuesAdapter(ReceivedFailure(exception)) + } + } } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index b8677f607a..b5339bcf15 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -6,29 +6,33 @@ package edu.ie3.simona.agent.grid -import edu.ie3.simona.agent.grid.GridAgent.Create +import edu.ie3.simona.actor.SimonaActorNaming +import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, - GridAgentInitData, - GridAgentUninitializedData + GridAgentInitData } -import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} -import edu.ie3.simona.agent.state.GridAgentState.{Initializing, SimulateGrid} -import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} +import edu.ie3.simona.agent.grid.GridAgentMessage._ +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.event.ResultEvent +import edu.ie3.simona.event.notifier.Notifier import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel -import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation } import edu.ie3.simona.ontology.messages.{Activation, StopMessage} -import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil -import org.apache.pekko.actor.{ActorRef, Props, Stash} -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + ClassicActorRefOps, + TypedActorContextOps +} +import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} +import org.apache.pekko.actor.typed.{ActorRef, Behavior} +import org.apache.pekko.actor.{ActorRef => classicRef} import java.time.ZonedDateTime import java.time.temporal.ChronoUnit @@ -36,142 +40,108 @@ import java.util.UUID import scala.language.postfixOps object GridAgent { - def props( + def apply( environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - listener: Iterable[ActorRef] - ): Props = - Props( - new GridAgent( + listener: Iterable[classicRef] + ): Behavior[GridAgentMessage] = Behaviors.withStash(100) { buffer => + Behaviors.setup[GridAgentMessage] { context => + context.messageAdapter(values => ValuesAdapter(values)) + context.messageAdapter(msg => PMAdapter(msg)) + context.messageAdapter(msg => VMAdapter(msg)) + val activationAdapter: ActorRef[Activation] = + context.messageAdapter[Activation](msg => ActivationAdapter(msg)) + + // val initialization + val resolution: Long = simonaConfig.simona.powerflow.resolution.get( + ChronoUnit.SECONDS + ) // this determines the agents regular time bin it wants to be triggered e.g one hour + + val simStartTime: ZonedDateTime = TimeUtil.withDefaults + .toZonedDateTime(simonaConfig.simona.time.startDateTime) + + val gridAgentController = + new GridAgentController( + context.toClassic, + environmentRefs, + simStartTime, + TimeUtil.withDefaults + .toZonedDateTime(simonaConfig.simona.time.endDateTime), + simonaConfig.simona.runtime.participant, + simonaConfig.simona.output.participant, + resolution, + listener.map(_.toTyped[ResultEvent]), + context.log + ) + + val agent = GridAgent( environmentRefs, simonaConfig, - listener + listener, + resolution, + simStartTime, + gridAgentController, + buffer, + activationAdapter, + SimonaActorNaming.actorName(context.self) ) - ) - /** GridAgent initialization data can only be constructed once all GridAgent - * actors are created. Thus, we need an extra initialization message. - * @param gridAgentInitData - * The initialization data - */ - final case class Create( - gridAgentInitData: GridAgentInitData, - unlockKey: ScheduleKey - ) - - /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to - * execute a power flow calculation - * - * @param tick - * current tick - */ - final case class DoPowerFlowTrigger(tick: Long, currentSweepNo: Int) - - /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to - * activate the superior grid agent to check for deviation after two sweeps - * and see if the power flow converges - * - * @param tick - * current tick - */ - final case class CheckPowerDifferencesTrigger(tick: Long) - - /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to - * trigger the [[edu.ie3.simona.agent.grid.GridAgent]] s to prepare - * themselves for a new sweep - * - * @param tick - * current tick - */ - final case class PrepareNextSweepTrigger(tick: Long) - - /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to - * indicate that a result has been found and each - * [[edu.ie3.simona.agent.grid.GridAgent]] should do it's cleanup work - * - * @param tick - * current tick - */ - final case class FinishGridSimulationTrigger(tick: Long) + agent.uninitialized + } + } } -class GridAgent( - val environmentRefs: EnvironmentRefs, +final case class GridAgent( + environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - val listener: Iterable[ActorRef] -) extends SimonaAgent[GridAgentData] - with DBFSAlgorithm - with Stash { - - // val initialization - protected val resolution: Long = simonaConfig.simona.powerflow.resolution.get( - ChronoUnit.SECONDS - ) // this determines the agents regular time bin it wants to be triggered e.g one hour - - protected val simStartTime: ZonedDateTime = TimeUtil.withDefaults - .toZonedDateTime(simonaConfig.simona.time.startDateTime) - - private val gridAgentController = - new GridAgentController( - context, - environmentRefs, - simStartTime, - TimeUtil.withDefaults - .toZonedDateTime(simonaConfig.simona.time.endDateTime), - simonaConfig.simona.runtime.participant, - simonaConfig.simona.output.participant, - resolution, - listener, - log - ) - - override def postStop(): Unit = { - log.debug("{} shutdown", self) - } + override val listener: Iterable[classicRef], + resolution: Long, + simStartTime: ZonedDateTime, + gridAgentController: GridAgentController, + buffer: StashBuffer[GridAgentMessage], + activationAdapter: ActorRef[Activation], + actorName: String +) extends DBFSAlgorithm + with Notifier { + + protected def uninitialized: Behavior[GridAgentMessage] = + Behaviors.receiveMessage[GridAgentMessage] { + case CreateGridAgent(gridAgentInitData, unlockKey) => + environmentRefs.scheduler ! ScheduleActivation( + activationAdapter, + INIT_SIM_TICK, + Some(unlockKey) + ) - override def preStart(): Unit = { - log.debug("{} started!", self) - } + initializing(gridAgentInitData) - // general agent states - // first fsm state of the agent - startWith(Uninitialized, GridAgentUninitializedData) - - when(Uninitialized) { - case Event( - Create(gridAgentInitData, unlockKey), - _ - ) => - environmentRefs.scheduler ! ScheduleActivation( - self.toTyped, - INIT_SIM_TICK, - Some(unlockKey) - ) + case GridAgentMessage.StopGridAgent => + Behaviors.stopped - goto(Initializing) using gridAgentInitData - } + case _ => + Behaviors.unhandled + } - when(Initializing) { - case Event( - Activation(INIT_SIM_TICK), - gridAgentInitData: GridAgentInitData - ) => + protected def initializing( + gridAgentInitData: GridAgentInitData + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + case (ctx, ActivationAdapter(Activation(INIT_SIM_TICK))) => // fail fast sanity checks - failFast(gridAgentInitData) + failFast(gridAgentInitData, SimonaActorNaming.actorName(ctx.self)) - log.debug( + ctx.log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", gridAgentInitData.inferiorGridIds, gridAgentInitData.inferiorGridNodeUuids ) - log.debug( + ctx.log.debug( s"Superior Subnets: {}; Superior Subnet Nodes: {}", gridAgentInitData.superiorGridIds, gridAgentInitData.superiorGridNodeUuids ) - log.debug("Received InitializeTrigger.") + ctx.log.debug("Received InitializeTrigger.") // build the assets concurrently val subGridContainer = gridAgentInitData.subGridContainer @@ -179,21 +149,22 @@ class GridAgent( val thermalGridsByBusId = gridAgentInitData.thermalIslandGrids.map { thermalGrid => thermalGrid.bus().getUuid -> thermalGrid }.toMap - log.debug(s"Thermal island grids: ${thermalGridsByBusId.size}") + ctx.log.debug(s"Thermal island grids: ${thermalGridsByBusId.size}") // get the [[GridModel]] val gridModel = GridModel( subGridContainer, refSystem, - TimeUtil.withDefaults - .toZonedDateTime(simonaConfig.simona.time.startDateTime), + TimeUtil.withDefaults.toZonedDateTime( + simonaConfig.simona.time.startDateTime + ), TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime ) ) /* Reassure, that there are also calculation models for the given uuids */ - val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef]] = + val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef[ParticipantMessage]]] = gridAgentController .buildSystemParticipants(subGridContainer, thermalGridsByBusId) .map { case (uuid: UUID, actorSet) => @@ -222,55 +193,62 @@ class GridAgent( simonaConfig.simona.powerflow.sweepTimeout, simonaConfig.simona.powerflow.stopOnFailure ), - log, - actorName + ctx.log, + ctx.self.toString ) - log.debug("Je suis initialized") + ctx.log.debug("Je suis initialized") environmentRefs.scheduler ! Completion( - self.toTyped, + activationAdapter, Some(resolution) ) - goto(Idle) using gridAgentBaseData - } + idle(gridAgentBaseData) - when(Idle) { + case (_, StopGridAgent) => + Behaviors.stopped - // needs to be set here to handle if the messages arrive too early - // before a transition to GridAgentBehaviour took place - case Event(RequestGridPowerMessage(_, _), _: GridAgentBaseData) => - stash() - stay() + case (_, _) => + Behaviors.unhandled + } - case Event( - Activation(tick), - gridAgentBaseData: GridAgentBaseData - ) => - unstashAll() + protected def idle( + gridAgentBaseData: GridAgentBaseData + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + case (_, pm: PMAdapter) => + // needs to be set here to handle if the messages arrive too early + // before a transition to GridAgentBehaviour took place + buffer.stash(pm) + Behaviors.same + case (_, ActivationAdapter(activation: Activation)) => environmentRefs.scheduler ! Completion( - self.toTyped, - Some(tick) + activationAdapter, + Some(activation.tick) ) + buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) - goto(SimulateGrid) using gridAgentBaseData - - case Event(StopMessage(_), data: GridAgentBaseData) => + case (ctx, ResultMessageAdapter(StopMessage(_))) => // shutdown children - data.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => - actors.foreach(context.stop) + gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => + actors.foreach(a => ctx.stop(a)) } // we are done - stop() - } + Behaviors.stopped - // everything else - whenUnhandled(myUnhandled()) + case (_, StopGridAgent) => + Behaviors.stopped - private def failFast(gridAgentInitData: GridAgentInitData): Unit = { + case _ => + Behaviors.unhandled + } + + private def failFast( + gridAgentInitData: GridAgentInitData, + actorName: String + ): Unit = { if ( gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala index 9ec4aca397..ebd5848693 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala @@ -6,14 +6,12 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorContext, ActorRef} -import org.apache.pekko.event.LoggingAdapter import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.datamodel.models.input.system._ import edu.ie3.simona.actor.SimonaActorNaming._ import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.{ ActorEvMovementsService, ActorWeatherService @@ -27,12 +25,20 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.Participa import edu.ie3.simona.agent.participant.wec.WecAgent import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig._ +import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.util.ConfigUtil import edu.ie3.simona.util.ConfigUtil._ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + ClassicActorRefOps, + TypedActorRefOps +} +import org.apache.pekko.actor.{ActorContext, ActorRef => classicRef} +import org.slf4j.Logger import java.time.ZonedDateTime import java.util.UUID @@ -62,20 +68,20 @@ import scala.jdk.CollectionConverters._ * @since 2019-07-18 */ class GridAgentController( - gridAgentContext: ActorContext, + gridAgentContext: ActorContext, // TODO: Change to typed after the participants are typed environmentRefs: EnvironmentRefs, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, participantsConfig: SimonaConfig.Simona.Runtime.Participant, outputConfig: SimonaConfig.Simona.Output.Participant, resolution: Long, - listener: Iterable[ActorRef], - log: LoggingAdapter + listener: Iterable[ActorRef[ResultEvent]], + log: Logger ) extends LazyLogging { def buildSystemParticipants( subGridContainer: SubGridContainer, thermalIslandGridsByBusId: Map[UUID, ThermalGrid] - ): Map[UUID, Set[ActorRef]] = { + ): Map[UUID, Set[ActorRef[ParticipantMessage]]] = { val systemParticipants = filterSysParts(subGridContainer, environmentRefs) @@ -127,7 +133,7 @@ class GridAgentController( // only include evcs if ev data service is present case evcsInput: EvcsInput if environmentRefs.evDataService.isEmpty => - log.warning( + log.warn( s"Evcs ${evcsInput.getId} has been removed because no ev movements service is present." ) (notProcessedElements, availableSystemParticipants) @@ -137,7 +143,7 @@ class GridAgentController( } if (notProcessedElements.nonEmpty) - log.warning( + log.warn( s"The following elements have been removed, " + s"as the agents are not implemented yet: $notProcessedElements" ) @@ -170,7 +176,7 @@ class GridAgentController( participants: Vector[SystemParticipantInput], thermalIslandGridsByBusId: Map[UUID, ThermalGrid], environmentRefs: EnvironmentRefs - ): Map[UUID, Set[ActorRef]] = { + ): Map[UUID, Set[ActorRef[ParticipantMessage]]] = { /* Prepare the config util for the participant models, which (possibly) utilizes as map to speed up the initialization * phase */ val participantConfigUtil = @@ -190,11 +196,11 @@ class GridAgentController( thermalIslandGridsByBusId, environmentRefs ) - introduceAgentToEnvironment(actorRef) + introduceAgentToEnvironment(actorRef.toClassic) // return uuid to actorRef node.getUuid -> actorRef }) - .toSet[(UUID, ActorRef)] + .toSet[(UUID, ActorRef[ParticipantMessage])] .groupMap(entry => entry._1)(entry => entry._2) } @@ -205,7 +211,7 @@ class GridAgentController( participantInputModel: SystemParticipantInput, thermalIslandGridsByBusId: Map[UUID, ThermalGrid], environmentRefs: EnvironmentRefs - ): ActorRef = participantInputModel match { + ): ActorRef[ParticipantMessage] = participantInputModel match { case input: FixedFeedInInput => buildFixedFeedIn( input, @@ -325,36 +331,38 @@ class GridAgentController( * @param outputConfig * Configuration of the output behavior * @return - * The [[FixedFeedInAgent]] 's [[ActorRef]] + * The [[FixedFeedInAgent]] 's [[classicRef]] */ private def buildFixedFeedIn( fixedFeedInInput: FixedFeedInInput, modelConfiguration: FixedFeedInRuntimeConfig, - primaryServiceProxy: ActorRef, + primaryServiceProxy: classicRef, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = - gridAgentContext.simonaActorOf( - FixedFeedInAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - fixedFeedInInput, - modelConfiguration, - primaryServiceProxy, - None, - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig + ): ActorRef[ParticipantMessage] = + gridAgentContext + .simonaActorOf( + FixedFeedInAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + fixedFeedInInput, + modelConfiguration, + primaryServiceProxy, + None, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) ), - listener - ), - fixedFeedInInput.getId - ) + fixedFeedInInput.getId + ) + .toTyped /** Creates a load agent and determines the needed additional information for * later initialization of the agent. @@ -376,36 +384,38 @@ class GridAgentController( * @param outputConfig * Configuration of the output behavior * @return - * The [[LoadAgent]] 's [[ActorRef]] + * The [[LoadAgent]] 's [[classicRef]] */ private def buildLoad( loadInput: LoadInput, modelConfiguration: LoadRuntimeConfig, - primaryServiceProxy: ActorRef, + primaryServiceProxy: classicRef, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = - gridAgentContext.simonaActorOf( - LoadAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - loadInput, - modelConfiguration, - primaryServiceProxy, - None, - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig + ): ActorRef[ParticipantMessage] = + gridAgentContext + .simonaActorOf( + LoadAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + loadInput, + modelConfiguration, + primaryServiceProxy, + None, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) ), - listener - ), - loadInput.getId - ) + loadInput.getId + ) + .toTyped /** Creates a pv agent and determines the needed additional information for * later initialization of the agent. @@ -429,37 +439,39 @@ class GridAgentController( * @param outputConfig * Configuration of the output behavior * @return - * The [[PvAgent]] 's [[ActorRef]] + * The [[PvAgent]] 's [[classicRef]] */ private def buildPv( pvInput: PvInput, modelConfiguration: PvRuntimeConfig, - primaryServiceProxy: ActorRef, - weatherService: ActorRef, + primaryServiceProxy: classicRef, + weatherService: classicRef, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = - gridAgentContext.simonaActorOf( - PvAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - pvInput, - modelConfiguration, - primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig + ): ActorRef[ParticipantMessage] = + gridAgentContext + .simonaActorOf( + PvAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + pvInput, + modelConfiguration, + primaryServiceProxy, + Some(Vector(ActorWeatherService(weatherService))), + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) ), - listener - ), - pvInput.getId - ) + pvInput.getId + ) + .toTyped /** Creates an Evcs agent and determines the needed additional information for * later initialization of the agent. @@ -483,19 +495,19 @@ class GridAgentController( * @param outputConfig * Configuration of the output behavior * @return - * The [[EvcsAgent]] 's [[ActorRef]] + * The [[EvcsAgent]] 's [[classicRef]] */ private def buildEvcs( evcsInput: EvcsInput, modelConfiguration: EvcsRuntimeConfig, - primaryServiceProxy: ActorRef, - evMovementsService: ActorRef, + primaryServiceProxy: classicRef, + evMovementsService: classicRef, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = { + ): ActorRef[ParticipantMessage] = { val sources = Some( Vector( ActorEvMovementsService( @@ -503,23 +515,25 @@ class GridAgentController( ) ) ) - gridAgentContext.simonaActorOf( - EvcsAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - evcsInput, - modelConfiguration, - primaryServiceProxy, - sources, - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig - ), - listener + gridAgentContext + .simonaActorOf( + EvcsAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + evcsInput, + modelConfiguration, + primaryServiceProxy, + sources, + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) + ) ) - ) + .toTyped } /** Builds an [[HpAgent]] from given input @@ -544,30 +558,32 @@ class GridAgentController( hpInput: HpInput, thermalGrid: ThermalGrid, modelConfiguration: HpRuntimeConfig, - primaryServiceProxy: ActorRef, - weatherService: ActorRef, + primaryServiceProxy: classicRef, + weatherService: classicRef, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = - gridAgentContext.simonaActorOf( - HpAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - hpInput, - thermalGrid, - modelConfiguration, - primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig + ): ActorRef[ParticipantMessage] = + gridAgentContext + .simonaActorOf( + HpAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + hpInput, + thermalGrid, + modelConfiguration, + primaryServiceProxy, + Some(Vector(ActorWeatherService(weatherService))), + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) ), - listener - ), - hpInput.getId - ) + hpInput.getId + ) + .toTyped /** Creates a pv agent and determines the needed additional information for * later initialization of the agent. @@ -591,37 +607,39 @@ class GridAgentController( * @param outputConfig * Configuration of the output behavior * @return - * The [[WecAgent]] 's [[ActorRef]] + * The [[WecAgent]] 's [[classicRef]] */ private def buildWec( wecInput: WecInput, modelConfiguration: WecRuntimeConfig, - primaryServiceProxy: ActorRef, - weatherService: ActorRef, + primaryServiceProxy: classicRef, + weatherService: classicRef, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = - gridAgentContext.simonaActorOf( - WecAgent.props( - environmentRefs.scheduler, - ParticipantInitializeStateData( - wecInput, - modelConfiguration, - primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), - simulationStartDate, - simulationEndDate, - resolution, - requestVoltageDeviationThreshold, - outputConfig + ): ActorRef[ParticipantMessage] = + gridAgentContext + .simonaActorOf( + WecAgent.props( + environmentRefs.scheduler, + ParticipantInitializeStateData( + wecInput, + modelConfiguration, + primaryServiceProxy, + Some(Vector(ActorWeatherService(weatherService))), + simulationStartDate, + simulationEndDate, + resolution, + requestVoltageDeviationThreshold, + outputConfig + ), + listener.map(_.toClassic) ), - listener - ), - wecInput.getId - ) + wecInput.getId + ) + .toTyped /** Introduces the given agent to scheduler * @@ -629,11 +647,11 @@ class GridAgentController( * Reference to the actor to add to the environment */ private def introduceAgentToEnvironment( - actorRef: ActorRef + actorRef: classicRef ): Unit = { gridAgentContext.watch(actorRef) environmentRefs.scheduler ! ScheduleActivation( - actorRef.toTyped, + actorRef.toTyped, // TODO: Add participant adapter INIT_SIM_TICK ) } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala index 038d72cbc5..4a498be6b3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorRef -import org.apache.pekko.event.LoggingAdapter import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.powerflow.model.PowerFlowResult @@ -17,6 +15,7 @@ import edu.ie3.simona.agent.grid.ReceivedValues.{ ReceivedSlackVoltageValues } import edu.ie3.simona.agent.grid.ReceivedValuesStore.NodeToReceivedPower +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.model.grid.{GridModel, RefSystem} import edu.ie3.simona.ontology.messages.PowerMessage.{ FailedPowerFlow, @@ -24,6 +23,8 @@ import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, ProvidePowerMessage } +import org.apache.pekko.actor.typed.ActorRef +import org.slf4j.Logger import java.util.UUID @@ -33,14 +34,10 @@ sealed trait GridAgentData */ object GridAgentData { - /** Initial state data of the [[GridAgent]] - */ - final case object GridAgentUninitializedData extends GridAgentData - /** Data that is send to the [[GridAgent]] directly after startup. It contains * the main information for initialization. This data should include all * [[GridAgent]] individual data, for data that is the same for all - * [[GridAgent]] s please use [[GridAgent.props()]] + * [[GridAgent]] s please use [[GridAgent.apply()]] * * @param subGridContainer * raw grid information in the input data format @@ -54,7 +51,7 @@ object GridAgentData { final case class GridAgentInitData( subGridContainer: SubGridContainer, thermalIslandGrids: Seq[ThermalGrid], - subGridGateToActorRef: Map[SubGridGate, ActorRef], + subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]], refSystem: RefSystem ) extends GridAgentData with GridAgentDataHelper { @@ -101,12 +98,12 @@ object GridAgentData { def apply( gridModel: GridModel, - subgridGateToActorRef: Map[SubGridGate, ActorRef], - nodeToAssetAgents: Map[UUID, Set[ActorRef]], + subgridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]], + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], superiorGridNodeUuids: Vector[UUID], inferiorGridGates: Vector[SubGridGate], powerFlowParams: PowerFlowParams, - log: LoggingAdapter, + log: Logger, actorName: String ): GridAgentBaseData = { @@ -194,7 +191,7 @@ object GridAgentData { currentSweepNo: Int, receivedValueStore: ReceivedValuesStore, sweepValueStores: Map[Int, SweepValueStore], - log: LoggingAdapter, + log: Logger, actorName: String ) extends GridAgentData with GridAgentDataHelper { @@ -301,7 +298,7 @@ object GridAgentData { private def updateNodalReceivedPower( powerResponse: PowerResponseMessage, nodeToReceived: NodeToReceivedPower, - senderRef: ActorRef, + senderRef: ActorRef[_], replace: Boolean ): NodeToReceivedPower = { // extract the nodeUuid that corresponds to the sender's actorRef and check if we expect a message from the sender @@ -359,7 +356,7 @@ object GridAgentData { */ private def getNodeUuidForSender( nodeToReceivedPower: NodeToReceivedPower, - senderRef: ActorRef, + senderRef: ActorRef[_], replace: Boolean ): Option[UUID] = nodeToReceivedPower diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala new file mode 100644 index 0000000000..c466cab896 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala @@ -0,0 +1,110 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.agent.grid + +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.ontology.messages.{ + Activation, + PowerMessage, + VoltageMessage +} +import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import org.apache.pekko.actor.typed.ActorRef + +/** Trait for [[GridAgent]] messages. + */ +sealed trait GridAgentMessage + +/** Defines all messages that can be received by a [[GridAgent]] without the + * need for an adapter. + */ +object GridAgentMessage { + + /** GridAgent initialization data can only be constructed once all GridAgent + * actors are created. Thus, we need an extra initialization message. + * + * @param gridAgentInitData + * The initialization data + */ + final case class CreateGridAgent( + gridAgentInitData: GridAgentInitData, + unlockKey: ScheduleKey + ) extends GridAgentMessage + + /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to + * execute a power flow calculation + * + * @param tick + * current tick + */ + final case class DoPowerFlowTrigger(tick: Long, currentSweepNo: Int) + extends GridAgentMessage + + /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to + * activate the superior grid agent to check for deviation after two sweeps + * and see if the power flow converges + * + * @param tick + * current tick + */ + final case class CheckPowerDifferencesTrigger(tick: Long) + extends GridAgentMessage + + /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to + * trigger the [[edu.ie3.simona.agent.grid.GridAgent]] s to prepare + * themselves for a new sweep + * + * @param tick + * current tick + */ + final case class PrepareNextSweepTrigger(tick: Long) extends GridAgentMessage + + /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to + * indicate that a result has been found and each + * [[edu.ie3.simona.agent.grid.GridAgent]] should do it's cleanup work + * + * @param tick + * current tick + */ + final case class FinishGridSimulationTrigger(tick: Long) + extends GridAgentMessage + + /** Message that should be send by the + */ + final object StopGridAgent extends GridAgentMessage + + /** Wrapper for string messages. NOTICE: Only for internal use. + * @param str + * message + * @param sender + * of the message + */ + private[grid] final case class StringAdapter( + str: String, + sender: ActorRef[GridAgentMessage] + ) extends GridAgentMessage + + /** Wrapper for activation values + * + * @param activation + * the tick + */ + final case class ActivationAdapter(activation: Activation) + extends GridAgentMessage + + final case class PMAdapter(msg: PowerMessage) extends GridAgentMessage + + final case class VMAdapter(msg: VoltageMessage) extends GridAgentMessage + + final case class ValuesAdapter(values: ReceivedValues) + extends GridAgentMessage + + final case class ResultMessageAdapter(msg: ResultMessage) + extends GridAgentMessage + +} diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala index 39dadc489f..89702688e3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala @@ -6,11 +6,12 @@ package edu.ie3.simona.agent.grid -import java.util.UUID - -import org.apache.pekko.actor.ActorRef import edu.ie3.datamodel.graph.SubGridGate +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.model.grid.GridModel +import org.apache.pekko.actor.typed.ActorRef + +import java.util.UUID /** Wrapper class containing all information on the grid environment a * [[GridAgent]] has access to @@ -25,6 +26,6 @@ import edu.ie3.simona.model.grid.GridModel */ final case class GridEnvironment( gridModel: GridModel, - subgridGateToActorRef: Map[SubGridGate, ActorRef], - nodeToAssetAgents: Map[UUID, Set[ActorRef]] + subgridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]], + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]] ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala index ecd073b1cf..86172838a0 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.event.LoggingAdapter import breeze.math.Complex import edu.ie3.datamodel.models.input.connector.ConnectorPort import edu.ie3.datamodel.models.result.NodeResult @@ -29,6 +28,7 @@ import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ import edu.ie3.simona.model.grid._ import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.QuantityUtil +import org.slf4j.Logger import squants.space.Degrees import squants.{Amperes, Angle, ElectricCurrent} import tech.units.indriya.quantity.Quantities @@ -43,8 +43,6 @@ import scala.math._ */ private[grid] trait GridResultsSupport { - protected val log: LoggingAdapter - /** Creates a tuple as [[PowerFlowResultEvent]] s entities based on the * provided grid data * @@ -61,7 +59,7 @@ private[grid] trait GridResultsSupport { def createResultModels( grid: GridModel, sweepValueStore: SweepValueStore - )(implicit timestamp: ZonedDateTime): PowerFlowResultEvent = { + )(implicit timestamp: ZonedDateTime, log: Logger): PowerFlowResultEvent = { // no sanity check for duplicated uuid result data as we expect valid data at this point implicit val sweepValueStoreData: Map[UUID, SweepValueStoreData] = sweepValueStore.sweepData @@ -111,7 +109,8 @@ private[grid] trait GridResultsSupport { private def buildLineResults(lines: Set[LineModel])(implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: squants.ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, + log: Logger ): Set[LineResult] = { lines.flatMap(lineModel => { sweepValueStoreData @@ -128,7 +127,7 @@ private[grid] trait GridResultsSupport { ) ) case None => - log.warning( + log.warn( "Cannot find power flow result data for line {} with nodeA {} and nodeB {}", lineModel.uuid, lineModel.nodeAUuid, @@ -158,7 +157,8 @@ private[grid] trait GridResultsSupport { implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, + log: Logger ): Set[Transformer2WResult] = { transformers.flatMap(trafo2w => { sweepValueStoreData @@ -175,7 +175,7 @@ private[grid] trait GridResultsSupport { ) ) case None => - log.warning( + log.warn( "Cannot find power flow result data for transformer2w {} with hvNode {} and lvNode {}", trafo2w.uuid, trafo2w.hvNodeUuid, @@ -205,7 +205,8 @@ private[grid] trait GridResultsSupport { implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, + log: Logger ): Set[PartialTransformer3wResult] = transformers3w.flatMap { trafo3w => { (trafo3w.powerFlowCase match { @@ -233,7 +234,7 @@ private[grid] trait GridResultsSupport { ) ) case None => - log.warning( + log.warn( s"Cannot find power flow result data for transformer3w {} with nodeHv {}, nodeMv {}, nodeLv {} and internalNode ${trafo3w.nodeInternalUuid}", trafo3w.uuid, trafo3w.hvNodeUuid, diff --git a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala index afc26f47c1..a768f1574b 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.event.LoggingAdapter import breeze.math.Complex import edu.ie3.powerflow.NewtonRaphsonPF import edu.ie3.powerflow.model.NodeData.{PresetData, StateData} @@ -20,6 +19,7 @@ import edu.ie3.simona.model.grid._ import edu.ie3.simona.ontology.messages.PowerMessage.ProvidePowerMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.util.scala.quantities.Kilovars +import org.slf4j.Logger import squants.electro.ElectricPotential import squants.energy.Kilowatts @@ -32,8 +32,6 @@ import scala.util.{Failure, Success, Try} */ trait PowerFlowSupport { - protected val log: LoggingAdapter - /** Composes the current operation point needed by * [[edu.ie3.powerflow.NewtonRaphsonPF.calculate()]] * @@ -561,7 +559,7 @@ trait PowerFlowSupport { maxIterations: Int, operatingPoint: Array[PresetData], slackVoltages: WithForcedStartVoltages - )(epsilons: Vector[Double]): PowerFlowResult = { + )(epsilons: Vector[Double])(implicit log: Logger): PowerFlowResult = { epsilons.headOption match { case Some(epsilon) => val admittanceMatrix = diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala index 53f04d5af8..2342144296 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala @@ -6,9 +6,11 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorRef +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.ontology.messages.PowerMessage.PowerResponseMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage +import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import org.apache.pekko.actor.typed.ActorRef /** Serves as a wrapper class that allows for matches against received values in * [[DBFSAlgorithm]] @@ -17,11 +19,18 @@ sealed trait ReceivedValues object ReceivedValues { - type ActorPowerRequestResponse = (ActorRef, PowerResponseMessage) - type ActorSlackVoltageRequestResponse = (ActorRef, ProvideSlackVoltageMessage) + type ParticipantPowerRequestResponse = + ( + ActorRef[_], + PowerResponseMessage + ) // necessary, because participants are still classic actors + type GridPowerRequestResponse = + (ActorRef[GridAgentMessage], PowerResponseMessage) + type ActorSlackVoltageRequestResponse = + (ActorRef[GridAgentMessage], ProvideSlackVoltageMessage) sealed trait ReceivedPowerValues extends ReceivedValues { - def values: Vector[ActorPowerRequestResponse] + def values: Vector[(ActorRef[_], PowerResponseMessage)] } /** Wrapper for received asset power values (p, q) @@ -30,7 +39,7 @@ object ReceivedValues { * the asset power values and their senders */ final case class ReceivedAssetPowerValues( - values: Vector[ActorPowerRequestResponse] + values: Vector[ParticipantPowerRequestResponse] ) extends ReceivedPowerValues /** Wrapper for received grid power values (p, q) @@ -39,7 +48,7 @@ object ReceivedValues { * the grid power values and their senders */ final case class ReceivedGridPowerValues( - values: Vector[ActorPowerRequestResponse] + values: Vector[GridPowerRequestResponse] ) extends ReceivedPowerValues /** Wrapper for received slack voltage values (v) @@ -51,4 +60,11 @@ object ReceivedValues { values: Vector[ActorSlackVoltageRequestResponse] ) extends ReceivedValues + /** Wrapper for received exception. + * @param exception + * that was received + */ + final case class ReceivedFailure( + exception: Throwable + ) extends ReceivedValues } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala index 4c083629f3..3d2125ee5c 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala @@ -6,17 +6,20 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorRef import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.simona.agent.grid.ReceivedValuesStore.{ NodeToReceivedPower, NodeToReceivedSlackVoltage } +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.ontology.messages.PowerMessage.{ PowerResponseMessage, ProvidePowerMessage } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.{ActorRef => classicRef} import java.util.UUID @@ -47,7 +50,7 @@ final case class ReceivedValuesStore private ( object ReceivedValuesStore { type NodeToReceivedPower = - Map[UUID, Map[ActorRef, Option[PowerResponseMessage]]] + Map[UUID, Map[ActorRef[_], Option[PowerResponseMessage]]] type NodeToReceivedSlackVoltage = Map[UUID, Option[ExchangeVoltage]] @@ -68,8 +71,10 @@ object ReceivedValuesStore { * `empty` [[ReceivedValuesStore]] with pre-initialized options as `None` */ def empty( - nodeToAssetAgents: Map[UUID, Set[ActorRef]], - inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef], + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], + inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef[ + GridAgentMessage + ]], superiorGridNodeUuids: Vector[UUID] ): ReceivedValuesStore = { val (nodeToReceivedPower, nodeToReceivedSlackVoltage) = @@ -94,12 +99,14 @@ object ReceivedValuesStore { * `empty` [[NodeToReceivedPower]] with pre-initialized options as `None` */ private def buildEmptyNodeToReceivedPowerMap( - nodeToAssetAgents: Map[UUID, Set[ActorRef]], - inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef] + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], + inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef[ + GridAgentMessage + ]] ): NodeToReceivedPower = { /* Collect everything, that I expect from my asset agents */ val assetsToReceivedPower: NodeToReceivedPower = nodeToAssetAgents.collect { - case (uuid: UUID, actorRefs: Set[ActorRef]) => + case (uuid: UUID, actorRefs: Set[ActorRef[ParticipantMessage]]) => (uuid, actorRefs.map(actorRef => actorRef -> None).toMap) } @@ -118,7 +125,7 @@ object ReceivedValuesStore { val actorRefToMessage = subordinateToReceivedPower .getOrElse( couplingNodeUuid, - Map.empty[ActorRef, Option[ProvidePowerMessage]] + Map.empty[ActorRef[_], Option[ProvidePowerMessage]] ) + (inferiorSubGridRef -> None) /* Update the existing map */ @@ -156,8 +163,10 @@ object ReceivedValuesStore { * `empty` [[NodeToReceivedSlackVoltage]] and [[NodeToReceivedPower]] */ private def buildEmptyReceiveMaps( - nodeToAssetAgents: Map[UUID, Set[ActorRef]], - inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef], + nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], + inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef[ + GridAgentMessage + ]], superiorGridNodeUuids: Vector[UUID] ): (NodeToReceivedPower, NodeToReceivedSlackVoltage) = { ( diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala index 063ff508f5..6f8aa9a459 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala @@ -6,11 +6,9 @@ package edu.ie3.simona.agent.participant -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorRef, FSM} import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.simona.agent.SimonaAgent -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger +import edu.ie3.simona.agent.grid.GridAgentMessage.FinishGridSimulationTrigger import edu.ie3.simona.agent.participant.ParticipantAgent.{ StartCalculationTrigger, getAndCheckNodalVoltage @@ -50,6 +48,8 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.{ActorRef, FSM} import squants.{Dimensionless, Power} import java.time.ZonedDateTime @@ -721,6 +721,8 @@ abstract class ParticipantAgent[ object ParticipantAgent { + trait ParticipantMessage + final case class StartCalculationTrigger(tick: Long) /** Verifies that a nodal voltage value has been provided in the model diff --git a/src/main/scala/edu/ie3/simona/agent/state/GridAgentState.scala b/src/main/scala/edu/ie3/simona/agent/state/GridAgentState.scala deleted file mode 100644 index f602b4dabe..0000000000 --- a/src/main/scala/edu/ie3/simona/agent/state/GridAgentState.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.agent.state - -sealed trait GridAgentState extends AgentState - -object GridAgentState { - - case object Initializing extends GridAgentState - - case object SimulateGrid extends GridAgentState - - case object CheckPowerDifferences extends GridAgentState - - case object HandlePowerFlowCalculations extends GridAgentState - -} diff --git a/src/main/scala/edu/ie3/simona/event/notifier/Notifier.scala b/src/main/scala/edu/ie3/simona/event/notifier/Notifier.scala index 916a97f9cb..b271a913e9 100644 --- a/src/main/scala/edu/ie3/simona/event/notifier/Notifier.scala +++ b/src/main/scala/edu/ie3/simona/event/notifier/Notifier.scala @@ -6,10 +6,10 @@ package edu.ie3.simona.event.notifier -import org.apache.pekko.actor.{Actor, ActorRef} import edu.ie3.simona.event.Event +import org.apache.pekko.actor.ActorRef -trait Notifier extends Actor { +trait Notifier { def listener: Iterable[ActorRef] diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala index d82961cd5a..5caf8967ab 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala @@ -6,8 +6,10 @@ package edu.ie3.simona.ontology.messages +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.util.scala.quantities.ReactivePower +import org.apache.pekko.actor.typed.ActorRef import squants.{Dimensionless, Power} import java.util.UUID @@ -79,7 +81,8 @@ object PowerMessage { */ final case class RequestGridPowerMessage( currentSweepNo: Int, - nodeUuids: Seq[UUID] + nodeUuids: Seq[UUID], + sender: ActorRef[GridAgentMessage] ) extends PowerRequestMessage /** Provide complex power at the nodes that the sender's sub grid shares with diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala index 3c836b599d..10a0e653fa 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala @@ -6,7 +6,9 @@ package edu.ie3.simona.ontology.messages +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import org.apache.pekko.actor.typed.ActorRef import java.util.UUID import squants.electro.ElectricPotential @@ -27,7 +29,8 @@ object VoltageMessage { */ final case class RequestSlackVoltageMessage( currentSweepNo: Int, - nodeUuids: Seq[UUID] + nodeUuids: Seq[UUID], + sender: ActorRef[GridAgentMessage] ) extends VoltageMessage /** Provide complex voltage at the nodes that the sender's sub grid shares diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 7a619552eb..94ee03ebee 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -10,15 +10,17 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import org.apache.pekko.actor.SupervisorStrategy.Stop import org.apache.pekko.actor.{ Actor, - ActorRef, AllForOneStrategy, Props, Stash, SupervisorStrategy, - Terminated + Terminated, + ActorRef => classicRef } import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage +import edu.ie3.simona.agent.grid.GridAgentMessage.StopGridAgent import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.StopMessage import edu.ie3.simona.scheduler.TimeAdvancer @@ -34,6 +36,7 @@ import edu.ie3.simona.sim.SimonaSim.{ SimonaSimStateData } import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} +import org.apache.pekko.actor.typed.ActorRef import scala.concurrent.duration.DurationInt import scala.language.postfixOps @@ -70,34 +73,32 @@ class SimonaSim(simonaSetup: SimonaSetup) /* start listener */ // output listener - val systemParticipantsListener: Seq[ActorRef] = + val systemParticipantsListener: Seq[classicRef] = simonaSetup.systemParticipantsListener(context) // runtime event listener - val runtimeEventListener - : org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = + val runtimeEventListener: ActorRef[RuntimeEvent] = simonaSetup.runtimeEventListener(context) /* start scheduler */ - val timeAdvancer - : org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = + val timeAdvancer: ActorRef[TimeAdvancer.Incoming] = simonaSetup.timeAdvancer(context, self, runtimeEventListener) - val scheduler: ActorRef = simonaSetup.scheduler(context, timeAdvancer) + val scheduler: classicRef = simonaSetup.scheduler(context, timeAdvancer) /* start services */ // primary service proxy - val primaryServiceProxy: ActorRef = + val primaryServiceProxy: classicRef = simonaSetup.primaryServiceProxy(context, scheduler) // weather service - val weatherService: ActorRef = + val weatherService: classicRef = simonaSetup.weatherService(context, scheduler) val extSimulationData: ExtSimSetupData = simonaSetup.extSimulations(context, scheduler) /* start grid agents */ - val gridAgents: Iterable[ActorRef] = simonaSetup.gridAgents( + val gridAgents: Iterable[ActorRef[GridAgentMessage]] = simonaSetup.gridAgents( context, EnvironmentRefs( scheduler, @@ -116,7 +117,7 @@ class SimonaSim(simonaSetup: SimonaSetup) context.watch(scheduler) context.watch(primaryServiceProxy) context.watch(weatherService) - gridAgents.foreach(context.watch) + gridAgents.foreach(ref => context.watch(ref.toClassic)) override def receive: Receive = simonaSimReceive(SimonaSimStateData()) @@ -195,9 +196,9 @@ class SimonaSim(simonaSetup: SimonaSetup) } def waitingForListener( - initSimSender: ActorRef, + initSimSender: classicRef, successful: Boolean, - remainingListeners: Seq[ActorRef] + remainingListeners: Seq[classicRef] ): Receive = { case Terminated(actor) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) @@ -231,8 +232,8 @@ class SimonaSim(simonaSetup: SimonaSetup) simulationSuccessful: Boolean ): Unit = { gridAgents.foreach { gridAgentRef => - context.unwatch(gridAgentRef) - gridAgentRef ! StopMessage(simulationSuccessful) + context.unwatch(gridAgentRef.toClassic) + gridAgentRef ! StopGridAgent } context.unwatch(scheduler) @@ -270,7 +271,7 @@ object SimonaSim { case object EmergencyShutdownInitiated private[SimonaSim] final case class SimonaSimStateData( - initSimSender: ActorRef = ActorRef.noSender + initSimSender: classicRef = classicRef.noSender ) def props(simonaSetup: SimonaSetup): Props = diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala index 1e319ecbcc..f689589755 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.ActorRef import com.typesafe.config.{Config => TypesafeConfig} import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridGate @@ -14,6 +13,7 @@ import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.datamodel.utils.ContainerUtils import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.config.RefSystemParser.ConfigRefSystems import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.InitializationException @@ -23,6 +23,7 @@ import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.util.ConfigUtil.{GridOutputConfigUtil, OutputConfigUtil} import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig import edu.ie3.simona.util.{EntityMapperUtil, ResultFileHierarchy} +import org.apache.pekko.actor.typed.ActorRef /** Methods to support the setup of a simona simulation * @@ -54,7 +55,7 @@ trait SetupHelper extends LazyLogging { */ def buildGridAgentInitData( subGridContainer: SubGridContainer, - subGridToActorRef: Map[Int, ActorRef], + subGridToActorRef: Map[Int, ActorRef[GridAgentMessage]], gridGates: Set[SubGridGate], configRefSystems: ConfigRefSystems, thermalGrids: Seq[ThermalGrid] @@ -95,10 +96,10 @@ trait SetupHelper extends LazyLogging { * A mapping from [[SubGridGate]] to corresponding actor reference */ def buildGateToActorRef( - subGridToActorRefMap: Map[Int, ActorRef], + subGridToActorRefMap: Map[Int, ActorRef[GridAgentMessage]], subGridGates: Set[SubGridGate], currentSubGrid: Int - ): Map[SubGridGate, ActorRef] = + ): Map[SubGridGate, ActorRef[GridAgentMessage]] = subGridGates .groupBy(gate => (gate.superiorNode, gate.inferiorNode)) .flatMap(_._2.headOption) @@ -140,10 +141,10 @@ trait SetupHelper extends LazyLogging { * The actor reference of the sub grid to look for */ def getActorRef( - subGridToActorRefMap: Map[Int, ActorRef], + subGridToActorRefMap: Map[Int, ActorRef[GridAgentMessage]], currentSubGrid: Int, queriedSubGrid: Int - ): ActorRef = { + ): ActorRef[GridAgentMessage] = { subGridToActorRefMap.get(queriedSubGrid) match { case Some(hit) => hit case _ => diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index caad2d1b7b..597c8e9127 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -6,12 +6,19 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} +import org.apache.pekko.actor.{ + ActorSystem, + ActorContext => classicContext, + ActorRef => classicRef +} import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.scheduler.TimeAdvancer +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext /** Trait that can be used to setup a customized simona simulation by providing * implementations for all setup information required by a @@ -43,8 +50,8 @@ trait SimonaSetup { * An actor reference to the runtime event listener */ def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] + context: classicContext + ): ActorRef[RuntimeEvent] /** Creates a sequence of system participant event listeners * @@ -54,8 +61,8 @@ trait SimonaSetup { * A sequence of actor references to runtime event listeners */ def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] + context: classicContext + ): Seq[classicRef] /** Creates a primary service proxy. The proxy is the first instance to ask * for primary data. If necessary, it delegates the registration request to @@ -69,9 +76,9 @@ trait SimonaSetup { * An actor reference to the service */ def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef - ): ActorRef + context: classicContext, + scheduler: classicRef + ): classicRef /** Creates a weather service * @@ -84,9 +91,9 @@ trait SimonaSetup { * the service */ def weatherService( - context: ActorContext, - scheduler: ActorRef - ): ActorRef + context: classicContext, + scheduler: classicRef + ): classicRef /** Loads external simulations and provides corresponding actors and init data * @@ -98,8 +105,8 @@ trait SimonaSetup { * External simulations and their init data */ def extSimulations( - context: ActorContext, - scheduler: ActorRef + context: classicContext, + scheduler: classicRef ): ExtSimSetupData /** Creates the time advancer @@ -114,10 +121,10 @@ trait SimonaSetup { * An actor reference to the time advancer */ def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + context: classicContext, + simulation: classicRef, + runtimeEventListener: ActorRef[RuntimeEvent] + ): ActorRef[TimeAdvancer.Incoming] /** Creates a scheduler service * @@ -129,9 +136,9 @@ trait SimonaSetup { * An actor reference to the scheduler */ def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] - ): ActorRef + context: classicContext, + timeAdvancer: ActorRef[TimeAdvancer.Incoming] + ): classicRef /** Creates all the needed grid agents * @@ -146,10 +153,10 @@ trait SimonaSetup { * be used when setting up the agents */ def gridAgents( - context: ActorContext, + context: classicContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] - ): Iterable[ActorRef] + systemParticipantListener: Seq[classicRef] + ): Iterable[ActorRef[GridAgentMessage]] /** SIMONA links sub grids connected by a three winding transformer a bit * different. Therefore, the internal node has to be set as superior node. diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index 246fda0101..829c015f63 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -6,12 +6,6 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorContextOps, - ClassicActorRefOps, - TypedActorRefOps -} -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import com.typesafe.config.Config import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridTopologyGraph @@ -19,7 +13,8 @@ import edu.ie3.datamodel.models.input.container.{GridContainer, ThermalGrid} import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.simona.actor.SimonaActorNaming._ import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgent +import edu.ie3.simona.agent.grid.GridAgentMessage.CreateGridAgent +import edu.ie3.simona.agent.grid.{GridAgent, GridAgentMessage} import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.api.data.ExtData import edu.ie3.simona.api.data.ev.{ExtEvData, ExtEvSimulation} @@ -42,6 +37,17 @@ import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.simona.util.TickUtil.RichZonedDateTime import edu.ie3.util.TimeUtil +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + ClassicActorContextOps, + ClassicActorRefOps, + TypedActorRefOps +} +import org.apache.pekko.actor.{ + ActorSystem, + ActorContext => classicContext, + ActorRef => classicRef +} import java.util.concurrent.LinkedBlockingQueue import scala.jdk.CollectionConverters._ @@ -61,10 +67,10 @@ class SimonaStandaloneSetup( ) extends SimonaSetup { override def gridAgents( - context: ActorContext, + context: classicContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] - ): Iterable[ActorRef] = { + systemParticipantListener: Seq[classicRef] + ): Iterable[ActorRef[GridAgentMessage]] = { /* get the grid */ val subGridTopologyGraph = GridProvider @@ -129,16 +135,16 @@ class SimonaStandaloneSetup( thermalGrids ) - currentActorRef ! GridAgent.Create(gridAgentInitData, key) + currentActorRef ! CreateGridAgent(gridAgentInitData, key) currentActorRef } } override def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef - ): ActorRef = { + context: classicContext, + scheduler: classicRef + ): classicRef = { val simulationStart = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) @@ -158,9 +164,9 @@ class SimonaStandaloneSetup( } override def weatherService( - context: ActorContext, - scheduler: ActorRef - ): ActorRef = { + context: classicContext, + scheduler: classicRef + ): classicRef = { val weatherService = context.simonaActorOf( WeatherService.props( scheduler, @@ -181,8 +187,8 @@ class SimonaStandaloneSetup( } override def extSimulations( - context: ActorContext, - scheduler: ActorRef + context: classicContext, + scheduler: classicRef ): ExtSimSetupData = { val jars = ExtSimLoader.scanInputFolder() @@ -206,7 +212,7 @@ class SimonaStandaloneSetup( // setup data services that belong to this external simulation val (extData, extDataInit): ( Iterable[ExtData], - Iterable[(Class[_ <: SimonaService[_]], ActorRef)] + Iterable[(Class[_ <: SimonaService[_]], classicRef)] ) = extLink.getExtDataSimulations.asScala.zipWithIndex.map { case (_: ExtEvSimulation, dIndex) => @@ -244,10 +250,10 @@ class SimonaStandaloneSetup( } override def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = { + context: classicContext, + simulation: classicRef, + runtimeEventListener: ActorRef[RuntimeEvent] + ): ActorRef[TimeAdvancer.Incoming] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) @@ -267,9 +273,9 @@ class SimonaStandaloneSetup( } override def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] - ): ActorRef = + context: classicContext, + timeAdvancer: ActorRef[TimeAdvancer.Incoming] + ): classicRef = context .spawn( Scheduler( @@ -280,8 +286,8 @@ class SimonaStandaloneSetup( .toClassic override def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = + context: classicContext + ): ActorRef[RuntimeEvent] = context .spawn( RuntimeEventListener( @@ -293,8 +299,8 @@ class SimonaStandaloneSetup( ) override def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] = { + context: classicContext + ): Seq[classicRef] = { // append ResultEventListener as well to write raw output files ArgsParser .parseListenerConfigOption(simonaConfig.simona.event.listener) @@ -317,17 +323,17 @@ class SimonaStandaloneSetup( def buildSubGridToActorRefMap( subGridTopologyGraph: SubGridTopologyGraph, - context: ActorContext, + context: classicContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] - ): Map[Int, ActorRef] = { + systemParticipantListener: Seq[classicRef] + ): Map[Int, ActorRef[GridAgentMessage]] = { subGridTopologyGraph .vertexSet() .asScala .map(subGridContainer => { val gridAgentRef = - context.simonaActorOf( - GridAgent.props( + context.spawn( + GridAgent( environmentRefs, simonaConfig, systemParticipantListener diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index 5beb87d7b0..9dcb20b9e9 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -6,18 +6,13 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.testkit.TestProbe -import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid +import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem -import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ @@ -26,15 +21,17 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid -import edu.ie3.simona.test.common.{ - ConfigTestData, - TestKitWithShutdown, - TestSpawnerClassic -} +import edu.ie3.simona.test.common.{ConfigTestData, TestSpawnerTyped} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import squants.electro.Kilovolts import squants.energy.Megawatts @@ -49,22 +46,14 @@ import scala.language.postfixOps * interaction or cover this behaviour by another (integration) test! */ class DBFSAlgorithmCenGridSpec - extends TestKitWithShutdown( - ActorSystem( - "DBFSAlgorithmCenGridSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) + extends ScalaTestWithActorTestKit with DBFSMockGridAgents with ConfigTestData with DbfsTestGrid - with TestSpawnerClassic { + with TestSpawnerTyped { - private val scheduler = TestProbe("scheduler") + private val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") private val runtimeEvents = TestProbe("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -86,23 +75,24 @@ class DBFSAlgorithmCenGridSpec ) private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, - runtimeEventListener = runtimeEvents.ref, - primaryServiceProxy = primaryService.ref, - weather = weatherService.ref, + scheduler = scheduler.ref.toClassic, + runtimeEventListener = runtimeEvents.ref.toClassic, + primaryServiceProxy = primaryService.ref.toClassic, + weather = weatherService.ref.toClassic, evDataService = None ) - val resultListener: TestProbe = TestProbe("resultListener") + val resultListener: TestProbe[ResultMessage] = + TestProbe[ResultMessage]("resultListener") "A GridAgent actor in center position with async test" should { val centerGridAgent = - system.actorOf( - GridAgent.props( + testKit.spawn( + GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref.toClassic) ) ) @@ -130,40 +120,29 @@ class DBFSAlgorithmCenGridSpec ) val key = - ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) - scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled + ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) + scheduler + .expectMessageType[ScheduleActivation] // lock activation scheduled - centerGridAgent ! GridAgent.Create( + centerGridAgent ! CreateGridAgent( gridAgentInitData, key ) - scheduler.expectMsg( - ScheduleActivation(centerGridAgent.toTyped, INIT_SIM_TICK, Some(key)) - ) - scheduler.send(centerGridAgent, Activation(INIT_SIM_TICK)) - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(3600) - ) - ) + val msg = scheduler.expectMessageType[ScheduleActivation] + msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) + centerGridAgent ! ActivationAdapter(Activation(INIT_SIM_TICK)) + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) } - s"go to $SimulateGrid when it receives an activity start trigger" in { + s"go to SimulateGrid when it receives an activity start trigger" in { - scheduler.send( - centerGridAgent, - Activation(3600) - ) + centerGridAgent ! ActivationAdapter(Activation(3600)) - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(3600) - ) - ) + val msg = scheduler.expectMessageType[Completion] + msg shouldBe Completion(msg.actor, Some(3600)) } s"start the simulation when activation is sent" in { @@ -171,7 +150,7 @@ class DBFSAlgorithmCenGridSpec val firstSweepNo = 0 // send the start grid simulation trigger - scheduler.send(centerGridAgent, Activation(3600)) + centerGridAgent ! ActivationAdapter(Activation(3600)) /* We expect one grid power request message per inferior grid */ @@ -188,7 +167,6 @@ class DBFSAlgorithmCenGridSpec // normally the inferior grid agents ask for the slack voltage as well to do their power flow calculations // we simulate this behaviour now by doing the same for our three inferior grid agents - inferiorGrid11.requestSlackVoltage(centerGridAgent, firstSweepNo) inferiorGrid12.requestSlackVoltage(centerGridAgent, firstSweepNo) @@ -239,8 +217,7 @@ class DBFSAlgorithmCenGridSpec // we now answer the request of our centerGridAgent // with three fake grid power messages and one fake slack voltage message - inferiorGrid11.gaProbe.send( - firstPowerRequestSender11, + firstPowerRequestSender11 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid11.nodeUuids.map(nodeUuid => ExchangePower( @@ -252,8 +229,7 @@ class DBFSAlgorithmCenGridSpec ) ) - inferiorGrid12.gaProbe.send( - firstPowerRequestSender12, + firstPowerRequestSender12 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid12.nodeUuids.map(nodeUuid => ExchangePower( @@ -265,8 +241,7 @@ class DBFSAlgorithmCenGridSpec ) ) - inferiorGrid13.gaProbe.send( - firstPowerRequestSender13, + firstPowerRequestSender13 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid13.nodeUuids.map(nodeUuid => ExchangePower( @@ -278,8 +253,7 @@ class DBFSAlgorithmCenGridSpec ) ) - superiorGridAgent.gaProbe.send( - firstSlackVoltageRequestSender, + firstSlackVoltageRequestSender ! VMAdapter( ProvideSlackVoltageMessage( firstSweepNo, Seq( @@ -327,8 +301,7 @@ class DBFSAlgorithmCenGridSpec superiorGridAgent.expectSlackVoltageRequest(secondSweepNo) // the superior grid would answer with updated slack voltage values - superiorGridAgent.gaProbe.send( - secondSlackAskSender, + secondSlackAskSender ! VMAdapter( ProvideSlackVoltageMessage( secondSweepNo, Seq( @@ -411,8 +384,8 @@ class DBFSAlgorithmCenGridSpec // we now answer the requests of our centerGridAgent // with three fake grid power message - inferiorGrid11.gaProbe.send( - secondPowerRequestSender11, + + secondPowerRequestSender11 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid11.nodeUuids.map(nodeUuid => ExchangePower( @@ -424,8 +397,7 @@ class DBFSAlgorithmCenGridSpec ) ) - inferiorGrid12.gaProbe.send( - secondPowerRequestSender12, + secondPowerRequestSender12 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid12.nodeUuids.map(nodeUuid => ExchangePower( @@ -437,8 +409,7 @@ class DBFSAlgorithmCenGridSpec ) ) - inferiorGrid13.gaProbe.send( - secondPowerRequestSender13, + secondPowerRequestSender13 ! PMAdapter( ProvideGridPowerMessage( inferiorGrid13.nodeUuids.map(nodeUuid => ExchangePower( @@ -468,27 +439,23 @@ class DBFSAlgorithmCenGridSpec // normally the slack node would send a FinishGridSimulationTrigger to all // connected inferior grids, because the slack node is just a mock, we imitate this behavior - superiorGridAgent.gaProbe.send( - centerGridAgent, - FinishGridSimulationTrigger(3600) - ) + centerGridAgent ! FinishGridSimulationTrigger(3600) // after a FinishGridSimulationTrigger is send the inferior grids, they themselves will send the // Trigger forward the trigger to their connected inferior grids. Therefore the inferior grid // agent should receive a FinishGridSimulationTrigger - inferiorGrid11.gaProbe.expectMsg(FinishGridSimulationTrigger(3600)) - inferiorGrid12.gaProbe.expectMsg(FinishGridSimulationTrigger(3600)) - inferiorGrid13.gaProbe.expectMsg(FinishGridSimulationTrigger(3600)) + inferiorGrid11.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) + + inferiorGrid12.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) + + inferiorGrid13.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(7200) - ) - ) + val cm = scheduler.expectMessageType[Completion] + cm shouldBe Completion(cm.actor, Some(7200)) - resultListener.expectMsgPF() { + val resultMessage = resultListener.expectMessageType[ResultMessage] + resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => // we expect results for 4 nodes, 5 lines and 2 transformer2ws powerFlowResultEvent.nodeResults.size shouldBe 4 diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index 85b4bb041a..5c63c8a0e8 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -6,17 +6,12 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorSystem -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.testkit.{ImplicitSender, TestProbe} -import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid +import edu.ie3.simona.agent.grid.GridAgentMessage._ +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem -import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ FailedPowerFlow, @@ -28,15 +23,17 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid -import edu.ie3.simona.test.common.{ - ConfigTestData, - TestKitWithShutdown, - TestSpawnerClassic -} +import edu.ie3.simona.test.common.{ConfigTestData, TestSpawnerTyped} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import squants.electro.Kilovolts import squants.energy.Megawatts @@ -44,23 +41,14 @@ import scala.concurrent.duration.DurationInt import scala.language.postfixOps class DBFSAlgorithmFailedPowerFlowSpec - extends TestKitWithShutdown( - ActorSystem( - "DBFSAlgorithmSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) + extends ScalaTestWithActorTestKit with DBFSMockGridAgents with ConfigTestData - with ImplicitSender with DbfsTestGrid - with TestSpawnerClassic { + with TestSpawnerTyped { - private val scheduler = TestProbe("scheduler") + private val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") private val runtimeEvents = TestProbe("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -74,23 +62,24 @@ class DBFSAlgorithmFailedPowerFlowSpec InferiorGA(TestProbe("inferiorGridAgent"), Seq(node1.getUuid)) private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, - runtimeEventListener = runtimeEvents.ref, - primaryServiceProxy = primaryService.ref, - weather = weatherService.ref, + scheduler = scheduler.ref.toClassic, + runtimeEventListener = runtimeEvents.ref.toClassic, + primaryServiceProxy = primaryService.ref.toClassic, + weather = weatherService.ref.toClassic, evDataService = None ) - val resultListener: TestProbe = TestProbe("resultListener") + val resultListener: TestProbe[ResultMessage] = + TestProbe[ResultMessage]("resultListener") "A GridAgent actor in center position with async test" should { val centerGridAgent = - system.actorOf( - GridAgent.props( + testKit.spawn( + GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref.toClassic) ) ) @@ -115,49 +104,40 @@ class DBFSAlgorithmFailedPowerFlowSpec ) val key = - ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) - scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled + ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) + scheduler.expectMessageType[SchedulerMessage] // lock activation scheduled - centerGridAgent ! GridAgent.Create( + centerGridAgent ! CreateGridAgent( gridAgentInitData, key ) - scheduler.expectMsg( - ScheduleActivation(centerGridAgent.toTyped, INIT_SIM_TICK, Some(key)) - ) - scheduler.send(centerGridAgent, Activation(INIT_SIM_TICK)) - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(3600) - ) + val message = scheduler.expectMessageType[ScheduleActivation] + message shouldBe ScheduleActivation( + message.actor, + INIT_SIM_TICK, + Some(key) ) + centerGridAgent ! ActivationAdapter(Activation(INIT_SIM_TICK)) + scheduler.expectMessage(Completion(message.actor, Some(3600))) } - s"go to $SimulateGrid when it receives an activation" in { + s"go to SimulateGrid when it receives an activation" in { // send init data to agent - scheduler.send( - centerGridAgent, - Activation(3600) - ) + centerGridAgent ! ActivationAdapter(Activation(3600)) // we expect a completion message - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(3600) - ) - ) + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(3600)) } s"start the simulation when an activation is sent is sent, handle failed power flow if it occurs" in { val sweepNo = 0 // send the start grid simulation trigger - scheduler.send(centerGridAgent, Activation(3600)) + centerGridAgent ! ActivationAdapter(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo val powerRequestSender = inferiorGridAgent.expectGridPowerRequest() @@ -186,8 +166,7 @@ class DBFSAlgorithmFailedPowerFlowSpec // we now answer the request of our centerGridAgent // with a fake grid power message and one fake slack voltage message - inferiorGridAgent.gaProbe.send( - powerRequestSender, + powerRequestSender ! PMAdapter( ProvideGridPowerMessage( inferiorGridAgent.nodeUuids.map(nodeUuid => ExchangePower( @@ -199,8 +178,7 @@ class DBFSAlgorithmFailedPowerFlowSpec ) ) - superiorGridAgent.gaProbe.send( - slackVoltageRequestSender, + slackVoltageRequestSender ! VMAdapter( ProvideSlackVoltageMessage( sweepNo, Seq( @@ -221,27 +199,23 @@ class DBFSAlgorithmFailedPowerFlowSpec // the requested power is to high for the grid to handle, therefore the superior grid agent // receives a FailedPowerFlow message // wait 30 seconds max for power flow to finish - superiorGridAgent.gaProbe.expectMsg(30 seconds, FailedPowerFlow) + superiorGridAgent.gaProbe.expectMessage( + 30 seconds, + PMAdapter(FailedPowerFlow) + ) // normally the slack node would send a FinishGridSimulationTrigger to all // connected inferior grids, because the slack node is just a mock, we imitate this behavior - superiorGridAgent.gaProbe.send( - centerGridAgent, - FinishGridSimulationTrigger(3600) - ) + centerGridAgent ! FinishGridSimulationTrigger(3600) // after a FinishGridSimulationTrigger is send to the inferior grids, they themselves will // forward the trigger to their connected inferior grids. Therefore the inferior grid agent // should receive a FinishGridSimulationTrigger - inferiorGridAgent.gaProbe.expectMsg(FinishGridSimulationTrigger(3600)) + inferiorGridAgent.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - scheduler.expectMsg( - Completion( - centerGridAgent.toTyped, - Some(7200) - ) - ) + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(7200)) resultListener.expectNoMessage() diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index f104f20bbf..3f1c8bc02d 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -6,20 +6,17 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorRefOps, - TypedActorRefOps -} -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.testkit.{ImplicitSender, TestProbe} -import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid +import edu.ie3.simona.agent.grid.GridAgentMessage.{ + ActivationAdapter, + VMAdapter, + CreateGridAgent, + FinishGridSimulationTrigger +} +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem -import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, @@ -27,53 +24,50 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.ontology.messages.services.ServiceMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationFailedMessage +import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGridWithParticipants -import edu.ie3.simona.test.common.{ - ConfigTestData, - TestKitWithShutdown, - TestSpawnerClassic -} +import edu.ie3.simona.test.common.{ConfigTestData, TestSpawnerTyped} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import squants.electro.Kilovolts import squants.energy.Megawatts import scala.language.postfixOps class DBFSAlgorithmParticipantSpec - extends TestKitWithShutdown( - ActorSystem( - "DBFSAlgorithmSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) + extends ScalaTestWithActorTestKit with DBFSMockGridAgents with ConfigTestData - with ImplicitSender with DbfsTestGridWithParticipants - with TestSpawnerClassic { + with TestSpawnerTyped { - private val scheduler = TestProbe("scheduler") + private val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") private val runtimeEvents = TestProbe("runtimeEvents") - private val primaryService = TestProbe("primaryService") + private val primaryService: TestProbe[ServiceMessage] = + TestProbe[ServiceMessage]("primaryService") private val weatherService = TestProbe("weatherService") private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, - runtimeEventListener = runtimeEvents.ref, - primaryServiceProxy = primaryService.ref, - weather = weatherService.ref, + scheduler = scheduler.ref.toClassic, + runtimeEventListener = runtimeEvents.ref.toClassic, + primaryServiceProxy = primaryService.ref.toClassic, + weather = weatherService.ref.toClassic, evDataService = None ) - protected val resultListener: TestProbe = TestProbe("resultListener") + protected val resultListener: TestProbe[ResultMessage] = + TestProbe[ResultMessage]("resultListener") private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), @@ -81,18 +75,18 @@ class DBFSAlgorithmParticipantSpec ) "Test participant" should { - val gridAgentWithParticipants = system.actorOf( - GridAgent.props( + val gridAgentWithParticipants = testKit.spawn( + GridAgent( environmentRefs, simonaConfig, - Iterable(resultListener.ref) + Iterable(resultListener.ref.toClassic) ) ) s"initialize itself when it receives an init activation" in { // this subnet has 1 superior grid (ehv) and 3 inferior grids (mv). Map the gates to test probes accordingly - val subGridGateToActorRef: Map[SubGridGate, ActorRef] = + val subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]] = hvSubGridGates.map { gate => gate -> superiorGridAgent.ref }.toMap @@ -105,74 +99,58 @@ class DBFSAlgorithmParticipantSpec ) val key = - ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) - scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled - - gridAgentWithParticipants ! GridAgent.Create(gridAgentInitData, key) - scheduler.expectMsg( - ScheduleActivation( - gridAgentWithParticipants.toTyped, - INIT_SIM_TICK, - Some(key) - ) - ) + ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) + scheduler + .expectMessageType[ScheduleActivation] // lock activation scheduled + + gridAgentWithParticipants ! CreateGridAgent(gridAgentInitData, key) + + val msg = scheduler.expectMessageType[ScheduleActivation] + msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) // send init data to agent and expect a CompletionMessage - scheduler.send(gridAgentWithParticipants, Activation(INIT_SIM_TICK)) - - val loadAgent = - scheduler.expectMsgPF() { - case ScheduleActivation( - loadAgent, - INIT_SIM_TICK, - _ - ) => - loadAgent - } - - scheduler.expectMsg( - Completion( - gridAgentWithParticipants.toTyped, - Some(3600) - ) - ) + gridAgentWithParticipants ! ActivationAdapter(Activation(INIT_SIM_TICK)) + + val message = scheduler.expectMessageType[ScheduleActivation] - scheduler.send(loadAgent.toClassic, Activation(INIT_SIM_TICK)) + val loadAgent: ActorRef[Activation] = message match { + case ScheduleActivation( + loadAgent, + INIT_SIM_TICK, + _ + ) => + loadAgent + } - primaryService.expectMsg( + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) + + loadAgent ! Activation(INIT_SIM_TICK) + + primaryService.expectMessage( PrimaryServiceRegistrationMessage(load1.getUuid) ) - primaryService.send(loadAgent.toClassic, RegistrationFailedMessage) + loadAgent.toClassic ! RegistrationFailedMessage - scheduler.expectMsg(Completion(loadAgent, Some(0))) + scheduler.expectMessage(Completion(loadAgent, Some(0))) // triggering the loadAgent's calculation - scheduler.send( - loadAgent.toClassic, - Activation(0) - ) + loadAgent ! Activation(0) + // the load agent should send a CompletionMessage - scheduler.expectMsg(Completion(loadAgent, None)) + scheduler.expectMessage(Completion(loadAgent, None)) } - s"go to $SimulateGrid when it receives an activity start trigger" in { + s"go to SimulateGrid when it receives an activity start trigger" in { // send init data to agent - scheduler.send( - gridAgentWithParticipants, - Activation(3600) - ) + gridAgentWithParticipants ! ActivationAdapter(Activation(3600)) // we expect a completion message - scheduler.expectMsg( - Completion( - gridAgentWithParticipants.toTyped, - Some(3600) - ) - ) - + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(3600)) } s"check the request asset power message indirectly" in { @@ -181,7 +159,7 @@ class DBFSAlgorithmParticipantSpec // send the start grid simulation trigger // the gird agent should send a RequestAssetPowerMessage to the load agent - scheduler.send(gridAgentWithParticipants, Activation(3600)) + gridAgentWithParticipants ! ActivationAdapter(Activation(3600)) // we expect a request for voltage values of our slack node // (voltages are requested by our agent under test from the superior grid) @@ -190,8 +168,7 @@ class DBFSAlgorithmParticipantSpec // we now answer the request of our gridAgentsWithParticipants // with a fake slack voltage message - superiorGridAgent.gaProbe.send( - firstSlackVoltageRequestSender, + firstSlackVoltageRequestSender ! VMAdapter( ProvideSlackVoltageMessage( firstSweepNo, Seq( @@ -238,8 +215,7 @@ class DBFSAlgorithmParticipantSpec superiorGridAgent.expectSlackVoltageRequest(secondSweepNo) // the superior grid would answer with updated slack voltage values - superiorGridAgent.gaProbe.send( - secondSlackAskSender, + secondSlackAskSender ! VMAdapter( ProvideSlackVoltageMessage( secondSweepNo, Seq( @@ -266,17 +242,10 @@ class DBFSAlgorithmParticipantSpec // normally the superior grid agent would send a FinishGridSimulationTrigger to the inferior grid agent after the convergence // (here we do it by hand) - superiorGridAgent.gaProbe.send( - gridAgentWithParticipants, - FinishGridSimulationTrigger(3600L) - ) + gridAgentWithParticipants ! FinishGridSimulationTrigger(3600L) - scheduler.expectMsg( - Completion( - gridAgentWithParticipants.toTyped, - Some(7200) - ) - ) + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(7200)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index ca8687a44b..30f031e6f5 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -6,19 +6,19 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.testkit.{ImplicitSender, TestProbe} -import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.agent.state.GridAgentState.SimulateGrid +import edu.ie3.simona.agent.grid.GridAgentMessage.{ + ActivationAdapter, + CreateGridAgent, + FinishGridSimulationTrigger, + PMAdapter +} import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem -import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, @@ -28,16 +28,19 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation } +import edu.ie3.simona.ontology.messages.services.ServiceMessage +import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid -import edu.ie3.simona.test.common.{ - ConfigTestData, - TestKitWithShutdown, - TestSpawnerClassic, - UnitSpec -} +import edu.ie3.simona.test.common.{ConfigTestData, TestSpawnerTyped, UnitSpec} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import squants.energy.Megawatts import java.util.UUID @@ -50,49 +53,43 @@ import scala.language.postfixOps * [[GridAgent]] are simulated by the TestKit. */ class DBFSAlgorithmSupGridSpec - extends TestKitWithShutdown( - ActorSystem( - "DBFSAlgorithmSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) + extends ScalaTestWithActorTestKit with UnitSpec with ConfigTestData - with ImplicitSender with DbfsTestGrid - with TestSpawnerClassic { + with TestSpawnerTyped { - private val scheduler: TestProbe = TestProbe("scheduler") + private val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") private val runtimeEvents = TestProbe("runtimeEvents") - private val primaryService: TestProbe = TestProbe("primaryService") - private val weatherService: TestProbe = TestProbe("weatherService") - private val hvGrid: TestProbe = TestProbe("hvGrid") + private val primaryService: TestProbe[ServiceMessage] = + TestProbe[ServiceMessage]("primaryService") + private val weatherService = TestProbe("weatherService") + private val hvGrid: TestProbe[GridAgentMessage] = + TestProbe[GridAgentMessage]("hvGrid") private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, - runtimeEventListener = runtimeEvents.ref, - primaryServiceProxy = primaryService.ref, - weather = weatherService.ref, + scheduler = scheduler.ref.toClassic, + runtimeEventListener = runtimeEvents.ref.toClassic, + primaryServiceProxy = primaryService.ref.toClassic, + weather = weatherService.ref.toClassic, evDataService = None ) - val resultListener: TestProbe = TestProbe("resultListener") + val resultListener: TestProbe[ResultMessage] = + TestProbe[ResultMessage]("resultListener") "A GridAgent actor in superior position with async test" should { - val superiorGridAgentFSM: ActorRef = system.actorOf( - GridAgent.props( + val superiorGridAgentFSM: ActorRef[GridAgentMessage] = testKit.spawn( + GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref.toClassic) ) ) s"initialize itself when it receives an init activation" in { - val subnetGatesToActorRef: Map[SubGridGate, ActorRef] = + val subnetGatesToActorRef: Map[SubGridGate, ActorRef[GridAgentMessage]] = ehvSubGridGates.map(gate => gate -> hvGrid.ref).toMap val gridAgentInitData = @@ -104,30 +101,28 @@ class DBFSAlgorithmSupGridSpec ) val key = - ScheduleLock.singleKey(TSpawner, scheduler.ref.toTyped, INIT_SIM_TICK) - scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled - - superiorGridAgentFSM ! GridAgent.Create(gridAgentInitData, key) - scheduler.expectMsg( - ScheduleActivation( - superiorGridAgentFSM.toTyped, - INIT_SIM_TICK, - Some(key) - ) - ) + ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) + scheduler + .expectMessageType[ScheduleActivation] // lock activation scheduled + + superiorGridAgentFSM ! CreateGridAgent(gridAgentInitData, key) - scheduler.send(superiorGridAgentFSM, Activation(INIT_SIM_TICK)) - scheduler.expectMsg(Completion(superiorGridAgentFSM.toTyped, Some(3600))) + val am = scheduler.expectMessageType[ScheduleActivation] + am shouldBe ScheduleActivation(am.actor, INIT_SIM_TICK, Some(key)) + superiorGridAgentFSM ! ActivationAdapter(Activation(INIT_SIM_TICK)) + + val cm = scheduler.expectMessageType[Completion] + cm shouldBe Completion(cm.actor, Some(3600)) } - s"go to $SimulateGrid when it receives an activity start trigger" in { + s"go to SimulateGrid when it receives an activity start trigger" in { // send init data to agent - scheduler.send(superiorGridAgentFSM, Activation(3600)) + superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) // we expect a completion message - scheduler.expectMsg(Completion(superiorGridAgentFSM.toTyped, Some(3600))) - + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(3600)) } s"start the simulation, do 2 sweeps and should end afterwards when no deviation on nodal " + @@ -139,25 +134,27 @@ class DBFSAlgorithmSupGridSpec Vector(UUID.fromString("9fe5fa33-6d3b-4153-a829-a16f4347bc4e")) // send the start grid simulation trigger - scheduler.send(superiorGridAgentFSM, Activation(3600)) + superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo - hvGrid.expectMsgPF() { - case requestGridPowerMessage: RequestGridPowerMessage => + val message = hvGrid.expectMessageType[PMAdapter] + + val lastSender = message match { + case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => requestGridPowerMessage.currentSweepNo shouldBe sweepNo requestGridPowerMessage.nodeUuids should contain allElementsOf requestedConnectionNodeUuids + + requestGridPowerMessage.sender case x => fail( s"Invalid message received when expecting a request for grid power values! Message was $x" ) - } // we return with a fake grid power message // / as we are using the ask pattern, we cannot send it to the grid agent directly but have to send it to the // / ask sender - hvGrid.send( - hvGrid.lastSender, + lastSender ! PMAdapter( ProvideGridPowerMessage( requestedConnectionNodeUuids.map { uuid => ExchangePower( @@ -172,12 +169,18 @@ class DBFSAlgorithmSupGridSpec // we expect a completion message here and that the agent goes back to simulate grid // and waits until the newly scheduled StartGridSimulationTrigger is send // wait 30 seconds max for power flow to finish - scheduler.expectMsgPF(30 seconds) { + val completionMessage = + scheduler.expectMessageType[Completion](130 seconds) + + completionMessage match { case Completion(_, Some(3600)) => // we expect another completion message when the agent is in SimulateGrid again case Completion(_, Some(7200)) => // agent should be in Idle again and listener should contain power flow result data - resultListener.expectMsgPF() { + val resultMessage = + resultListener.expectMessageType[ResultMessage] + + resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => powerFlowResultEvent.nodeResults.headOption match { case Some(value) => @@ -196,7 +199,7 @@ class DBFSAlgorithmSupGridSpec // no failed power flow runtimeEvents.expectNoMessage() - hvGrid.expectMsg(FinishGridSimulationTrigger(3600)) + hvGrid.expectMessage(FinishGridSimulationTrigger(3600)) case x => fail( @@ -240,12 +243,11 @@ class DBFSAlgorithmSupGridSpec ) // bring agent in simulate grid state - scheduler.send(superiorGridAgentFSM, Activation(3600)) + superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) // we expect a completion message - scheduler.expectMsg( - Completion(superiorGridAgentFSM.toTyped, Some(3600)) - ) + val message = scheduler.expectMessageType[Completion] + message shouldBe Completion(message.actor, Some(3600)) // go on with testing the sweep behaviour for (sweepNo <- 0 to maxNumberOfTestSweeps) { @@ -254,13 +256,17 @@ class DBFSAlgorithmSupGridSpec Vector(UUID.fromString("9fe5fa33-6d3b-4153-a829-a16f4347bc4e")) // send the start grid simulation trigger - scheduler.send(superiorGridAgentFSM, Activation(3600)) + superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo - hvGrid.expectMsgPF() { - case requestGridPowerMessage: RequestGridPowerMessage => + val message = hvGrid.expectMessageType[GridAgentMessage] + + val lastSender = message match { + case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => requestGridPowerMessage.currentSweepNo shouldBe sweepNo requestGridPowerMessage.nodeUuids should contain allElementsOf requestedConnectionNodeUuids + + requestGridPowerMessage.sender case x => fail( s"Invalid message received when expecting a request for grid power values! Message was $x" @@ -270,8 +276,7 @@ class DBFSAlgorithmSupGridSpec // we return with a fake grid power message // / as we are using the ask pattern, we cannot send it to the grid agent directly but have to send it to the // / ask sender - hvGrid.send( - hvGrid.lastSender, + lastSender ! PMAdapter( ProvideGridPowerMessage( requestedConnectionNodeUuids.map { uuid => ExchangePower( @@ -288,13 +293,19 @@ class DBFSAlgorithmSupGridSpec // Simulate Grid // wait 30 seconds max for power flow to finish - scheduler.expectMsgPF(30 seconds) { + val completionMessage = + scheduler.expectMessageType[Completion](30 seconds) + + completionMessage match { case Completion(_, Some(3600)) => // when we received a FinishGridSimulationTrigger (as inferior grid agent) // we expect another completion message then as well (scheduler view) case Completion(_, Some(7200)) => // after doing cleanup stuff, our agent should go back to idle again and listener should contain power flow result data - resultListener.expectMsgPF() { + val resultMessage = + resultListener.expectMessageType[ResultMessage] + + resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => powerFlowResultEvent.nodeResults.headOption match { case Some(value) => @@ -313,7 +324,7 @@ class DBFSAlgorithmSupGridSpec // no failed power flow runtimeEvents.expectNoMessage() - hvGrid.expectMsg(FinishGridSimulationTrigger(3600)) + hvGrid.expectMessage(FinishGridSimulationTrigger(3600)) case x => fail( diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index 0f19e2055d..61ecde6092 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -6,8 +6,8 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorRef -import org.apache.pekko.testkit.TestProbe +import edu.ie3.simona.agent.grid.GridAgentMessage.{PMAdapter, VMAdapter} +import org.apache.pekko.actor.typed.ActorRef import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, @@ -20,6 +20,7 @@ import edu.ie3.simona.ontology.messages.VoltageMessage.{ } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} +import org.apache.pekko.actor.testkit.typed.scaladsl.TestProbe import squants.Power import squants.electro.Volts import squants.energy.Megawatts @@ -40,36 +41,41 @@ trait DBFSMockGridAgents extends UnitSpec { : squants.electro.ElectricPotential = Volts(1e-6) sealed trait GAActorAndModel { - val gaProbe: TestProbe + val gaProbe: TestProbe[GridAgentMessage] val nodeUuids: Seq[UUID] - def ref: ActorRef = gaProbe.ref + def ref: ActorRef[GridAgentMessage] = gaProbe.ref } final case class InferiorGA( - override val gaProbe: TestProbe, + override val gaProbe: TestProbe[GridAgentMessage], override val nodeUuids: Seq[UUID] ) extends GAActorAndModel { - def expectGridPowerRequest(): ActorRef = { - gaProbe - .expectMsgType[RequestGridPowerMessage] - .nodeUuids should contain allElementsOf nodeUuids + def expectGridPowerRequest(): ActorRef[GridAgentMessage] = { + val message = gaProbe.expectMessageType[GridAgentMessage] - gaProbe.lastSender + message match { + case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => + requestGridPowerMessage.nodeUuids should contain allElementsOf nodeUuids + + requestGridPowerMessage.sender + } } def expectSlackVoltageProvision( expectedSweepNo: Int, expectedExchangedVoltages: Seq[ExchangeVoltage] ): Unit = { - inside(gaProbe.expectMsgType[ProvideSlackVoltageMessage]) { - case ProvideSlackVoltageMessage(sweepNo, exchangedVoltages) => - sweepNo shouldBe expectedSweepNo + val message = gaProbe.expectMessageType[GridAgentMessage] + + message match { + case VMAdapter(msg: ProvideSlackVoltageMessage) => + msg.currentSweepNo shouldBe expectedSweepNo - exchangedVoltages.size shouldBe expectedExchangedVoltages.size + msg.nodalSlackVoltages.size shouldBe expectedExchangedVoltages.size expectedExchangedVoltages.foreach { expectedVoltage => - exchangedVoltages.find( + msg.nodalSlackVoltages.find( _.nodeUuid == expectedVoltage.nodeUuid ) match { case Some(ExchangeVoltage(_, actualE, actualF)) => @@ -85,42 +91,51 @@ trait DBFSMockGridAgents extends UnitSpec { } } - def requestSlackVoltage(receiver: ActorRef, sweepNo: Int): Unit = - gaProbe.send( - receiver, - RequestSlackVoltageMessage(sweepNo, nodeUuids) + def requestSlackVoltage( + receiver: ActorRef[GridAgentMessage], + sweepNo: Int + ): Unit = + receiver ! VMAdapter( + RequestSlackVoltageMessage(sweepNo, nodeUuids, gaProbe.ref) ) } final case class SuperiorGA( - override val gaProbe: TestProbe, + override val gaProbe: TestProbe[GridAgentMessage], override val nodeUuids: Seq[UUID] ) extends GAActorAndModel { - def expectSlackVoltageRequest(expectedSweepNo: Int): ActorRef = { - inside( - gaProbe - .expectMsgType[RequestSlackVoltageMessage] - ) { - case RequestSlackVoltageMessage(msgSweepNo: Int, msgUuids: Seq[UUID]) => - msgSweepNo shouldBe expectedSweepNo - msgUuids should have size nodeUuids.size - msgUuids should contain allElementsOf nodeUuids - } + def expectSlackVoltageRequest( + expectedSweepNo: Int + ): ActorRef[GridAgentMessage] = { + val message = gaProbe.expectMessageType[GridAgentMessage] + + message match { + case VMAdapter( + requestSlackVoltageMessage: RequestSlackVoltageMessage + ) => + requestSlackVoltageMessage.currentSweepNo shouldBe expectedSweepNo + requestSlackVoltageMessage.nodeUuids should have size nodeUuids.size + requestSlackVoltageMessage.nodeUuids should contain allElementsOf nodeUuids - gaProbe.lastSender + requestSlackVoltageMessage.sender + } } def expectGridPowerProvision( expectedExchangedPowers: Seq[ExchangePower], maxDuration: FiniteDuration = 30 seconds ): Unit = { - inside(gaProbe.expectMsgType[ProvideGridPowerMessage](maxDuration)) { - case ProvideGridPowerMessage(exchangedPower) => - exchangedPower should have size expectedExchangedPowers.size + val message = gaProbe.expectMessageType[GridAgentMessage](maxDuration) + + message match { + case PMAdapter(msg: ProvideGridPowerMessage) => + msg.nodalResidualPower should have size expectedExchangedPowers.size expectedExchangedPowers.foreach { expectedPower => - exchangedPower.find(_.nodeUuid == expectedPower.nodeUuid) match { + msg.nodalResidualPower.find( + _.nodeUuid == expectedPower.nodeUuid + ) match { case Some(ExchangePower(_, actualP, actualQ)) => (actualP ~= expectedPower.p) shouldBe true (actualQ ~= expectedPower.q) shouldBe true @@ -131,17 +146,15 @@ trait DBFSMockGridAgents extends UnitSpec { ) } } - } } - def requestGridPower(receiver: ActorRef, sweepNo: Int): Unit = { - gaProbe.send( - receiver, - RequestGridPowerMessage( - sweepNo, - nodeUuids - ) + def requestGridPower( + receiver: ActorRef[GridAgentMessage], + sweepNo: Int + ): Unit = { + receiver ! PMAdapter( + RequestGridPowerMessage(sweepNo, nodeUuids, gaProbe.ref) ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala index e58ad3c2fb..6c7e9ce9be 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala @@ -6,26 +6,32 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.{ - Actor, - ActorIdentity, - ActorRef, - ActorSystem, - Identify, - Props -} -import org.apache.pekko.testkit.ImplicitSender -import org.apache.pekko.util.Timeout -import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage.StringAdapter import edu.ie3.simona.io.result.ResultSinkType import edu.ie3.simona.sim.setup.SimonaStandaloneSetup +import edu.ie3.simona.test.common.ConfigTestData import edu.ie3.simona.test.common.input.TransformerInputTestData -import edu.ie3.simona.test.common.{ConfigTestData, TestKitWithShutdown} import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit +import org.apache.pekko.actor.typed.receptionist.Receptionist.{ + Listing, + Register, + Subscribe +} +import org.apache.pekko.actor.typed.receptionist.ServiceKey +import org.apache.pekko.actor.typed.scaladsl.AskPattern.Askable +import org.apache.pekko.actor.typed.scaladsl.Behaviors +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + TypedActorContextOps, + TypedActorRefOps +} +import org.apache.pekko.actor.typed.{ActorRef, Scheduler} +import org.apache.pekko.actor.{ActorRef => classicRef} +import org.apache.pekko.util.Timeout import org.scalatest.wordspec.AnyWordSpecLike import java.util.concurrent.TimeUnit @@ -33,17 +39,7 @@ import scala.concurrent.Await import scala.concurrent.duration.Duration class GridAgentSetup2WSpec - extends TestKitWithShutdown( - ActorSystem( - "GridAgentSetupSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) - with ImplicitSender + extends ScalaTestWithActorTestKit with AnyWordSpecLike with TransformerInputTestData with ConfigTestData @@ -52,18 +48,26 @@ class GridAgentSetup2WSpec "The setup of grid agents" must { "provide two grid agents on presence of a two winding transformer" in { - import org.apache.pekko.pattern._ implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) + implicit val scheduler: Scheduler = system.scheduler // in order to get an actor system we need a tmp actor that calls the corresponding method - Await.ready( - system.actorOf(Props(new Actor { - override def receive: Receive = { case "setup" => + val serviceKey = ServiceKey[GridAgentMessage]("gridAgent") + + val actor = testKit.spawn(Behaviors.setup[GridAgentMessage] { ctx => + ctx.system.receptionist ! Register(serviceKey, ctx.self) + + Behaviors.receive[GridAgentMessage] { + case (ctx, StringAdapter("ping", sender)) => + // replying to ping signal + sender ! StringAdapter("pong", ctx.self) + Behaviors.same + case (ctx, StringAdapter("setup", _)) => val environmentRefs = EnvironmentRefs( - scheduler = self, - runtimeEventListener = self, - primaryServiceProxy = self, - weather = ActorRef.noSender, + scheduler = ctx.self.toClassic, + runtimeEventListener = ctx.self.toClassic, + primaryServiceProxy = ctx.self.toClassic, + weather = classicRef.noSender, evDataService = None ) @@ -82,43 +86,45 @@ class GridAgentSetup2WSpec ) ).buildSubGridToActorRefMap( gridContainer.getSubGridTopologyGraph, - context, + ctx.toClassic, environmentRefs, - Seq.empty[ActorRef] + Seq.empty[classicRef] ) - sender() ! "done" - } - })) ? "setup", - Duration(1, TimeUnit.SECONDS) + ctx.self ! StringAdapter("done", ctx.self) + Behaviors.same + } + }) + + Await.ready( + actor.ask[GridAgentMessage](ref => StringAdapter("setup", ref)), + Duration(10, TimeUnit.SECONDS) ) - val sel = system.actorSelection("user/**/GridAgent_*") - sel ! Identify(0) + testKit.spawn(Behaviors.setup[Listing] { ctx => + logger.debug("Subscribing to the actors.") + ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) - logger.debug("Waiting 500 ms to collect all responses") - val responses: Seq[ActorIdentity] = - receiveWhile( - max = Duration.create(500, "ms"), - idle = Duration.create(250, "ms") - ) { case msg: ActorIdentity => - msg - } - logger.debug("All responses received. Evaluating...") + Behaviors.receiveMessagePartial[Listing] { + case serviceKey.Listing(listings) => + logger.debug("All responses received. Evaluating...") - responses.size should be(2) + listings.size should be(2) - val regex = """GridAgent_\d*""".r - val expectedSenders = Vector("GridAgent_1", "GridAgent_2") - val actualSenders = responses - .collect { case actorId: ActorIdentity => - val actorRefString = actorId.getActorRef.toString - regex.findFirstIn(actorRefString) - } - .flatten - .sorted - .toVector + val regex = """GridAgent_\d*""".r + val expectedSenders = Vector("GridAgent_1", "GridAgent_2") + val actualSenders = listings + .collect { case actorId: ActorRef[GridAgentMessage] => + val actorRefString = actorId.toString + regex.findFirstIn(actorRefString) + } + .flatten + .toVector - actualSenders should be(expectedSenders) + actualSenders should be(expectedSenders) + + Behaviors.same + } + }) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala index f2b2d44f41..19771d39ff 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala @@ -6,29 +6,31 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.{ - Actor, - ActorIdentity, - ActorRef, - ActorSystem, - Identify, - Props -} -import org.apache.pekko.testkit.ImplicitSender -import org.apache.pekko.util.Timeout -import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage.StringAdapter import edu.ie3.simona.io.result.ResultSinkType import edu.ie3.simona.sim.setup.SimonaStandaloneSetup -import edu.ie3.simona.test.common.{ - ConfigTestData, - TestKitWithShutdown, - ThreeWindingTestData -} +import edu.ie3.simona.test.common.{ConfigTestData, ThreeWindingTestData} import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit +import org.apache.pekko.actor.typed.receptionist.Receptionist.{ + Listing, + Register, + Subscribe +} +import org.apache.pekko.actor.typed.receptionist.ServiceKey +import org.apache.pekko.actor.typed.scaladsl.AskPattern.Askable +import org.apache.pekko.actor.typed.scaladsl.Behaviors +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + TypedActorContextOps, + TypedActorRefOps +} +import org.apache.pekko.actor.typed.{ActorRef, Scheduler} +import org.apache.pekko.actor.{ActorRef => classicRef} +import org.apache.pekko.util.Timeout import org.scalatest.wordspec.AnyWordSpecLike import java.util.concurrent.TimeUnit @@ -36,17 +38,7 @@ import scala.concurrent.Await import scala.concurrent.duration.Duration class GridAgentSetup3WSpec - extends TestKitWithShutdown( - ActorSystem( - "GridAgentSetupSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="DEBUG" - """.stripMargin) - ) - ) - with ImplicitSender + extends ScalaTestWithActorTestKit with AnyWordSpecLike with ThreeWindingTestData with ConfigTestData @@ -54,18 +46,27 @@ class GridAgentSetup3WSpec "The setup of grid agents" must { "provide three grid agents on presence of a three winding transformer" in { - import org.apache.pekko.pattern._ implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) + implicit val scheduler: Scheduler = system.scheduler // in order to get an actor system we need a tmp actor that calls the corresponding method - Await.ready( - system.actorOf(Props(new Actor { - override def receive: Receive = { case "setup" => + val serviceKey = ServiceKey[GridAgentMessage]("gridAgent") + + val actor = testKit.spawn(Behaviors.setup[GridAgentMessage] { ctx => + ctx.system.receptionist ! Register(serviceKey, ctx.self) + + Behaviors.receive[GridAgentMessage] { + case (ctx, StringAdapter("ping", sender)) => + // replying to ping signal + sender ! StringAdapter("pong", ctx.self) + Behaviors.same + + case (ctx, StringAdapter("setup", _)) => val environmentRefs = EnvironmentRefs( - scheduler = self, - runtimeEventListener = self, - primaryServiceProxy = self, - weather = ActorRef.noSender, + scheduler = ctx.self.toClassic, + runtimeEventListener = ctx.self.toClassic, + primaryServiceProxy = ctx.self.toClassic, + weather = classicRef.noSender, evDataService = None ) @@ -84,42 +85,45 @@ class GridAgentSetup3WSpec ) ).buildSubGridToActorRefMap( threeWindingTestGrid.getSubGridTopologyGraph, - context, + ctx.toClassic, environmentRefs, - Seq.empty[ActorRef] + Seq.empty[classicRef] ) - sender() ! "done" - } - })) ? "setup", - Duration(1, TimeUnit.SECONDS) + ctx.self ! StringAdapter("done", ctx.self) + Behaviors.same + } + }) + + Await.ready( + actor.ask[GridAgentMessage](ref => StringAdapter("setup", ref)), + Duration(10, TimeUnit.SECONDS) ) - val sel = system.actorSelection("user/**/GridAgent_*") - sel ! Identify(0) + testKit.spawn(Behaviors.setup[Listing] { ctx => + logger.debug("Subscribing to the actors.") + ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) - logger.debug("Waiting 500ms to collect all responses") - val responses: Seq[ActorIdentity] = - receiveWhile( - max = Duration.create(500, "ms"), - idle = Duration.create(250, "ms") - ) { case msg: ActorIdentity => - msg - } - logger.debug("All responses received. Evaluating...") - - responses.size should be(3) - val regex = """GridAgent_\d*""".r - val expectedSenders = Vector("GridAgent_1", "GridAgent_2", "GridAgent_3") - val actualSenders = responses - .collect { case actorId: ActorIdentity => - val actorRefString = actorId.getActorRef.toString - regex.findFirstIn(actorRefString) - } - .flatten - .sorted - .toVector + Behaviors.receiveMessagePartial[Listing] { + case serviceKey.Listing(listings) => + logger.debug("All responses received. Evaluating...") + + listings.size should be(3) + val regex = """GridAgent_\d*""".r + val expectedSenders = + Vector("GridAgent_1", "GridAgent_2", "GridAgent_3") + val actualSenders = listings + .collect { case actorId: ActorRef[GridAgentMessage] => + val actorRefString = actorId.toString + regex.findFirstIn(actorRefString) + } + .flatten + .toVector - actualSenders should be(expectedSenders) + actualSenders should be(expectedSenders) + + Behaviors.same + } + }) } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala index c9d17d2379..529b27780c 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.event.{LoggingAdapter, NoLogging} import breeze.math.Complex import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.connector.ConnectorPort @@ -61,7 +60,6 @@ class GridResultsSupportSpec with GridInputTestData with TableDrivenPropertyChecks { - override protected val log: LoggingAdapter = NoLogging implicit val currentTolerance: squants.electro.ElectricCurrent = Amperes(1e-6) implicit val angleTolerance: squants.Angle = Degrees(1e-6) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala index 66805b06d9..bf2717d845 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.ActorRef -import org.apache.pekko.event.{LoggingAdapter, NoLogging} import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower @@ -16,6 +14,12 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.BasicGridWithSwitches import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.quantities.Megavars +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.ActorRef +import org.slf4j.{Logger, LoggerFactory} import squants.electro.Kilovolts import squants.energy.Megawatts import tech.units.indriya.ComparableQuantity @@ -31,12 +35,16 @@ import javax.measure.quantity.Angle * order to comprehend the expected test results. */ class PowerFlowSupportSpec - extends UnitSpec + extends ScalaTestWithActorTestKit + with UnitSpec with BasicGridWithSwitches with PowerFlowSupport with GridResultsSupport { - override val log: LoggingAdapter = NoLogging + implicit val log: Logger = + LoggerFactory.getLogger(PowerFlowSupportSpec.super.getClass) + val actorRef: ActorRef[GridAgentMessage] = + TestProbe[GridAgentMessage]("noSender").ref /** Setting voltage at slack node to 110 kV and introducing a load of 1 MW at * node 1 @@ -55,7 +63,7 @@ class PowerFlowSupportSpec ), nodeToReceivedPower = Map( node1.uuid -> Map( - ActorRef.noSender -> Some( + actorRef -> Some( ExchangePower( node1.uuid, Megawatts(1d), @@ -119,7 +127,10 @@ class PowerFlowSupportSpec ) val pfResult = - createResultModels(gridModel, sweepValueStore)(ZonedDateTime.now()) + createResultModels(gridModel, sweepValueStore)( + ZonedDateTime.now(), + log + ) // left/top side segments should have similar currents val loadLinesLeft = @@ -220,7 +231,7 @@ class PowerFlowSupportSpec gridModel.gridComponents.nodes, gridModel.nodeUuidToIndexMap ) - )(ZonedDateTime.now()) + )(ZonedDateTime.now(), log) // left/top side segments (lines that are adjacent to the open switch) should have no load val loadLinesLeft = @@ -305,7 +316,7 @@ class PowerFlowSupportSpec gridModel.gridComponents.nodes, gridModel.nodeUuidToIndexMap ) - )(ZonedDateTime.now()) + )(ZonedDateTime.now(), log) // left/top side segments (lines that are adjacent to the open switch) should have load val expectedLoadLines = diff --git a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala index e4d9fedf2c..37159c59c9 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala @@ -6,37 +6,35 @@ package edu.ie3.simona.agent.grid -import java.util.UUID - -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.testkit.{TestKit, TestProbe} -import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.graph.SubGridGate -import edu.ie3.simona.test.common.{TestKitWithShutdown, UnitSpec} +import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage +import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.SubGridGateMokka +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} +import org.apache.pekko.actor.typed.ActorRef + +import java.util.UUID class ReceivedValuesStoreSpec - extends TestKitWithShutdown( - ActorSystem( - "ReceivedValuesStoreSpec", - ConfigFactory - .parseString(""" - |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] - |pekko.loglevel="OFF" - """.stripMargin) - ) - ) + extends ScalaTestWithActorTestKit with UnitSpec with SubGridGateMokka { // test actorRefs - val actorProbe1: TestProbe = TestProbe() - val actorProbe2: TestProbe = TestProbe() - val actorProbe3: TestProbe = TestProbe() + val actorProbe1: TestProbe[ParticipantMessage] = + TestProbe[ParticipantMessage]() + val actorProbe2: TestProbe[ParticipantMessage] = + TestProbe[ParticipantMessage]() + val actorProbe3: TestProbe[ParticipantMessage] = + TestProbe[ParticipantMessage]() + val actorProbe4: TestProbe[GridAgentMessage] = TestProbe[GridAgentMessage]() // test data used by almost all tests // / node to asset agents mapping - val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef]] = Map( + val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef[ParticipantMessage]]] = Map( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") -> Set( actorProbe1.ref ), @@ -46,13 +44,14 @@ class ReceivedValuesStoreSpec ) // / subnet gate mapping for inferior grids - val inferiorSubGridGateToActorRefMap: Map[SubGridGate, ActorRef] = Map( + val inferiorSubGridGateToActorRefMap + : Map[SubGridGate, ActorRef[GridAgentMessage]] = Map( build2wSubGridGate( UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8"), 1, UUID.fromString("1676360a-c7c4-43a9-a667-90ddfe8a18e6"), 2 - ) -> actorProbe3.ref + ) -> actorProbe4.ref ) // / superior grid nodeUuid vector @@ -64,8 +63,10 @@ class ReceivedValuesStoreSpec "initialize an empty store correctly when everything is empty" in { - val nodeToAssetAgentsMap = Map.empty[UUID, Set[ActorRef]] - val inferiorSubGridGateToActorRefMap = Map.empty[SubGridGate, ActorRef] + val nodeToAssetAgentsMap = + Map.empty[UUID, Set[ActorRef[ParticipantMessage]]] + val inferiorSubGridGateToActorRefMap = + Map.empty[SubGridGate, ActorRef[GridAgentMessage]] val superiorGridNodeUuids = Vector.empty[UUID] val receivedValuesStore = @@ -98,7 +99,7 @@ class ReceivedValuesStoreSpec ) shouldBe Map(actorProbe2.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8") - ) shouldBe Map(actorProbe3.ref -> None) + ) shouldBe Map(actorProbe4.ref -> None) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 1 receivedValuesStore.nodeToReceivedSlackVoltage( @@ -120,7 +121,8 @@ class ReceivedValuesStoreSpec ) ) - val inferiorSubGridGateToActorRefMap = Map.empty[SubGridGate, ActorRef] + val inferiorSubGridGateToActorRefMap = + Map.empty[SubGridGate, ActorRef[GridAgentMessage]] val superiorGridNodeUuids = Vector.empty[UUID] val receivedValuesStore = @@ -167,14 +169,16 @@ class ReceivedValuesStoreSpec ) shouldBe Map(actorProbe2.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8") - ) shouldBe Map(actorProbe3.ref -> None) + ) shouldBe Map(actorProbe4.ref -> None) } "initialize an empty store correctly when only information on the superior grid slack nodes are provided" in { - val nodeToAssetAgentsMap = Map.empty[UUID, Set[ActorRef]] - val inferiorSubGridGateToActorRefMap = Map.empty[SubGridGate, ActorRef] + val nodeToAssetAgentsMap = + Map.empty[UUID, Set[ActorRef[ParticipantMessage]]] + val inferiorSubGridGateToActorRefMap = + Map.empty[SubGridGate, ActorRef[GridAgentMessage]] val superiorGridNodeUuids = Vector( UUID.fromString("baded8c4-b703-4316-b62f-75ffe09c9843"), @@ -202,7 +206,8 @@ class ReceivedValuesStoreSpec "initialize an empty store correctly when only an invalid mapping for asset agents with duplicates is provided" in { - val inferiorSubGridGateToActorRefMap = Map.empty[SubGridGate, ActorRef] + val inferiorSubGridGateToActorRefMap = + Map.empty[SubGridGate, ActorRef[GridAgentMessage]] val superiorGridNodeUuids = Vector.empty[UUID] val receivedValuesStore = diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 1007da8e77..31ac506a89 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.participant import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.datamodel.models.result.system.SystemParticipantResult -import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger +import edu.ie3.simona.agent.grid.GridAgentMessage.FinishGridSimulationTrigger import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig diff --git a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala index a654ec289a..6db51d4b74 100644 --- a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala @@ -7,7 +7,13 @@ package edu.ie3.simona.event import java.util.{Calendar, Date} -import org.apache.pekko.actor.{ActorLogging, ActorRef, ActorSystem, Props} +import org.apache.pekko.actor.{ + Actor, + ActorLogging, + ActorRef, + ActorSystem, + Props +} import org.apache.pekko.testkit.ImplicitSender import org.apache.pekko.util.Timeout import com.typesafe.config.ConfigFactory @@ -40,6 +46,7 @@ class NotifierSpec // test listenerActor class NotifierActor(override val listener: Iterable[ActorRef]) extends Notifier + with Actor with ActorLogging { override def preStart(): Unit = { log.debug(s"{} started!", self) diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala index 27c6c80fae..85049cb148 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala @@ -13,13 +13,15 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.{ import org.apache.pekko.actor.{ Actor, ActorContext, - ActorRef, ActorSystem, - Props + Props, + ActorRef => classicRef } +import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.testkit.{TestActorRef, TestProbe} import com.typesafe.config.ConfigFactory import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage @@ -77,10 +79,10 @@ object SimonaSimFailSpec { timeAdvancer ) ) { - val child: ActorRef = context.actorOf(Props(new Loser)) + val child: classicRef = context.actorOf(Props(new Loser)) context.watch(child) - def getChild: ActorRef = child + def getChild: classicRef = child } class Loser extends Actor { @@ -108,23 +110,23 @@ object SimonaSimFailSpec { override def systemParticipantsListener( context: ActorContext - ): Seq[ActorRef] = Seq.empty[ActorRef] + ): Seq[classicRef] = Seq.empty[classicRef] override def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef - ): ActorRef = + scheduler: classicRef + ): classicRef = TestProbe("primaryService")(actorSystem).ref override def weatherService( context: ActorContext, - scheduler: ActorRef - ): ActorRef = + scheduler: classicRef + ): classicRef = TestProbe("weatherService")(actorSystem).ref override def timeAdvancer( context: ActorContext, - simulation: ActorRef, + simulation: classicRef, runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[ RuntimeEvent ] @@ -136,17 +138,17 @@ object SimonaSimFailSpec { timeAdvancer: org.apache.pekko.actor.typed.ActorRef[ TimeAdvancer.Incoming ] - ): ActorRef = TestProbe("scheduler")(actorSystem).ref + ): classicRef = TestProbe("scheduler")(actorSystem).ref override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] - ): Iterable[ActorRef] = Iterable.empty + systemParticipantListener: Seq[classicRef] + ): Iterable[ActorRef[GridAgentMessage]] = Iterable.empty override def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: classicRef ): ExtSimSetupData = ExtSimSetupData(Iterable.empty, Map.empty) } diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala index 93ae23d06b..cf7ee5bdc3 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala @@ -7,8 +7,7 @@ package edu.ie3.simona.sim.setup import java.util.UUID - -import org.apache.pekko.actor.ActorRef +import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.testkit.TestException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.connector.{ @@ -19,16 +18,27 @@ import edu.ie3.datamodel.models.input.container.{ JointGridContainer, RawGridElements } +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.input.GridInputTestData +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe +} import scala.jdk.CollectionConverters._ -class SetupHelperSpec extends UnitSpec with GridInputTestData { +class SetupHelperSpec + extends ScalaTestWithActorTestKit + with UnitSpec + with GridInputTestData { private final object SetupHelperInstance extends SetupHelper "A setup helper" should { + val actorRef: ActorRef[GridAgentMessage] = + TestProbe[GridAgentMessage]("noSender").ref + "reduce multiple SubGridGates between the same superior and inferior nodes to one unique SubGridGate" in { // build dummy grid with two transformers between the same nodes based on the basic grid input test data @@ -83,7 +93,7 @@ class SetupHelperSpec extends UnitSpec with GridInputTestData { ) val subGridToActorRefMap = - Map(1 -> ActorRef.noSender, 100 -> ActorRef.noSender) + Map(1 -> actorRef, 100 -> actorRef) // subGrid gates should be the same for this case gridModel.getSubGridTopologyGraph.edgesOf( diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 26b6246e42..47e16fd8a7 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -6,13 +6,19 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} +import org.apache.pekko.actor.{ + ActorContext, + ActorRef => classicRef, + ActorSystem +} +import org.apache.pekko.actor.typed.ActorRef import edu.ie3.datamodel.exceptions.NotImplementedException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, Transformer3WInput } import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.test.common.UnitSpec @@ -29,48 +35,50 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def runtimeEventListener( context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = + ): ActorRef[RuntimeEvent] = throw new NotImplementedException("This is a dummy setup") override def systemParticipantsListener( context: ActorContext - ): Seq[ActorRef] = throw new NotImplementedException("This is a dummy setup") + ): Seq[classicRef] = throw new NotImplementedException( + "This is a dummy setup" + ) override def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef - ): ActorRef = + scheduler: classicRef + ): classicRef = throw new NotImplementedException("This is a dummy setup") override def weatherService( context: ActorContext, - scheduler: ActorRef - ): ActorRef = + scheduler: classicRef + ): classicRef = throw new NotImplementedException("This is a dummy setup") override def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: classicRef ): ExtSimSetupData = throw new NotImplementedException("This is a dummy setup") override def timeAdvancer( context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = + simulation: classicRef, + runtimeEventListener: ActorRef[RuntimeEvent] + ): ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException("This is a dummy setup") override def scheduler( context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] - ): ActorRef = throw new NotImplementedException("This is a dummy setup") + timeAdvancer: ActorRef[TimeAdvancer.Incoming] + ): classicRef = throw new NotImplementedException("This is a dummy setup") override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] - ): Iterable[ActorRef] = + systemParticipantListener: Seq[classicRef] + ): Iterable[ActorRef[GridAgentMessage]] = throw new NotImplementedException("This is a dummy setup") "Attempting to modify a sub grid gate" should { From db816e16b3e5da28653527c0cc70e9f80fed90fb Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 1 Feb 2024 15:02:00 +0100 Subject: [PATCH 177/305] Fixing code example --- src/main/scala/edu/ie3/util/scala/Scope.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/edu/ie3/util/scala/Scope.scala b/src/main/scala/edu/ie3/util/scala/Scope.scala index 093419e449..0ed4889c17 100644 --- a/src/main/scala/edu/ie3/util/scala/Scope.scala +++ b/src/main/scala/edu/ie3/util/scala/Scope.scala @@ -29,6 +29,7 @@ package edu.ie3.util.scala * .map(transform) * .map(_.doStuff) * .map(maybeBar.calculate) + * .get * }}} * * @param obj From 70a56e3f00b28003c165aff0de3f6c415590b6a4 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 10:03:42 +0100 Subject: [PATCH 178/305] Fixing ref system voltage validation --- .../edu/ie3/simona/sim/setup/SetupHelper.scala | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala index 1e319ecbcc..95ccfa34a5 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.ActorRef import com.typesafe.config.{Config => TypesafeConfig} import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridGate @@ -23,6 +22,9 @@ import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.util.ConfigUtil.{GridOutputConfigUtil, OutputConfigUtil} import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig import edu.ie3.simona.util.{EntityMapperUtil, ResultFileHierarchy} +import edu.ie3.util.quantities.PowerSystemUnits +import org.apache.pekko.actor.ActorRef +import squants.electro.Kilovolts /** Methods to support the setup of a simona simulation * @@ -179,15 +181,17 @@ trait SetupHelper extends LazyLogging { ) ) - if ( - !refSystem.nominalVoltage.equals( - subGridContainer.getPredominantVoltageLevel.getNominalVoltage - ) + val containerPotential = Kilovolts( + subGridContainer.getPredominantVoltageLevel.getNominalVoltage + .to(PowerSystemUnits.KILOVOLT) + .getValue + .doubleValue ) + + if (refSystem.nominalVoltage != containerPotential) logger.warn( s"The configured RefSystem for subGrid ${subGridContainer.getSubnet} differs in its nominal voltage (${refSystem.nominalVoltage}) from the grids" + - s"predominant voltage level nominal voltage (${subGridContainer.getPredominantVoltageLevel.getNominalVoltage}). If this is by intention and still valid, this " + - s"warning can be just ignored!" + s"predominant voltage level nominal voltage ($containerPotential). If this is by intention and still valid, this warning can be just ignored!" ) refSystem From 80eec4ef7b6e8e5d0fa54397f9165dd0b879394f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 10:04:05 +0100 Subject: [PATCH 179/305] case obj --- src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala index 95ccfa34a5..4f4ffa58cd 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala @@ -240,7 +240,7 @@ trait SetupHelper extends LazyLogging { } } -case object SetupHelper { +object SetupHelper { /** Determine a comprehensive collection of all [[ResultEntity]] classes, that * will have to be considered From 3f83b404e7988376d67639dda15884ebd6d6487b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 10:04:34 +0100 Subject: [PATCH 180/305] Using squants imports --- .../edu/ie3/simona/model/grid/RefSystem.scala | 75 +++++++++---------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala b/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala index 53ee866930..a6bb35a617 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala @@ -9,22 +9,19 @@ package edu.ie3.simona.model.grid import breeze.math.Complex import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.{ReactivePower, Vars} -import squants.Each -import squants.electro.Kilovolts +import squants.electro._ import squants.energy.{Megawatts, Watts} +import squants.{Dimensionless, Each, Power} import tech.units.indriya.quantity.Quantities -import javax.measure.quantity.{ElectricPotential, Power} - /** Provides the values a [[GridModel]] is referenced to as well as functions to * reference some standard parameters to the nominal impedance. */ - final case class RefSystem private ( - nominalVoltage: squants.electro.ElectricPotential, - nominalCurrent: squants.electro.ElectricCurrent, - nominalPower: squants.Power, - nominalImpedance: squants.electro.ElectricalResistance + nominalVoltage: ElectricPotential, + nominalCurrent: ElectricCurrent, + nominalPower: Power, + nominalImpedance: ElectricalResistance ) { /** Calculates the referenced resistance r (real part of impedance z) of a @@ -36,8 +33,8 @@ final case class RefSystem private ( * referenced resistance r in p.u. */ def rInPu( - r: squants.electro.ElectricalResistance - ): squants.Dimensionless = { + r: ElectricalResistance + ): Dimensionless = { Each(r.toOhms / nominalImpedance.toOhms) } @@ -50,8 +47,8 @@ final case class RefSystem private ( * referenced reactance x in p.u. */ def xInPu( - x: squants.electro.ElectricalResistance - ): squants.Dimensionless = + x: ElectricalResistance + ): Dimensionless = rInPu(x) /** Calculates the referenced susceptance b (imaginary part of admittance y) @@ -63,8 +60,8 @@ final case class RefSystem private ( * referenced susceptance b in p.u. */ def bInPu( - b: squants.electro.ElectricalConductance - ): squants.Dimensionless = { + b: ElectricalConductance + ): Dimensionless = { Each(b.toSiemens * nominalImpedance.toOhms) } @@ -77,8 +74,8 @@ final case class RefSystem private ( * referenced conductance g in p.u. */ def gInPu( - g: squants.electro.ElectricalConductance - ): squants.Dimensionless = + g: ElectricalConductance + ): Dimensionless = bInPu(g) /** Converts a provided referenced active power value from p.u. into physical @@ -89,10 +86,10 @@ final case class RefSystem private ( * @return * unreferenced active power value in Watt */ - def pInSi(pInPu: squants.Dimensionless): squants.Power = + def pInSi(pInPu: Dimensionless): Power = Watts(nominalPower.toWatts * pInPu.toEach) - def pInSi(pInPu: Double): squants.Power = + def pInSi(pInPu: Double): Power = pInSi(Each(pInPu)) /** Converts a provided active power value from physical SI to referenced p.u. @@ -102,7 +99,7 @@ final case class RefSystem private ( * @return * referenced active power value in p.u. */ - def pInPu(pInSi: squants.Power): squants.Dimensionless = + def pInPu(pInSi: Power): Dimensionless = Each(pInSi.toWatts / nominalPower.toWatts) /** Converts a provided reactive power value from p.u. into physical SI value @@ -112,7 +109,7 @@ final case class RefSystem private ( * @return * unreferenced active power value in Var */ - def qInSi(qInPu: squants.Dimensionless): ReactivePower = + def qInSi(qInPu: Dimensionless): ReactivePower = Vars(nominalPower.toWatts * qInPu.toEach) def qInSi(qInPu: Double): ReactivePower = @@ -126,7 +123,7 @@ final case class RefSystem private ( * @return * referenced active power value in p.u. */ - def qInPu(qInSi: ReactivePower): squants.Dimensionless = + def qInPu(qInSi: ReactivePower): Dimensionless = Each(qInSi.toVars / nominalPower.toWatts) /** Converts a provided voltage value from p.u. into physical SI value @@ -137,16 +134,16 @@ final case class RefSystem private ( * unreferenced voltage value in Volt */ def vInSi( - vInPu: squants.Dimensionless - ): squants.electro.ElectricPotential = + vInPu: Dimensionless + ): ElectricPotential = Kilovolts(nominalVoltage.toKilovolts * vInPu.toEach) - def vInSi(vInPu: Double): squants.electro.ElectricPotential = + def vInSi(vInPu: Double): ElectricPotential = vInSi(Each(vInPu)) def vInSi(vInPu: Complex): ( - squants.electro.ElectricPotential, - squants.electro.ElectricPotential + ElectricPotential, + ElectricPotential ) = ( vInSi(Each(vInPu.real)), @@ -161,22 +158,22 @@ final case class RefSystem private ( * referenced voltage value in p.u. */ def vInPu( - vInSi: squants.electro.ElectricPotential - ): squants.Dimensionless = + vInSi: ElectricPotential + ): Dimensionless = Each(vInSi.toVolts / nominalVoltage.toVolts) } case object RefSystem { def apply( - nominalPower: squants.Power, - nominalVoltage: squants.electro.ElectricPotential + nominalPower: Power, + nominalVoltage: ElectricPotential ): RefSystem = { - val nominalCurrent: squants.electro.ElectricCurrent = + val nominalCurrent: ElectricCurrent = nominalPower / (nominalVoltage * Math.sqrt(3)) - val nominalImpedance: squants.electro.ElectricalResistance = + val nominalImpedance: ElectricalResistance = nominalVoltage / (nominalCurrent * Math.sqrt(3)) new RefSystem( @@ -197,7 +194,7 @@ case object RefSystem { val sNom = Megawatts( Quantities .getQuantity(nominalPower) - .asType(classOf[Power]) + .asType(classOf[javax.measure.quantity.Power]) .to(PowerSystemUnits.MEGAVOLTAMPERE) .getValue .doubleValue() @@ -205,7 +202,7 @@ case object RefSystem { val vNom = Kilovolts( Quantities .getQuantity(nominalVoltage) - .asType(classOf[ElectricPotential]) + .asType(classOf[javax.measure.quantity.ElectricPotential]) .to(PowerSystemUnits.KILOVOLT) .getValue .doubleValue() @@ -225,10 +222,10 @@ case object RefSystem { * Dimensionless impedance with regard the to target reference system */ def transferImpedance( - impedance: squants.Dimensionless, + impedance: Dimensionless, from: RefSystem, to: RefSystem - ): squants.Dimensionless = { + ): Dimensionless = { val ratio = from.nominalImpedance.toOhms / to.nominalImpedance.toOhms Each(impedance.toEach * ratio) } @@ -246,10 +243,10 @@ case object RefSystem { * Dimensionless admittance with regard the to target reference system */ def transferAdmittance( - admittance: squants.Dimensionless, + admittance: Dimensionless, from: RefSystem, to: RefSystem - ): squants.Dimensionless = { + ): Dimensionless = { val ratio = to.nominalImpedance.toOhms / from.nominalImpedance.toOhms Each(admittance.toEach * ratio) From 837f993384bbc832f9dd3687df64e3a2dcbe3bb8 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 10:17:24 +0100 Subject: [PATCH 181/305] Adding to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 475c746d92..5ee9f2a846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed PV Model documentation [#684](https://github.com/ie3-institute/simona/issues/684), [#686](https://github.com/ie3-institute/simona/issues/686) - Removed `CsvDataSourceAdapter` workaround [#702](https://github.com/ie3-institute/simona/issues/702) - Logging wrong duration in the first simulation hour [#705](https://github.com/ie3-institute/simona/issues/705) +- Fixing false negative in ref system voltage validation [#706](https://github.com/ie3-institute/simona/issues/706) ## [3.0.0] - 2023-08-07 From 3c716dcb9be6f5a55e208031b057f8dd717a6aa9 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Fri, 2 Feb 2024 12:57:28 +0100 Subject: [PATCH 182/305] Improving implementation. --- .../agent/grid/DBFSMockGridAgents.scala | 8 +-- .../agent/grid/GridResultsSupportSpec.scala | 16 ++--- .../EvcsAgentModelCalculationSpec.scala | 26 ++++---- ...FixedFeedInAgentModelCalculationSpec.scala | 20 +++---- .../HpAgentModelCalculationSpec.scala | 48 +++++++-------- .../LoadAgentFixedModelCalculationSpec.scala | 20 +++---- ...LoadAgentProfileModelCalculationSpec.scala | 16 ++--- .../ParticipantAgentExternalSourceSpec.scala | 32 +++++----- .../ParticipantAgentFundamentalsSpec.scala | 24 ++++---- .../PvAgentModelCalculationSpec.scala | 24 ++++---- .../WecAgentModelCalculationSpec.scala | 24 ++++---- .../model/assets/control/QControlSpec.scala | 12 ++-- .../edu/ie3/simona/model/grid/LineSpec.scala | 22 ++++--- .../model/grid/NodeInputModelSpec.scala | 3 +- .../model/grid/Transformer3wModelSpec.scala | 24 ++++---- .../model/grid/TransformerModelSpec.scala | 12 ++-- .../ApparentPowerAndHeatSpec.scala | 13 ++-- .../participant/CharacteristicSpec.scala | 20 +++---- .../participant/FixedFeedInModelSpec.scala | 3 +- .../model/participant/HpModelSpec.scala | 5 +- .../participant/load/LoadModelSpec.scala | 4 +- .../load/LoadProfileStoreSpec.scala | 2 +- .../model/thermal/ThermalGridSpec.scala | 16 ++--- .../ThermalGridWithHouseAndStorageSpec.scala | 60 +++++++++---------- .../ThermalGridWithHouseOnlySpec.scala | 33 +++++----- .../ThermalGridWithStorageOnlySpec.scala | 29 +++++---- .../primary/PrimaryServiceWorkerSpec.scala | 2 +- .../weather/SampleWeatherSourceSpec.scala | 17 +++--- .../weather/WeatherSourceWrapperSpec.scala | 50 ++++++++-------- .../test/matchers/SquantsMatchers.scala | 22 ++++--- .../util/quantities/QuantityUtilSpec.scala | 10 ++-- 31 files changed, 298 insertions(+), 319 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index 310e1522e6..1e12ac315e 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -73,8 +73,8 @@ trait DBFSMockGridAgents extends UnitSpec { _.nodeUuid == expectedVoltage.nodeUuid ) match { case Some(ExchangeVoltage(_, actualE, actualF)) => - equalWithTolerance(actualE, expectedVoltage.e) - equalWithTolerance(actualF, expectedVoltage.f) + actualE should approximate(expectedVoltage.e) + actualF should approximate(expectedVoltage.f) case None => fail( s"Expected ExchangeVoltage with node UUID ${expectedVoltage.nodeUuid} " + @@ -122,8 +122,8 @@ trait DBFSMockGridAgents extends UnitSpec { expectedExchangedPowers.foreach { expectedPower => exchangedPower.find(_.nodeUuid == expectedPower.nodeUuid) match { case Some(ExchangePower(_, actualP, actualQ)) => - equalWithTolerance(actualP, expectedPower.p) - equalWithTolerance(actualQ, expectedPower.q) + actualP should approximate(expectedPower.p) + actualQ should approximate(expectedPower.q) case None => fail( s"Expected ExchangePower with node UUID ${expectedPower.nodeUuid} " + diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala index e69efca8b3..2ae971cc5f 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala @@ -489,8 +489,8 @@ class GridResultsSupportSpec time shouldBe timeStamp input shouldBe transformerA.uuid tapPos shouldBe transformerA.currentTapPos - equalWithTolerance(currentMagnitude, Amperes(13.15547500d)) - equalWithTolerance(currentAngle, Degrees(-45.0000000d)) + currentMagnitude should approximate(Amperes(13.15547500d)) + currentAngle should approximate(Degrees(-45.0000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -515,8 +515,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformerB.uuid - equalWithTolerance(currentMagnitude, Amperes(14.14213562d)) - equalWithTolerance(currentAngle, Degrees(135.000000d)) + currentMagnitude should approximate(Amperes(14.14213562d)) + currentAngle should approximate(Degrees(135.000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -541,8 +541,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformerC.uuid - equalWithTolerance(currentMagnitude, Amperes(14.14213562d)) - equalWithTolerance(currentAngle, Degrees(135.0000000d)) + currentMagnitude should approximate(Amperes(14.14213562d)) + currentAngle should approximate(Degrees(135.0000000d)) case wrong => fail(s"Got wrong result: '$wrong'") } } @@ -569,8 +569,8 @@ class GridResultsSupportSpec ) => time shouldBe timeStamp input shouldBe transformer3wInput.getUuid - equalWithTolerance(currentMagnitude, Amperes(11.4542161d)) - equalWithTolerance(currentAngle, Degrees(-89.4475391d)) + currentMagnitude should approximate(Amperes(11.4542161d)) + currentAngle should approximate(Degrees(-89.4475391d)) case wrong => fail(s"Got wrong result: '$wrong'") } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index f53cfe9d73..fa043a5022 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -49,7 +49,7 @@ import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.testkit.{TestFSMRef, TestProbe} import squants.energy.{Megawatts, Watts} -import squants.{Each, Power} +import squants.{Each, Power, energy} import java.util.UUID @@ -461,8 +461,8 @@ class EvcsAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) } } case _ => @@ -568,8 +568,8 @@ class EvcsAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) } } case _ => @@ -613,8 +613,8 @@ class EvcsAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } @@ -825,8 +825,8 @@ class EvcsAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.00572)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.00572)) + q should approximate(Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -843,8 +843,8 @@ class EvcsAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.00572)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.00572)) + q should approximate(Megavars(0.0)) } } @@ -859,8 +859,8 @@ class EvcsAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.00572)) - equalWithTolerance(q, Megavars(-0.00335669)) + p should approximate(Megawatts(0.00572)) + q should approximate(Megavars(-0.00335669)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index 66945de876..305c230602 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -317,8 +317,8 @@ class FixedFeedInAgentModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(-268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(-268.603e-6)) + q should approximate(Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 900.") @@ -364,8 +364,8 @@ class FixedFeedInAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(-268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(-268.603e-6)) + q should approximate(Megavars(0.0)) } } @@ -402,8 +402,8 @@ class FixedFeedInAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(-268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(-268.603e-6)) + q should approximate(Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -420,8 +420,8 @@ class FixedFeedInAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(-268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(-268.603e-6)) + q should approximate(Megavars(0.0)) } } @@ -436,8 +436,8 @@ class FixedFeedInAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(-0.000268603)) - equalWithTolerance(q, Megavars(-22.07138418e-6)) + p should approximate(Megawatts(-0.000268603)) + q should approximate(Megavars(-22.07138418e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index d025c025a1..cbffc3bb7a 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -487,14 +487,12 @@ class HpAgentModelCalculationSpec ) => isRunning shouldBe false lastTimeTick shouldBe 0L - equalWithTolerance(activePower, Kilowatts(0d)) - - equalWithTolerance(qDot, Kilowatts(0d)) + activePower should approximate(Kilowatts(0d)) + qDot should approximate(Kilowatts(0d)) thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - equalWithTolerance( - innerTemperature, + innerTemperature should approximate( Celsius(20.9999769069444444444444444444444) ) case None => @@ -504,7 +502,7 @@ class HpAgentModelCalculationSpec } currentTimeTick shouldBe 0L - equalWithTolerance(ambientTemperature, Celsius(1.815d)) + ambientTemperature should approximate(Celsius(1.815d)) case None => fail("Did expect to get hp relevant data for tick 0L") } @@ -519,9 +517,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) - equalWithTolerance(qDot, Megawatts(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) + qDot should approximate(Megawatts(0d)) } } case _ => @@ -620,14 +618,12 @@ class HpAgentModelCalculationSpec ) => isRunning shouldBe false lastTimeTick shouldBe 0L - equalWithTolerance(activePower, Kilowatts(0d)) - - equalWithTolerance(qDot, Kilowatts(0d)) + activePower should approximate(Kilowatts(0d)) + qDot should approximate(Kilowatts(0d)) thermalGridState.houseState match { case Some(ThermalHouseState(_, innerTemperature, _)) => - equalWithTolerance( - innerTemperature, + innerTemperature should approximate( Celsius(20.9999769069444444444444444444444) ) case None => @@ -637,7 +633,7 @@ class HpAgentModelCalculationSpec } currentTimeTick shouldBe 0L - equalWithTolerance(ambientTemperature, Celsius(1.815d)) + ambientTemperature should approximate(Celsius(1.815d)) case None => fail("Did expect to get hp relevant data for tick 0L") } @@ -652,9 +648,9 @@ class HpAgentModelCalculationSpec fail("Expected a simulation result for tick 0.") ) match { case ApparentPowerAndHeat(p, q, qDot) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) - equalWithTolerance(qDot, Megawatts(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) + qDot should approximate(Megawatts(0d)) } } case _ => @@ -719,8 +715,8 @@ class HpAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) } } @@ -809,8 +805,8 @@ class HpAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) case answer => fail(s"Did not expect to get that answer: $answer") } @@ -828,8 +824,8 @@ class HpAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) } } @@ -844,8 +840,8 @@ class HpAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index 6637e8186d..b44fce6012 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -311,8 +311,8 @@ class LoadAgentFixedModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(268.603e-6)) + q should approximate(Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 0.") @@ -358,8 +358,8 @@ class LoadAgentFixedModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(268.603e-6)) + q should approximate(Megavars(0.0)) } } @@ -396,8 +396,8 @@ class LoadAgentFixedModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(268.603e-6)) + q should approximate(Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -414,8 +414,8 @@ class LoadAgentFixedModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(268.603e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(268.603e-6)) + q should approximate(Megavars(0.0)) } } @@ -430,8 +430,8 @@ class LoadAgentFixedModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(268.603e-6)) - equalWithTolerance(q, Megavars(-22.07138e-6)) + p should approximate(Megawatts(268.603e-6)) + q should approximate(Megavars(-22.07138e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index 49c942708a..5d6a169bc0 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -311,8 +311,8 @@ class LoadAgentProfileModelCalculationSpec case Some((tick, entry)) => tick shouldBe 0L inside(entry) { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(84.000938e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(84.000938e-6)) + q should approximate(Megavars(0.0)) } case None => fail("Result value store does not contain entry for tick 0.") @@ -360,8 +360,8 @@ class LoadAgentProfileModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(79.750890e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(79.750890e-6)) + q should approximate(Megavars(0.0)) } } @@ -377,8 +377,8 @@ class LoadAgentProfileModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(79.750890e-6)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(79.750890e-6)) + q should approximate(Megavars(0.0)) } } @@ -393,8 +393,8 @@ class LoadAgentProfileModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(79.750890e-6)) - equalWithTolerance(q, Megavars(-22.0714e-6)) + p should approximate(Megawatts(79.750890e-6)) + q should approximate(Megavars(-22.0714e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index 3959e62587..467bd9a9f0 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -55,7 +55,7 @@ import edu.ie3.util.scala.quantities.{Kilovars, Megavars, ReactivePower, Vars} import org.mockito.ArgumentMatchers.any import org.mockito.Mockito.when import org.scalatestplus.mockito.MockitoSugar -import squants.Each +import squants.{Each, Power} import squants.energy.{Kilowatts, Megawatts, Watts} import tech.units.indriya.quantity.Quantities @@ -98,8 +98,8 @@ class ParticipantAgentExternalSourceSpec SystemParticipant[CalcRelevantData.FixedRelevantData.type, ApparentPower] ] when(mockModel.getUuid).thenReturn(testUUID) - private val activeToReactivePowerFunction: squants.Power => ReactivePower = - (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) + private val activeToReactivePowerFunction: Power => ReactivePower = + (p: Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) when( mockModel.activeToReactivePowerFunc( any(classOf[squants.Dimensionless]) @@ -117,7 +117,7 @@ class ParticipantAgentExternalSourceSpec private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds - private implicit val powerTolerance: squants.Power = Watts(0.1) + private implicit val powerTolerance: Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) "A participant agent with externally given data provider" should { @@ -563,7 +563,7 @@ class ParticipantAgentExternalSourceSpec val actualFunction = mockAgent.underlyingActor.getReactivePowerFunction(0L, baseStateData) - equalWithTolerance(actualFunction(Kilowatts(100.0)), Kilovars(0.0)) + actualFunction(Kilowatts(100.0)) should approximate(Kilovars(0.0)) } "correctly determine the reactive power function from model when requested" in { @@ -592,7 +592,7 @@ class ParticipantAgentExternalSourceSpec val actualFunction = mockAgent.underlyingActor.getReactivePowerFunction(0L, baseStateData) - equalWithTolerance(actualFunction(Kilowatts(100.0)), Kilovars(48.43221)) + actualFunction(Kilowatts(100.0)) should approximate(Kilovars(48.43221)) } "provide correct average power after three data ticks are available" in { @@ -667,8 +667,8 @@ class ParticipantAgentExternalSourceSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.095)) - equalWithTolerance(q, Megavars(0.0312)) + p should approximate(Megawatts(0.095)) + q should approximate(Megavars(0.0312)) } } @@ -684,8 +684,8 @@ class ParticipantAgentExternalSourceSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.095)) - equalWithTolerance(q, Megavars(0.0312)) + p should approximate(Megawatts(0.095)) + q should approximate(Megavars(0.0312)) } } @@ -701,8 +701,8 @@ class ParticipantAgentExternalSourceSpec /* Expect, that nothing has changed, as this model is meant to forward information from outside */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.095)) - equalWithTolerance(q, Megavars(0.0312)) + p should approximate(Megawatts(0.095)) + q should approximate(Megavars(0.0312)) } } @@ -764,8 +764,8 @@ class ParticipantAgentExternalSourceSpec participantAgent.prepareData(data, reactivePowerFunction) match { case Success(ApparentPower(p, q)) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) case Success(value) => fail(s"Succeeded, but with wrong data: '$value'.") case Failure(exception) => @@ -788,8 +788,8 @@ class ParticipantAgentExternalSourceSpec (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) ) match { case Success(ApparentPower(p, q)) => - equalWithTolerance(p, Kilowatts(100.0)) - equalWithTolerance(q, Kilovars(48.43221)) + p should approximate(Kilowatts(100.0)) + q should approximate(Kilovars(48.43221)) case Success(value) => fail(s"Succeeded, but with wrong data: '$value'.") case Failure(exception) => diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala index 0c944e6a9e..74bcc21cf5 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala @@ -320,8 +320,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.8666666666666667)) - equalWithTolerance(q, Megavars(0.5333333333333334)) + p should approximate(Megawatts(0.8666666666666667)) + q should approximate(Megavars(0.5333333333333334)) } } @@ -335,8 +335,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(4.571428571428573)) - equalWithTolerance(q, Megavars(3.571428571428571)) + p should approximate(Megawatts(4.571428571428573)) + q should approximate(Megavars(3.571428571428571)) } } @@ -350,8 +350,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(4.571428571428573)) - equalWithTolerance(q, Megavars(3.571428571428571)) + p should approximate(Megawatts(4.571428571428573)) + q should approximate(Megavars(3.571428571428571)) } } @@ -365,8 +365,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.8666666666666667)) - equalWithTolerance(q, Megavars(2.8666666666666667)) + p should approximate(Megawatts(0.8666666666666667)) + q should approximate(Megavars(2.8666666666666667)) } } @@ -380,8 +380,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(4.571428571428573)) - equalWithTolerance(q, Megavars(21.71428571428571)) + p should approximate(Megawatts(4.571428571428573)) + q should approximate(Megavars(21.71428571428571)) } } @@ -395,8 +395,8 @@ class ParticipantAgentFundamentalsSpec ) apparentPower match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(4.571428571428573)) - equalWithTolerance(q, Megavars(21.71428571428571)) + p should approximate(Megawatts(4.571428571428573)) + q should approximate(Megavars(21.71428571428571)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index a2e5be7fec..57826f5c2b 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -487,8 +487,8 @@ class PvAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } case _ => @@ -590,8 +590,8 @@ class PvAgentModelCalculationSpec fail("Expected a simulation result for tick 0.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } case _ => @@ -656,8 +656,8 @@ class PvAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } @@ -746,8 +746,8 @@ class PvAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -764,8 +764,8 @@ class PvAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } @@ -780,8 +780,8 @@ class PvAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(-780.6e-6)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(-780.6e-6)) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index 0422140a36..c2e61cea69 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -479,8 +479,8 @@ class WecAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } case _ => @@ -589,8 +589,8 @@ class WecAgentModelCalculationSpec fail("Expected a simulation result for tick 900.") ) match { case ApparentPower(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } case _ => @@ -655,8 +655,8 @@ class WecAgentModelCalculationSpec /* Appreciate the answer to my previous request */ expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } @@ -745,8 +745,8 @@ class WecAgentModelCalculationSpec expectMsgType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) case answer => fail(s"Did not expect to get that answer: $answer") } } @@ -763,8 +763,8 @@ class WecAgentModelCalculationSpec /* Expect, that nothing has changed */ expectMsgType[AssetPowerUnchangedMessage] match { case AssetPowerUnchangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(0.0)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(0.0)) } } @@ -779,8 +779,8 @@ class WecAgentModelCalculationSpec /* Expect, the correct values (this model has fixed power factor) */ expectMsgClass(classOf[AssetPowerChangedMessage]) match { case AssetPowerChangedMessage(p, q) => - equalWithTolerance(p, Megawatts(0.0)) - equalWithTolerance(q, Megavars(-156.1249e-3)) + p should approximate(Megawatts(0.0)) + q should approximate(Megavars(-156.1249e-3)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala index 2951f5c376..0540ed770a 100644 --- a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala @@ -119,18 +119,18 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { "provide correct values when the requested value is part of the containing xy coordinates" in { val requestedValue = Each(0.5) - equalWithTolerance(validCosPhiP.cosPhi(requestedValue), Each(-0.8)) + validCosPhiP.cosPhi(requestedValue) should approximate(Each(-0.8)) } "provide an interpolated value when the requested value is not part of the containing xy coordinates" in { val requestedValue = Each(0.75) - equalWithTolerance(validCosPhiP.cosPhi(requestedValue), Each(-0.5)) + validCosPhiP.cosPhi(requestedValue) should approximate(Each(-0.5)) } "provide the last known value when the requested value is outside of the containing xy coordinates" in { - equalWithTolerance(validCosPhiP.cosPhi(Each(2.0)), Each(-0.2)) - equalWithTolerance(validCosPhiP.cosPhi(Each(-1.0)), Each(-1.0)) + validCosPhiP.cosPhi(Each(2.0)) should approximate(Each(-0.2)) + validCosPhiP.cosPhi(Each(-1.0)) should approximate(Each(-1.0)) } } @@ -162,7 +162,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => - equalWithTolerance(validQV.q(Each(v), qMax), qMax * scaleExpected) + validQV.q(Each(v), qMax) should approximate(qMax * scaleExpected) } } @@ -200,7 +200,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => - equalWithTolerance(validQV.q(Each(v), qMax), qMax * scaleExpected) + validQV.q(Each(v), qMax) should approximate(qMax * scaleExpected) } } } diff --git a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala index 124001bf22..33d068ed65 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala @@ -86,21 +86,20 @@ class LineSpec extends UnitSpec with LineInputTestData { nodeAUuid shouldBe lineInputMs10Kv.getNodeA.getUuid nodeBUuid shouldBe lineInputMs10Kv.getNodeB.getUuid amount shouldBe lineInputMs10Kv.getParallelDevices - equalWithTolerance( - iMax, + iMax should approximate( Amperes(lineInputMs10Kv.getType.getiMax().getValue.doubleValue()) ) - equalWithTolerance(r, Each(0.0013109999999999999d)) - equalWithTolerance(x, Each(0.0010680000000000002d)) - equalWithTolerance(g, Each(0d)) - equalWithTolerance(b, Each(0.00000060375d)) + r should approximate(Each(0.0013109999999999999d)) + x should approximate(Each(0.0010680000000000002d)) + g should approximate(Each(0d)) + b should approximate(Each(0.00000060375d)) } - equalWithTolerance(validLineModel.b0(), Each(0.000000301875d)) - equalWithTolerance(validLineModel.bij(), Each(-373.5121155369499d)) - equalWithTolerance(validLineModel.g0(), Each(0d)) - equalWithTolerance(validLineModel.gij(), Each(458.4966137349637d)) + validLineModel.b0() should approximate(Each(0.000000301875d)) + validLineModel.bij() should approximate(Each(-373.5121155369499d)) + validLineModel.g0() should approximate(Each(0d)) + validLineModel.gij() should approximate(Each(458.4966137349637d)) } } @@ -152,8 +151,7 @@ class LineSpec extends UnitSpec with LineInputTestData { val iNodeB: squants.electro.ElectricCurrent = Amperes(145d) - equalWithTolerance( - LineModel.utilisation(validLineModel, iNodeA, iNodeB), + LineModel.utilisation(validLineModel, iNodeA, iNodeB) should approximate( Each(22.222222222222218) ) } diff --git a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala index db70889638..87532ffa3d 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala @@ -43,8 +43,7 @@ class NodeInputModelSpec extends UnitSpec with NodeInputTestData { id shouldBe nodeInputNoSlackNs04KvA.getId operationInterval shouldBe defaultOperationInterval isSlack shouldBe nodeInputNoSlackNs04KvA.isSlack - equalWithTolerance( - vTarget, + vTarget should approximate( Each(nodeInputNoSlackNs04KvA.getvTarget.getValue.doubleValue()) ) voltLvl shouldBe nodeInputNoSlackNs04KvA.getVoltLvl diff --git a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala index c1570a8b24..3fe005b09c 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala @@ -85,10 +85,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseA - equalWithTolerance(r, Each(1.03878e-3)) - equalWithTolerance(x, Each(166.34349e-3)) - equalWithTolerance(g, Each(1.874312e-6)) - equalWithTolerance(b, Each(-75.012912e-6)) + r should approximate(Each(1.03878e-3)) + x should approximate(Each(166.34349e-3)) + g should approximate(Each(1.874312e-6)) + b should approximate(Each(-75.012912e-6)) } val yii: Complex = Transformer3wModel.y0( @@ -160,10 +160,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseB - equalWithTolerance(r, Each(240.9972299e-6)) - equalWithTolerance(x, Each(24.99307479224e-3)) - equalWithTolerance(g, Each(0d)) - equalWithTolerance(b, Each(0d)) + r should approximate(Each(240.9972299e-6)) + x should approximate(Each(24.99307479224e-3)) + g should approximate(Each(0d)) + b should approximate(Each(0d)) } val yii: Complex = Transformer3wModel.y0( @@ -235,10 +235,10 @@ class Transformer3wModelSpec transformerTappingModel shouldBe expectedTappingModel amount shouldBe transformer3wInput.getParallelDevices powerFlowCase shouldBe PowerFlowCaseC - equalWithTolerance(r, Each(3.185595567e-6)) - equalWithTolerance(x, Each(556.0941828e-6)) - equalWithTolerance(g, Each(0d)) - equalWithTolerance(b, Each(0d)) + r should approximate(Each(3.185595567e-6)) + x should approximate(Each(556.0941828e-6)) + g should approximate(Each(0d)) + b should approximate(Each(0d)) } val yii: Complex = Transformer3wModel.y0( diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index 789f3aa8d6..1c5fdfa093 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -129,12 +129,12 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { amount shouldBe inputModel.getParallelDevices voltRatioNominal shouldBe BigDecimal("25") - equalWithTolerance(iNomHv, Amperes(36.373066958946424d)) - equalWithTolerance(iNomLv, Amperes(909.3266739736606d)) - equalWithTolerance(r, Each(7.357e-3)) - equalWithTolerance(x, Each(24.30792e-3)) - equalWithTolerance(g, Each(0.0)) - equalWithTolerance(b, Each(-3.75e-3)) + iNomHv should approximate(Amperes(36.373066958946424d)) + iNomLv should approximate(Amperes(909.3266739736606d)) + r should approximate(Each(7.357e-3)) + x should approximate(Each(24.30792e-3)) + g should approximate(Each(0.0)) + b should approximate(Each(-3.75e-3)) } /* The following tests are with regard to the tap position = 0 */ diff --git a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala index ee5f6662fc..c34bec6455 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala @@ -30,9 +30,9 @@ class ApparentPowerAndHeatSpec extends UnitSpec { FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => - equalWithTolerance(p, Megawatts(0d)) - equalWithTolerance(q, Megavars(0d)) - equalWithTolerance(qDot, Megawatts(0d)) + p should approximate(Megawatts(0d)) + q should approximate(Megavars(0d)) + qDot should approximate(Megawatts(0d)) } } @@ -45,10 +45,9 @@ class ApparentPowerAndHeatSpec extends UnitSpec { FixedRelevantData ) match { case ApparentPowerAndHeat(p, q, qDot) => - equalWithTolerance(p, Megawatts(43d)) - equalWithTolerance(q, Megavars(0d)) - equalWithTolerance(qDot, Megawatts(42d)) - + p should approximate(Megawatts(43d)) + q should approximate(Megavars(0d)) + qDot should approximate(Megawatts(42d)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala index f96eeeb02d..1a0baf5b1f 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/CharacteristicSpec.scala @@ -45,28 +45,28 @@ class CharacteristicSpec extends UnitSpec with CharacteristicTestData { interpolation1 match { case (x, y) => - equalWithTolerance(x, Each(1)) - equalWithTolerance(y, Each(2)) + x should approximate(Each(1)) + y should approximate(Each(2)) } interpolation2 match { case (x, y) => - equalWithTolerance(x, Each(2)) - equalWithTolerance(y, Each(4)) + x should approximate(Each(2)) + y should approximate(Each(4)) } interpolation3 match { case (x, y) => - equalWithTolerance(x, Each(3)) - equalWithTolerance(y, Each(8)) + x should approximate(Each(3)) + y should approximate(Each(8)) } interpolation4 match { case (x, y) => - equalWithTolerance(x, Each(1.5)) - equalWithTolerance(y, Each(3)) + x should approximate(Each(1.5)) + y should approximate(Each(3)) } interpolation5 match { case (x, y) => - equalWithTolerance(x, Each(2.5)) - equalWithTolerance(y, Each(6)) + x should approximate(Each(2.5)) + y should approximate(Each(6)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala index 00fe6e6eb3..b2f153e850 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala @@ -65,8 +65,7 @@ class FixedFeedInModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(fixedFeedInput.getqCharacteristics) - equalWithTolerance( - sRated, + sRated should approximate( Megawatts( fixedFeedInput.getsRated().to(MEGAVOLTAMPERE).getValue.doubleValue ) diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index 9d9f26bc7f..6a71eb998e 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -176,9 +176,8 @@ class HpModelSpec ThermalGridState(Some(thermalHouseState), _) ) => isRunning shouldBe expectedRunningState - equalWithTolerance(activePower, Kilowatts(expectedActivePower)) - equalWithTolerance( - thermalHouseState.innerTemperature, + activePower should approximate(Kilowatts(expectedActivePower)) + thermalHouseState.innerTemperature should approximate( Celsius( expectedInnerTemperature ) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala index 912f22a3a2..d22eb65b07 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala @@ -67,7 +67,7 @@ class LoadModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(loadInput.getqCharacteristics) - equalWithTolerance(sRated, expsRated) + sRated should approximate(expsRated) cosPhiRated shouldBe loadInput.getCosPhiRated loadProfile shouldBe loadInput.getLoadProfile reference shouldBe foreSeenReference @@ -115,7 +115,7 @@ class LoadModelSpec operationInterval shouldBe defaultOperationInterval scalingFactor shouldBe foreSeenScalingFactor qControl shouldBe QControl(loadInput.getqCharacteristics) - equalWithTolerance(sRated, expsRated) + sRated should approximate(expsRated) cosPhiRated shouldBe loadInput.getCosPhiRated reference shouldBe foreSeenReference } diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala index 11c225e430..5b20449de8 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala @@ -143,7 +143,7 @@ class LoadProfileStoreSpec implicit val powerTolerance: squants.Energy = KilowattHours(1.0) /* Check the deviation against the expected value (deviation should be smaller than 1 kWh) */ - equalWithTolerance(annualEnergy, expected) + annualEnergy should approximate(expected) }) } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala index b273467b91..efe070abae 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala @@ -26,8 +26,8 @@ class ThermalGridSpec extends UnitSpec { val energyDemand = ThermalEnergyDemand(required, possible) - equalWithTolerance(energyDemand.required, possible) - equalWithTolerance(energyDemand.possible, possible) + energyDemand.required should approximate(possible) + energyDemand.possible should approximate(possible) } "set the correct values, if they are sensible" in { @@ -36,8 +36,8 @@ class ThermalGridSpec extends UnitSpec { val energyDemand = ThermalEnergyDemand(required, possible) - equalWithTolerance(energyDemand.required, required) - equalWithTolerance(energyDemand.possible, possible) + energyDemand.required should approximate(required) + energyDemand.possible should approximate(possible) } } @@ -45,8 +45,8 @@ class ThermalGridSpec extends UnitSpec { "actually have no demand" in { val energyDemand = ThermalEnergyDemand.noDemand - equalWithTolerance(energyDemand.required, MegawattHours(0d)) - equalWithTolerance(energyDemand.possible, MegawattHours(0d)) + energyDemand.required should approximate(MegawattHours(0d)) + energyDemand.possible should approximate(MegawattHours(0d)) } } @@ -92,8 +92,8 @@ class ThermalGridSpec extends UnitSpec { val totalDemand = energyDemand1 + energyDemand2 - equalWithTolerance(totalDemand.required, MegawattHours(68d)) - equalWithTolerance(totalDemand.possible, MegawattHours(75d)) + totalDemand.required should approximate(MegawattHours(68d)) + totalDemand.possible should approximate(MegawattHours(75d)) } } } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala index 2c683ca790..8b3774a17a 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -77,16 +77,15 @@ class ThermalGridWithHouseAndStorageSpec ) => houseTick shouldBe expectedHouseStartingState.tick storageTick shouldBe expectedHouseStartingState.tick - equalWithTolerance( - innerTemperature, + + innerTemperature should approximate( expectedHouseStartingState.innerTemperature ) - equalWithTolerance( - storedEnergy, + storedEnergy should approximate( expectedStorageStartingState.storedEnergy ) - equalWithTolerance(qDotHouse, expectedHouseStartingState.qDot) - equalWithTolerance(qDotStorage, expectedStorageStartingState.qDot) + qDotHouse should approximate(expectedHouseStartingState.qDot) + qDotStorage should approximate(expectedStorageStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -103,9 +102,8 @@ class ThermalGridWithHouseAndStorageSpec ThermalGrid.startingState(thermalGrid) ) - equalWithTolerance(gridDemand.required, KilowattHours(0d)) - equalWithTolerance( - gridDemand.possible, + gridDemand.required should approximate(KilowattHours(0d)) + gridDemand.possible should approximate( KilowattHours(31.05009722 + 920) ) } @@ -124,8 +122,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) - equalWithTolerance(gridDemand.required, KilowattHours(0d)) - equalWithTolerance(gridDemand.possible, KilowattHours(1041.200111111)) + gridDemand.required should approximate(KilowattHours(0d)) + gridDemand.possible should approximate(KilowattHours(1041.200111111)) } "consider stored energy to reduce house demand if stored energy is not enough" in { @@ -141,8 +139,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) ) - equalWithTolerance(gridDemand.required, KilowattHours(8.64987499999)) - equalWithTolerance(gridDemand.possible, KilowattHours(1418.64987499999)) + gridDemand.required should approximate(KilowattHours(8.64987499999)) + gridDemand.possible should approximate(KilowattHours(1418.64987499999)) } } @@ -179,8 +177,8 @@ class ThermalGridWithHouseAndStorageSpec ) ) => storageTick shouldBe 0L - equalWithTolerance(storedEnergy, initialLoading) - equalWithTolerance(qDotStorage, externalQDot) + storedEnergy should approximate(initialLoading) + qDotStorage should approximate(externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -215,12 +213,12 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDotHouse, Kilowatts(0d)) + innerTemperature should approximate(Celsius(18.9999d)) + qDotHouse should approximate(Kilowatts(0d)) storageTick shouldBe 0L - equalWithTolerance(storedEnergy, initialLoading) - equalWithTolerance(qDotStorage, externalQDot) + storedEnergy should approximate(initialLoading) + qDotStorage should approximate(externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageEmpty(17142L)) @@ -462,9 +460,9 @@ class ThermalGridWithHouseAndStorageSpec houseTick shouldBe tick storageTick shouldBe tick - equalWithTolerance(revisedQDotHouse, thermalStorage.chargingPower) - equalWithTolerance( - revisedQDotStorage, + revisedQDotHouse should approximate(thermalStorage.chargingPower) + + revisedQDotStorage should approximate( thermalStorage.chargingPower * (-1) ) @@ -502,18 +500,17 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDotHouse, externalQDot) + innerTemperature should approximate(Celsius(18.9999d)) + qDotHouse should approximate(externalQDot) storageTick shouldBe -1L - equalWithTolerance( - storedEnergy, + storedEnergy should approximate( initialGridState.storageState .map(_.storedEnergy) .getOrElse(fail("No initial storage state found")) ) - equalWithTolerance(qDotStorage, Kilowatts(0d)) + qDotStorage should approximate(Kilowatts(0d)) case _ => fail("Thermal grid state has been calculated wrong.") } @@ -548,12 +545,11 @@ class ThermalGridWithHouseAndStorageSpec ) ) => houseTick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(20.99999167d)) - equalWithTolerance(qDotHouse, Kilowatts(0d)) + innerTemperature should approximate(Celsius(20.99999167d)) + qDotHouse should approximate(Kilowatts(0d)) storageTick shouldBe 0L - equalWithTolerance( - storedEnergy, + storedEnergy should approximate( gridState.storageState .map(_.storedEnergy) .getOrElse( @@ -561,7 +557,7 @@ class ThermalGridWithHouseAndStorageSpec ) ) - equalWithTolerance(qDotStorage, externalQDot) + qDotStorage should approximate(externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala index 58970c91a7..4fe2d2d182 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -61,11 +61,10 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe expectedHouseStartingState.tick - equalWithTolerance( - innerTemperature, + innerTemperature should approximate( expectedHouseStartingState.innerTemperature ) - equalWithTolerance(thermalInfeed, expectedHouseStartingState.qDot) + thermalInfeed should approximate(expectedHouseStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -87,8 +86,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { ThermalGrid.startingState(thermalGrid) ) - equalWithTolerance(gridDemand.required, houseDemand.required) - equalWithTolerance(gridDemand.possible, houseDemand.possible) + gridDemand.required should approximate(houseDemand.required) + gridDemand.possible should approximate(houseDemand.possible) } } @@ -117,8 +116,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, externalQDot) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(externalQDot) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -144,8 +143,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, Megawatts(0d)) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(Megawatts(0d)) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -178,8 +177,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { None ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, testGridQDotInfeed) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(testGridQDotInfeed) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( @@ -204,8 +203,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureUpperBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, testGridQDotInfeed) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(testGridQDotInfeed) thresholdTick shouldBe 7372L case _ => fail("Thermal grid state updated failed") } @@ -226,8 +225,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, Megawatts(0d)) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(Megawatts(0d)) thresholdTick shouldBe 154284L case _ => fail("Thermal grid state updated failed") } @@ -248,8 +247,8 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) ) => tick shouldBe 0L - equalWithTolerance(innerTemperature, Celsius(18.9999d)) - equalWithTolerance(qDot, Kilowatts(0d)) + innerTemperature should approximate(Celsius(18.9999d)) + qDot should approximate(Kilowatts(0d)) thresholdTick shouldBe 154284L case _ => fail("Thermal grid state updated failed") } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala index 3ae623baf1..5476321e2d 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -66,11 +66,10 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe expectedStorageStartingState.tick - equalWithTolerance( - storedEnergy, + storedEnergy should approximate( expectedStorageStartingState.storedEnergy ) - equalWithTolerance(qDot, expectedStorageStartingState.qDot) + qDot should approximate(expectedStorageStartingState.qDot) case _ => fail("Determination of starting state failed") } @@ -87,8 +86,8 @@ class ThermalGridWithStorageOnlySpec ThermalGrid.startingState(thermalGrid) ) - equalWithTolerance(gridDemand.required, MegawattHours(0d)) - equalWithTolerance(gridDemand.possible, MegawattHours(0.92d)) + gridDemand.required should approximate(MegawattHours(0d)) + gridDemand.possible should approximate(MegawattHours(0.92d)) } } @@ -126,8 +125,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - equalWithTolerance(storedEnergy, KilowattHours(430d)) - equalWithTolerance(qDot, testGridQDotConsumptionHigh) + storedEnergy should approximate(KilowattHours(430d)) + qDot should approximate(testGridQDotConsumptionHigh) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageEmpty(3600L)) @@ -158,8 +157,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - equalWithTolerance(storedEnergy, KilowattHours(230d)) - equalWithTolerance(qDot, testGridQDotInfeed) + storedEnergy should approximate(KilowattHours(230d)) + qDot should approximate(testGridQDotInfeed) case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some(StorageFull(220800L)) @@ -183,8 +182,8 @@ class ThermalGridWithStorageOnlySpec Some(ThermalStorageState(tick, storedEnergy, qDot)) ) => tick shouldBe 0L - equalWithTolerance(storedEnergy, KilowattHours(230d)) - equalWithTolerance(qDot, testGridQDotInfeed) + storedEnergy should approximate(KilowattHours(230d)) + qDot should approximate(testGridQDotInfeed) case _ => fail("Thermal grid state updated failed") } } @@ -214,8 +213,8 @@ class ThermalGridWithStorageOnlySpec Some(StorageEmpty(thresholdTick)) ) => tick shouldBe 0L - equalWithTolerance(storedEnergy, KilowattHours(430d)) - equalWithTolerance(qDot, testGridQDotConsumptionHigh) + storedEnergy should approximate(KilowattHours(430d)) + qDot should approximate(testGridQDotConsumptionHigh) thresholdTick shouldBe 3600L case _ => fail("Thermal grid state updated failed") } @@ -237,8 +236,8 @@ class ThermalGridWithStorageOnlySpec None ) => tick shouldBe 0L - equalWithTolerance(storedEnergy, KilowattHours(230d)) - equalWithTolerance(qDot, Megawatts(0d)) + storedEnergy should approximate(KilowattHours(230d)) + qDot should approximate(Megawatts(0d)) case _ => fail("Thermal grid state updated failed") } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala index e69b111a35..187c1795f5 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala @@ -346,7 +346,7 @@ class PrimaryServiceWorkerSpec tick shouldBe 900L inside(data) { case ActivePower(p) => - equalWithTolerance(p, Kilowatts(1250.0)) + p should approximate(Kilowatts(1250.0)) case _ => fail("Expected to get active power only.") } nextDataTick shouldBe None diff --git a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala index bbc66667e9..36ad06427c 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala @@ -92,10 +92,10 @@ class SampleWeatherSourceSpec actual.windVel.unit shouldBe MetersPerSecond /* Values meet expectations */ - equalWithTolerance(actual.diffIrr, WattsPerSquareMeter(72.7656)) - equalWithTolerance(actual.dirIrr, WattsPerSquareMeter(80.1172)) - equalWithTolerance(actual.windVel, MetersPerSecond(11.11602)) - equalWithTolerance(actual.temp, Celsius(6.459)) + actual.diffIrr should approximate(WattsPerSquareMeter(72.7656)) + actual.dirIrr should approximate(WattsPerSquareMeter(80.1172)) + actual.windVel should approximate(MetersPerSecond(11.11602)) + actual.temp should approximate(Celsius(6.459)) } @@ -106,17 +106,16 @@ class SampleWeatherSourceSpec source.getWeather(tick, weightedCoordinates) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => diffIrr.unit shouldBe WattsPerSquareMeter - equalWithTolerance(diffIrr, WattsPerSquareMeter(72.7656)) + diffIrr should approximate(WattsPerSquareMeter(72.7656)) dirIrr.unit shouldBe WattsPerSquareMeter - equalWithTolerance(dirIrr, WattsPerSquareMeter(80.1172)) + dirIrr should approximate(WattsPerSquareMeter(80.1172)) temp.unit shouldBe Celsius - equalWithTolerance(temp, Celsius(6.459d)) + temp should approximate(Celsius(6.459d)) windVel.unit shouldBe MetersPerSecond - equalWithTolerance(windVel, MetersPerSecond(11.11602d)) - + windVel should approximate(MetersPerSecond(11.11602d)) } } } diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala index 1c1788bad8..a6fe3b9dab 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala @@ -78,10 +78,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 + 13 - equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 4)) - equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 4)) - equalWithTolerance(result.temp, Celsius(sumOfAll / 4)) - equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 4)) + result.dirIrr should approximate(WattsPerSquareMeter(sumOfAll / 4)) + result.diffIrr should approximate(WattsPerSquareMeter(sumOfAll / 4)) + result.temp should approximate(Celsius(sumOfAll / 4)) + result.windVel should approximate(MetersPerSecond(sumOfAll / 4)) } @@ -96,10 +96,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 + 13 - equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 4)) - equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 4)) - equalWithTolerance(result.temp, Celsius((1 + 1 + 1) / 3)) - equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 4)) + result.dirIrr should approximate(WattsPerSquareMeter(sumOfAll / 4)) + result.diffIrr should approximate(WattsPerSquareMeter(sumOfAll / 4)) + result.temp should approximate(Celsius((1 + 1 + 1) / 3)) + result.windVel should approximate(MetersPerSecond(sumOfAll / 4)) } "Calculate the correct weighted value for 4 coordinates with 0.25 weight each, where one is empty" in { @@ -113,20 +113,20 @@ class WeatherSourceWrapperSpec extends UnitSpec { ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) val sumOfAll = 1 + 1 + 1 - equalWithTolerance(result.dirIrr, WattsPerSquareMeter(sumOfAll / 3)) - equalWithTolerance(result.diffIrr, WattsPerSquareMeter(sumOfAll / 3)) - equalWithTolerance(result.temp, Celsius(sumOfAll / 3)) - equalWithTolerance(result.windVel, MetersPerSecond(sumOfAll / 3)) + result.dirIrr should approximate(WattsPerSquareMeter(sumOfAll / 3)) + result.diffIrr should approximate(WattsPerSquareMeter(sumOfAll / 3)) + result.temp should approximate(Celsius(sumOfAll / 3)) + result.windVel should approximate(MetersPerSecond(sumOfAll / 3)) } "calculate the correct weighted value for 1 coordinate with a weight of 1" in { val weightedCoordinates = WeightedCoordinates(Map(coordinate13 -> 1d)) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) - equalWithTolerance(result.dirIrr, WattsPerSquareMeter(13d)) - equalWithTolerance(result.diffIrr, WattsPerSquareMeter(13d)) - equalWithTolerance(result.temp, Celsius(13d)) - equalWithTolerance(result.windVel, MetersPerSecond(13d)) + result.dirIrr should approximate(WattsPerSquareMeter(13d)) + result.diffIrr should approximate(WattsPerSquareMeter(13d)) + result.temp should approximate(Celsius(13d)) + result.windVel should approximate(MetersPerSecond(13d)) } "return temperature quantity on absolute scale" in { @@ -169,10 +169,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weightedWeather) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => - equalWithTolerance(diffIrr, WattsPerSquareMeter(19.83)) - equalWithTolerance(dirIrr, WattsPerSquareMeter(3.01)) - equalWithTolerance(temp, Kelvin(290.75)) - equalWithTolerance(windVel, MetersPerSecond(10.6)) + diffIrr should approximate(WattsPerSquareMeter(19.83)) + dirIrr should approximate(WattsPerSquareMeter(3.01)) + temp should approximate(Kelvin(290.75)) + windVel should approximate(MetersPerSecond(10.6)) } } } @@ -219,7 +219,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weightedWeather) match { case WeatherData(_, _, temp, _) => - equalWithTolerance(temp, Kelvin(290d)) + temp should approximate(Kelvin(290d)) } } @@ -234,10 +234,10 @@ class WeatherSourceWrapperSpec extends UnitSpec { weightSum.scale(weatherData) match { case WeatherData(diffIrr, dirIrr, temp, windVel) => - equalWithTolerance(diffIrr, WattsPerSquareMeter(4.0)) - equalWithTolerance(dirIrr, WattsPerSquareMeter(2.0)) - equalWithTolerance(temp, Kelvin(1.25d)) - equalWithTolerance(windVel, MetersPerSecond(1.0d)) + diffIrr should approximate(WattsPerSquareMeter(4.0)) + dirIrr should approximate(WattsPerSquareMeter(2.0)) + temp should approximate(Kelvin(1.25d)) + windVel should approximate(MetersPerSecond(1.0d)) } } } diff --git a/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala index 6f1ea53813..1fdeb01349 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala @@ -6,22 +6,20 @@ package edu.ie3.simona.test.matchers -import edu.ie3.simona.exceptions.QuantityException +import org.scalatest.matchers.{MatchResult, Matcher} import squants.Quantity /** Trait, to simplify test coding, that is reliant on squants */ trait SquantsMatchers { - def equalWithTolerance[T <: Quantity[T]](actual: T, expected: T)(implicit - tolerance: T - ): Boolean = { - val bool = actual =~ expected - - if (!bool) { - throw new QuantityException( - s"The actual quantity $actual and the expected quantity $expected differ more than $tolerance in value" - ) - } - bool + class SquantsMatcher[Q <: Quantity[Q]](right: Q, implicit val tolerance: Q) + extends Matcher[Quantity[Q]] { + override def apply(left: Quantity[Q]): MatchResult = MatchResult( + left =~ right, + s"The quantities $left and $right differ more than $tolerance in value", + s"The quantities $left and $right differ less than $tolerance in value" + ) } + def approximate[Q <: Quantity[Q]](right: Q)(implicit tolerance: Q) = + new SquantsMatcher(right, tolerance) } diff --git a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala index d727df6beb..88707805a6 100644 --- a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala @@ -75,7 +75,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { QuantityUtil invokePrivate endingValue(values, 2L) match { case (tick, value) => tick shouldBe 2L - equalWithTolerance(value, unit(5d)) + value should approximate(unit(5d)) } } } @@ -91,13 +91,11 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { ) forAll(cases) { (windowStart, windowEnd, expectedResult) => - val actualResult = QuantityUtil.integrate[Power, Energy]( + QuantityUtil.integrate[Power, Energy]( values, windowStart, windowEnd - ) - - equalWithTolerance(actualResult, expectedResult) + ) approx expectedResult } } } @@ -159,7 +157,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { windowEnd ) match { case Success(result) => - equalWithTolerance(result, expectedResult) + result should approximate(expectedResult) case Failure(exception) => fail( "Averaging with fine input should pass, but failed.", From 8ebc060a49ffe0df8a95b51ca1804ddd780f3354 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 13:38:21 +0100 Subject: [PATCH 183/305] Tiny cleanup --- src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala index 88707805a6..55755258c0 100644 --- a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala @@ -8,7 +8,6 @@ package edu.ie3.util.quantities import edu.ie3.simona.exceptions.QuantityException import edu.ie3.simona.test.common.UnitSpec -import edu.ie3.simona.test.matchers.SquantsMatchers import edu.ie3.util.scala.quantities.QuantityUtil import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.{Kilojoules, Kilowatts, WattHours, Watts} @@ -95,7 +94,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { values, windowStart, windowEnd - ) approx expectedResult + ) =~ expectedResult } } } From 3f873aa6d58d70ab33beea4ed7d0cc31d9fe560d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Fri, 2 Feb 2024 17:29:11 +0100 Subject: [PATCH 184/305] import cleanup --- .../agent/participant/EvcsAgentModelCalculationSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 6565f666a5..e9617c1550 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -62,7 +62,7 @@ import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.testkit.{TestFSMRef, TestProbe} import squants.energy._ -import squants.{Each, Energy, Power, energy} +import squants.{Each, Energy, Power} import java.time.ZonedDateTime import java.util.UUID @@ -1255,7 +1255,7 @@ class EvcsAgentModelCalculationSpec modelUuid shouldBe evcsInputModelQv.getUuid refPower should approximate(Kilowatts(0.0)) minPower should approximate(Kilowatts(0.0)) - (maxPower ~= Kilowatts(0.0)) + maxPower should approximate(Kilowatts(0.0)) } resultListener.expectMsgPF() { case FlexOptionsResultEvent(flexResult) => From df313384a43f77a58c56657fade6b3a314d41520 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Mon, 5 Feb 2024 14:00:12 +0100 Subject: [PATCH 185/305] Solving some compiler warnings. --- CHANGELOG.md | 1 + .../edu/ie3/simona/config/ArgsParser.scala | 46 +++--- .../io/result/ResultEntityCsvSink.scala | 26 ++-- .../model/grid/Transformer3wModel.scala | 10 +- .../simona/model/grid/TransformerModel.scala | 4 +- .../model/grid/TransformerTappingModel.scala | 3 +- .../simona/model/participant/ChpModel.scala | 1 + .../load/random/RandomLoadParamStore.scala | 7 +- .../service/weather/SampleWeatherSource.scala | 3 +- .../service/weather/WeatherSource.scala | 147 +++++++++--------- .../edu/ie3/util/scala/DoubleUtils.scala | 17 -- .../edu/ie3/util/scala/ReflectionTools.scala | 11 +- .../scala/quantities/ScalaNumberSystem.scala | 4 - .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 4 + .../HpAgentModelCalculationSpec.scala | 4 +- .../model/grid/TransformerModelSpec.scala | 7 - .../model/participant/HpModelSpec.scala | 2 + .../model/participant/HpModelTestData.scala | 2 +- .../primary/PrimaryServiceProxySqlIT.scala | 3 +- .../primary/PrimaryServiceWorkerSqlIT.scala | 3 +- 20 files changed, 142 insertions(+), 163 deletions(-) delete mode 100644 src/main/scala/edu/ie3/util/scala/DoubleUtils.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a4879970..3ea6909c12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed PV Model documentation [#684](https://github.com/ie3-institute/simona/issues/684), [#686](https://github.com/ie3-institute/simona/issues/686) - Removed `CsvDataSourceAdapter` workaround [#702](https://github.com/ie3-institute/simona/issues/702) - Logging wrong duration in the first simulation hour [#705](https://github.com/ie3-institute/simona/issues/705) +- Fixed some compiler warnings [#657](https://github.com/ie3-institute/simona/issues/657) ## [3.0.0] - 2023-08-07 diff --git a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala index 502564d5d6..132b2f4c50 100644 --- a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala +++ b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala @@ -169,32 +169,28 @@ object ArgsParser extends LazyLogging { def parseListenerConfigOption( listenerConfigOption: Option[List[SimonaConfig.Simona.Event.Listener$Elm]] ): Map[SimonaListenerCompanion, Option[List[String]]] = { - val clusterSingletonsWithEvents - : Map[SimonaListenerCompanion, Option[List[String]]] = - listenerConfigOption match { - case Some(listenerElems) => - listenerElems.foldLeft( - Map.empty[SimonaListenerCompanion, Option[List[String]]] - )((listenerMap, listenerElem) => - ReflectionTools - .resolveClassNameToCompanion(listenerElem.fullClassPath) match { - case Some(listener: SimonaListenerCompanion) => - listenerMap + (listener -> listenerElem.eventsToProcess) - case nonListenerCompanion => - logger.warn( - s"Invalid value ${nonListenerCompanion.getClass} for 'event.listener' config parameter!" - ) - listenerMap - } - ) - case None => - logger.info( - "No listener assigned in configuration value 'event.listener'. No event are going to be processed!" - ) + listenerConfigOption match { + case Some(listenerElems) => + listenerElems.foldLeft( Map.empty[SimonaListenerCompanion, Option[List[String]]] - } - - clusterSingletonsWithEvents + )((listenerMap, listenerElem) => + ReflectionTools + .resolveClassNameToCompanion(listenerElem.fullClassPath) match { + case Some(listener: SimonaListenerCompanion) => + listenerMap + (listener -> listenerElem.eventsToProcess) + case nonListenerCompanion => + logger.warn( + s"Invalid value ${nonListenerCompanion.getClass} for 'event.listener' config parameter!" + ) + listenerMap + } + ) + case None => + logger.info( + "No listener assigned in configuration value 'event.listener'. No event are going to be processed!" + ) + Map.empty[SimonaListenerCompanion, Option[List[String]]] + } } /** Prepare the config by parsing the provided program arguments diff --git a/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala b/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala index 304dfde6a6..0b41aebbe0 100644 --- a/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala +++ b/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala @@ -17,6 +17,7 @@ import edu.ie3.util.io.FileIOUtils import java.io.{BufferedWriter, File, FileWriter, Writer} import java.lang +import java.nio.file.Path import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration.DurationInt import scala.concurrent.{Await, Future} @@ -85,7 +86,7 @@ final case class ResultEntityCsvSink private ( } } - /** Creat the initial the .csv-file and write the header in the first row + /** Create the initial the .csv-file and write the header in the first row * * @return * a future with information on the I/O operation @@ -109,17 +110,20 @@ final case class ResultEntityCsvSink private ( ) ) - FileIOUtils.gzip(outfileName).asScala.andThen { - case Success(_) => - logger.debug(logPrefix(s"Compressed $outfileName.")) - FileIOUtils.deleteFileIfExists(outFileName).asScala - case Failure(_) => - Future.failed[IOResult]( - new ProcessResultEventException( - s"Failed to zip file $outFileName!" + FileIOUtils + .compressFile(Path.of(outFileName), Path.of(outFileName + ".gz")) + .asScala + .andThen { + case Success(_) => + logger.debug(logPrefix(s"Compressed $outfileName.")) + FileIOUtils.deleteFileIfExists(outFileName).asScala + case Failure(_) => + Future.failed[IOResult]( + new ProcessResultEventException( + s"Failed to zip file $outFileName!" + ) ) - ) - } + } } /** Contains all cleanup operations before closing this sink diff --git a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala index 42f365a630..25e1ffeca4 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala @@ -246,15 +246,15 @@ case object Transformer3wModel extends LazyLogging { BigDecimal.apply("1").setScale(5, RoundingMode.HALF_UP) case PowerFlowCaseB => BigDecimal - .apply(trafo3wType.getvRatedA.to(KILOVOLT).getValue.doubleValue) + .apply(trafo3wType.getvRatedA.to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) / BigDecimal - .apply(trafo3wType.getvRatedB.to(KILOVOLT).getValue.doubleValue) + .apply(trafo3wType.getvRatedB.to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) case PowerFlowCaseC => BigDecimal - .apply(trafo3wType.getvRatedA.to(KILOVOLT).getValue.doubleValue) + .apply(trafo3wType.getvRatedA.to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) / BigDecimal - .apply(trafo3wType.getvRatedC.to(KILOVOLT).getValue.doubleValue) + .apply(trafo3wType.getvRatedC.to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) } @@ -503,7 +503,7 @@ case object Transformer3wModel extends LazyLogging { transformerModel.powerFlowCase match { case Transformer3wPowerFlowCase.PowerFlowCaseA => BigDecimal - .apply(transformerModel.tapRatio) + .apply(transformerModel.tapRatio.toString) .setScale(5, RoundingMode.HALF_UP) case Transformer3wPowerFlowCase.PowerFlowCaseB | Transformer3wPowerFlowCase.PowerFlowCaseC => diff --git a/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala b/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala index e7f7abf08f..a34e2f3abc 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala @@ -131,9 +131,9 @@ case object TransformerModel { // get referenced electric values val trafoType = transformerInput.getType val voltRatioNominal = BigDecimal - .apply(trafoType.getvRatedA().to(KILOVOLT).getValue.doubleValue) + .apply(trafoType.getvRatedA().to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) / BigDecimal - .apply(trafoType.getvRatedB().to(KILOVOLT).getValue.doubleValue) + .apply(trafoType.getvRatedB().to(KILOVOLT).getValue.toString) .setScale(5, RoundingMode.HALF_UP) val squaredNominalVoltRatio = voltRatioNominal * voltRatioNominal diff --git a/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala b/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala index a40e4a5568..a04b3548e2 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala @@ -96,8 +96,7 @@ final case class TransformerTappingModel( s"Provided tap pos $newTapPos is not between allowed tapping range of tapMin: $tapMin and tapMax: $tapMax!" ) _currentTapPos = newTapPos - val tapRatio: Double = 1 + (_currentTapPos - tapNeutr) * deltaVval - tapRatio + 1 + (_currentTapPos - tapNeutr) * deltaVval } /** Determine the amount of tap positions to increase oder decrease in order diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 5b5baa8924..8d0fdd8bca 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -10,6 +10,7 @@ import edu.ie3.datamodel.models.input.system.ChpInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.participant.ChpModel._ import edu.ie3.simona.model.participant.control.QControl +import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.{MutableStorage, ThermalStorage} import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala index 44f481eafe..c83620ef84 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala @@ -73,6 +73,11 @@ case object RandomLoadParamStore extends LazyLogging { def apply(reader: Reader): RandomLoadParamStore = new RandomLoadParamStore(reader) + /** Returns a [[CSVFormat]] with the first line as its header + */ + private def csvParser: CSVFormat = + CSVFormat.DEFAULT.builder().setHeader().setSkipHeaderRecord(true).build() + /** Initializes all type day values by receiving values from provided reader. * * @param reader @@ -81,7 +86,7 @@ case object RandomLoadParamStore extends LazyLogging { def initializeDayTypeValues( reader: Reader ): Map[DayType.Value, TypeDayParameters] = { - val parser = CSVFormat.DEFAULT.withFirstRecordAsHeader.parse(reader) + val parser = csvParser.parse(reader) /* records list is an ArrayList */ val records = parser.getRecords diff --git a/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala b/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala index d8bf55443f..06c62354ba 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala @@ -75,7 +75,7 @@ final class SampleWeatherSource( ) 2011 else wallClockTime.get(YEAR) val index = (((year - 2011) * 288) + (month * 24) + hour) + 1 - val weatherResult = WeatherData( + WeatherData( WattsPerSquareMeter( SampleWeatherSource .diffuseRadiation(index) @@ -99,7 +99,6 @@ final class SampleWeatherSource( .doubleValue ) ) - weatherResult } /** Determine an Array with all ticks between the request frame's start and diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala index eb7262560c..e054b01715 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala @@ -352,81 +352,78 @@ object WeatherSource { s"Multiple weather sources defined: '${definedWeatherSources.map(_.getClass.getSimpleName).mkString("\n\t")}'." + s"Please define only one source!\nAvailable sources:\n\t${supportedWeatherSources.mkString("\n\t")}" ) - val weatherSourceFunction: ZonedDateTime => WeatherSource = - definedWeatherSources.headOption match { - case Some( - Some(baseCsvParams @ BaseCsvParams(csvSep, directoryPath, _)) - ) => - checkBaseCsvParams(baseCsvParams, "WeatherSource") - (simulationStart: ZonedDateTime) => - WeatherSourceWrapper( - csvSep, - Paths.get(directoryPath), - coordinateSourceFunction, - timestampPattern, - scheme, - resolution, - distance - )(simulationStart) - case Some(Some(params: CouchbaseParams)) => - checkCouchbaseParams(params) - (simulationStart: ZonedDateTime) => - WeatherSourceWrapper( - params, - coordinateSourceFunction, - timestampPattern, - scheme, - resolution, - distance - )(simulationStart) - case Some(Some(params @ InfluxDb1xParams(database, _, url))) => - checkInfluxDb1xParams("WeatherSource", url, database) - (simulationStart: ZonedDateTime) => - WeatherSourceWrapper( - params, - coordinateSourceFunction, - timestampPattern, - scheme, - resolution, - distance - )(simulationStart) - case Some(Some(params: SqlParams)) => - checkSqlParams(params) - (simulationStart: ZonedDateTime) => - WeatherSourceWrapper( - params, - coordinateSourceFunction, - timestampPattern, - scheme, - resolution, - distance - )(simulationStart) - case Some(Some(_: SampleParams)) => - // sample weather, no check required - // coordinate source must be sample coordinate source - // calling the function here is not an issue as the sample coordinate source is already - // an object (= no overhead costs) - coordinateSourceFunction() match { - case _: SampleWeatherSource.SampleIdCoordinateSource.type => - // all fine - (simulationStart: ZonedDateTime) => - new SampleWeatherSource()(simulationStart) - case coordinateSource => - // cannot use sample weather source with other combination of weather source than sample weather source - throw new InvalidConfigParameterException( - s"Invalid coordinate source " + - s"'${coordinateSource.getClass.getSimpleName}' defined for SampleWeatherSource. " + - "Please adapt the configuration to use sample coordinate source for weather data!" - ) - } - case None | Some(_) => - throw new InvalidConfigParameterException( - s"No weather source defined! This is currently not supported! Please provide the config parameters for one " + - s"of the following weather sources:\n\t${supportedWeatherSources.mkString("\n\t")}" - ) - } - - weatherSourceFunction + definedWeatherSources.headOption match { + case Some( + Some(baseCsvParams @ BaseCsvParams(csvSep, directoryPath, _)) + ) => + checkBaseCsvParams(baseCsvParams, "WeatherSource") + (simulationStart: ZonedDateTime) => + WeatherSourceWrapper( + csvSep, + Paths.get(directoryPath), + coordinateSourceFunction, + timestampPattern, + scheme, + resolution, + distance + )(simulationStart) + case Some(Some(params: CouchbaseParams)) => + checkCouchbaseParams(params) + (simulationStart: ZonedDateTime) => + WeatherSourceWrapper( + params, + coordinateSourceFunction, + timestampPattern, + scheme, + resolution, + distance + )(simulationStart) + case Some(Some(params @ InfluxDb1xParams(database, _, url))) => + checkInfluxDb1xParams("WeatherSource", url, database) + (simulationStart: ZonedDateTime) => + WeatherSourceWrapper( + params, + coordinateSourceFunction, + timestampPattern, + scheme, + resolution, + distance + )(simulationStart) + case Some(Some(params: SqlParams)) => + checkSqlParams(params) + (simulationStart: ZonedDateTime) => + WeatherSourceWrapper( + params, + coordinateSourceFunction, + timestampPattern, + scheme, + resolution, + distance + )(simulationStart) + case Some(Some(_: SampleParams)) => + // sample weather, no check required + // coordinate source must be sample coordinate source + // calling the function here is not an issue as the sample coordinate source is already + // an object (= no overhead costs) + coordinateSourceFunction() match { + case _: SampleWeatherSource.SampleIdCoordinateSource.type => + // all fine + (simulationStart: ZonedDateTime) => + new SampleWeatherSource()(simulationStart) + case coordinateSource => + // cannot use sample weather source with other combination of weather source than sample weather source + throw new InvalidConfigParameterException( + s"Invalid coordinate source " + + s"'${coordinateSource.getClass.getSimpleName}' defined for SampleWeatherSource. " + + "Please adapt the configuration to use sample coordinate source for weather data!" + ) + } + case None | Some(_) => + throw new InvalidConfigParameterException( + s"No weather source defined! This is currently not supported! Please provide the config parameters for one " + + s"of the following weather sources:\n\t${supportedWeatherSources.mkString("\n\t")}" + ) + } } /** Check the provided coordinate id data source configuration to ensure its diff --git a/src/main/scala/edu/ie3/util/scala/DoubleUtils.scala b/src/main/scala/edu/ie3/util/scala/DoubleUtils.scala deleted file mode 100644 index 67bc7cf7cf..0000000000 --- a/src/main/scala/edu/ie3/util/scala/DoubleUtils.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.util.scala - -@deprecated("Use implementation in power system utils package") -object DoubleUtils { - implicit class ImplicitDouble(d: Double) { - def ~=(other: Double)(implicit precision: Double): Boolean = - (d - other).abs <= precision - def !~=(other: Double)(implicit precision: Double): Boolean = - (d - other).abs > precision - } -} diff --git a/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala b/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala index d37280e16d..e29a537bea 100644 --- a/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala +++ b/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala @@ -17,11 +17,9 @@ import scala.util.Try object ReflectionTools { def identifyValidCompanions(classNames: Iterable[String]): Iterable[Any] = { - val validCompanionObjects = - classNames.flatMap(name => resolveClassNameToCompanion(name)).collect { - case companion: Any => companion - } - validCompanionObjects + classNames.flatMap(name => resolveClassNameToCompanion(name)).collect { + case companion: Any => companion + } } def resolveClassNameToCompanion(className: String): Option[Any] = { @@ -33,10 +31,9 @@ object ReflectionTools { ) ) val mirror = universe.runtimeMirror(getClass.getClassLoader) - val companionObj = Try( + Try( mirror.reflectModule(mirror.moduleSymbol(clazz)).instance ).toOption - companionObj } /** Determine the field and their value of the provided object instance diff --git a/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala b/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala index 8b4f5e1eb3..7440920287 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala @@ -84,8 +84,4 @@ final class ScalaNumberSystem extends DefaultNumberSystem { override def isLessThanOne(number: Number): Boolean = number.doubleValue < 1d - - override def isInteger(number: Number): Boolean = - super.isInteger(number) - } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index ca8687a44b..41fefc20d6 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -183,6 +183,8 @@ class DBFSAlgorithmSupGridSpec case Some(value) => value.getvMag().getValue shouldBe 1 value.getvAng().getValue shouldBe 0 + case None => + fail(s"Expected a result but got none.") } // due to the fact that the used grid does not contain anything besides the one ehv node @@ -300,6 +302,8 @@ class DBFSAlgorithmSupGridSpec case Some(value) => value.getvMag().getValue shouldBe 1 value.getvAng().getValue shouldBe 0 + case None => + fail(s"Expected a result but got none.") } // due to the fact that the used grid does not contain anything besides the one ehv node diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index cbffc3bb7a..aa24db2385 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -503,7 +503,7 @@ class HpAgentModelCalculationSpec currentTimeTick shouldBe 0L ambientTemperature should approximate(Celsius(1.815d)) - case None => + case _ => fail("Did expect to get hp relevant data for tick 0L") } } @@ -634,7 +634,7 @@ class HpAgentModelCalculationSpec currentTimeTick shouldBe 0L ambientTemperature should approximate(Celsius(1.815d)) - case None => + case _ => fail("Did expect to get hp relevant data for tick 0L") } } diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index 1c5fdfa093..ecaa55b2e5 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -43,13 +43,6 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { Amperes(1e-9) implicit val dimensionlessTolerance: squants.Dimensionless = Each(1e-9) - def mainRefSystem: RefSystem = { - val nominalPower = Kilowatts(400d) - val nominalVoltage = Kilovolts(0.4d) - RefSystem(nominalPower, nominalVoltage) - /* Z_Ref = 0.4 Ω, Y_Ref = 2.5 Siemens */ - } - "A valid TransformerInput " should { "be validated without an exception" in new TransformerTestData { val unmodifiedTransformerInputModel: Transformer2WInput = diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index 6a71eb998e..d9130b9291 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -182,6 +182,8 @@ class HpModelSpec expectedInnerTemperature ) ) + case unexpected => + fail(s"Expected a hp state but got none $unexpected.") } } } diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala index 464e8f9653..f2510830ab 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala @@ -123,7 +123,7 @@ trait HpModelTestData { "thermal storage", OperatorInput.NO_OPERATOR_ASSIGNED, OperationTime.notLimited(), - null, + thermalBus, KilowattHours(20d), KilowattHours(500d), Kilowatts(10d), diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala index 99418e035f..e805b99f02 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala @@ -32,6 +32,7 @@ import edu.ie3.simona.test.helper.TestContainerHelper import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil import org.scalatest.BeforeAndAfterAll +import org.testcontainers.utility.DockerImageName import java.util.UUID @@ -51,7 +52,7 @@ class PrimaryServiceProxySqlIT with TestSpawnerClassic { override val container: PostgreSQLContainer = PostgreSQLContainer( - "postgres:14.2" + DockerImageName.parse("postgres:14.2") ) private val simulationStart = diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala index 8d0c4a9299..c21fb2d596 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala @@ -39,6 +39,7 @@ import edu.ie3.util.TimeUtil import edu.ie3.util.scala.quantities.Kilovars import org.scalatest.BeforeAndAfterAll import org.scalatest.prop.TableDrivenPropertyChecks +import org.testcontainers.utility.DockerImageName import squants.energy.Kilowatts import java.util.UUID @@ -61,7 +62,7 @@ class PrimaryServiceWorkerSqlIT with TestSpawnerClassic { override val container: PostgreSQLContainer = PostgreSQLContainer( - "postgres:14.2" + DockerImageName.parse("postgres:14.2") ) private val simulationStart = From b714cc8ba4d6462279210aa9c2fe0c235959a762 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 6 Feb 2024 10:58:15 +0100 Subject: [PATCH 186/305] Unused import --- src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 8d0fdd8bca..5b5baa8924 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -10,7 +10,6 @@ import edu.ie3.datamodel.models.input.system.ChpInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.model.participant.ChpModel._ import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.{MutableStorage, ThermalStorage} import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval From 35bb28198224a5b9f7fe680bb8f5da65d373feba Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 11:08:39 +0100 Subject: [PATCH 187/305] Reinstating broken test --- .../model/participant/load/RandomLoadModelTest.groovy | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index c7d7e4e48f..d1a47fae37 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -34,8 +34,7 @@ import java.time.temporal.ChronoUnit import java.util.stream.Collectors class RandomLoadModelTest extends Specification { - def loadInput = - new LoadInput( + def loadInput = new LoadInput( UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), "testLoad", OperatorInput.NO_OPERATOR_ASSIGNED, @@ -140,12 +139,14 @@ class RandomLoadModelTest extends Specification { startDate.plus(cnt * 15, ChronoUnit.MINUTES)) }).collect(Collectors.toSet()) - and: + when: def avgEnergy = (0..10).parallelStream().mapToDouble( { runCnt -> relevantDatas.parallelStream().mapToDouble( { relevantData -> (dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() }).sum() }).average().orElse(0d) - avgEnergy + + then: + abs(avgEnergy - 3000) / 3000 < 0.01 } } From dd494a9619023f223a0a7729143a3a61d963fa29 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 12:37:05 +0100 Subject: [PATCH 188/305] Removing duplicate test --- .../load/ProfileLoadModelTest.groovy | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy index 757888884d..b4b3e88ec0 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy @@ -33,8 +33,6 @@ import tech.units.indriya.quantity.Quantities import java.time.temporal.ChronoUnit import java.util.stream.Collectors - - class ProfileLoadModelTest extends Specification { def loadInput = new LoadInput( @@ -71,27 +69,6 @@ class ProfileLoadModelTest extends Specification { ) def wattTolerance = 1 // Equals to 1 W power - def "A profile load model should be instantiated from valid input correctly"() { - when: - def actual = ProfileLoadModel.apply( - loadInput.copy().loadprofile(profile).build(), - foreSeenOperationInterval, - 1.0, - reference) - - then: - abs((actual.sRated().toWatts() * actual.cosPhiRated()).toDouble() - expectedsRated.doubleValue()) < wattTolerance - - where: - profile | reference || expectedsRated - H0 | new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) || 268.6d - H0 | new EnergyConsumption(Sq.create(3000d, KilowattHours$.MODULE$)) || 805.8089d - L0 | new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) || 268.6d - L0 | new EnergyConsumption(Sq.create(3000d, KilowattHours$.MODULE$)) || 721.2d - G0 | new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) || 268.6d - G0 | new EnergyConsumption(Sq.create(3000d, KilowattHours$.MODULE$)) || 721.2d - } - def "A profile load model should reach the targeted maximum power within a year"() { given: def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") From cfe030df327abd0820523b1973fb93b71254daf3 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 12:37:34 +0100 Subject: [PATCH 189/305] Better value testing --- .../model/participant/load/ProfileLoadModelSpec.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index 1dc66e57e5..948ec4ce80 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -29,7 +29,9 @@ import tech.units.indriya.quantity.Quantities import java.util.UUID class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { - implicit val tolerance: Power = Watts(1d) + + private implicit val tolerance: Power = Watts(1d) + "Having a profile load model" when { val loadInput = new LoadInput( @@ -117,7 +119,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { reference ) - (actual.sRated =~ expectedSRated) shouldBe true + actual.sRated should approximate(expectedSRated) } } } From 5b3af586e46785114248acd23e5d58a230f74d9b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 12:47:14 +0100 Subject: [PATCH 190/305] Removing duplicate tests --- .../load/RandomLoadModelTest.groovy | 56 ------------------- .../load/RandomLoadModelSpec.scala | 2 +- 2 files changed, 1 insertion(+), 57 deletions(-) diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy index d1a47fae37..d3cf2f5e20 100644 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy @@ -7,7 +7,6 @@ package edu.ie3.simona.model.participant.load import static edu.ie3.datamodel.models.profile.BdewStandardLoadProfile.H0 -import static edu.ie3.simona.model.participant.load.LoadReference.ActivePower import static edu.ie3.simona.model.participant.load.LoadReference.EnergyConsumption import static edu.ie3.util.quantities.PowerSystemUnits.* import static org.apache.commons.math3.util.FastMath.abs @@ -21,7 +20,6 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.random.RandomLoadModel -import edu.ie3.simona.model.participant.load.random.RandomLoadParameters import edu.ie3.util.TimeUtil import squants.energy.* import spock.lang.Specification @@ -66,60 +64,6 @@ class RandomLoadModelTest extends Specification { simulationEndDate, loadInput.operationTime ) - def testingTolerance = 1e-6 // Equals to 1 W power - - def "A random load model should be instantiated from valid input correctly"() { - when: - def actual = RandomLoadModel.apply( - loadInput, - foreSeenOperationInterval, - 1.0, - reference - ) - - then: - abs(actual.sRated().toWatts().doubleValue() - (expSRated.value().doubleValue())) < testingTolerance - - where: - reference || expSRated - new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) || Sq.create(311.0105263157895d, Watts$.MODULE$) - new EnergyConsumption(Sq.create(2000d, KilowattHours$.MODULE$)) || Sq.create(513.8717370343667d, Watts$.MODULE$) - } - - def "A random load model is able to deliver the correct distribution on request"() { - given: - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - Sq.create(loadInput.sRated.to(KILOWATT).value.doubleValue(), Kilowatts$.MODULE$), - loadInput.cosPhiRated, - new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) - ) - /* Working day, 61th quarter hour */ - def queryDate = TimeUtil.withDefaults.toZonedDateTime('2019-07-19 15:21:00') - def expectedParams = new RandomLoadParameters(0.405802458524704, 0.0671483352780342, 0.0417016632854939) - - when: - /* First query leeds to generation of distribution */ - def firstHit = dut.getGevDistribution(queryDate) - - then: - firstHit.with { - assert k == expectedParams.k() - assert mu == expectedParams.my() - assert sigma == expectedParams.sigma() - } - - when: - /* Second query is only look up in storage */ - def secondHit = dut.getGevDistribution(queryDate) - - then: - secondHit == firstHit - } def "A random load model should approx. reach the targeted annual energy consumption"() { given: diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 641c4658a5..f2fd1117d7 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -110,7 +110,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue() ), loadInput.getCosPhiRated, - new ActivePower(Watts(268.6)) + ActivePower(Watts(268.6)) ) /* Working day, 61th quarter hour */ val queryDate = From e5b457d5856c43138f5693af076abfd44117e55d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 13:48:54 +0100 Subject: [PATCH 191/305] Fixing test --- .../load/LoadModelScalingSpec.scala | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 818c48d89f..27602628a7 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.model.participant.load -import breeze.numerics.abs import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed @@ -38,7 +37,6 @@ import java.time.temporal.ChronoUnit import java.util.UUID class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { - implicit val tolerance: Dimensionless = Each(1e-10) "Testing correct scaling of load models" when { val simulationStartDate = @@ -78,8 +76,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profileLoadInput.getOperationTime ) - val targetEnergyConsumption = - KilowattHours(3000d) + val targetEnergyConsumption = KilowattHours(3000d) + "reach the targeted annual energy consumption" in { /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % @@ -117,7 +115,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, targetEnergyConsumption - ) =~ Percent(2d) + ) should be < Percent(2d) } } @@ -149,12 +147,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, expectedEnergy - ) =~ Percent(2d) + ) should be < Percent(2d) } val targetMaximumPower = Watts(268.6) "approximately reach the maximum power" in { implicit val tolerance: Power = Watts(1d) + forAll( Table( "profile", @@ -187,7 +186,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut ).maxOption match { case Some(maximumPower) => - maximumPower =~ targetMaximumPower + maximumPower should approximate(targetMaximumPower) case None => fail("Unable to determine maximum power.") } } @@ -197,7 +196,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val scalingFactor = 1.5 val expectedMaximum = Watts(402.0044899478780) - implicit val tolerance: Power = Watts(1d) + val dut = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, @@ -222,7 +221,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut ).maxOption match { case Some(maximumPower) => - maximumPower =~ expectedMaximum + maximumPower should be < expectedMaximum case None => fail("Unable to determine maximum power.") } @@ -286,7 +285,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, targetEnergyConsumption - ) =~ Percent(1d) + ) should be < Percent(1d) } "correctly account for the scaling factor, when targeting a given annual energy consumption" in { @@ -316,7 +315,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { dut, simulationStartDate, expectedEnergy - ) =~ Percent(2d) + ) should be < Percent(2d) } val targetMaximumPower = Watts(268.6) @@ -350,14 +349,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { getRelativeResult( quantile95, targetMaximumPower - ) =~ Percent(1d) - + ) should be < Percent(1d) } "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 val expectedMaximum = targetMaximumPower * scalingFactor - implicit val tolerance: Power = Watts(1d) + implicit val tolerance: Power = Watts(10d) + val dut = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, @@ -382,7 +381,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ).sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ - RandomLoadModelSpec.get95Quantile(powers) =~ expectedMaximum + RandomLoadModelSpec.get95Quantile(powers) should approximate( + expectedMaximum + ) } } } @@ -390,11 +391,8 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { def getRelativeResult[Q <: squants.Quantity[Q]]( avgResult: Q, expectedResult: Q - ): Dimensionless = { - val result = Percent(100) - - Percent(abs(avgResult.divide(expectedResult))) - Percent(abs(result.value.doubleValue())) - } + ): Dimensionless = + Each(1) - Each(avgResult.divide(expectedResult)).abs def getRelevantData[ C <: LoadRelevantData From ef5adeec9da14d8ffa2e31338eb8db98f382e8d0 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 14:02:51 +0100 Subject: [PATCH 192/305] Removing unnecessary matchers --- .../test/matchers/QuantityMatchers.scala | 121 +----------------- .../test/matchers/QuantityMatchersSpec.scala | 58 ++------- 2 files changed, 15 insertions(+), 164 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala index c415cb7bf1..9a65564964 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala @@ -6,17 +6,12 @@ package edu.ie3.simona.test.matchers -import edu.ie3.simona.test.matchers.QuantityMatchers.{ - EqualMatcher, - GreaterMatcher, - LessMatcher -} +import edu.ie3.simona.test.matchers.QuantityMatchers.EqualMatcher import edu.ie3.util.quantities.QuantityUtil +import org.scalatest.matchers.{MatchResult, Matcher} import javax.measure.Quantity -import org.scalatest.matchers.{MatchResult, Matcher} -import tech.units.indriya.ComparableQuantity -import tech.units.indriya.quantity.Quantities + @deprecated("Use implementation in power system utils package") /** Trait, to simplify test coding, that is reliant on [[Quantity]] s */ @@ -25,16 +20,6 @@ trait QuantityMatchers { right: Quantity[Q], tolerance: Double = 1e-10 ) = new EqualMatcher(right, tolerance) - - def beLessThanWithTolerance[Q <: Quantity[Q]]( - right: ComparableQuantity[Q], - tolerance: Double = 1e-10 - ) = new LessMatcher[Q](right, tolerance) - - def beGreaterThanWithTolerance[Q <: Quantity[Q]]( - right: ComparableQuantity[Q], - tolerance: Double = 1e-10 - ) = new GreaterMatcher[Q](right, tolerance) } object QuantityMatchers { @@ -46,104 +31,4 @@ object QuantityMatchers { s"The quantities $left and $right differ less than $tolerance in value" ) } - - class LessMatcher[Q <: Quantity[Q]]( - right: ComparableQuantity[Q], - tolerance: Double - ) extends Matcher[ComparableQuantity[Q]] { - override def apply(left: ComparableQuantity[Q]): MatchResult = compare( - left, - right, - tolerance, - (right: ComparableQuantity[Q], tolerance: ComparableQuantity[Q]) => - right.add(tolerance), - (left: ComparableQuantity[Q], right: ComparableQuantity[Q]) => - left.isLessThan(right), - ( - lhs: ComparableQuantity[Q], - rhs: ComparableQuantity[Q], - toleranceQuantity: ComparableQuantity[Q] - ) => s"The quantity $lhs is not less than $rhs + $toleranceQuantity.", - ( - lhs: ComparableQuantity[Q], - rhs: ComparableQuantity[Q], - toleranceQuantity: ComparableQuantity[Q] - ) => s"The quantity $lhs is less than $rhs + $toleranceQuantity." - ) - } - - class GreaterMatcher[Q <: Quantity[Q]]( - right: ComparableQuantity[Q], - tolerance: Double - ) extends Matcher[ComparableQuantity[Q]] { - override def apply(left: ComparableQuantity[Q]): MatchResult = compare( - left, - right, - tolerance, - (right: ComparableQuantity[Q], tolerance: ComparableQuantity[Q]) => - right.subtract(tolerance), - (left: ComparableQuantity[Q], right: ComparableQuantity[Q]) => - left.isGreaterThan(right), - ( - lhs: ComparableQuantity[Q], - rhs: ComparableQuantity[Q], - toleranceQuantity: ComparableQuantity[Q] - ) => s"The quantity $lhs is not greater than $rhs - $toleranceQuantity.", - ( - lhs: ComparableQuantity[Q], - rhs: ComparableQuantity[Q], - toleranceQuantity: ComparableQuantity[Q] - ) => s"The quantity $lhs is greater than $rhs - $toleranceQuantity." - ) - } - - /** Compares two Quantities with tolerance - * - * @param left - * Left hand side of the comparison - * @param right - * Right hand side of the comparison - * @param tolerance - * Numerical tolerance to be applied to the right hand side - * @param rightWithToleranceFun - * Function, how to build the right hand side with tolerance - * @param compareFun - * Compare function (lhs, rhs) => Condition - * @param rawFailureMessage - * Failure message in case condition is not satisfied - * @param rawNegatedFailureMessage - * Failure message in case the condition is negated - * @tparam Q - * Type of [[ComparableQuantity]] to compare - * @return - * A [[MatchResult]] - */ - private def compare[Q <: Quantity[Q]]( - left: ComparableQuantity[Q], - right: ComparableQuantity[Q], - tolerance: Double, - rightWithToleranceFun: ( - ComparableQuantity[Q], - ComparableQuantity[Q] - ) => ComparableQuantity[Q], - compareFun: (ComparableQuantity[Q], ComparableQuantity[Q]) => Boolean, - rawFailureMessage: ( - ComparableQuantity[Q], - ComparableQuantity[Q], - ComparableQuantity[Q] - ) => String, - rawNegatedFailureMessage: ( - ComparableQuantity[Q], - ComparableQuantity[Q], - ComparableQuantity[Q] - ) => String - ): MatchResult = { - val toleranceQuantity = Quantities.getQuantity(tolerance, right.getUnit) - val rightWithTolerance = rightWithToleranceFun(right, toleranceQuantity) - MatchResult( - compareFun(left, rightWithTolerance), - rawFailureMessage(left, right, toleranceQuantity), - rawNegatedFailureMessage(left, right, toleranceQuantity) - ) - } } diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala index ceae05e4f9..ef1662da07 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala @@ -10,68 +10,34 @@ import edu.ie3.simona.test.common.UnitSpec import tech.units.indriya.quantity.Quantities import tech.units.indriya.unit.Units -import javax.measure.quantity.Length - class QuantityMatchersSpec extends UnitSpec { "Testing quantities with custom quantity matchers" when { - val a = Quantities.getQuantity(5d, Units.METRE) - val b = Quantities.getQuantity(6d, Units.METRE) + val quant = Quantities.getQuantity(5d, Units.METRE) val toleranceQuantity = Quantities.getQuantity(1e-10, Units.METRE) + val testTolerance = 1e-10 + "testing for equality" should { "pass if quantities are exactly the same" in { - a should equalWithTolerance(a, 1e-10) + quant should equalWithTolerance(quant, testTolerance) } "pass if quantities are approximately the same" in { - a should equalWithTolerance( - a.add(toleranceQuantity.multiply(0.9)), - 1e-10 - ) - } - - "detect mismatch on tolerance exceeding" in { - a should not( - equalWithTolerance(a.add(toleranceQuantity.multiply(1.1)), 1e-10) - ) - } - } - - "testing for less than" should { - "pass if the quantity is really less" in { - a should beLessThanWithTolerance(b, 1e-10) - } - - "pass if the quantity is less with tolerance" in { - a.add(toleranceQuantity.multiply(0.9)) should beLessThanWithTolerance( - a, - 1e-10 + quant should equalWithTolerance( + quant.add(toleranceQuantity.multiply(0.9)), + testTolerance ) } "detect mismatch on tolerance exceeding" in { - a.add(toleranceQuantity.multiply(1.1)) should not( - beLessThanWithTolerance(a, 1e-10) + quant should not( + equalWithTolerance( + quant.add(toleranceQuantity.multiply(1.1)), + testTolerance + ) ) } } - "testing for greater than" should { - "pass if the quantity is really greater" in { - b should beGreaterThanWithTolerance(a, 1e-10) - } - - "pass if the quantity is greater with tolerance" in { - a.subtract( - toleranceQuantity.multiply(0.9) - ) should beGreaterThanWithTolerance(a, 1e-10) - } - - "detect mismatch on tolerance exceeding" in { - a.subtract(toleranceQuantity.multiply(1.1)) should not( - beGreaterThanWithTolerance(a, 1e-10) - ) - } - } } } From d18838f299714905b1372a23eaaa9b0da604108c Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 14:21:37 +0100 Subject: [PATCH 193/305] Better matcher --- .../ie3/simona/model/participant/load/RandomLoadModelSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index f2fd1117d7..497812c662 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -89,7 +89,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { reference ) - (actual.sRated =~ expectedSRated) shouldBe true + actual.sRated should approximate(expectedSRated) } } } From ccc18ec26550d8851763b2772ae9db2c1b112836 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 14:44:21 +0100 Subject: [PATCH 194/305] Refactoring getRelevantData --- .../load/LoadModelScalingSpec.scala | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 27602628a7..677bf2772c 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -394,30 +394,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ): Dimensionless = Each(1) - Each(avgResult.divide(expectedResult)).abs - def getRelevantData[ - C <: LoadRelevantData - ](dut: LoadModel[C], simulationStartDate: ZonedDateTime): Map[Long, C] = { - dut match { - case _: RandomLoadModel => - (0L until 35040) - .map(tick => - tick -> RandomLoadModel.RandomRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap[Long, C] - case _: ProfileLoadModel => - (0L until 35040) - .map(tick => - tick -> ProfileLoadModel - .ProfileRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap[Long, C] - } - } - def calculateAverageEnergy[C <: LoadRelevantData]( dut: LoadModel[C], simulationStartDate: ZonedDateTime, @@ -477,4 +453,24 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } } } + + def getRelevantData[C <: LoadRelevantData]( + dut: LoadModel[C], + simulationStartDate: ZonedDateTime + ): Map[Long, C] = { + val createRelevantData: ZonedDateTime => C = dut match { + case _: RandomLoadModel => RandomLoadModel.RandomRelevantData + case _: ProfileLoadModel => ProfileLoadModel.ProfileRelevantData + } + + val quarterHoursInYear = 365L * 96L + (0L until quarterHoursInYear) + .map(tick => + tick -> createRelevantData( + simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) + ) + ) + .toMap[Long, C] + } + } From 178eb3c637dfb40c36cbd209f7261e2f194ba8e2 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 16:56:08 +0100 Subject: [PATCH 195/305] Aggregating one year is enough Refactoring and further speeding up test --- .../load/LoadModelScalingSpec.scala | 194 +++++++----------- 1 file changed, 78 insertions(+), 116 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 677bf2772c..e9c24012aa 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -20,16 +20,14 @@ import edu.ie3.simona.model.participant.load.LoadReference.{ EnergyConsumption } import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel -import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.random.RandomLoadModel -import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil import edu.ie3.util.quantities.PowerSystemUnits import org.scalatest.prop.TableDrivenPropertyChecks import squants.energy.{KilowattHours, Kilowatts, Watts} import squants.time.Minutes -import squants.{Dimensionless, Each, Energy, Percent, Power} +import squants.{Dimensionless, Each, Energy, Percent, Power, Quantity} import tech.units.indriya.quantity.Quantities import java.time.ZonedDateTime @@ -103,7 +101,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), profileLoadInput.getCosPhiRated, profile, @@ -111,7 +109,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy[ProfileRelevantData]( + calculateEnergyDiffForYear( dut, simulationStartDate, targetEnergyConsumption @@ -121,8 +119,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "correctly account for the scaling factor, when targeting a given annual energy consumption" in { val scalingFactor = 1.5 - val expectedEnergy = - KilowattHours(4500d) + val expectedEnergy = KilowattHours(4500d) val dut = ProfileLoadModel( profileLoadInput.getUuid, @@ -135,7 +132,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, @@ -143,7 +140,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculateAverageEnergy[ProfileRelevantData]( + calculateEnergyDiffForYear( dut, simulationStartDate, expectedEnergy @@ -151,6 +148,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } val targetMaximumPower = Watts(268.6) + "approximately reach the maximum power" in { implicit val tolerance: Power = Watts(1d) @@ -173,7 +171,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), profileLoadInput.getCosPhiRated, profile, @@ -181,21 +179,18 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculatePowerFromRelevantData[ProfileRelevantData]( - simulationStartDate, - dut - ).maxOption match { - case Some(maximumPower) => - maximumPower should approximate(targetMaximumPower) - case None => fail("Unable to determine maximum power.") - } + val maximumPower = calculatePowerForYear( + dut, + simulationStartDate + ).maxOption.value + + maximumPower should approximate(targetMaximumPower) } } "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 - val expectedMaximum = - Watts(402.0044899478780) + val expectedMaximum = Watts(402.0044899478780) val dut = ProfileLoadModel( profileLoadInput.getUuid, @@ -208,7 +203,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, @@ -216,15 +211,12 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ) dut.enable() - calculatePowerFromRelevantData[ProfileRelevantData]( - simulationStartDate, - dut - ).maxOption match { - case Some(maximumPower) => - maximumPower should be < expectedMaximum + val maximumPower = calculatePowerForYear( + dut, + simulationStartDate + ).maxOption.value - case None => fail("Unable to determine maximum power.") - } + maximumPower should be < expectedMaximum } } @@ -274,14 +266,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) dut.enable() - calculateAverageEnergy[RandomRelevantData]( + calculateEnergyDiffForYear( dut, simulationStartDate, targetEnergyConsumption @@ -304,14 +296,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) dut.enable() - calculateAverageEnergy[RandomRelevantData]( + calculateEnergyDiffForYear( dut, simulationStartDate, expectedEnergy @@ -331,22 +323,21 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) dut.enable() - val powers = - calculatePowerFromRelevantData[RandomRelevantData]( - simulationStartDate, - dut - ).sorted.toArray + val powers = calculatePowerForYear( + dut, + simulationStartDate + ).toIndexedSeq.sorted.toArray val quantile95 = RandomLoadModelSpec.get95Quantile(powers) - getRelativeResult( + getRelativeDifference( quantile95, targetMaximumPower ) should be < Percent(1d) @@ -355,7 +346,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 val expectedMaximum = targetMaximumPower * scalingFactor - implicit val tolerance: Power = Watts(10d) val dut = RandomLoadModel( randomLoadInput.getUuid, @@ -368,109 +358,81 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .getsRated() .to(PowerSystemUnits.KILOWATT) .getValue - .doubleValue() + .doubleValue ), randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) dut.enable() - val powers = - calculatePowerFromRelevantData[RandomRelevantData]( - simulationStartDate, - dut - ).sorted.toArray + val powers = calculatePowerForYear( + dut, + simulationStartDate + ).toIndexedSeq.sorted.toArray + /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the * target maximum power. Because of the stochastic nature, the maximum power cannot be met perfectly */ - RandomLoadModelSpec.get95Quantile(powers) should approximate( - expectedMaximum - ) + implicit val tolerance: Power = Watts(10d) + RandomLoadModelSpec.get95Quantile(powers) should + approximate(expectedMaximum) } } } - def getRelativeResult[Q <: squants.Quantity[Q]]( - avgResult: Q, - expectedResult: Q - ): Dimensionless = - Each(1) - Each(avgResult.divide(expectedResult)).abs - - def calculateAverageEnergy[C <: LoadRelevantData]( + def calculateEnergyDiffForYear[C <: LoadRelevantData]( dut: LoadModel[C], simulationStartDate: ZonedDateTime, expectedEnergy: Energy ): Dimensionless = { + val duration = Minutes(15d) - val relevantData = getRelevantData(dut, simulationStartDate) - - val totalRuns = 10 - val avgEnergy = (0 until totalRuns) - .map { _ => - relevantData - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Each(0d), - relevantData - ) - .p * Minutes(15d) - } - .fold(KilowattHours(0))( - _ + _ - ) - } - .fold(KilowattHours(0d))( - _ + _ - ) - .divide(totalRuns) + val avgEnergy = calculatePowerForYear( + dut: LoadModel[C], + simulationStartDate: ZonedDateTime + ).foldLeft(KilowattHours(0)) { case (energySum, power) => + energySum + (power * duration) + } - getRelativeResult( + getRelativeDifference( avgEnergy, expectedEnergy ) - } - def calculatePowerFromRelevantData[C <: LoadRelevantData]( - simulationStartDate: ZonedDateTime, - dut: LoadModel[C] - ): IndexedSeq[Power] = { - - val relevantData = getRelevantData(dut, simulationStartDate) - - val totalRuns = 10 - (0 until totalRuns) - .flatMap { _ => - relevantData - .map { case (tick, relevantData) => - dut - .calculatePower( - tick, - Each(0d), - relevantData - ) - .p - } + def calculatePowerForYear[C <: LoadRelevantData]( + dut: LoadModel[C], + simulationStartDate: ZonedDateTime + ): Iterable[Power] = { + val quarterHoursInYear = 365L * 96L + + (0L until quarterHoursInYear) + .map { quarterHour => + val tick = quarterHour * 15 * 60 + val relevantData = createRelevantData(dut)( + simulationStartDate.plus(quarterHour * 15, ChronoUnit.MINUTES) + ) + + dut + .calculatePower( + tick, + Each(0d), + relevantData + ) + .p } } - def getRelevantData[C <: LoadRelevantData]( - dut: LoadModel[C], - simulationStartDate: ZonedDateTime - ): Map[Long, C] = { - val createRelevantData: ZonedDateTime => C = dut match { + def createRelevantData[C <: LoadRelevantData]( + dut: LoadModel[C] + ): ZonedDateTime => C = + dut match { case _: RandomLoadModel => RandomLoadModel.RandomRelevantData case _: ProfileLoadModel => ProfileLoadModel.ProfileRelevantData } - val quarterHoursInYear = 365L * 96L - (0L until quarterHoursInYear) - .map(tick => - tick -> createRelevantData( - simulationStartDate.plus(tick * 15, ChronoUnit.MINUTES) - ) - ) - .toMap[Long, C] - } + def getRelativeDifference[Q <: Quantity[Q]]( + actualResult: Q, + expectedResult: Q + ): Dimensionless = + Each((expectedResult - actualResult) / expectedResult) } From dfdeb34dccd60d42bbb755c66762811886d217c8 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 17:08:14 +0100 Subject: [PATCH 196/305] Don't make it too simple --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index e9c24012aa..9339015ff6 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -433,6 +433,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { actualResult: Q, expectedResult: Q ): Dimensionless = - Each((expectedResult - actualResult) / expectedResult) + Each((expectedResult - actualResult).abs / expectedResult) } From 528a7dd1eaebdbe8bdd5bf32405c4ee576d3f951 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 17:50:32 +0100 Subject: [PATCH 197/305] Refactorings and small corrections --- .../load/LoadModelScalingSpec.scala | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 9339015ff6..45f4fbafe1 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -77,11 +77,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val targetEnergyConsumption = KilowattHours(3000d) "reach the targeted annual energy consumption" in { - /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles - * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % - * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach - * this accuracy. */ - forAll( Table( "profile", @@ -90,7 +85,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.G0 ) ) { profile => - val dut = ProfileLoadModel( + val model = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, @@ -107,10 +102,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profile, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() + model.enable() + + /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles + * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % + * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach + * this accuracy. */ calculateEnergyDiffForYear( - dut, + model, simulationStartDate, targetEnergyConsumption ) should be < Percent(2d) @@ -121,7 +121,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val scalingFactor = 1.5 val expectedEnergy = KilowattHours(4500d) - val dut = ProfileLoadModel( + val model = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, @@ -138,10 +138,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.H0, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() + model.enable() calculateEnergyDiffForYear( - dut, + model, simulationStartDate, expectedEnergy ) should be < Percent(2d) @@ -150,8 +150,6 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val targetMaximumPower = Watts(268.6) "approximately reach the maximum power" in { - implicit val tolerance: Power = Watts(1d) - forAll( Table( "profile", @@ -160,7 +158,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.G0 ) ) { profile => - val dut = ProfileLoadModel( + val model = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, @@ -177,22 +175,23 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { profile, ActivePower(targetMaximumPower) ) - dut.enable() + model.enable() val maximumPower = calculatePowerForYear( - dut, + model, simulationStartDate ).maxOption.value + implicit val tolerance: Power = Watts(1d) maximumPower should approximate(targetMaximumPower) } } "correctly account for the scaling factor when targeting at maximum power" in { val scalingFactor = 1.5 - val expectedMaximum = Watts(402.0044899478780) + val expectedMaximum = Watts(402.9) - val dut = ProfileLoadModel( + val model = ProfileLoadModel( profileLoadInput.getUuid, profileLoadInput.getId, foreSeenOperationInterval, @@ -209,14 +208,15 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { BdewStandardLoadProfile.H0, ActivePower(targetMaximumPower) ) - dut.enable() + model.enable() val maximumPower = calculatePowerForYear( - dut, + model, simulationStartDate ).maxOption.value - maximumPower should be < expectedMaximum + implicit val tolerance: Power = Watts(1.5d) + maximumPower should approximate(expectedMaximum) } } @@ -252,10 +252,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getOperationTime ) - val targetEnergyConsumption = - KilowattHours(3000d) + val targetEnergyConsumption = KilowattHours(3000d) + "reach the targeted annual energy consumption" in { - val dut = RandomLoadModel( + val model = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, foreSeenOperationInterval, @@ -271,10 +271,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() + model.enable() calculateEnergyDiffForYear( - dut, + model, simulationStartDate, targetEnergyConsumption ) should be < Percent(1d) @@ -282,10 +282,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "correctly account for the scaling factor, when targeting a given annual energy consumption" in { val scalingFactor = 1.5 - val expectedEnergy = - KilowattHours(4500d) + val expectedEnergy = KilowattHours(4500d) - val dut = RandomLoadModel( + val model = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, foreSeenOperationInterval, @@ -301,10 +300,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, EnergyConsumption(targetEnergyConsumption) ) - dut.enable() + model.enable() calculateEnergyDiffForYear( - dut, + model, simulationStartDate, expectedEnergy ) should be < Percent(2d) @@ -312,7 +311,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val targetMaximumPower = Watts(268.6) "approximately reach the maximum power" in { - val dut = RandomLoadModel( + val model = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, foreSeenOperationInterval, @@ -328,10 +327,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) - dut.enable() + model.enable() val powers = calculatePowerForYear( - dut, + model, simulationStartDate ).toIndexedSeq.sorted.toArray @@ -347,7 +346,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { val scalingFactor = 1.5 val expectedMaximum = targetMaximumPower * scalingFactor - val dut = RandomLoadModel( + val model = RandomLoadModel( randomLoadInput.getUuid, randomLoadInput.getId, foreSeenOperationInterval, @@ -363,9 +362,10 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { randomLoadInput.getCosPhiRated, ActivePower(targetMaximumPower) ) - dut.enable() + model.enable() + val powers = calculatePowerForYear( - dut, + model, simulationStartDate ).toIndexedSeq.sorted.toArray @@ -379,14 +379,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def calculateEnergyDiffForYear[C <: LoadRelevantData]( - dut: LoadModel[C], + model: LoadModel[C], simulationStartDate: ZonedDateTime, expectedEnergy: Energy ): Dimensionless = { val duration = Minutes(15d) val avgEnergy = calculatePowerForYear( - dut: LoadModel[C], + model: LoadModel[C], simulationStartDate: ZonedDateTime ).foldLeft(KilowattHours(0)) { case (energySum, power) => energySum + (power * duration) @@ -399,7 +399,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def calculatePowerForYear[C <: LoadRelevantData]( - dut: LoadModel[C], + model: LoadModel[C], simulationStartDate: ZonedDateTime ): Iterable[Power] = { val quarterHoursInYear = 365L * 96L @@ -407,11 +407,11 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { (0L until quarterHoursInYear) .map { quarterHour => val tick = quarterHour * 15 * 60 - val relevantData = createRelevantData(dut)( + val relevantData = createRelevantData(model)( simulationStartDate.plus(quarterHour * 15, ChronoUnit.MINUTES) ) - dut + model .calculatePower( tick, Each(0d), @@ -422,9 +422,9 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { } def createRelevantData[C <: LoadRelevantData]( - dut: LoadModel[C] + model: LoadModel[C] ): ZonedDateTime => C = - dut match { + model match { case _: RandomLoadModel => RandomLoadModel.RandomRelevantData case _: ProfileLoadModel => ProfileLoadModel.ProfileRelevantData } From 82142f103fd73ee41a778f1f6adc8822935164de Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 17:50:43 +0100 Subject: [PATCH 198/305] Completely removing duplicate tests --- .../load/ProfileLoadModelTest.groovy | 144 ------------------ .../load/RandomLoadModelTest.groovy | 96 ------------ 2 files changed, 240 deletions(-) delete mode 100644 src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy delete mode 100644 src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy deleted file mode 100644 index b4b3e88ec0..0000000000 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/ProfileLoadModelTest.groovy +++ /dev/null @@ -1,144 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.load - -import static edu.ie3.datamodel.models.profile.BdewStandardLoadProfile.* -import static edu.ie3.simona.model.participant.load.LoadReference.ActivePower -import static edu.ie3.simona.model.participant.load.LoadReference.EnergyConsumption -import static edu.ie3.util.quantities.PowerSystemUnits.* -import static org.apache.commons.math3.util.FastMath.abs - -import edu.ie3.datamodel.models.OperationTime -import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.OperatorInput -import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel -import edu.ie3.util.TimeUtil -import spock.lang.Specification -import squants.energy.KilowattHours$ -import squants.energy.Kilowatts$ -import squants.energy.Watts$ -import edu.ie3.util.scala.quantities.Sq -import squants.time.Minutes$ -import tech.units.indriya.quantity.Quantities - -import java.time.temporal.ChronoUnit -import java.util.stream.Collectors - -class ProfileLoadModelTest extends Specification { - def loadInput = - new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) - - def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) - def wattTolerance = 1 // Equals to 1 W power - - def "A profile load model should reach the targeted maximum power within a year"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - Sq.create(loadInput.sRated.to(KILOWATT).value.doubleValue(), Kilowatts$.MODULE$), - loadInput.cosPhiRated, - profile, - new ActivePower(Sq.create(268.6d, Watts$.MODULE$)) - ) - def relevantData = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def max = relevantData.stream().mapToDouble({ data -> - dut.calculateActivePower(data).toMegawatts().doubleValue() - }).max().getAsDouble() - - then: - abs(max - expectedMax) < wattTolerance - - where: - profile || expectedMax - H0 || 268.0029932985852E-6 - L0 || 268.0029932985852E-6 - G0 || 268.0029932985852E-6 - } - - def "A profile load model should reach the targeted annual energy consumption"() { - given: - /* Test against a permissible deviation of 2 %. As per official documentation of the bdew load profiles - * [https://www.bdew.de/media/documents/2000131_Anwendung-repraesentativen_Lastprofile-Step-by-step.pdf] 1.5 % - * are officially permissible. But, as we currently do not take (bank) holidays into account, we cannot reach - * this accuracy. */ - def testingTolerance = 0.02 - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new ProfileLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - Sq.create(loadInput.getsRated().to(KILOWATT).value.doubleValue(), Kilowatts$.MODULE$), - loadInput.cosPhiRated, - profile, - new EnergyConsumption(Sq.create(3000d, KilowattHours$.MODULE$)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new ProfileLoadModel.ProfileRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def annualEnergy = relevantDatas.stream().mapToDouble({ relevantData -> - ((dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$)).toKilowattHours())) - }).sum() - - then: - abs(annualEnergy - expectedEnergy) / expectedEnergy < testingTolerance - - where: - profile || expectedEnergy - H0 || 3000d - L0 || 3000d - G0 || 3000d - } -} diff --git a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy b/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy deleted file mode 100644 index d3cf2f5e20..0000000000 --- a/src/test/groovy/edu/ie3/simona/model/participant/load/RandomLoadModelTest.groovy +++ /dev/null @@ -1,96 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.model.participant.load - -import static edu.ie3.datamodel.models.profile.BdewStandardLoadProfile.H0 -import static edu.ie3.simona.model.participant.load.LoadReference.EnergyConsumption -import static edu.ie3.util.quantities.PowerSystemUnits.* -import static org.apache.commons.math3.util.FastMath.abs - -import edu.ie3.datamodel.models.OperationTime -import edu.ie3.datamodel.models.input.NodeInput -import edu.ie3.datamodel.models.input.OperatorInput -import edu.ie3.datamodel.models.input.system.LoadInput -import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.participant.load.random.RandomLoadModel -import edu.ie3.util.TimeUtil -import squants.energy.* -import spock.lang.Specification - -import squants.time.Minutes$ -import tech.units.indriya.quantity.Quantities -import edu.ie3.util.scala.quantities.Sq - -import java.time.temporal.ChronoUnit -import java.util.stream.Collectors - -class RandomLoadModelTest extends Specification { - def loadInput = new LoadInput( - UUID.fromString("4eeaf76a-ec17-4fc3-872d-34b7d6004b03"), - "testLoad", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - new NodeInput( - UUID.fromString("e5c1cde5-c161-4a4f-997f-fcf31fecbf57"), - "TestNodeInputModel", - OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited(), - Quantities.getQuantity(1d, PU), - false, - NodeInput.DEFAULT_GEO_POSITION, - GermanVoltageLevelUtils.LV, - -1 - ), - new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - H0, - false, - Quantities.getQuantity(3000d, KILOWATTHOUR), - Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 - ) - - def simulationStartDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def simulationEndDate = TimeUtil.withDefaults.toZonedDateTime("2019-12-31 23:59:00") - def foreSeenOperationInterval = - SystemComponent.determineOperationInterval( - simulationStartDate, - simulationEndDate, - loadInput.operationTime - ) - - def "A random load model should approx. reach the targeted annual energy consumption"() { - given: - def startDate = TimeUtil.withDefaults.toZonedDateTime("2019-01-01 00:00:00") - def dut = new RandomLoadModel( - loadInput.uuid, - loadInput.id, - foreSeenOperationInterval, - 1.0, - QControl.apply(loadInput.qCharacteristics), - Sq.create(loadInput.sRated.to(KILOWATT).value.doubleValue(), Kilowatts$.MODULE$), - loadInput.cosPhiRated, - new EnergyConsumption(Sq.create(3000d, KilowattHours$.MODULE$)) - ) - def relevantDatas = (0..35040).stream().map({ cnt -> - new RandomLoadModel.RandomRelevantData( - startDate.plus(cnt * 15, ChronoUnit.MINUTES)) - }).collect(Collectors.toSet()) - - when: - def avgEnergy = (0..10).parallelStream().mapToDouble( { runCnt -> - relevantDatas.parallelStream().mapToDouble( { relevantData -> - (dut.calculateActivePower(relevantData).$times(Sq.create(15d, Minutes$.MODULE$))).toKilowattHours() - }).sum() - }).average().orElse(0d) - - then: - abs(avgEnergy - 3000) / 3000 < 0.01 - } -} From 757398db822f7e7a7e8876d6ac1e0dadd7c67fa8 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 18:05:58 +0100 Subject: [PATCH 199/305] Removing protected modifier --- src/main/scala/edu/ie3/simona/model/participant/BMModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala | 2 +- .../edu/ie3/simona/model/participant/FixedFeedInModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/PvModel.scala | 2 +- .../edu/ie3/simona/model/participant/SystemParticipant.scala | 2 +- src/main/scala/edu/ie3/simona/model/participant/WecModel.scala | 2 +- .../edu/ie3/simona/model/participant/load/FixedLoadModel.scala | 2 +- .../model/participant/load/profile/ProfileLoadModel.scala | 2 +- .../simona/model/participant/load/random/RandomLoadModel.scala | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index 9b46ac236b..931f2cbecc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -24,7 +24,7 @@ final case class BMModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhi: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index e1fb4ba9e5..9af810e84e 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -48,7 +48,7 @@ final case class ChpModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala index ad51c99662..3a56870053 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/EvcsModel.scala @@ -50,7 +50,7 @@ final case class EvcsModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: squants.Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index bfaf528903..8df152324a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -43,7 +43,7 @@ final case class FixedFeedInModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index b1ea5f6daa..fae1cbe111 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -51,7 +51,7 @@ final case class HpModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index 789d172ec5..e3c4a2554a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -29,7 +29,7 @@ final case class PvModel private ( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 72d6e9219d..a5bee2de2a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -51,7 +51,7 @@ abstract class SystemParticipant[ uuid: UUID, id: String, operationInterval: OperationInterval, - protected val scalingFactor: Double, + val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double diff --git a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala index 4999c57108..9b4adebb4a 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala @@ -57,7 +57,7 @@ final case class WecModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 0862c93ff0..1ac7d08cec 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -45,7 +45,7 @@ final case class FixedLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index ce8e8f7574..1ba083ab09 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -44,7 +44,7 @@ final case class ProfileLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 91d49aed60..f7f8f0331e 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -50,7 +50,7 @@ final case class RandomLoadModel( uuid: UUID, id: String, operationInterval: OperationInterval, - override protected val scalingFactor: Double, + override val scalingFactor: Double, qControl: QControl, sRated: Power, cosPhiRated: Double, From 4268248ae6b01534780ef0e0c4931b7c4a8f8091 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 18:30:26 +0100 Subject: [PATCH 200/305] Correcting ScalaDoc --- .../scala/edu/ie3/simona/model/participant/ChpModel.scala | 4 ++-- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 9af810e84e..ad68f6d32d 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -337,9 +337,9 @@ case object ChpModel { * @param chpInput * instance of [[ChpInput]] this chp model should be built from * @param simulationStartDate - * wall-clock time, the simulation starts + * Simulation time at which the simulation starts * @param simulationEndDate - * wall-clock time, the simulation ends + * Simulation time at which the simulation ends * @param qControl * Strategy to control the reactive power output * @param scalingFactor diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index fae1cbe111..2444ff85bc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -276,9 +276,9 @@ case object HpModel { * @param hpInput * instance of [[HpInput]] this chp model should be built from * @param simulationStartDate - * wall-clock time, the simulation starts + * Simulation time at which the simulation starts * @param simulationEndDate - * wall-clock time, the simulation ends + * Simulation time at which the simulation ends * @param qControl * Strategy to control the reactive power output * @param scalingFactor From 683b0bde9506f35c108f957a6003667d97e8dbc2 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 18:36:45 +0100 Subject: [PATCH 201/305] Removing (now) duplicate usage of scalingFactor --- src/main/scala/edu/ie3/simona/model/participant/PvModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index e3c4a2554a..34c2ba0376 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -141,7 +141,7 @@ final case class PvModel private ( eTotal, data.dateTime, irraditionSTC - ) * scalingFactor + ) } /** Calculates the position of the earth in relation to the sun (day angle) From 454579b9fed96245e5b06881ad4b2f6fc4ebdd6d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 7 Feb 2024 18:45:17 +0100 Subject: [PATCH 202/305] Improved log msg --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d1962470d..0c6fbf1af2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Replaced akka with pekko [#641](https://github.com/ie3-institute/simona/issues/641) - Use `ThermalGrid` to calculate thermal environment of a heat pump [#315](https://github.com/ie3-institute/simona/issues/315) - Enable windows path as config parameters [#549](https://github.com/ie3-institute/simona/issues/549) -- Respect for scaling factor when simulating the system participants [#81](https://github.com/ie3-institute/simona/issues/81) +- Unified consideration of scaling factor when simulating system participants [#81](https://github.com/ie3-institute/simona/issues/81) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) From debb57374ad930db243c0bc0fe847a304a743366 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:50:28 +0000 Subject: [PATCH 203/305] Bump org.scalatest:scalatest_2.13 from 3.2.17 to 3.2.18 (#728) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d707adb0c6..ad615a23bf 100644 --- a/build.gradle +++ b/build.gradle @@ -103,7 +103,7 @@ dependencies { testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' testImplementation 'org.mockito:mockito-core:5.10.0' // mocking framework - testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.17" + testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.18" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0' testImplementation "org.apache.pekko:pekko-testkit_${scalaVersion}:${pekkoVersion}" // pekko testkit From 86429a9d83178a297c0c7e639902ccf4ecbc2781 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:06:17 +0100 Subject: [PATCH 204/305] Update src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala Fixing random stored energy state Co-authored-by: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> --- .../edu/ie3/simona/model/thermal/RandomStorageState.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala index f9a1a5aa91..c6438e1a3f 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala @@ -19,8 +19,7 @@ trait RandomStorageState { override def startingState: ThermalStorage.ThermalStorageState = { def rnd: Double = new Random(seed).nextDouble() def storedEnergy: Energy = getMinEnergyThreshold + ( - getMaxEnergyThreshold - (getMinEnergyThreshold * rnd) - ) + getMaxEnergyThreshold - getMinEnergyThreshold) * rnd ThermalStorageState( -1L, From 8d63c64aa497c35d116cb31777b4a3a713e9bd86 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:11:17 +0100 Subject: [PATCH 205/305] fmt --- .../edu/ie3/simona/model/thermal/RandomStorageState.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala index c6438e1a3f..1ccb5cc024 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala @@ -18,8 +18,8 @@ trait RandomStorageState { override def startingState: ThermalStorage.ThermalStorageState = { def rnd: Double = new Random(seed).nextDouble() - def storedEnergy: Energy = getMinEnergyThreshold + ( - getMaxEnergyThreshold - getMinEnergyThreshold) * rnd + def storedEnergy: Energy = + getMinEnergyThreshold + (getMaxEnergyThreshold - getMinEnergyThreshold) * rnd ThermalStorageState( -1L, From cfdf0ea7a645a40aa226d68815194c1023418c13 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:12:07 +0100 Subject: [PATCH 206/305] Removing obsolete ScalaDoc --- .../ie3/simona/agent/participant/ServiceRegistration.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala index 7b3662bfef..06de9ba700 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala @@ -45,10 +45,6 @@ trait ServiceRegistration[ * Input model definition * @param services * Definition of where to get what - * @param scheduleTriggerFunc - * function providing the proper ScheduleTriggerMessage for a given trigger - * @param emControlled - * whether the agent is em-controlled or not * @return * a vector of actor references to wait for responses */ From 2f6b178a6516bf52b09e998898fd5d7c413a9b00 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:12:30 +0100 Subject: [PATCH 207/305] Better collection type for services --- .../agent/grid/GridAgentController.scala | 26 ++++++++----------- .../agent/participant/ParticipantAgent.scala | 8 ++---- .../ParticipantAgentFundamentals.scala | 14 +++------- .../participant/ServiceRegistration.scala | 16 +++++------- .../evcs/EvcsAgentFundamentals.scala | 10 +++---- .../FixedFeedInAgentFundamentals.scala | 4 +-- .../participant/hp/HpAgentFundamentals.scala | 4 +-- .../load/LoadAgentFundamentals.scala | 4 +-- .../participant/pv/PvAgentFundamentals.scala | 10 +++---- .../participant/statedata/BaseStateData.scala | 6 ++--- .../statedata/ParticipantStateData.scala | 26 ++++++++----------- .../wec/WecAgentFundamentals.scala | 10 +++---- .../EvcsAgentModelCalculationSpec.scala | 24 ++++++----------- ...FixedFeedInAgentModelCalculationSpec.scala | 2 +- .../HpAgentModelCalculationSpec.scala | 8 +++--- .../LoadAgentFixedModelCalculationSpec.scala | 2 +- ...LoadAgentProfileModelCalculationSpec.scala | 2 +- .../ParticipantAgent2ListenerSpec.scala | 4 +-- .../ParticipantAgentExternalSourceSpec.scala | 2 +- .../participant/ParticipantAgentMock.scala | 2 +- .../PvAgentModelCalculationSpec.scala | 8 +++--- .../WecAgentModelCalculationSpec.scala | 6 ++--- 22 files changed, 74 insertions(+), 124 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala index 9ec4aca397..236f398d82 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala @@ -344,7 +344,7 @@ class GridAgentController( fixedFeedInInput, modelConfiguration, primaryServiceProxy, - None, + Iterable.empty, simulationStartDate, simulationEndDate, resolution, @@ -395,7 +395,7 @@ class GridAgentController( loadInput, modelConfiguration, primaryServiceProxy, - None, + Iterable.empty, simulationStartDate, simulationEndDate, resolution, @@ -449,7 +449,7 @@ class GridAgentController( pvInput, modelConfiguration, primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), + Iterable(ActorWeatherService(weatherService)), simulationStartDate, simulationEndDate, resolution, @@ -495,14 +495,7 @@ class GridAgentController( resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig - ): ActorRef = { - val sources = Some( - Vector( - ActorEvMovementsService( - evMovementsService - ) - ) - ) + ): ActorRef = gridAgentContext.simonaActorOf( EvcsAgent.props( environmentRefs.scheduler, @@ -510,7 +503,11 @@ class GridAgentController( evcsInput, modelConfiguration, primaryServiceProxy, - sources, + Iterable( + ActorEvMovementsService( + evMovementsService + ) + ), simulationStartDate, simulationEndDate, resolution, @@ -520,7 +517,6 @@ class GridAgentController( listener ) ) - } /** Builds an [[HpAgent]] from given input * @param hpInput @@ -557,7 +553,7 @@ class GridAgentController( thermalGrid, modelConfiguration, primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), + Iterable(ActorWeatherService(weatherService)), simulationStartDate, simulationEndDate, resolution, @@ -611,7 +607,7 @@ class GridAgentController( wecInput, modelConfiguration, primaryServiceProxy, - Some(Vector(ActorWeatherService(weatherService))), + Iterable(ActorWeatherService(weatherService)), simulationStartDate, simulationEndDate, resolution, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala index 176a67fecc..20902cedd6 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala @@ -264,7 +264,7 @@ abstract class ParticipantAgent[ ParticipantInitializingStateData( inputModel: InputModelContainer[I], modelConfig: MC, - secondaryDataServices, + _, simulationStartDate, simulationEndDate, resolution, @@ -277,7 +277,6 @@ abstract class ParticipantAgent[ initializeParticipantForPrimaryDataReplay( inputModel, modelConfig, - secondaryDataServices, simulationStartDate, simulationEndDate, resolution, @@ -501,8 +500,6 @@ abstract class ParticipantAgent[ * Input model * @param modelConfig * Configuration for the model - * @param services - * Optional list of services, that are needed * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -525,7 +522,6 @@ abstract class ParticipantAgent[ def initializeParticipantForPrimaryDataReplay( inputModel: InputModelContainer[I], modelConfig: MC, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -563,7 +559,7 @@ abstract class ParticipantAgent[ def initializeParticipantForModelCalculation( inputModel: InputModelContainer[I], modelConfig: MC, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala index 8afd11c7a8..f1e502dfd4 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala @@ -119,7 +119,6 @@ protected trait ParticipantAgentFundamentals[ override def initializeParticipantForPrimaryDataReplay( inputModel: InputModelContainer[I], modelConfig: MC, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -260,7 +259,7 @@ protected trait ParticipantAgentFundamentals[ override def initializeParticipantForModelCalculation( inputModel: InputModelContainer[I], modelConfig: MC, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -340,7 +339,7 @@ protected trait ParticipantAgentFundamentals[ def determineModelBaseStateData( inputModel: InputModelContainer[I], modelConfig: MC, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -1967,7 +1966,7 @@ protected trait ParticipantAgentFundamentals[ /** Returns secondary service of type T or throws exception * @param services - * the services Option used in + * the services used in * [[edu.ie3.simona.agent.participant.statedata.BaseStateData.ModelBaseStateData]] * @param tag * ClassTag of T @@ -1977,14 +1976,9 @@ protected trait ParticipantAgentFundamentals[ * secondary service of given type */ protected def getService[T <: SecondaryDataService[_]]( - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]] + services: Iterable[SecondaryDataService[_ <: SecondaryData]] )(implicit tag: ClassTag[T]): ActorRef = services - .getOrElse( - throw new InconsistentStateException( - "No services provided by ParticipantModelBaseStateData." - ) - ) .find { case _: T => true case _ => false diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala index 06de9ba700..bca34cc95f 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala @@ -46,19 +46,15 @@ trait ServiceRegistration[ * @param services * Definition of where to get what * @return - * a vector of actor references to wait for responses + * an iterable of actor references to wait for responses */ def registerForServices( inputModel: I, - services: Option[Seq[SecondaryDataService[_ <: SecondaryData]]] - ): Seq[ActorRef] = - services - .map(sources => - sources.flatMap(service => - registerForSecondaryService(service, inputModel) - ) - ) - .getOrElse(Seq.empty[ActorRef]) + services: Iterable[SecondaryDataService[_ <: SecondaryData]] + ): Iterable[ActorRef] = + services.flatMap(service => + registerForSecondaryService(service, inputModel) + ) /** Register for the distinct secondary service * diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index 9818f25524..d91295d5ba 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -88,7 +88,7 @@ protected trait EvcsAgentFundamentals * @param modelConfig * Configuration of the model * @param services - * Optional collection of services to register with + * Collection of services to register with * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -107,7 +107,7 @@ protected trait EvcsAgentFundamentals override def determineModelBaseStateData( inputModel: InputModelContainer[EvcsInput], modelConfig: EvcsRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -121,11 +121,7 @@ protected trait EvcsAgentFundamentals EvcsModel ] = { /* Check for needed services */ - if ( - !services.exists(serviceDefinitions => - serviceDefinitions.map(_.getClass).containsSlice(neededServices) - ) - ) + if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) throw new AgentInitializationException( s"EvcsAgent cannot be initialized without an ev data service!" ) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala index 22e6f1dd0d..c68b8a4b82 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala @@ -84,7 +84,7 @@ protected trait FixedFeedInAgentFundamentals * @param modelConfig * Configuration of the model * @param services - * Optional collection of services to register with + * Collection of services to register with * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -103,7 +103,7 @@ protected trait FixedFeedInAgentFundamentals override def determineModelBaseStateData( inputModel: InputModelContainer[FixedFeedInInput], modelConfig: FixedFeedInRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 8cea8f51c5..12ccac04e8 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -292,7 +292,7 @@ trait HpAgentFundamentals override def determineModelBaseStateData( inputModel: InputModelContainer[HpInput], modelConfig: HpRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: Data.SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: Data.SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -305,7 +305,7 @@ trait HpAgentFundamentals HpState, HpModel ] = { - if (!services.exists(_.map(_.getClass).containsSlice(neededServices))) + if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) throw new AgentInitializationException( "HpAgent cannot be initialized without its needed services." ) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index 31df2fa55e..6717d0050b 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -95,7 +95,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ * @param modelConfig * Configuration of the model * @param services - * Optional collection of services to register with + * Collection of services to register with * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -114,7 +114,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ override def determineModelBaseStateData( inputModel: InputModelContainer[LoadInput], modelConfig: LoadRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, diff --git a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala index 68fb802091..03f8060ebe 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala @@ -87,7 +87,7 @@ protected trait PvAgentFundamentals * @param modelConfig * Configuration of the model * @param services - * Optional collection of services to register with + * Collection of services to register with * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -106,7 +106,7 @@ protected trait PvAgentFundamentals override def determineModelBaseStateData( inputModel: InputModelContainer[PvInput], modelConfig: PvRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -120,11 +120,7 @@ protected trait PvAgentFundamentals PvModel ] = { /* Check for needed services */ - if ( - !services.exists(serviceDefinitions => - serviceDefinitions.map(_.getClass).containsSlice(neededServices) - ) - ) + if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) throw new AgentInitializationException( s"PvAgent cannot be initialized without a weather service!" ) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala index 9d13b158c5..0f3a72a881 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala @@ -109,7 +109,7 @@ object BaseStateData { /** The services, the physical model depends on */ - val services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]] + val services: Iterable[SecondaryDataService[_ <: SecondaryData]] /** Stores all data that are relevant to model calculation */ @@ -214,9 +214,7 @@ object BaseStateData { override val startDate: ZonedDateTime, override val endDate: ZonedDateTime, override val model: M, - override val services: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] - ], + override val services: Iterable[SecondaryDataService[_ <: SecondaryData]], override val outputConfig: NotifierConfig, override val additionalActivationTicks: SortedSet[Long], override val foreseenDataTicks: Map[ClassicActorRef, Option[Long]], diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala index 5b759e2933..f7c3312a59 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala @@ -71,9 +71,7 @@ object ParticipantStateData { ]( inputModel: InputModelContainer[I], modelConfig: C, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] - ], + secondaryDataServices: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -118,9 +116,7 @@ object ParticipantStateData { inputModel: InputModelContainer[I], modelConfig: C, primaryServiceProxy: ClassicActorRef, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] - ], + secondaryDataServices: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -139,8 +135,8 @@ object ParticipantStateData { inputModel: I, modelConfig: C, primaryServiceProxy: ClassicActorRef, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] + secondaryDataServices: Iterable[ + SecondaryDataService[_ <: SecondaryData] ], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, @@ -168,8 +164,8 @@ object ParticipantStateData { inputModel: I, modelConfig: C, primaryServiceProxy: ClassicActorRef, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] + secondaryDataServices: Iterable[ + SecondaryDataService[_ <: SecondaryData] ], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, @@ -200,8 +196,8 @@ object ParticipantStateData { thermalGrid: ThermalGrid, modelConfig: C, primaryServiceProxy: ClassicActorRef, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] + secondaryDataServices: Iterable[ + SecondaryDataService[_ <: SecondaryData] ], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, @@ -231,8 +227,8 @@ object ParticipantStateData { thermalGrid: ThermalGrid, modelConfig: C, primaryServiceProxy: ClassicActorRef, - secondaryDataServices: Option[ - Vector[SecondaryDataService[_ <: SecondaryData]] + secondaryDataServices: Iterable[ + SecondaryDataService[_ <: SecondaryData] ], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, @@ -272,7 +268,7 @@ object ParticipantStateData { +PD <: PrimaryDataWithApparentPower[PD] ]( baseStateData: BaseStateData[PD], - pendingResponses: Seq[ClassicActorRef], + pendingResponses: Iterable[ClassicActorRef], foreseenNextDataTicks: Map[ClassicActorRef, Long] = Map.empty ) extends ParticipantStateData[PD] diff --git a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala index 8ca46cea85..f39fbd8d3b 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala @@ -82,7 +82,7 @@ protected trait WecAgentFundamentals * @param modelConfig * Configuration of the model * @param services - * Optional collection of services to register with + * Collection of services to register with * @param simulationStartDate * Real world time date time, when the simulation starts * @param simulationEndDate @@ -101,7 +101,7 @@ protected trait WecAgentFundamentals override def determineModelBaseStateData( inputModel: InputModelContainer[WecInput], modelConfig: WecRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, @@ -115,11 +115,7 @@ protected trait WecAgentFundamentals WecModel ] = { /* Check for needed services */ - if ( - !services.exists(serviceDefinitions => - serviceDefinitions.map(_.getClass).containsSlice(neededServices) - ) - ) + if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) throw new AgentInitializationException( s"$actorName cannot be initialized without a weather service!" ) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index e9617c1550..1c22a887ac 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -190,10 +190,8 @@ class EvcsAgentModelCalculationSpec ]( inputModel = evcsInputModel, modelConfig = modelConfig, - secondaryDataServices = Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices = Iterable( + ActorEvMovementsService(evService.ref) ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, @@ -824,10 +822,8 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = evcsInputModelQv, modelConfig = modelConfig, - secondaryDataServices = Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices = Iterable( + ActorEvMovementsService(evService.ref) ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, @@ -1010,10 +1006,8 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = evcsInputModelQv, modelConfig = modelConfig, - secondaryDataServices = Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices = Iterable( + ActorEvMovementsService(evService.ref) ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, @@ -1150,10 +1144,8 @@ class EvcsAgentModelCalculationSpec initStateData = ParticipantInitializeStateData( inputModel = SimpleInputContainer(evcsInputModelQv), modelConfig = modelConfig, - secondaryDataServices = Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices = Iterable( + ActorEvMovementsService(evService.ref) ), simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index df5e0e00db..4769963bc6 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -98,7 +98,7 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedConfigUtil.getOrDefault[FixedFeedInRuntimeConfig]( voltageSensitiveInput.getUuid ) - private val services = None + private val services = Iterable.empty private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds "A fixed feed in agent with model calculation " should { diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 5dffce6988..294a007f90 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -110,11 +110,9 @@ class HpAgentModelCalculationSpec participantConfigUtil.getOrDefault[HpRuntimeConfig]( hpInput.getUuid ) - private val noServices = None - private val services = Some( - Vector( - ActorWeatherService(weatherService.ref) - ) + private val noServices = Iterable.empty + private val services = Iterable( + ActorWeatherService(weatherService.ref) ) private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index 8a038ea59b..4c8f8f894c 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -89,7 +89,7 @@ class LoadAgentFixedModelCalculationSpec loadConfigUtil.getOrDefault[LoadRuntimeConfig]( voltageSensitiveInput.getUuid ) - private val services = None + private val services = Iterable.empty private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds private implicit val powerTolerance: squants.Power = Watts(0.1) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index 27056df1ec..9ae1d86522 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -89,7 +89,7 @@ class LoadAgentProfileModelCalculationSpec loadConfigUtil.getOrDefault[LoadRuntimeConfig]( voltageSensitiveInput.getUuid ) - private val services = None + private val services = Iterable.empty private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds private implicit val powerTolerance: squants.Power = Watts(0.1) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 963112261a..27b47099cb 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -79,7 +79,7 @@ class ParticipantAgent2ListenerSpec when(mockInputModel.getUuid).thenReturn(testUUID) when(mockInputModel.getId).thenReturn(testID) - private val sources = None + private val services = Iterable.empty "A participant agent" should { val initStateData: NotifierConfig => ParticipantInitializeStateData[ @@ -94,7 +94,7 @@ class ParticipantAgent2ListenerSpec ]( inputModel = mockInputModel, modelConfig = mock[BaseRuntimeConfig], - secondaryDataServices = sources, + secondaryDataServices = services, simulationStartDate = defaultSimulationStart, simulationEndDate = defaultSimulationEnd, resolution = simonaConfig.simona.powerflow.resolution.getSeconds, diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index 8d04e3febc..34ca9b5d52 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -132,7 +132,7 @@ class ParticipantAgentExternalSourceSpec ]( inputModel = mockInputModel, modelConfig = mock[BaseRuntimeConfig], - secondaryDataServices = None, + secondaryDataServices = Iterable.empty, simulationStartDate = defaultSimulationStart, simulationEndDate = defaultSimulationEnd, resolution = simonaConfig.simona.powerflow.resolution.getSeconds, diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala index 9dec4de3d4..e4971bf29e 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala @@ -186,7 +186,7 @@ class ParticipantAgentMock( override def determineModelBaseStateData( inputModel: InputModelContainer[SystemParticipantInput], modelConfig: SimonaConfig.BaseRuntimeConfig, - services: Option[Vector[SecondaryDataService[_ <: SecondaryData]]], + services: Iterable[SecondaryDataService[_ <: SecondaryData]], simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, resolution: Long, diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index 472cf3c47a..9e317fd00c 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -109,11 +109,9 @@ class PvAgentModelCalculationSpec private val modelConfig = configUtil.getOrDefault[PvRuntimeConfig]( voltageSensitiveInput.getUuid ) - private val noServices = None - private val withServices = Some( - Vector( - ActorWeatherService(weatherService.ref) - ) + private val noServices = Iterable.empty + private val withServices = Iterable( + ActorWeatherService(weatherService.ref) ) private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index a0de3e4d06..04df72b30b 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -114,9 +114,7 @@ class WecAgentModelCalculationSpec voltageSensitiveInput.getUuid ) - private val withServices = Some( - Vector(ActorWeatherService(weatherService.ref)) - ) + private val withServices = Iterable(ActorWeatherService(weatherService.ref)) private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds @@ -137,7 +135,7 @@ class WecAgentModelCalculationSpec simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, modelConfig = modelConfig, primaryServiceProxy = primaryServiceProxy.ref, - secondaryDataServices = None, + secondaryDataServices = Iterable.empty, outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, From f8cda1aa741a5985f4561ab5401758139fd9c817 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:31:43 +0100 Subject: [PATCH 208/305] Throwing instead of logging error --- .../agent/participant/ParticipantAgentFundamentals.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala index f1e502dfd4..ecb7dce11a 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala @@ -53,6 +53,7 @@ import edu.ie3.simona.event.ResultEvent.{ ThermalResultEvent } import edu.ie3.simona.event.notifier.NotifierConfig +import edu.ie3.simona.exceptions.CriticalFailureException import edu.ie3.simona.exceptions.agent.{ ActorNotRegisteredException, AgentInitializationException, @@ -790,10 +791,10 @@ protected trait ParticipantAgentFundamentals[ setPointActivePower ) - // sanity check, simulation will hang if this matches + // sanity check, simulation would hang if this matches flexChangeIndicator.changesAtTick match { case Some(changeAtTick) if changeAtTick <= flexCtrl.tick => - log.error( + throw new CriticalFailureException( s"Scheduling agent ${self.path} (${baseStateData.modelUuid}) for activation at tick $changeAtTick, although current tick is ${flexCtrl.tick}" ) case _ => From 83a6dc18537d2d8473c3b055abac8825bcce6bd4 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:36:47 +0100 Subject: [PATCH 209/305] Fixing tests --- .../EvcsAgentModelCalculationSpec.scala | 32 +++++++------------ ...FixedFeedInAgentModelCalculationSpec.scala | 2 +- .../HpAgentModelCalculationSpec.scala | 8 ++--- .../ParticipantAgent2ListenerSpec.scala | 2 +- .../ParticipantAgentExternalSourceSpec.scala | 2 +- .../participant/ParticipantAgentMock.scala | 2 +- .../PvAgentModelCalculationSpec.scala | 10 +++--- .../WecAgentModelCalculationSpec.scala | 4 +-- 8 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index 1c22a887ac..ad8fbca59d 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -252,10 +252,8 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModel) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices shouldBe Iterable( + ActorEvMovementsService(evService.ref) ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate @@ -302,10 +300,8 @@ class EvcsAgentModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + services shouldBe Iterable( + ActorEvMovementsService(evService.ref) ) outputConfig shouldBe NotifierConfig( simulationResultInfo = false, @@ -322,7 +318,7 @@ class EvcsAgentModelCalculationSpec requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ - awaitRegistrationResponsesFrom shouldBe Vector(evService.ref) + awaitRegistrationResponsesFrom shouldBe Iterable(evService.ref) foreseenNextDataTicks shouldBe Map.empty case _ => fail( @@ -1043,10 +1039,8 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices shouldBe Iterable( + ActorEvMovementsService(evService.ref) ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate @@ -1108,10 +1102,8 @@ class EvcsAgentModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + services shouldBe Iterable( + ActorEvMovementsService(evService.ref) ) outputConfig shouldBe defaultOutputConfig additionalActivationTicks shouldBe empty @@ -1185,10 +1177,8 @@ class EvcsAgentModelCalculationSpec ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe Some( - Vector( - ActorEvMovementsService(evService.ref) - ) + secondaryDataServices shouldBe Iterable( + ActorEvMovementsService(evService.ref) ) simulationStartDate shouldBe simulationStartDate simulationEndDate shouldBe simulationEndDate diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index 4769963bc6..8b64aa9c26 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -212,7 +212,7 @@ class FixedFeedInAgentModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe None + services shouldBe Iterable.empty outputConfig shouldBe defaultOutputConfig additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 294a007f90..88508845f5 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -299,10 +299,8 @@ class HpAgentModelCalculationSpec /* Base state data */ startDate shouldBe defaultSimulationStart endDate shouldBe defaultSimulationEnd - services shouldBe Some( - Vector( - ActorWeatherService(weatherService.ref) - ) + services shouldBe Iterable( + ActorWeatherService(weatherService.ref) ) outputConfig shouldBe NotifierConfig( simulationResultInfo = true, @@ -321,7 +319,7 @@ class HpAgentModelCalculationSpec ) /* Additional information */ - awaitRegistrationResponsesFrom shouldBe Vector(weatherService.ref) + awaitRegistrationResponsesFrom shouldBe Iterable(weatherService.ref) foreseenNextDataTicks shouldBe Map.empty case _ => fail( diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 27b47099cb..0395abb332 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -63,7 +63,7 @@ class ParticipantAgent2ListenerSpec implicit val noReceiveTimeOut: Timeout = Timeout(1, TimeUnit.SECONDS) /* Assign this test to receive the result events from agent */ - override val systemListener: Iterable[ActorRef] = Vector(self) + override val systemListener: Iterable[ActorRef] = Iterable(self) private val testUUID = UUID.randomUUID private val testID = "PartAgentExternalMock" diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index 34ca9b5d52..976a2c25b6 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -192,7 +192,7 @@ class ParticipantAgentExternalSourceSpec ) => inputModel shouldBe SimpleInputContainer(mockInputModel) modelConfig shouldBe modelConfig - secondaryDataServices shouldBe None + secondaryDataServices shouldBe Iterable.empty simulationStartDate shouldBe defaultSimulationStart simulationEndDate shouldBe defaultSimulationEnd resolution shouldBe this.resolution diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala index e4971bf29e..82e6d896f8 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala @@ -68,7 +68,7 @@ class ParticipantAgentMock( SimonaConfig.BaseRuntimeConfig, ApparentPower ], - override val listener: Iterable[ActorRef] = Vector.empty[ActorRef] + override val listener: Iterable[ActorRef] = Iterable.empty[ActorRef] ) extends ParticipantAgent[ ApparentPower, FixedRelevantData.type, diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index 9e317fd00c..471ce0dff6 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -91,7 +91,7 @@ class PvAgentModelCalculationSpec .build() /* Assign this test to receive the result events from agent */ - override val systemListener: Iterable[ActorRef] = Vector(self) + override val systemListener: Iterable[ActorRef] = Iterable(self) private val simonaConfig: SimonaConfig = createSimonaConfig( @@ -299,10 +299,8 @@ class PvAgentModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe Some( - Vector( - ActorWeatherService(weatherService.ref) - ) + services shouldBe Iterable( + ActorWeatherService(weatherService.ref) ) outputConfig shouldBe NotifierConfig( simulationResultInfo = false, @@ -319,7 +317,7 @@ class PvAgentModelCalculationSpec requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ - awaitRegistrationResponsesFrom shouldBe Vector(weatherService.ref) + awaitRegistrationResponsesFrom shouldBe Iterable(weatherService.ref) foreseenNextDataTicks shouldBe Map.empty case _ => fail( diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index 04df72b30b..a0b6df4aaf 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -99,7 +99,7 @@ class WecAgentModelCalculationSpec .build() /* Assign this test to receive the result events from agent */ - override val systemListener: Iterable[ActorRef] = Vector(self) + override val systemListener: Iterable[ActorRef] = Iterable(self) private val simonaConfig: SimonaConfig = createSimonaConfig( @@ -294,7 +294,7 @@ class WecAgentModelCalculationSpec requestValueStore shouldBe ValueStore[ApparentPower](resolution) /* Additional information */ - awaitRegistrationResponsesFrom shouldBe Vector(weatherService.ref) + awaitRegistrationResponsesFrom shouldBe Iterable(weatherService.ref) foreseenNextDataTicks shouldBe Map.empty case _ => fail( From 6d6f9afee58538cadca744fc2a26c5bfedcde24b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:38:31 +0100 Subject: [PATCH 210/305] Update src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala Fix grammatical error Co-authored-by: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> --- .../ie3/simona/agent/participant/hp/HpAgentFundamentals.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 12ccac04e8..2136bb7776 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -320,7 +320,7 @@ trait HpAgentFundamentals simulationEndDate ) - /* Determine a proper starting model state and safe it into the base state data */ + /* Determine a proper starting model state and save it into the base state data */ val startingModelState = startingState(model.thermalGrid) val stateDataStore = ValueStore.updateValueStore( ValueStore(resolution), From cbac13c419bee20160eef05b5a34a705b1ae26ca Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:42:52 +0100 Subject: [PATCH 211/305] More test fixes --- .../agent/participant/LoadAgentFixedModelCalculationSpec.scala | 2 +- .../participant/LoadAgentProfileModelCalculationSpec.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index 4c8f8f894c..544f9c58b1 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -206,7 +206,7 @@ class LoadAgentFixedModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe None + services shouldBe Iterable.empty outputConfig shouldBe defaultOutputConfig additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index 9ae1d86522..6ce6f8761b 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -205,7 +205,7 @@ class LoadAgentProfileModelCalculationSpec /* Base state data */ startDate shouldBe simulationStartDate endDate shouldBe simulationEndDate - services shouldBe None + services shouldBe Iterable.empty outputConfig shouldBe defaultOutputConfig additionalActivationTicks .corresponds(Seq(900L, 1800L, 2700L, 3600L))(_ == _) shouldBe true From c5e3b1a7f777b613cc5fe280ddd9e86e7a79a3af Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 11:45:54 +0100 Subject: [PATCH 212/305] Update src/main/scala/edu/ie3/simona/model/participant/HpModel.scala Co-authored-by: Daniel Feismann <98817556+danielfeismann@users.noreply.github.com> --- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 69f5bbb720..326731da10 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -116,7 +116,7 @@ final case class HpModel( ): Power = modelState.qDot /** Given a [[HpRelevantData]] object and the current [[HpState]], this - * function calculates the heat pump's next state To get the actual active + * function calculates the heat pump's next state to get the actual active * power of this state use [[calculateActivePower]] with the generated state * * @param state From 3cf4c3da738d00d2c2497820f39e6f7a796eb493 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 12:54:45 +0100 Subject: [PATCH 213/305] Enhanced test commentary --- .../model/participant/evcs/EvcsModelSpec.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index b7c61948d9..3d83e05bec 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -658,9 +658,9 @@ class EvcsModelSpec (0.0, 0.0, 5.0, 15.0, 10.0, 15.0), // 2: mid-way full (set to 7.5 kWh), forced charging (0.0, 7.5, 0.0, 15.0, 10.0, 15.0), - // 2: almost full (12.5 kWh), forced charging + // 2: almost full (charged to 12.5 kWh), forced charging (0.0, 5.0, 5.0, 15.0, 10.0, 15.0), - // 2: full (set) + // 2: full (set to 15 kWh) (0.0, 15.0, 0.0, 10.0, 10.0, 10.0), /* 1: at lower margin (set to 2 kWh) */ @@ -672,9 +672,9 @@ class EvcsModelSpec (2.0, 0.0, 5.0, 15.0, -5.0, 15.0), // 2: mid-way full (set to 7.5 kWh) (2.0, 7.5, 0.0, 15.0, -5.0, 15.0), - // 2: almost full (12.5 kWh) + // 2: almost full (charged to 12.5 kWh) (2.0, 5.0, 5.0, 15.0, -5.0, 15.0), - // 2: full (set) + // 2: full (set to 15 kWh) (2.0, 15.0, 0.0, 10.0, -5.0, 10.0), /* 1: mid-way full (set to 5 kWh) */ @@ -684,9 +684,9 @@ class EvcsModelSpec (5.0, 0.0, 5.0, 15.0, -15.0, 15.0), // 2: mid-way full (set to 7.5 kWh) (5.0, 7.5, 0.0, 15.0, -15.0, 15.0), - // 2: almost full (12.5 kWh) + // 2: almost full (charged to 12.5 kWh) (5.0, 5.0, 5.0, 15.0, -15.0, 15.0), - // 2: full (set) + // 2: full (set to 15 kWh) (5.0, 15.0, 0.0, 10.0, -15.0, 10.0), /* 1: full (set to 10 kWh) */ @@ -696,9 +696,9 @@ class EvcsModelSpec (10.0, 0.0, 5.0, 5.0, -15.0, 5.0), // 2: mid-way full (set to 7.5 kWh) (10.0, 7.5, 0.0, 5.0, -15.0, 5.0), - // 2: almost full (12.5 kWh) + // 2: almost full (charged to 12.5 kWh) (10.0, 5.0, 5.0, 5.0, -15.0, 5.0), - // 2: full (set) + // 2: full (set to 15 kWh) (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) ) From 094276993d9e489701432ff82e2a8865ee52a9bd Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 14:58:13 +0100 Subject: [PATCH 214/305] flex provider -> flex options provider --- .../messages/flex/FlexibilityMessage.scala | 43 ++++++++++--------- .../flex/MinMaxFlexibilityMessage.scala | 27 ++++++------ 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala index 5e264425fe..7a4706c3c4 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala @@ -21,7 +21,7 @@ import java.util.UUID object FlexibilityMessage { /** Trait that is extended by all messages that are supposed to be received by - * a flexibility provider, which could be any + * a flex options provider, which could be any * [[edu.ie3.simona.agent.participant.ParticipantAgent]] or * [[edu.ie3.simona.agent.em.EmAgent]], if it is EM-controlled. */ @@ -36,15 +36,15 @@ object FlexibilityMessage { val modelUuid: UUID } - /** Message that registers a flex provider with an + /** Message that registers a flex options provider with an * [[edu.ie3.simona.agent.em.EmAgent]]. * * @param modelUuid - * The UUID of the flex provider asset model + * The UUID of the flex options provider asset model * @param participant - * The actor reference to the flex provider + * The actor reference to the flex options provider * @param inputModel - * The asset input model of the flex provider + * The asset input model of the flex options provider */ final case class RegisterParticipant( override val modelUuid: UUID, @@ -52,12 +52,13 @@ object FlexibilityMessage { inputModel: AssetInput ) extends FlexResponse - /** Message that schedules a flex request for a flex provider at given tick. + /** Message that schedules a flex request for a flex options provider at given + * tick. * * @param modelUuid - * The UUID of the flex provider asset model + * The UUID of the flex options provider asset model * @param tick - * The tick to schedule the flex provider for + * The tick to schedule the flex options provider for * @param scheduleKey * Optionally a schedule key that unlocks the scheduler once the scheduling * chain is completed @@ -68,7 +69,8 @@ object FlexibilityMessage { scheduleKey: Option[ScheduleKey] = None ) extends FlexResponse - /** Message that requests flex options from a flex provider for given tick + /** Message that requests flex options from a flex options provider for given + * tick * * @param tick * The tick to request flex options for @@ -82,8 +84,9 @@ object FlexibilityMessage { */ trait ProvideFlexOptions extends FlexResponse - /** Message that issues flexibility control to a flex provider, i.e. a - * feasible set point is delivered that the flex provider should adhere to + /** Message that issues flexibility control to a flex options provider, i.e. a + * feasible set point is delivered that the flex options provider should + * adhere to */ trait IssueFlexControl extends FlexRequest @@ -111,24 +114,24 @@ object FlexibilityMessage { final case class IssueNoControl(override val tick: Long) extends IssueFlexControl - /** Message sent by flex providers indicating that the [[IssueFlexControl]] - * message has been handled and the flex communication for the current tick - * is completed. + /** Message sent by flex options providers indicating that the + * [[IssueFlexControl]] message has been handled and the flex communication + * for the current tick is completed. * * @param modelUuid - * The UUID of the flex provider asset model + * The UUID of the flex options provider asset model * @param result - * The apparent power that is produced/consumed by the flex provider, which - * can deviate from the set point communicated by a [[IssueFlexControl]] - * message if it is not feasible. + * The apparent power that is produced/consumed by the flex options + * provider, which can deviate from the set point communicated by a + * [[IssueFlexControl]] message if it is not feasible. * @param requestAtNextActivation * Whether or not to request flex options at the very next activation of * the receiving EM agent. This is the case if flex options change the very * next second after the current tick. * @param requestAtTick * Optionally the tick at which flex options are foreseen to have changed, - * i.e. the tick at which the flex provider would like to be activated at the - * latest. + * i.e. the tick at which the flex options provider would like to be + * activated at the latest. */ final case class FlexCtrlCompletion( override val modelUuid: UUID, diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala index 760575571e..59fc3b0935 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala @@ -22,16 +22,17 @@ object MinMaxFlexibilityMessage { * negative or all positive, meaning that feed-in or load is mandatory. * * @param modelUuid - * The UUID of the flex provider asset model + * The UUID of the flex options provider asset model * @param ref - * The reference active power that the flex provider would produce/consume - * regularly at the current tick, i.e. if it was not flex-controlled + * The reference active power that the flex options provider would + * produce/consume regularly at the current tick, i.e. if it was not + * flex-controlled * @param min - * The minimum active power that the flex provider allows at the current - * tick + * The minimum active power that the flex options provider allows at the + * current tick * @param max - * The maximum active power that the flex provider allows at the current - * tick + * The maximum active power that the flex options provider allows at the + * current tick */ final case class ProvideMinMaxFlexOptions private ( override val modelUuid: UUID, @@ -57,17 +58,17 @@ object MinMaxFlexibilityMessage { * regarding the power values * * @param modelUuid - * The UUID of the flex provider asset model + * The UUID of the flex options provider asset model * @param ref - * The reference active power that the flex provider would + * The reference active power that the flex options provider would * produce/consume regularly at the current tick, i.e. if it was not * flex-controlled * @param min - * The minimum active power that the flex provider allows at the current - * tick + * The minimum active power that the flex options provider allows at the + * current tick * @param max - * The maximum active power that the flex provider allows at the current - * tick + * The maximum active power that the flex options provider allows at the + * current tick * @return * The [[ProvideMinMaxFlexOptions]] message */ From 211163737519a30d372238d04e867b50911a9726 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 15:32:24 +0100 Subject: [PATCH 215/305] explanatory commentary --- .../simona/model/thermal/ThermalHouse.scala | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala index ad20981b72..874b7c10e3 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -97,7 +97,7 @@ final case class ThermalHouse( ): ThermalEnergyDemand = { /* Calculate the inner temperature of the house, at the questioned instance in time */ val duration = Seconds(tick - state.tick) - val innerTemperature = newInnerTemperature( + val currentInnerTemp = newInnerTemperature( state.qDot, duration, state.innerTemperature, @@ -107,24 +107,28 @@ final case class ThermalHouse( /* Determine, which temperature boundary triggers a needed energy to reach the temperature constraints */ val temperatureToTriggerRequiredEnergy = if ( - innerTemperature <= state.innerTemperature && + currentInnerTemp <= state.innerTemperature && state.qDot <= Kilowatts(0d) - ) + ) { + // temperature has been decreasing and heat source has been turned off + // => we have reached target temp before and are now targeting lower temp lowerBoundaryTemperature - else targetTemperature + } else targetTemperature val requiredEnergy = if ( isInnerTemperatureTooLow( - innerTemperature, + currentInnerTemp, temperatureToTriggerRequiredEnergy ) - ) energy(targetTemperature, innerTemperature) + ) energy(targetTemperature, currentInnerTemp) else MegawattHours(0d) val possibleEnergy = - if (!isInnerTemperatureTooHigh(innerTemperature)) { - energy(upperBoundaryTemperature, innerTemperature) + if (!isInnerTemperatureTooHigh(currentInnerTemp)) { + // if upper boundary has not been reached, + // there is an amount of optional energy that could be stored + energy(upperBoundaryTemperature, currentInnerTemp) } else MegawattHours(0d) ThermalEnergyDemand(requiredEnergy, possibleEnergy) From 3ff9363bfb56ca0b315ecb95c341b168fa9b19ad Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 16:39:53 +0100 Subject: [PATCH 216/305] Setting config for trailing commas --- .scalafmt.conf | 4 ++++ gradle/scripts/spotless.gradle | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e69de29bb2..b9ff87f158 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -0,0 +1,4 @@ +version = 3.7.3 +runner.dialect = scala213 + +rewrite.trailingCommas.style = multiple diff --git a/gradle/scripts/spotless.gradle b/gradle/scripts/spotless.gradle index 525b407e68..104ff70c86 100644 --- a/gradle/scripts/spotless.gradle +++ b/gradle/scripts/spotless.gradle @@ -34,7 +34,7 @@ spotless { //sets a license header, removes unused imports and formats conforming to the scala fmt formatter scala { - scalafmt() + scalafmt().configFile(".scalafmt.conf") licenseHeader ie3LicHead, "package.*\\n" } From c3f3f5a49ab7beb132b0058f3f8dc4a72a68ec1d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 8 Feb 2024 16:40:21 +0100 Subject: [PATCH 217/305] Applying trailing commas --- .../edu/ie3/simona/actor/ActorUtil.scala | 2 +- .../ie3/simona/agent/EnvironmentRefs.scala | 2 +- .../edu/ie3/simona/agent/SimonaAgent.scala | 2 +- .../edu/ie3/simona/agent/ValueStore.scala | 8 +- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 180 +- .../edu/ie3/simona/agent/grid/GridAgent.scala | 36 +- .../agent/grid/GridAgentController.scala | 80 +- .../ie3/simona/agent/grid/GridAgentData.scala | 58 +- .../simona/agent/grid/GridEnvironment.scala | 2 +- .../agent/grid/GridResultsSupport.scala | 86 +- .../simona/agent/grid/PowerFlowParams.scala | 2 +- .../simona/agent/grid/PowerFlowSupport.scala | 72 +- .../agent/grid/ReceivedValuesStore.scala | 22 +- .../simona/agent/grid/SweepValueStore.scala | 4 +- .../agent/participant/ParticipantAgent.scala | 140 +- .../ParticipantAgentFundamentals.scala | 278 +-- .../participant/ServiceRegistration.scala | 16 +- .../simona/agent/participant/data/Data.scala | 18 +- .../agent/participant/evcs/EvcsAgent.scala | 32 +- .../evcs/EvcsAgentFundamentals.scala | 134 +- .../fixedfeedin/FixedFeedInAgent.scala | 10 +- .../FixedFeedInAgentFundamentals.scala | 68 +- .../simona/agent/participant/hp/HpAgent.scala | 12 +- .../participant/hp/HpAgentFundamentals.scala | 76 +- .../agent/participant/load/LoadAgent.scala | 32 +- .../load/LoadAgentFundamentals.scala | 114 +- .../simona/agent/participant/pv/PvAgent.scala | 14 +- .../participant/pv/PvAgentFundamentals.scala | 68 +- .../participant/statedata/BaseStateData.scala | 22 +- .../statedata/DataCollectionStateData.scala | 2 +- .../statedata/InitializeStateData.scala | 2 +- .../statedata/ParticipantStateData.scala | 36 +- .../agent/participant/wec/WecAgent.scala | 12 +- .../wec/WecAgentFundamentals.scala | 70 +- .../ie3/simona/agent/state/AgentState.scala | 2 +- .../edu/ie3/simona/api/ExtSimAdapter.scala | 14 +- .../edu/ie3/simona/config/ArgsParser.scala | 6 +- .../ie3/simona/config/ConfigFailFast.scala | 38 +- .../ie3/simona/config/RefSystemParser.scala | 4 +- .../edu/ie3/simona/config/SimonaConfig.scala | 622 +++--- .../edu/ie3/simona/config/VoltLvlParser.scala | 10 +- .../edu/ie3/simona/event/ResultEvent.scala | 6 +- .../edu/ie3/simona/event/RuntimeEvent.scala | 2 +- .../event/listener/ResultEventListener.scala | 42 +- .../event/listener/RuntimeEventListener.scala | 14 +- .../listener/SimonaListenerWithFilter.scala | 2 +- .../listener/Transformer3wResultSupport.scala | 18 +- .../event/notifier/NotifierConfig.scala | 2 +- .../exceptions/WeatherServiceException.scala | 8 +- .../ie3/simona/io/grid/CsvGridSource.scala | 6 +- .../edu/ie3/simona/io/grid/GridProvider.scala | 10 +- .../io/result/ResultEntityCsvSink.scala | 6 +- .../io/result/ResultEntityInfluxDbSink.scala | 2 +- .../io/result/ResultEntityKafkaSink.scala | 18 +- .../ie3/simona/io/result/ResultSinkType.scala | 8 +- .../simona/io/result/plain/PlainResult.scala | 2 +- .../simona/io/result/plain/PlainWriter.scala | 4 +- .../io/runtime/RuntimeEventKafkaSink.scala | 16 +- .../io/runtime/RuntimeEventLogSink.scala | 2 +- .../io/runtime/RuntimeEventQueueSink.scala | 2 +- .../simona/io/runtime/RuntimeEventSink.scala | 2 +- .../logging/SimonaFSMActorLogging.scala | 2 +- .../ie3/simona/logging/SimonaLogging.scala | 12 +- .../logback/LogbackConfiguration.scala | 4 +- .../scala/edu/ie3/simona/main/RunSimona.scala | 2 +- .../ie3/simona/main/RunSimonaStandalone.scala | 4 +- .../ie3/simona/model/SystemComponent.scala | 6 +- .../edu/ie3/simona/model/em/EmTools.scala | 6 +- .../edu/ie3/simona/model/grid/GridModel.scala | 62 +- .../edu/ie3/simona/model/grid/LineModel.scala | 24 +- .../edu/ie3/simona/model/grid/NodeModel.scala | 10 +- .../model/grid/PiEquivalentCircuit.scala | 2 +- .../edu/ie3/simona/model/grid/RefSystem.scala | 14 +- .../ie3/simona/model/grid/SwitchModel.scala | 10 +- .../model/grid/Transformer3wModel.scala | 56 +- .../grid/Transformer3wPowerFlowCase.scala | 2 +- .../simona/model/grid/TransformerModel.scala | 30 +- .../model/grid/TransformerTapping.scala | 2 +- .../model/grid/TransformerTappingModel.scala | 8 +- .../ApparentPowerAndHeatParticipant.scala | 6 +- .../ApparentPowerParticipant.scala | 2 +- .../simona/model/participant/BMModel.scala | 20 +- .../simona/model/participant/ChpModel.scala | 34 +- .../model/participant/FixedFeedInModel.scala | 20 +- .../participant/FlexChangeIndicator.scala | 2 +- .../simona/model/participant/HpModel.scala | 50 +- .../simona/model/participant/PvModel.scala | 58 +- .../model/participant/SystemParticipant.scala | 30 +- .../simona/model/participant/WecModel.scala | 28 +- .../model/participant/control/QControl.scala | 16 +- .../participant/evcs/EvModelWrapper.scala | 4 +- .../model/participant/evcs/EvcsModel.scala | 118 +- .../uncontrolled/ConstantPowerCharging.scala | 4 +- .../uncontrolled/MaximumPowerCharging.scala | 4 +- .../participant/load/FixedLoadModel.scala | 12 +- .../model/participant/load/LoadModel.scala | 16 +- .../participant/load/LoadReference.scala | 2 +- .../load/profile/LoadProfileKey.scala | 12 +- .../load/profile/LoadProfileStore.scala | 6 +- .../load/profile/ProfileLoadModel.scala | 14 +- .../load/random/RandomLoadModel.scala | 18 +- .../load/random/RandomLoadParamStore.scala | 12 +- .../simona/model/system/Characteristic.scala | 6 +- .../thermal/CylindricalThermalStorage.scala | 26 +- .../model/thermal/RandomStorageState.scala | 2 +- .../simona/model/thermal/ThermalGrid.scala | 82 +- .../simona/model/thermal/ThermalHouse.scala | 62 +- .../simona/model/thermal/ThermalSink.scala | 2 +- .../simona/model/thermal/ThermalStorage.scala | 6 +- .../ontology/messages/PowerMessage.scala | 10 +- .../ontology/messages/SchedulerMessage.scala | 4 +- .../ontology/messages/VoltageMessage.scala | 6 +- .../messages/flex/FlexibilityMessage.scala | 8 +- .../flex/MinMaxFlexibilityMessage.scala | 6 +- .../messages/services/EvMessage.scala | 8 +- .../services/PrimaryDataMessage.scala | 2 +- .../messages/services/ServiceMessage.scala | 4 +- .../messages/services/WeatherMessage.scala | 8 +- .../simona/scheduler/RuntimeNotifier.scala | 14 +- .../ie3/simona/scheduler/ScheduleLock.scala | 22 +- .../edu/ie3/simona/scheduler/Scheduler.scala | 30 +- .../ie3/simona/scheduler/TimeAdvancer.scala | 28 +- .../edu/ie3/simona/scheduler/core/Core.scala | 2 +- .../scheduler/core/PhaseSwitchCore.scala | 14 +- .../scheduler/core/RegularSchedulerCore.scala | 10 +- .../ie3/simona/service/SimonaService.scala | 18 +- .../simona/service/ev/ExtEvDataService.scala | 42 +- .../service/primary/PrimaryServiceProxy.scala | 94 +- .../primary/PrimaryServiceWorker.scala | 58 +- .../service/weather/SampleWeatherSource.scala | 14 +- .../service/weather/WeatherService.scala | 48 +- .../service/weather/WeatherSource.scala | 56 +- .../weather/WeatherSourceWrapper.scala | 62 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 26 +- .../simona/sim/setup/ExtSimSetupData.scala | 2 +- .../ie3/simona/sim/setup/SetupHelper.scala | 26 +- .../ie3/simona/sim/setup/SimonaSetup.scala | 14 +- .../sim/setup/SimonaStandaloneSetup.scala | 74 +- .../edu/ie3/simona/util/CollectionUtils.scala | 4 +- .../edu/ie3/simona/util/ConfigUtil.scala | 58 +- .../ie3/simona/util/EntityMapperUtil.scala | 4 +- .../edu/ie3/simona/util/ReceiveDataMap.scala | 10 +- .../ie3/simona/util/ResultFileHierarchy.scala | 20 +- .../scala/edu/ie3/simona/util/TickUtil.scala | 2 +- .../edu/ie3/util/scala/ReflectionTools.scala | 2 +- .../immutable/PrioritySwitchBiSet.scala | 14 +- .../mutable/PriorityMultiBiSet.scala | 12 +- .../util/scala/io/GraphicDataCleaner.scala | 4 +- .../util/scala/io/ScalaReflectionSerde.scala | 6 +- .../util/scala/quantities/EnergyDensity.scala | 2 +- .../util/scala/quantities/EnergyPrice.scala | 2 +- .../util/scala/quantities/QuantityUtil.scala | 16 +- .../util/scala/quantities/ReactivePower.scala | 2 +- .../scala/quantities/ScalaNumberSystem.scala | 2 +- .../quantities/SpecificHeatCapacity.scala | 6 +- .../scala/quantities/ThermalConductance.scala | 4 +- .../edu/ie3/simona/agent/ValueStoreSpec.scala | 8 +- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 116 +- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 42 +- .../grid/DBFSAlgorithmParticipantSpec.scala | 54 +- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 36 +- .../agent/grid/DBFSMockGridAgents.scala | 18 +- .../agent/grid/GridAgentDataHelperSpec.scala | 22 +- .../agent/grid/GridAgentSetup2WSpec.scala | 20 +- .../agent/grid/GridAgentSetup3WSpec.scala | 22 +- .../agent/grid/GridResultsSupportSpec.scala | 104 +- .../agent/grid/PowerFlowSupportSpec.scala | 72 +- .../agent/grid/ReceivedValuesStoreSpec.scala | 26 +- .../EvcsAgentModelCalculationSpec.scala | 258 +-- ...FixedFeedInAgentModelCalculationSpec.scala | 58 +- .../HpAgentModelCalculationSpec.scala | 138 +- .../LoadAgentFixedModelCalculationSpec.scala | 58 +- ...LoadAgentProfileModelCalculationSpec.scala | 52 +- .../ParticipantAgent2ListenerSpec.scala | 44 +- .../ParticipantAgentExternalSourceSpec.scala | 146 +- .../ParticipantAgentFundamentalsSpec.scala | 150 +- .../participant/ParticipantAgentMock.scala | 98 +- .../PvAgentModelCalculationSpec.scala | 132 +- .../agent/participant/RichValueSpec.scala | 42 +- .../WecAgentModelCalculationSpec.scala | 150 +- .../ie3/simona/api/ExtSimAdapterSpec.scala | 12 +- .../simona/config/ConfigFailFastSpec.scala | 70 +- .../simona/config/RefSystemParserSpec.scala | 40 +- .../edu/ie3/simona/deploy/DeploySpec.scala | 2 +- .../edu/ie3/simona/event/NotifierSpec.scala | 6 +- .../ie3/simona/event/SimonaListenerSpec.scala | 8 +- .../listener/ResultEventListenerSpec.scala | 62 +- .../RuntimeEventListenerKafkaSpec.scala | 18 +- .../listener/RuntimeEventListenerSpec.scala | 28 +- .../ThreeWindingResultHandlingSpec.scala | 16 +- .../listener/ThreeWindingResultTestData.scala | 8 +- .../integration/RunSimonaStandaloneIT.scala | 14 +- .../io/file/ResultFileHierarchySpec.scala | 8 +- .../io/result/ResultEntityCsvSinkSpec.scala | 16 +- .../io/result/ResultEntityKafkaSpec.scala | 26 +- .../simona/io/result/ResultSinkTypeSpec.scala | 22 +- .../io/result/plain/PlainWriterSpec.scala | 6 +- .../model/assets/control/QControlSpec.scala | 20 +- .../edu/ie3/simona/model/grid/GridSpec.scala | 40 +- .../edu/ie3/simona/model/grid/LineSpec.scala | 8 +- .../model/grid/NodeInputModelSpec.scala | 4 +- .../simona/model/grid/SwitchModelSpec.scala | 4 +- .../model/grid/SystemComponentSpec.scala | 4 +- .../model/grid/Transformer3wModelSpec.scala | 64 +- .../model/grid/TransformerModelSpec.scala | 40 +- .../ApparentPowerAndHeatSpec.scala | 20 +- .../participant/FixedFeedInModelSpec.scala | 6 +- .../model/participant/HpModelSpec.scala | 60 +- .../model/participant/HpModelTestData.scala | 30 +- .../participant/evcs/EvcsModelSpec.scala | 142 +- .../ConstantPowerChargingSpec.scala | 26 +- .../MaximumPowerChargingSpec.scala | 26 +- .../load/LoadModelScalingSpec.scala | 64 +- .../participant/load/LoadModelSpec.scala | 20 +- .../load/LoadProfileStoreSpec.scala | 18 +- .../load/ProfileLoadModelSpec.scala | 24 +- .../load/RandomLoadModelSpec.scala | 18 +- .../load/RandomLoadParamStoreSpec.scala | 28 +- .../load/TypeDayParametersSpec.scala | 6 +- .../model/thermal/ThermalGridSpec.scala | 4 +- .../model/thermal/ThermalGridTestData.scala | 2 +- .../ThermalGridWithHouseAndStorageSpec.scala | 90 +- .../ThermalGridWithHouseOnlySpec.scala | 42 +- .../ThermalGridWithStorageOnlySpec.scala | 40 +- .../model/thermal/ThermalHouseTestData.scala | 4 +- .../thermal/ThermalStorageTestData.scala | 6 +- .../flex/MinMaxFlexibilityMessageTest.scala | 8 +- .../scheduler/PhaseSwitchSchedulerSpec.scala | 26 +- .../ie3/simona/scheduler/ScheduleLockIT.scala | 22 +- .../simona/scheduler/ScheduleLockSpec.scala | 4 +- .../ie3/simona/scheduler/SchedulerSpec.scala | 40 +- .../simona/scheduler/TimeAdvancerSpec.scala | 24 +- .../service/ev/ExtEvDataServiceSpec.scala | 56 +- .../primary/PrimaryServiceProxySpec.scala | 124 +- .../primary/PrimaryServiceProxySqlIT.scala | 24 +- .../primary/PrimaryServiceWorkerSpec.scala | 50 +- .../primary/PrimaryServiceWorkerSqlIT.scala | 32 +- .../weather/SampleWeatherSourceSpec.scala | 10 +- .../service/weather/WeatherServiceSpec.scala | 34 +- .../service/weather/WeatherSourceSpec.scala | 88 +- .../weather/WeatherSourceWrapperSpec.scala | 72 +- .../ie3/simona/sim/SimonaSimFailSpec.scala | 28 +- .../simona/sim/setup/SetupHelperSpec.scala | 18 +- .../simona/sim/setup/SimonaSetupSpec.scala | 16 +- .../edu/ie3/simona/test/KafkaSpecLike.scala | 4 +- .../simona/test/common/DefaultTestData.scala | 6 +- .../ie3/simona/test/common/EvTestData.scala | 4 +- .../test/common/SilentTestEventListener.scala | 2 +- .../test/common/ThreeWindingTestData.scala | 20 +- .../CylindricalStorageInputTestData.scala | 4 +- .../test/common/input/EvcsInputTestData.scala | 4 +- .../common/input/FixedFeedInputTestData.scala | 2 +- .../test/common/input/GridInputTestData.scala | 14 +- .../test/common/input/LineInputTestData.scala | 30 +- .../test/common/input/LoadInputTestData.scala | 2 +- .../test/common/input/NodeInputTestData.scala | 12 +- .../test/common/input/PvInputTestData.scala | 2 +- .../common/input/SwitchInputTestData.scala | 6 +- .../common/input/TimeSeriesTestData.scala | 6 +- .../common/input/Transformer3wTestData.scala | 76 +- .../input/TransformerInputTestData.scala | 18 +- .../test/common/input/WecInputTestData.scala | 2 +- .../common/input/WecTypeInputTestData.scala | 2 +- .../test/common/model/grid/BasicGrid.scala | 10 +- .../model/grid/BasicGridWithSwitches.scala | 42 +- .../test/common/model/grid/DbfsTestGrid.scala | 74 +- .../grid/DbfsTestGridWithParticipants.scala | 24 +- .../model/grid/FiveLinesWithNodes.scala | 46 +- .../common/model/grid/SubGridGateMokka.scala | 10 +- .../test/common/model/grid/TapTestData.scala | 88 +- .../model/grid/TransformerTestData.scala | 1858 ++++++++--------- .../model/grid/TransformerTestGrid.scala | 32 +- .../common/model/participant/HpTestData.scala | 14 +- .../model/participant/LoadTestData.scala | 2 +- .../common/result/PowerFlowResultData.scala | 12 +- .../test/matchers/QuantityMatchers.scala | 18 +- .../test/matchers/QuantityMatchersSpec.scala | 4 +- .../test/matchers/SquantsMatchers.scala | 2 +- .../edu/ie3/simona/util/ActorUtils.scala | 4 +- .../ie3/simona/util/CollectionUtilsSpec.scala | 6 +- .../edu/ie3/simona/util/ConfigUtilSpec.scala | 118 +- .../edu/ie3/simona/util/TestGridFactory.scala | 20 +- .../ie3/util/quantities/IrradianceSpec.scala | 2 +- .../ie3/util/quantities/IrradiationSpec.scala | 2 +- .../util/quantities/QuantityUtilSpec.scala | 26 +- .../quantities/SpecificHeatCapacitySpec.scala | 4 +- .../quantities/ThermalConductanceSpec.scala | 4 +- 287 files changed, 5396 insertions(+), 5396 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/actor/ActorUtil.scala b/src/main/scala/edu/ie3/simona/actor/ActorUtil.scala index 6f59446915..bfe44d97ad 100644 --- a/src/main/scala/edu/ie3/simona/actor/ActorUtil.scala +++ b/src/main/scala/edu/ie3/simona/actor/ActorUtil.scala @@ -12,7 +12,7 @@ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} object ActorUtil { def stopOnError[M]( ctx: ActorContext[M], - msg: String + msg: String, ): Behavior[M] = { ctx.log.error(s"$msg. Stopping.") Behaviors.stopped diff --git a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala index af7b168e41..2179b90202 100644 --- a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala +++ b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala @@ -27,5 +27,5 @@ final case class EnvironmentRefs( runtimeEventListener: ActorRef, primaryServiceProxy: ActorRef, weather: ActorRef, - evDataService: Option[ActorRef] + evDataService: Option[ActorRef], ) diff --git a/src/main/scala/edu/ie3/simona/agent/SimonaAgent.scala b/src/main/scala/edu/ie3/simona/agent/SimonaAgent.scala index cfdd3372c3..ff916942fd 100644 --- a/src/main/scala/edu/ie3/simona/agent/SimonaAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/SimonaAgent.scala @@ -37,7 +37,7 @@ trait SimonaAgent[D] case Event(Status.Failure(ex), _) => log.error( ex, - "Received a failure status message with following exception." + "Received a failure status message with following exception.", ) self ! PoisonPill stay() diff --git a/src/main/scala/edu/ie3/simona/agent/ValueStore.scala b/src/main/scala/edu/ie3/simona/agent/ValueStore.scala index 38fea13e80..a21f7d0f58 100644 --- a/src/main/scala/edu/ie3/simona/agent/ValueStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/ValueStore.scala @@ -22,7 +22,7 @@ import scala.collection.SortedMap */ final case class ValueStore[+D]( maxTickSpan: Long, - private val store: SortedMap[Long, D] = SortedMap.empty[Long, D] + private val store: SortedMap[Long, D] = SortedMap.empty[Long, D], ) { /** Determine the lastly known data tick, if available. Includes the given @@ -105,11 +105,11 @@ object ValueStore { */ def forVoltage( maxTickSpan: Long, - initialPerUnit: Dimensionless + initialPerUnit: Dimensionless, ): ValueStore[Dimensionless] = new ValueStore( maxTickSpan, - SortedMap(SimonaConstants.FIRST_TICK_IN_SIMULATION -> initialPerUnit) + SortedMap(SimonaConstants.FIRST_TICK_IN_SIMULATION -> initialPerUnit), ) /** Create a value store for result values. A result value store requires a @@ -144,7 +144,7 @@ object ValueStore { def updateValueStore[D]( valueStore: ValueStore[D], tick: Long, - newEntry: D + newEntry: D, ): ValueStore[D] = { val updatedStore = valueStore.store ++ SortedMap(tick -> newEntry) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index 309fb1b7ef..1cab5c0589 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -22,7 +22,7 @@ import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.simona.agent.grid.GridAgent._ import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, - PowerFlowDoneData + PowerFlowDoneData, } import edu.ie3.simona.agent.grid.ReceivedValues._ import edu.ie3.simona.agent.state.AgentState @@ -30,7 +30,7 @@ import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.agent.state.GridAgentState.{ CheckPowerDifferences, HandlePowerFlowCalculations, - SimulateGrid + SimulateGrid, } import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException @@ -41,7 +41,7 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.simona.ontology.messages.VoltageMessage.{ ProvideSlackVoltageMessage, - RequestSlackVoltageMessage + RequestSlackVoltageMessage, } import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.scala.quantities.Megavars @@ -69,7 +69,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // we start with a forward-sweep by requesting the data from our child assets and grids (if any) case Event( Activation(currentTick), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => log.debug("Start sweep number: {}", gridAgentBaseData.currentSweepNo) // hold tick and trigger for the whole time the dbfs is executed or @@ -85,7 +85,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .get(gridAgentBaseData.currentSweepNo), gridAgentBaseData.gridEnv.nodeToAssetAgents, gridAgentBaseData.gridEnv.gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) // 2. inferior grids p/q values @@ -93,7 +93,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.currentSweepNo, gridAgentBaseData.gridEnv.subgridGateToActorRef, gridAgentBaseData.inferiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) // 3. superior grids slack voltage @@ -101,7 +101,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.currentSweepNo, gridAgentBaseData.gridEnv.subgridGateToActorRef, gridAgentBaseData.superiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) stay() @@ -109,7 +109,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // if we receive power values as response on our request, we process them here case Event( receivedValues: ReceivedValues, - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => // we just received either all provided slack voltage values or all provided power values val updatedGridAgentBaseData: GridAgentBaseData = receivedValues match { @@ -137,31 +137,31 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { if (allValuesReceived) "Got answers for all my requests for Slack Voltages and Power Values." else - "Still waiting for answers my requests for Slack Voltages and Power Values." + "Still waiting for answers my requests for Slack Voltages and Power Values.", ) if (gridAgentBaseData.isSuperior) { goToCheckPowerDifferencesOrStay( allValuesReceived, - updatedGridAgentBaseData + updatedGridAgentBaseData, ) } else { goToPowerFlowCalculationOrStay( allValuesReceived, - updatedGridAgentBaseData + updatedGridAgentBaseData, ) } // if we receive a request for slack voltages from our inferior grids we want to answer it case Event( RequestSlackVoltageMessage(currentSweepNo, nodeUuids), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => log.debug( s"Received Slack Voltages request from {} for nodes {} and sweepNo: {}", sender(), nodeUuids, - gridAgentBaseData.currentSweepNo + gridAgentBaseData.currentSweepNo, ) nodeUuids.map { nodeUuid => @@ -177,7 +177,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { log.debug( "Unable to find slack voltage for nodes '{}' in sweep '{}'. Try to get voltage of previous sweep.", nodeUuids, - currentSweepNo + currentSweepNo, ) gridAgentBaseData.sweepValueStores .get(currentSweepNo - 1) @@ -191,7 +191,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.gridEnv.gridModel.mainRefSystem ( mainRefSystem.vInSi(slackVoltageInPu.real), - mainRefSystem.vInSi(slackVoltageInPu.imag) + mainRefSystem.vInSi(slackVoltageInPu.imag), ) case None => throw new DBFSAlgorithmException( @@ -205,7 +205,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { "Unable to get slack voltage for node '{}' in sweeps '{}' and '{}'. Returning target voltage.", nodeUuid, currentSweepNo, - currentSweepNo - 1 + currentSweepNo - 1, ) val refSystem = @@ -224,7 +224,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ( vSlack, - refSystem.vInSi(0d) + refSystem.vInSi(0d), ) } match { case (slackE, slackF) => @@ -233,7 +233,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { s"$slackE, $slackF", sender(), nodeUuid, - gridAgentBaseData.currentSweepNo + gridAgentBaseData.currentSweepNo, ) ExchangeVoltage(nodeUuid, slackE, slackF) @@ -242,7 +242,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { case exchangeVoltages => stay() replying ProvideSlackVoltageMessage( currentSweepNo, - exchangeVoltages + exchangeVoltages, ) } @@ -251,12 +251,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // / or trigger a new run for the next sweepNo case Event( RequestGridPowerMessage(requestSweepNo, _), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => if (gridAgentBaseData.currentSweepNo == requestSweepNo) { log.debug( s"Received request for grid power values for sweepNo {} before my first power flow calc. Stashing away.", - requestSweepNo + requestSweepNo, ) stash() stay() @@ -264,7 +264,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { log.debug( s"Received request for grid power values for a NEW sweep (request: {}, my: {})", requestSweepNo, - gridAgentBaseData.currentSweepNo + gridAgentBaseData.currentSweepNo, ) self ! PrepareNextSweepTrigger(currentTick) @@ -278,8 +278,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { powerFlowDoneData @ PowerFlowDoneData( gridAgentBaseData, powerFlowResult, - pendingRequestAnswers - ) + pendingRequestAnswers, + ), ) => /* Determine the subgrid number of the grid agent, that has sent the request */ val firstRequestedNodeUuid = requestedNodeUuids.headOption.getOrElse( @@ -319,13 +319,13 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // (Inferior grid is a feed in facility to superior grid, which is negative then). Analogously for load case. ( refSystem.pInSi(pInPu) * (-1), - refSystem.qInSi(qInPu) * (-1) + refSystem.qInSi(qInPu) * (-1), ) case _ => /* TODO: As long as there are no multiple slack nodes, provide "real" power only for the slack node */ ( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) } .getOrElse { @@ -338,7 +338,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ProvideGridPowerMessage.ExchangePower( nodeUuid, p, - q + q, ) } @@ -355,7 +355,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.storeSweepDataAndClearReceiveMaps( validNewtonRaphsonPFResult, gridAgentBaseData.superiorGridNodeUuids, - gridAgentBaseData.inferiorGridGates + gridAgentBaseData.inferiorGridGates, ) } else { powerFlowDoneData.copy(pendingRequestAnswers = @@ -385,14 +385,14 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // based on the just carried out power flow case Event( PrepareNextSweepTrigger(_), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => // request the updated slack voltages from the superior grid askSuperiorGridsForSlackVoltages( gridAgentBaseData.currentSweepNo, gridAgentBaseData.gridEnv.subgridGateToActorRef, gridAgentBaseData.superiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) log.debug(s"Going to {}", HandlePowerFlowCalculations) @@ -403,7 +403,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // b) cleanup of receiveMaps and sweepStore case Event( FinishGridSimulationTrigger(currentTick), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => // inform my child grids about the end of this grid simulation gridAgentBaseData.inferiorGridGates @@ -426,7 +426,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { log.debug("Calculate results and sending the results to the listener ...") createAndSendPowerFlowResults( gridAgentBaseData, - currentTick.toDateTime(simStartTime) + currentTick.toDateTime(simStartTime), ) // do my cleanup stuff @@ -436,7 +436,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { val cleanedGridAgentBaseData = GridAgentBaseData.clean( gridAgentBaseData, gridAgentBaseData.superiorGridNodeUuids, - gridAgentBaseData.inferiorGridGates + gridAgentBaseData.inferiorGridGates, ) // / release tick for the whole simulation (StartGridSimulationTrigger) @@ -445,7 +445,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // / inform scheduler that we are done with the whole simulation and request new trigger for next time step environmentRefs.scheduler ! Completion( self.toTyped, - Some(currentTick + resolution) + Some(currentTick + resolution), ) // return to Idle @@ -462,11 +462,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // main method for power flow calculations case Event( DoPowerFlowTrigger(currentTick, _), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => log.debug( "Received the following power values to the corresponding nodes: {}", - gridAgentBaseData.receivedValueStore.nodeToReceivedPower + gridAgentBaseData.receivedValueStore.nodeToReceivedPower, ) val gridModel = gridAgentBaseData.gridEnv.gridModel @@ -477,14 +477,14 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridModel.gridComponents.transformers3w, gridModel.nodeUuidToIndexMap, gridAgentBaseData.receivedValueStore, - gridModel.mainRefSystem + gridModel.mainRefSystem, ) newtonRaphsonPF( gridModel, gridAgentBaseData.powerFlowParams.maxIterations, operatingPoint, - slackNodeVoltages + slackNodeVoltages, )(gridAgentBaseData.powerFlowParams.epsilon) match { // if res is valid, ask our assets (if any) for updated power values based on the newly determined nodal voltages case validPowerFlowResult: ValidNewtonRaphsonPFResult => @@ -492,8 +492,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { "{}", composeValidNewtonRaphsonPFResultVoltagesDebugString( validPowerFlowResult, - gridModel - ) + gridModel, + ), ) val powerFlowDoneData = @@ -503,7 +503,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { SweepValueStore( validPowerFlowResult, gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap + gridModel.nodeUuidToIndexMap, ) ) askForAssetPowers( @@ -511,14 +511,14 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { sweepValueStoreOpt, gridAgentBaseData.gridEnv.nodeToAssetAgents, gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) match { case None => // when we don't have assets we can skip another request for different asset behaviour due to changed // voltage values and go back to SimulateGrid directly log.debug( s"No generation or load assets in the grid. Going back to {}.", - SimulateGrid + SimulateGrid, ) unstashAll() // we can answer the stashed grid power requests now goto(SimulateGrid) using powerFlowDoneData @@ -541,7 +541,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // of assets based on updated nodal voltages case Event( receivedPowerValues: ReceivedPowerValues, - powerFlowDoneData: PowerFlowDoneData + powerFlowDoneData: PowerFlowDoneData, ) => val gridAgentBaseData = powerFlowDoneData.gridAgentBaseData @@ -562,7 +562,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { case receivedPowers: ReceivedPowerValues => gridAgentBaseData.updateWithReceivedPowerValues( receivedPowers, - replace = true + replace = true, ) case unknownValuesReceived => throw new DBFSAlgorithmException( @@ -580,19 +580,19 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { if (readyForPowerFlow) "Got answers for all my requests for Slack Voltages and Power Values." else - "Still waiting for answers my requests for Slack Voltages and Power Values." + "Still waiting for answers my requests for Slack Voltages and Power Values.", ) goToPowerFlowCalculationOrStay( readyForPowerFlow, - updatedGridAgentBaseData + updatedGridAgentBaseData, ) } else { // no changes from assets, we want to go back to SimulateGrid and report the LF results to our parent grids if any requests log.debug( s"Assets have not changed their exchanged power or no voltage dependent behaviour. Going back to {}.", - SimulateGrid + SimulateGrid, ) unstashAll() // we can answer the stashed grid power requests now goto(SimulateGrid) using powerFlowDoneData @@ -604,7 +604,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // updated power values for our power flow calculations case Event( receivedSlackValues: ReceivedSlackVoltageValues, - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => log.debug( "Received Slack values for new forward sweep with same power but updated voltage values" @@ -616,7 +616,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.currentSweepNo - 1, throw new DBFSAlgorithmException( s"$actorName Unable to get results from previous sweep ${gridAgentBaseData.currentSweepNo - 1}!" - ) + ), ) val (operatingPoint, slackNodeVoltages) = @@ -625,29 +625,29 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { previousSweepData.sweepData, gridModel.gridComponents.transformers, gridModel.gridComponents.transformers3w, - gridModel.mainRefSystem + gridModel.mainRefSystem, ) newtonRaphsonPF( gridModel, gridAgentBaseData.powerFlowParams.maxIterations, operatingPoint, - slackNodeVoltages + slackNodeVoltages, )(gridAgentBaseData.powerFlowParams.epsilon) match { case validPowerFlowResult: ValidNewtonRaphsonPFResult => log.debug( "{}", composeValidNewtonRaphsonPFResultVoltagesDebugString( validPowerFlowResult, - gridModel - ) + gridModel, + ), ) // update the data val sweepValueStore = SweepValueStore( validPowerFlowResult, gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap + gridModel.nodeUuidToIndexMap, ) val updatedSweepValueStore = gridAgentBaseData.sweepValueStores + (gridAgentBaseData.currentSweepNo -> sweepValueStore) @@ -662,7 +662,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { Some(sweepValueStore), gridAgentBaseData.gridEnv.nodeToAssetAgents, gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) // 2. inferior grids p/q values @@ -671,7 +671,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.currentSweepNo, gridAgentBaseData.gridEnv.subgridGateToActorRef, gridAgentBaseData.inferiorGridGates, - gridAgentBaseData.powerFlowParams.sweepTimeout + gridAgentBaseData.powerFlowParams.sweepTimeout, ) // when we don't have inferior grids and no assets both methods return None and we can skip doing another power @@ -704,7 +704,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { val powerFlowDoneData = PowerFlowDoneData( gridAgentBaseData, - failedNewtonRaphsonPFResult + failedNewtonRaphsonPFResult, ) log.warning( "Power flow with updated slack voltage did finally not converge!" @@ -719,7 +719,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // by a superior grid arrives) case Event( _: RequestGridPowerMessage, - _: GridAgentBaseData + _: GridAgentBaseData, ) => log.debug("Received Request for Grid Power too early. Stashing away") stash() @@ -730,7 +730,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // with its power flow calculation in this state as the request by a superior grid arrives) case Event( _: RequestGridPowerMessage, - _: PowerFlowDoneData + _: PowerFlowDoneData, ) => log.debug("Received Request for Grid Power too early. Stashing away") stash() @@ -743,7 +743,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { case Event( CheckPowerDifferencesTrigger(currentTick), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => log.debug("Starting the power differences check ...") val currentSweepNo = gridAgentBaseData.currentSweepNo @@ -759,7 +759,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridModel.nodeUuidToIndexMap, gridAgentBaseData.receivedValueStore, gridModel.mainRefSystem, - targetVoltageFromReceivedData = false + targetVoltageFromReceivedData = false, ) /* Regarding the power flow result of this grid, there are two cases. If this is the "highest" grid in a @@ -777,15 +777,15 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridModel, gridAgentBaseData.powerFlowParams.maxIterations, operationPoint, - slackNodeVoltages + slackNodeVoltages, )(gridAgentBaseData.powerFlowParams.epsilon) match { case validPowerFlowResult: ValidNewtonRaphsonPFResult => log.debug( "{}", composeValidNewtonRaphsonPFResultVoltagesDebugString( validPowerFlowResult, - gridModel - ) + gridModel, + ), ) validPowerFlowResult case result: PowerFlowResult.FailedPowerFlowResult => @@ -798,7 +798,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .storeSweepDataAndClearReceiveMaps( validResult, gridAgentBaseData.superiorGridNodeUuids, - gridAgentBaseData.inferiorGridGates + gridAgentBaseData.inferiorGridGates, ) .copy(currentSweepNo = currentSweepNo + 1) @@ -808,7 +808,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { log.debug("Sweep value store is empty. Starting a second sweep ...") goToSimulateGridForNextSweepWith( updatedGridAgentBaseData, - currentTick + currentTick, ) } else { log.debug("Sweep value store is not empty. Check for deviation ...") @@ -821,7 +821,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo - 1, throw new DBFSAlgorithmException( s"No data for previous sweep with no ${currentSweepNo - 1} available!" - ) + ), ) .sweepData .map(_.stateData.power) @@ -834,7 +834,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo, throw new DBFSAlgorithmException( s"No data for current sweep with no $currentSweepNo available!" - ) + ), ) .sweepData .map(_.stateData.power) @@ -852,18 +852,18 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { case Some(deviation) => // next sweep log.debug( "Deviation between the last two sweeps: {}", - deviation + deviation, ) goToSimulateGridForNextSweepWith( updatedGridAgentBaseData, - currentTick + currentTick, ) case None => // we're done log.debug("We found a result! :-)") log.debug( "Final deviation: {}", - (previousSweepNodePower - currentSweepNodePower).toScalaVector + (previousSweepNodePower - currentSweepNodePower).toScalaVector, ) // go back to SimulateGrid and trigger a finish @@ -876,7 +876,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { log.warning( "Power flow for high voltage branch of three winding transformer failed after {} iterations. Cause: {}", failedResult.iteration, - failedResult.cause + failedResult.cause, ) self ! FinishGridSimulationTrigger(currentTick) handlePowerFlowFailure(gridAgentBaseData) @@ -904,7 +904,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ private def goToPowerFlowCalculationOrStay( allReceived: Boolean, - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ): FSM.State[AgentState, GridAgentData] = { if (allReceived) { @@ -922,7 +922,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { unstashAll() // we want to answer the requests from our parent stay() using PowerFlowDoneData( gridAgentBaseData, - FailedNewtonRaphsonPFResult(-1, CalculationFailed) + FailedNewtonRaphsonPFResult(-1, CalculationFailed), ) } else { self ! DoPowerFlowTrigger(currentTick, gridAgentBaseData.currentSweepNo) @@ -964,7 +964,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ private def goToCheckPowerDifferencesOrStay( allReceived: Boolean, - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ): FSM.State[AgentState, GridAgentData] = { if (allReceived) { log.debug("All power values of child assets + inferior grids received.") @@ -1022,13 +1022,13 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ private def goToSimulateGridForNextSweepWith( gridAgentBaseData: GridAgentBaseData, - currentTick: Long + currentTick: Long, ): FSM.State[AgentState, GridAgentData] = { releaseTick() environmentRefs.scheduler ! Completion( self.toTyped, - Some(currentTick) + Some(currentTick), ) goto(SimulateGrid) using gridAgentBaseData @@ -1060,7 +1060,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { sweepValueStore: Option[SweepValueStore], nodeToAssetAgents: Map[UUID, Set[ActorRef]], refSystem: RefSystem, - askTimeout: Duration + askTimeout: Duration, ): Option[Future[ReceivedPowerValues]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) @@ -1090,19 +1090,19 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) ( refSystem.vInPu(eInSi), - refSystem.vInPu(fInSi) + refSystem.vInPu(fInSi), ) case None => ( Each(1d), - Each(0d) + Each(0d), ) } (assetAgent ? RequestAssetPowerMessage( currentTick, eInPu, - fInPU + fInPU, )).map { case providedPowerValuesMessage: AssetPowerChangedMessage => (assetAgent, providedPowerValuesMessage) @@ -1137,12 +1137,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo: Int, subGridGateToActorRef: Map[SubGridGate, ActorRef], inferiorGridGates: Seq[SubGridGate], - askTimeout: Duration + askTimeout: Duration, ): Option[Future[ReceivedPowerValues]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) log.debug( s"asking inferior grids for power values: {}", - inferiorGridGates + inferiorGridGates, ) Option.when(inferiorGridGates.nonEmpty) { Future @@ -1163,7 +1163,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .map { case (inferiorGridAgentRef, inferiorGridGateNodes) => (inferiorGridAgentRef ? RequestGridPowerMessage( currentSweepNo, - inferiorGridGateNodes.distinct + inferiorGridGateNodes.distinct, )).map { case provideGridPowerMessage: ProvideGridPowerMessage => (inferiorGridAgentRef, provideGridPowerMessage) @@ -1196,12 +1196,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo: Int, subGridGateToActorRef: Map[SubGridGate, ActorRef], superiorGridGates: Vector[SubGridGate], - askTimeout: Duration + askTimeout: Duration, ): Option[Future[ReceivedSlackVoltageValues]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) log.debug( s"asking superior grids for slack voltage values: {}", - superiorGridGates + superiorGridGates, ) Option.when(superiorGridGates.nonEmpty) { @@ -1212,7 +1212,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .map { case (superiorGridAgent, gridGates) => (superiorGridAgent ? RequestSlackVoltageMessage( currentSweepNo, - gridGates.map(_.superiorNode.getUuid) + gridGates.map(_.superiorNode.getUuid), )).map { case providedSlackValues: ProvideSlackVoltageMessage => (superiorGridAgent, providedSlackValues) } @@ -1238,14 +1238,14 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ def createAndSendPowerFlowResults( gridAgentBaseData: GridAgentBaseData, - currentTimestamp: ZonedDateTime + currentTimestamp: ZonedDateTime, ): Unit = { gridAgentBaseData.sweepValueStores.lastOption.foreach { case (_, valueStore) => notifyListener( this.createResultModels( gridAgentBaseData.gridEnv.gridModel, - valueStore + valueStore, )( currentTimestamp ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index b8677f607a..8ea4b12f5d 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -10,7 +10,7 @@ import edu.ie3.simona.agent.grid.GridAgent.Create import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, GridAgentInitData, - GridAgentUninitializedData + GridAgentUninitializedData, } import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.{Initializing, SimulateGrid} @@ -21,7 +21,7 @@ import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey @@ -39,13 +39,13 @@ object GridAgent { def props( environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props( new GridAgent( environmentRefs, simonaConfig, - listener + listener, ) ) @@ -56,7 +56,7 @@ object GridAgent { */ final case class Create( gridAgentInitData: GridAgentInitData, - unlockKey: ScheduleKey + unlockKey: ScheduleKey, ) /** Trigger used inside of [[edu.ie3.simona.agent.grid.DBFSAlgorithm]] to @@ -98,7 +98,7 @@ object GridAgent { class GridAgent( val environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - val listener: Iterable[ActorRef] + val listener: Iterable[ActorRef], ) extends SimonaAgent[GridAgentData] with DBFSAlgorithm with Stash { @@ -122,7 +122,7 @@ class GridAgent( simonaConfig.simona.output.participant, resolution, listener, - log + log, ) override def postStop(): Unit = { @@ -140,12 +140,12 @@ class GridAgent( when(Uninitialized) { case Event( Create(gridAgentInitData, unlockKey), - _ + _, ) => environmentRefs.scheduler ! ScheduleActivation( self.toTyped, INIT_SIM_TICK, - Some(unlockKey) + Some(unlockKey), ) goto(Initializing) using gridAgentInitData @@ -154,7 +154,7 @@ class GridAgent( when(Initializing) { case Event( Activation(INIT_SIM_TICK), - gridAgentInitData: GridAgentInitData + gridAgentInitData: GridAgentInitData, ) => // fail fast sanity checks failFast(gridAgentInitData) @@ -162,13 +162,13 @@ class GridAgent( log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", gridAgentInitData.inferiorGridIds, - gridAgentInitData.inferiorGridNodeUuids + gridAgentInitData.inferiorGridNodeUuids, ) log.debug( s"Superior Subnets: {}; Superior Subnet Nodes: {}", gridAgentInitData.superiorGridIds, - gridAgentInitData.superiorGridNodeUuids + gridAgentInitData.superiorGridNodeUuids, ) log.debug("Received InitializeTrigger.") @@ -189,7 +189,7 @@ class GridAgent( .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime - ) + ), ) /* Reassure, that there are also calculation models for the given uuids */ @@ -220,17 +220,17 @@ class GridAgent( simonaConfig.simona.powerflow.newtonraphson.epsilon.toVector.sorted, simonaConfig.simona.powerflow.newtonraphson.iterations, simonaConfig.simona.powerflow.sweepTimeout, - simonaConfig.simona.powerflow.stopOnFailure + simonaConfig.simona.powerflow.stopOnFailure, ), log, - actorName + actorName, ) log.debug("Je suis initialized") environmentRefs.scheduler ! Completion( self.toTyped, - Some(resolution) + Some(resolution), ) goto(Idle) using gridAgentBaseData @@ -246,13 +246,13 @@ class GridAgent( case Event( Activation(tick), - gridAgentBaseData: GridAgentBaseData + gridAgentBaseData: GridAgentBaseData, ) => unstashAll() environmentRefs.scheduler ! Completion( self.toTyped, - Some(tick) + Some(tick), ) goto(SimulateGrid) using gridAgentBaseData diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala index 236f398d82..895afb7cc1 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.actor.SimonaActorNaming._ import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.{ ActorEvMovementsService, - ActorWeatherService + ActorWeatherService, } import edu.ie3.simona.agent.participant.evcs.EvcsAgent import edu.ie3.simona.agent.participant.fixedfeedin.FixedFeedInAgent @@ -70,11 +70,11 @@ class GridAgentController( outputConfig: SimonaConfig.Simona.Output.Participant, resolution: Long, listener: Iterable[ActorRef], - log: LoggingAdapter + log: LoggingAdapter, ) extends LazyLogging { def buildSystemParticipants( subGridContainer: SubGridContainer, - thermalIslandGridsByBusId: Map[UUID, ThermalGrid] + thermalIslandGridsByBusId: Map[UUID, ThermalGrid], ): Map[UUID, Set[ActorRef]] = { val systemParticipants = @@ -86,7 +86,7 @@ class GridAgentController( outputConfig, systemParticipants, thermalIslandGridsByBusId, - environmentRefs + environmentRefs, ) } @@ -105,7 +105,7 @@ class GridAgentController( */ private def filterSysParts( subGridContainer: SubGridContainer, - environmentRefs: EnvironmentRefs + environmentRefs: EnvironmentRefs, ) = { val (notProcessedElements, availableSysParts) = @@ -115,14 +115,14 @@ class GridAgentController( .foldLeft((Set.empty[String], Vector.empty[SystemParticipantInput])) { case ( (notProcessedElements, availableSystemParticipants), - curSysPart + curSysPart, ) => curSysPart match { case entity @ (_: BmInput | _: ChpInput | _: EvInput | _: StorageInput) => ( notProcessedElements + entity.getClass.getSimpleName, - availableSystemParticipants + availableSystemParticipants, ) // only include evcs if ev data service is present case evcsInput: EvcsInput @@ -169,7 +169,7 @@ class GridAgentController( outputConfig: SimonaConfig.Simona.Output.Participant, participants: Vector[SystemParticipantInput], thermalIslandGridsByBusId: Map[UUID, ThermalGrid], - environmentRefs: EnvironmentRefs + environmentRefs: EnvironmentRefs, ): Map[UUID, Set[ActorRef]] = { /* Prepare the config util for the participant models, which (possibly) utilizes as map to speed up the initialization * phase */ @@ -188,7 +188,7 @@ class GridAgentController( outputConfigUtil, participant, thermalIslandGridsByBusId, - environmentRefs + environmentRefs, ) introduceAgentToEnvironment(actorRef) // return uuid to actorRef @@ -204,7 +204,7 @@ class GridAgentController( outputConfigUtil: OutputConfigUtil, participantInputModel: SystemParticipantInput, thermalIslandGridsByBusId: Map[UUID, ThermalGrid], - environmentRefs: EnvironmentRefs + environmentRefs: EnvironmentRefs, ): ActorRef = participantInputModel match { case input: FixedFeedInInput => buildFixedFeedIn( @@ -217,7 +217,7 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.FixedFeedIn) + outputConfigUtil.getOrDefault(NotifierIdentifier.FixedFeedIn), ) case input: LoadInput => buildLoad( @@ -230,7 +230,7 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.Load) + outputConfigUtil.getOrDefault(NotifierIdentifier.Load), ) case input: PvInput => buildPv( @@ -244,7 +244,7 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.PvPlant) + outputConfigUtil.getOrDefault(NotifierIdentifier.PvPlant), ) case input: WecInput => buildWec( @@ -258,7 +258,7 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.Wec) + outputConfigUtil.getOrDefault(NotifierIdentifier.Wec), ) case input: EvcsInput => buildEvcs( @@ -276,7 +276,7 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.Evcs) + outputConfigUtil.getOrDefault(NotifierIdentifier.Evcs), ) case hpInput: HpInput => thermalIslandGridsByBusId.get(hpInput.getThermalBus.getUuid) match { @@ -288,7 +288,7 @@ class GridAgentController( environmentRefs.primaryServiceProxy, environmentRefs.weather, requestVoltageDeviationThreshold, - outputConfigUtil.getOrDefault(NotifierIdentifier.Hp) + outputConfigUtil.getOrDefault(NotifierIdentifier.Hp), ) case None => throw new GridAgentInitializationException( @@ -335,7 +335,7 @@ class GridAgentController( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( FixedFeedInAgent.props( @@ -349,11 +349,11 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ), - fixedFeedInInput.getId + fixedFeedInInput.getId, ) /** Creates a load agent and determines the needed additional information for @@ -386,7 +386,7 @@ class GridAgentController( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( LoadAgent.props( @@ -400,11 +400,11 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ), - loadInput.getId + loadInput.getId, ) /** Creates a pv agent and determines the needed additional information for @@ -440,7 +440,7 @@ class GridAgentController( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( PvAgent.props( @@ -454,11 +454,11 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ), - pvInput.getId + pvInput.getId, ) /** Creates an Evcs agent and determines the needed additional information for @@ -494,7 +494,7 @@ class GridAgentController( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( EvcsAgent.props( @@ -512,9 +512,9 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ) ) @@ -543,7 +543,7 @@ class GridAgentController( primaryServiceProxy: ActorRef, weatherService: ActorRef, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( HpAgent.props( @@ -558,11 +558,11 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ), - hpInput.getId + hpInput.getId, ) /** Creates a pv agent and determines the needed additional information for @@ -598,7 +598,7 @@ class GridAgentController( simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ActorRef = gridAgentContext.simonaActorOf( WecAgent.props( @@ -612,11 +612,11 @@ class GridAgentController( simulationEndDate, resolution, requestVoltageDeviationThreshold, - outputConfig + outputConfig, ), - listener + listener, ), - wecInput.getId + wecInput.getId, ) /** Introduces the given agent to scheduler @@ -630,7 +630,7 @@ class GridAgentController( gridAgentContext.watch(actorRef) environmentRefs.scheduler ! ScheduleActivation( actorRef.toTyped, - INIT_SIM_TICK + INIT_SIM_TICK, ) } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala index 038d72cbc5..03ec0fd641 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala @@ -14,7 +14,7 @@ import edu.ie3.powerflow.model.PowerFlowResult import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.simona.agent.grid.ReceivedValues.{ ReceivedPowerValues, - ReceivedSlackVoltageValues + ReceivedSlackVoltageValues, } import edu.ie3.simona.agent.grid.ReceivedValuesStore.NodeToReceivedPower import edu.ie3.simona.model.grid.{GridModel, RefSystem} @@ -22,7 +22,7 @@ import edu.ie3.simona.ontology.messages.PowerMessage.{ FailedPowerFlow, PowerResponseMessage, ProvideGridPowerMessage, - ProvidePowerMessage + ProvidePowerMessage, } import java.util.UUID @@ -55,7 +55,7 @@ object GridAgentData { subGridContainer: SubGridContainer, thermalIslandGrids: Seq[ThermalGrid], subGridGateToActorRef: Map[SubGridGate, ActorRef], - refSystem: RefSystem + refSystem: RefSystem, ) extends GridAgentData with GridAgentDataHelper { override protected val subgridGates: Vector[SubGridGate] = @@ -76,13 +76,13 @@ object GridAgentData { final case class PowerFlowDoneData private ( gridAgentBaseData: GridAgentBaseData, powerFlowResult: PowerFlowResult, - pendingRequestAnswers: Set[Int] + pendingRequestAnswers: Set[Int], ) extends GridAgentData object PowerFlowDoneData { def apply( gridAgentBaseData: GridAgentBaseData, - powerFlowResult: PowerFlowResult + powerFlowResult: PowerFlowResult, ): PowerFlowDoneData = { /* Determine the subgrid numbers of all superior grids */ val superiorSubGrids = gridAgentBaseData.gridEnv.subgridGateToActorRef @@ -107,14 +107,14 @@ object GridAgentData { inferiorGridGates: Vector[SubGridGate], powerFlowParams: PowerFlowParams, log: LoggingAdapter, - actorName: String + actorName: String, ): GridAgentBaseData = { val currentSweepNo = 0 // initialization is assumed to be always @ sweep 0 val sweepValueStores: Map[Int, SweepValueStore] = Map .empty[ Int, - SweepValueStore + SweepValueStore, ] // initialization is assumed to be always with no sweep data val inferiorGridGateToActorRef = subgridGateToActorRef.filter { case (gate, _) => inferiorGridGates.contains(gate) @@ -126,11 +126,11 @@ object GridAgentData { ReceivedValuesStore.empty( nodeToAssetAgents, inferiorGridGateToActorRef, - superiorGridNodeUuids + superiorGridNodeUuids, ), sweepValueStores, log, - actorName + actorName, ) } @@ -152,7 +152,7 @@ object GridAgentData { def clean( gridAgentBaseData: GridAgentBaseData, superiorGridNodeUuids: Vector[UUID], - inferiorGridGates: Vector[SubGridGate] + inferiorGridGates: Vector[SubGridGate], ): GridAgentBaseData = { gridAgentBaseData.copy( @@ -161,10 +161,10 @@ object GridAgentData { gridAgentBaseData.gridEnv.subgridGateToActorRef.filter { case (gate, _) => inferiorGridGates.contains(gate) }, - superiorGridNodeUuids + superiorGridNodeUuids, ), currentSweepNo = 0, - sweepValueStores = Map.empty[Int, SweepValueStore] + sweepValueStores = Map.empty[Int, SweepValueStore], ) } @@ -195,7 +195,7 @@ object GridAgentData { receivedValueStore: ReceivedValuesStore, sweepValueStores: Map[Int, SweepValueStore], log: LoggingAdapter, - actorName: String + actorName: String, ) extends GridAgentData with GridAgentDataHelper { @@ -217,11 +217,11 @@ object GridAgentData { .forall(_.isDefined) log.debug( "slackMap: {}", - receivedValueStore.nodeToReceivedSlackVoltage + receivedValueStore.nodeToReceivedSlackVoltage, ) log.debug( "powerMap: {}", - receivedValueStore.nodeToReceivedPower + receivedValueStore.nodeToReceivedPower, ) assetAndGridPowerValuesReady & slackVoltageValuesReady } @@ -239,7 +239,7 @@ object GridAgentData { */ def updateWithReceivedPowerValues( receivedPowerValues: ReceivedPowerValues, - replace: Boolean = false + replace: Boolean = false, ): GridAgentBaseData = { val updatedNodeToReceivedPowersMap = receivedPowerValues.values.foldLeft( receivedValueStore.nodeToReceivedPower @@ -248,8 +248,8 @@ object GridAgentData { nodeToReceivedPowerValuesMapWithAddedPowerResponse, ( senderRef, - provideGridPowerMessage: ProvideGridPowerMessage - ) + provideGridPowerMessage: ProvideGridPowerMessage, + ), ) => /* Go over all includes messages and add them. */ provideGridPowerMessage.nodalResidualPower.foldLeft( @@ -257,25 +257,25 @@ object GridAgentData { ) { case ( nodeToReceivedPowerValuesMapWithAddedExchangedPower, - exchangedPower + exchangedPower, ) => updateNodalReceivedPower( exchangedPower, nodeToReceivedPowerValuesMapWithAddedExchangedPower, senderRef, - replace + replace, ) } case ( nodeToReceivedPowerValuesMapWithAddedPowerResponse, - (senderRef, powerResponseMessage) + (senderRef, powerResponseMessage), ) => // some other singular power response message updateNodalReceivedPower( powerResponseMessage, nodeToReceivedPowerValuesMapWithAddedPowerResponse, senderRef, - replace + replace, ) } this.copy( @@ -302,7 +302,7 @@ object GridAgentData { powerResponse: PowerResponseMessage, nodeToReceived: NodeToReceivedPower, senderRef: ActorRef, - replace: Boolean + replace: Boolean, ): NodeToReceivedPower = { // extract the nodeUuid that corresponds to the sender's actorRef and check if we expect a message from the sender val nodeUuid = powerResponse match { @@ -334,7 +334,7 @@ object GridAgentData { nodeUuid, throw new RuntimeException( s"NodeId $nodeUuid is not part of nodeToReceivedPowerValuesMap!" - ) + ), ) + // add or update entry in map of node entries (senderRef -> Some(powerResponse)) @@ -360,7 +360,7 @@ object GridAgentData { private def getNodeUuidForSender( nodeToReceivedPower: NodeToReceivedPower, senderRef: ActorRef, - replace: Boolean + replace: Boolean, ): Option[UUID] = nodeToReceivedPower .find { case (_, receivedPowerMessages) => @@ -431,13 +431,13 @@ object GridAgentData { def storeSweepDataAndClearReceiveMaps( validPowerFlowResult: ValidNewtonRaphsonPFResult, superiorGridNodeUuids: Vector[UUID], - inferiorGridGates: Vector[SubGridGate] + inferiorGridGates: Vector[SubGridGate], ): GridAgentBaseData = { val sweepValueStore = SweepValueStore( validPowerFlowResult, gridEnv.gridModel.gridComponents.nodes, - gridEnv.gridModel.nodeUuidToIndexMap + gridEnv.gridModel.nodeUuidToIndexMap, ) val updatedSweepValueStore = sweepValueStores + (currentSweepNo -> sweepValueStore) @@ -449,8 +449,8 @@ object GridAgentData { gridEnv.subgridGateToActorRef.filter { case (gate, _) => inferiorGridGates.contains(gate) }, - superiorGridNodeUuids - ) + superiorGridNodeUuids, + ), ) } } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala index 39dadc489f..622cf4f614 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridEnvironment.scala @@ -26,5 +26,5 @@ import edu.ie3.simona.model.grid.GridModel final case class GridEnvironment( gridModel: GridModel, subgridGateToActorRef: Map[SubGridGate, ActorRef], - nodeToAssetAgents: Map[UUID, Set[ActorRef]] + nodeToAssetAgents: Map[UUID, Set[ActorRef]], ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala index ecd073b1cf..1118041f93 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridResultsSupport.scala @@ -14,7 +14,7 @@ import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, Transformer2WResult, - Transformer3WResult + Transformer3WResult, } import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult @@ -24,7 +24,7 @@ import edu.ie3.simona.model.grid.Transformer3wModel.yij import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, - PowerFlowCaseC + PowerFlowCaseC, } import edu.ie3.simona.model.grid._ import edu.ie3.util.quantities.PowerSystemUnits @@ -60,7 +60,7 @@ private[grid] trait GridResultsSupport { */ def createResultModels( grid: GridModel, - sweepValueStore: SweepValueStore + sweepValueStore: SweepValueStore, )(implicit timestamp: ZonedDateTime): PowerFlowResultEvent = { // no sanity check for duplicated uuid result data as we expect valid data at this point implicit val sweepValueStoreData: Map[UUID, SweepValueStoreData] = @@ -90,7 +90,7 @@ private[grid] trait GridResultsSupport { grid.gridComponents.switches.map(calcSwitchResult(_, timestamp)), buildLineResults(grid.gridComponents.lines), buildTransformer2wResults(grid.gridComponents.transformers), - buildTransformer3wResults(grid.gridComponents.transformers3w) + buildTransformer3wResults(grid.gridComponents.transformers3w), ) } @@ -111,7 +111,7 @@ private[grid] trait GridResultsSupport { private def buildLineResults(lines: Set[LineModel])(implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: squants.ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): Set[LineResult] = { lines.flatMap(lineModel => { sweepValueStoreData @@ -124,7 +124,7 @@ private[grid] trait GridResultsSupport { nodeAStateData.stateData, nodeBStateData.stateData, iNominal, - timestamp + timestamp, ) ) case None => @@ -132,7 +132,7 @@ private[grid] trait GridResultsSupport { "Cannot find power flow result data for line {} with nodeA {} and nodeB {}", lineModel.uuid, lineModel.nodeAUuid, - lineModel.nodeBUuid + lineModel.nodeBUuid, ) None } @@ -158,7 +158,7 @@ private[grid] trait GridResultsSupport { implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): Set[Transformer2WResult] = { transformers.flatMap(trafo2w => { sweepValueStoreData @@ -171,7 +171,7 @@ private[grid] trait GridResultsSupport { hvNodeStateData.stateData, lvNodeStateData.stateData, iNominal, - timestamp + timestamp, ) ) case None => @@ -179,7 +179,7 @@ private[grid] trait GridResultsSupport { "Cannot find power flow result data for transformer2w {} with hvNode {} and lvNode {}", trafo2w.uuid, trafo2w.hvNodeUuid, - trafo2w.lvNodeUuid + trafo2w.lvNodeUuid, ) None } @@ -205,7 +205,7 @@ private[grid] trait GridResultsSupport { implicit sweepValueStoreData: Map[UUID, SweepValueStoreData], iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): Set[PartialTransformer3wResult] = transformers3w.flatMap { trafo3w => { (trafo3w.powerFlowCase match { @@ -229,7 +229,7 @@ private[grid] trait GridResultsSupport { upperNodeStateData.stateData, internalNodeStateData.stateData, iNominal, - timestamp + timestamp, ) ) case None => @@ -238,7 +238,7 @@ private[grid] trait GridResultsSupport { trafo3w.uuid, trafo3w.hvNodeUuid, trafo3w.mvNodeUuid, - trafo3w.lvNodeUuid + trafo3w.lvNodeUuid, ) None } @@ -257,7 +257,7 @@ private[grid] trait GridResultsSupport { */ protected def calcNodeResult( sweepValueStoreData: SweepValueStoreData, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): NodeResult = { val nodeStateData = sweepValueStoreData.stateData @@ -268,7 +268,7 @@ private[grid] trait GridResultsSupport { timestamp, sweepValueStoreData.nodeUuid, Quantities.getQuantity(vMag, PowerSystemUnits.PU), - Quantities.getQuantity(vAng, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(vAng, PowerSystemUnits.DEGREE_GEOM), ) } @@ -284,13 +284,13 @@ private[grid] trait GridResultsSupport { */ protected def calcSwitchResult( switchModel: SwitchModel, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): SwitchResult = { /* can be adapted when https://github.com/ie3-institute/PowerSystemDataModel/issues/151 has been resolved */ new SwitchResult( timestamp, switchModel.uuid, - switchModel.isClosed + switchModel.isClosed, ) } @@ -315,17 +315,17 @@ private[grid] trait GridResultsSupport { nodeAStateData: StateData, nodeBStateData: StateData, iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): LineResult = { if (line.isInOperation) { val yij = new Complex( line.gij().value.doubleValue, - line.bij().value.doubleValue + line.bij().value.doubleValue, ) val y0 = new Complex( line.g0().value.doubleValue, - line.b0().value.doubleValue + line.b0().value.doubleValue, ) val (iAComplexPu, iBComplexPu) = @@ -340,7 +340,7 @@ private[grid] trait GridResultsSupport { Quantities.getQuantity(iAMag.toAmperes, Units.AMPERE), Quantities.getQuantity(iAAng.toDegrees, PowerSystemUnits.DEGREE_GEOM), Quantities.getQuantity(iBMag.toAmperes, Units.AMPERE), - Quantities.getQuantity(iBAng.toDegrees, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(iBAng.toDegrees, PowerSystemUnits.DEGREE_GEOM), ) } else { new LineResult( @@ -349,7 +349,7 @@ private[grid] trait GridResultsSupport { QuantityUtil.zeroCompQuantity(Units.AMPERE), QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), QuantityUtil.zeroCompQuantity(Units.AMPERE), - QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM) + QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), ) } } @@ -377,13 +377,13 @@ private[grid] trait GridResultsSupport { hvNodeStateData: StateData, lvNodeStateData: StateData, iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): Transformer2WResult = { if (trafo2w.isInOperation) { val (yab, yaa, ybb) = ( TransformerModel.yij(trafo2w), TransformerModel.y0(trafo2w, ConnectorPort.A), - TransformerModel.y0(trafo2w, ConnectorPort.B) + TransformerModel.y0(trafo2w, ConnectorPort.B), ) val voltRatioNominal = trafo2w.voltRatioNominal @@ -393,7 +393,7 @@ private[grid] trait GridResultsSupport { lvNodeStateData.voltage, yab, yaa, - Some(ybb) + Some(ybb), ) /* Transfer port current A to high voltage level */ @@ -408,7 +408,7 @@ private[grid] trait GridResultsSupport { Quantities.getQuantity(iAAng.toDegrees, PowerSystemUnits.DEGREE_GEOM), Quantities.getQuantity(iBMag.toAmperes, Units.AMPERE), Quantities.getQuantity(iBAng.toDegrees, PowerSystemUnits.DEGREE_GEOM), - trafo2w.currentTapPos + trafo2w.currentTapPos, ) } else { @@ -419,7 +419,7 @@ private[grid] trait GridResultsSupport { QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), QuantityUtil.zeroCompQuantity(Units.AMPERE), QuantityUtil.zeroCompQuantity(PowerSystemUnits.DEGREE_GEOM), - trafo2w.currentTapPos + trafo2w.currentTapPos, ) } } @@ -446,7 +446,7 @@ private[grid] trait GridResultsSupport { nodeStateData: StateData, internalNodeStateData: StateData, iNominal: ElectricCurrent, - timestamp: ZonedDateTime + timestamp: ZonedDateTime, ): PartialTransformer3wResult = { val (_, iComplexPu) = iIJComplexPu( internalNodeStateData.voltage, @@ -458,9 +458,9 @@ private[grid] trait GridResultsSupport { case PowerFlowCaseA => Transformer3wModel.Transformer3wPort.A case PowerFlowCaseB => Transformer3wModel.Transformer3wPort.B case PowerFlowCaseC => Transformer3wModel.Transformer3wPort.C - } + }, ), - None + None, ) val (iMag, iAng) = iMagAndAngle(iComplexPu, iNominal) @@ -472,21 +472,21 @@ private[grid] trait GridResultsSupport { trafo3w.uuid, iMag, iAng, - trafo3w.currentTapPos + trafo3w.currentTapPos, ) case Transformer3wPowerFlowCase.PowerFlowCaseB => PartialTransformer3wResult.PortB( timestamp, trafo3w.uuid, iMag, - iAng + iAng, ) case Transformer3wPowerFlowCase.PowerFlowCaseC => PartialTransformer3wResult.PortC( timestamp, trafo3w.uuid, iMag, - iAng + iAng, ) } } @@ -510,11 +510,11 @@ private[grid] trait GridResultsSupport { */ private def iMagAndAngle( iPu: Complex, - iNominal: ElectricCurrent + iNominal: ElectricCurrent, ): (ElectricCurrent, Angle) = ( Amperes(iNominal.toAmperes * iPu.abs), - complexToAngle(iPu) + complexToAngle(iPu), ) /** Calculate the angle of the complex value given. The angle has the proper @@ -535,7 +535,7 @@ private[grid] trait GridResultsSupport { Angle can be 90 or 270 degrees, depending on sign of the imaginary part */ angleOffsetCorrection( Degrees(90d), - imag + imag, ) case Complex(real, imag) => /* Both real and imaginary parts are != 0. This means that the angle @@ -547,7 +547,7 @@ private[grid] trait GridResultsSupport { val baseAngle = atan(imag / real).toDegrees angleOffsetCorrection( Degrees(baseAngle), - real + real, ) } @@ -556,7 +556,7 @@ private[grid] trait GridResultsSupport { */ private def angleOffsetCorrection( angle: Angle, - dir: Double + dir: Double, ): Angle = if (dir < 0) angle + Degrees(180d) @@ -588,11 +588,11 @@ private[grid] trait GridResultsSupport { ujPu: Complex, yij: Complex, y0i: Complex, - y0j: Option[Complex] = None + y0j: Option[Complex] = None, ): (Complex, Complex) = { ( (uiPu - ujPu) * yij + (uiPu * y0i), - (ujPu - uiPu) * yij + (ujPu * y0j.getOrElse(y0i)) + (ujPu - uiPu) * yij + (ujPu * y0j.getOrElse(y0i)), ) } @@ -630,7 +630,7 @@ object GridResultsSupport { override val input: UUID, override val currentMagnitude: ElectricCurrent, override val currentAngle: Angle, - tapPos: Int + tapPos: Int, ) extends PartialTransformer3wResult /** Partial result for the port at the medium voltage side @@ -648,7 +648,7 @@ object GridResultsSupport { override val time: ZonedDateTime, override val input: UUID, override val currentMagnitude: ElectricCurrent, - override val currentAngle: Angle + override val currentAngle: Angle, ) extends PartialTransformer3wResult /** Partial result for the port at the low voltage side @@ -666,7 +666,7 @@ object GridResultsSupport { override val time: ZonedDateTime, override val input: UUID, override val currentMagnitude: ElectricCurrent, - override val currentAngle: Angle + override val currentAngle: Angle, ) extends PartialTransformer3wResult } } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala index 8e5284cb15..0235cb56de 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala @@ -30,5 +30,5 @@ final case class PowerFlowParams( epsilon: Vector[Double], maxIterations: Int, sweepTimeout: Duration, - stopOnFailure: Boolean + stopOnFailure: Boolean, ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala index afc26f47c1..f06ab993c7 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala @@ -71,7 +71,7 @@ trait PowerFlowSupport { receivedValuesStore: ReceivedValuesStore, gridMainRefSystem: RefSystem, targetVoltageFromReceivedData: Boolean = true, - ignoreTargetVoltage: Boolean = false + ignoreTargetVoltage: Boolean = false, ): (Array[PresetData], WithForcedStartVoltages) = { val (operatingPoints, stateData) = nodes.map { nodeModel => // note: currently we only support pq nodes as we not distinguish between pq/pv nodes - @@ -83,7 +83,7 @@ trait PowerFlowSupport { nodeModel.uuid, throw new RuntimeException( s"Received data for node ${nodeModel.id} [${nodeModel.uuid}] which is not in my nodeUuidToIndexMap!" - ) + ), ) val apparentPower: Complex = @@ -107,18 +107,18 @@ trait PowerFlowSupport { .foldLeft( ( Kilowatts(0d), - Kilovars(0d) + Kilovars(0d), ) ) { case ((pSum, qSum), powerMessage) => ( pSum + powerMessage.p, - qSum + powerMessage.q + qSum + powerMessage.q, ) } new Complex( gridMainRefSystem.pInPu(p).value.doubleValue, - gridMainRefSystem.qInPu(q).value.doubleValue + gridMainRefSystem.qInPu(q).value.doubleValue, ) case None => new Complex(0, 0) } @@ -142,7 +142,7 @@ trait PowerFlowSupport { nodeModel.uuid, transformers2w, transformers3w, - gridMainRefSystem + gridMainRefSystem, ) } else { // Either the received data shall not be considered or the node is not a slack node @@ -157,7 +157,7 @@ trait PowerFlowSupport { nodeIdx, NodeType.SL, targetVoltage, - apparentPower + apparentPower, ) ) @@ -166,9 +166,9 @@ trait PowerFlowSupport { nodeIdx, nodeType, apparentPower, - targetVoltage.abs + targetVoltage.abs, ), - optStateData + optStateData, ) }.unzip @@ -195,7 +195,7 @@ trait PowerFlowSupport { ( combineOperatingPoint(adaptedOperatingPoint.toArray), - WithForcedStartVoltages(Array(slackNodeData)) + WithForcedStartVoltages(Array(slackNodeData)), ) } @@ -226,7 +226,7 @@ trait PowerFlowSupport { sweepDataValues: Vector[SweepValueStore.SweepValueStoreData], transformers2w: Set[TransformerModel], transformers3w: Set[Transformer3wModel], - gridMainRefSystem: RefSystem + gridMainRefSystem: RefSystem, ): (Array[PresetData], WithForcedStartVoltages) = sweepDataValues.map { sweepValueStoreData => val nodeStateData = sweepValueStoreData.stateData @@ -247,7 +247,7 @@ trait PowerFlowSupport { sweepValueStoreData.nodeUuid, transformers2w, transformers3w, - gridMainRefSystem + gridMainRefSystem, ) } else Complex.one @@ -258,22 +258,22 @@ trait PowerFlowSupport { nodeStateData.index, nodeStateData.nodeType, nodeStateData.power, - targetVoltage.abs + targetVoltage.abs, ), Option.when(nodeStateData.nodeType == NodeType.SL)( StateData( nodeStateData.index, nodeStateData.nodeType, targetVoltage, - nodeStateData.power + nodeStateData.power, ) - ) + ), ) }.unzip match { case (operatingPoint, stateData) => ( combineOperatingPoint(operatingPoint.toArray), - WithForcedStartVoltages(stateData.flatten.toArray) + WithForcedStartVoltages(stateData.flatten.toArray), ) } @@ -318,15 +318,15 @@ trait PowerFlowSupport { private def combinePresetData(a: PresetData, b: PresetData): PresetData = { require( a.index == b.index, - "Preset Data should only be combined when they map to the same index." + "Preset Data should only be combined when they map to the same index.", ) require( a.nodeType == b.nodeType, - "Preset Data combination is only supported for the same node types for now." + "Preset Data combination is only supported for the same node types for now.", ) require( math.abs(a.targetVoltage - b.targetVoltage) < 1e-6, - "Nodes to be combined have to be located in the same voltage level." + "Nodes to be combined have to be located in the same voltage level.", ) val index = a.index @@ -337,7 +337,7 @@ trait PowerFlowSupport { def combineOptionals( a: Option[Double], b: Option[Double], - f: (Double, Double) => Double + f: (Double, Double) => Double, ): Option[Double] = (a, b) match { case (Some(a), Some(b)) => Some(f(a, b)) case (Some(a), None) => Some(a) @@ -362,7 +362,7 @@ trait PowerFlowSupport { activePowerMin, activePowerMax, reactivePowerMin, - reactivePowerMax + reactivePowerMax, ) } @@ -378,7 +378,7 @@ trait PowerFlowSupport { */ protected def composeValidNewtonRaphsonPFResultVoltagesDebugString( validResult: ValidNewtonRaphsonPFResult, - gridModel: GridModel + gridModel: GridModel, ): String = { val debugString = new mutable.StringBuilder("Power flow result: ") validResult.nodeData.foreach(nodeStateData => { @@ -431,23 +431,23 @@ trait PowerFlowSupport { nodeUuid: UUID, transformers2w: Set[TransformerModel], transformers3w: Set[Transformer3wModel], - gridRefSystem: RefSystem + gridRefSystem: RefSystem, ): Complex = { (( transformers2w.find(_.hvNodeUuid == nodeUuid), - transformers3w.find(_.nodeInternalUuid == nodeUuid) + transformers3w.find(_.nodeInternalUuid == nodeUuid), ) match { case (Some(transformer2w), None) => transferToVoltageLevel( receivedSlackVoltage.e, receivedSlackVoltage.f, - transformer2w + transformer2w, ) case (None, Some(transformer3w)) => transferToVoltageLevel( receivedSlackVoltage.e, receivedSlackVoltage.f, - transformer3w + transformer3w, ) case (Some(transformer2w), Some(transformer3w)) => throw new RuntimeException( @@ -480,7 +480,7 @@ trait PowerFlowSupport { private def transferToVoltageLevel( e: ElectricPotential, f: ElectricPotential, - transformerModel: TransformerModel + transformerModel: TransformerModel, ): (ElectricPotential, ElectricPotential) = { val voltRatio = transformerModel.voltRatioNominal (e.divide(voltRatio.toDouble), f.divide(voltRatio.toDouble)) @@ -501,7 +501,7 @@ trait PowerFlowSupport { private def transferToVoltageLevel( e: ElectricPotential, f: ElectricPotential, - transformerModel: Transformer3wModel + transformerModel: Transformer3wModel, ): (ElectricPotential, ElectricPotential) = { val voltRatio = Transformer3wModel.voltRatio(transformerModel) (e.divide(voltRatio.toDouble), f.divide(voltRatio.toDouble)) @@ -521,10 +521,10 @@ trait PowerFlowSupport { private def toPu( e: ElectricPotential, f: ElectricPotential, - gridRefSystem: RefSystem + gridRefSystem: RefSystem, ): (squants.Dimensionless, squants.Dimensionless) = ( gridRefSystem.vInPu(e), - gridRefSystem.vInPu(f) + gridRefSystem.vInPu(f), ) /** Build a [[Complex]] from both parts of the voltage @@ -560,14 +560,14 @@ trait PowerFlowSupport { gridModel: GridModel, maxIterations: Int, operatingPoint: Array[PresetData], - slackVoltages: WithForcedStartVoltages + slackVoltages: WithForcedStartVoltages, )(epsilons: Vector[Double]): PowerFlowResult = { epsilons.headOption match { case Some(epsilon) => val admittanceMatrix = GridModel.composeAdmittanceMatrix( gridModel.nodeUuidToIndexMap, - gridModel.gridComponents + gridModel.gridComponents, ) // / execute @@ -577,7 +577,7 @@ trait PowerFlowSupport { Try { powerFlow.calculate( operatingPoint, - Some(slackVoltages) + Some(slackVoltages), ) }.map { case _: PowerFlowResult.FailedPowerFlowResult if epsilons.size > 1 => @@ -586,13 +586,13 @@ trait PowerFlowSupport { log.debug( "NR power flow with ɛ = {} failed. Relaxing to {}.", epsilon, - epsilonsLeft.headOption.getOrElse("") + epsilonsLeft.headOption.getOrElse(""), ) newtonRaphsonPF( gridModel, maxIterations, operatingPoint, - slackVoltages + slackVoltages, )( epsilonsLeft ) @@ -603,7 +603,7 @@ trait PowerFlowSupport { case Failure(exception) => throw new DBFSAlgorithmException( s"Power flow calculation in subgrid ${gridModel.subnetNo} failed.", - exception + exception, ) } case None => diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala index 4c083629f3..e74f0f82df 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala @@ -10,11 +10,11 @@ import org.apache.pekko.actor.ActorRef import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.simona.agent.grid.ReceivedValuesStore.{ NodeToReceivedPower, - NodeToReceivedSlackVoltage + NodeToReceivedSlackVoltage, } import edu.ie3.simona.ontology.messages.PowerMessage.{ PowerResponseMessage, - ProvidePowerMessage + ProvidePowerMessage, } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage @@ -41,7 +41,7 @@ import java.util.UUID */ final case class ReceivedValuesStore private ( nodeToReceivedPower: NodeToReceivedPower, - nodeToReceivedSlackVoltage: NodeToReceivedSlackVoltage + nodeToReceivedSlackVoltage: NodeToReceivedSlackVoltage, ) object ReceivedValuesStore { @@ -70,13 +70,13 @@ object ReceivedValuesStore { def empty( nodeToAssetAgents: Map[UUID, Set[ActorRef]], inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef], - superiorGridNodeUuids: Vector[UUID] + superiorGridNodeUuids: Vector[UUID], ): ReceivedValuesStore = { val (nodeToReceivedPower, nodeToReceivedSlackVoltage) = buildEmptyReceiveMaps( nodeToAssetAgents, inferiorSubGridGateToActorRef, - superiorGridNodeUuids + superiorGridNodeUuids, ) ReceivedValuesStore(nodeToReceivedPower, nodeToReceivedSlackVoltage) } @@ -95,7 +95,7 @@ object ReceivedValuesStore { */ private def buildEmptyNodeToReceivedPowerMap( nodeToAssetAgents: Map[UUID, Set[ActorRef]], - inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef] + inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef], ): NodeToReceivedPower = { /* Collect everything, that I expect from my asset agents */ val assetsToReceivedPower: NodeToReceivedPower = nodeToAssetAgents.collect { @@ -111,14 +111,14 @@ object ReceivedValuesStore { .foldLeft(assetsToReceivedPower) { case ( subordinateToReceivedPower, - couplingNodeUuid -> inferiorSubGridRef + couplingNodeUuid -> inferiorSubGridRef, ) => /* Check, if there is already something expected for the given coupling node * and add reference to the subordinate grid agent */ val actorRefToMessage = subordinateToReceivedPower .getOrElse( couplingNodeUuid, - Map.empty[ActorRef, Option[ProvidePowerMessage]] + Map.empty[ActorRef, Option[ProvidePowerMessage]], ) + (inferiorSubGridRef -> None) /* Update the existing map */ @@ -158,14 +158,14 @@ object ReceivedValuesStore { private def buildEmptyReceiveMaps( nodeToAssetAgents: Map[UUID, Set[ActorRef]], inferiorSubGridGateToActorRef: Map[SubGridGate, ActorRef], - superiorGridNodeUuids: Vector[UUID] + superiorGridNodeUuids: Vector[UUID], ): (NodeToReceivedPower, NodeToReceivedSlackVoltage) = { ( buildEmptyNodeToReceivedPowerMap( nodeToAssetAgents, - inferiorSubGridGateToActorRef + inferiorSubGridGateToActorRef, ), - buildEmptyNodeToReceivedSlackVoltageValuesMap(superiorGridNodeUuids) + buildEmptyNodeToReceivedSlackVoltageValuesMap(superiorGridNodeUuids), ) } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/SweepValueStore.scala b/src/main/scala/edu/ie3/simona/agent/grid/SweepValueStore.scala index dfe459fc72..ddc46a1ba3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/SweepValueStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/SweepValueStore.scala @@ -36,7 +36,7 @@ case object SweepValueStore { */ final case class SweepValueStoreData private ( nodeUuid: UUID, - stateData: StateData + stateData: StateData, ) /** Creates an empty [[SweepValueStore]] from on a valid power flow result @@ -55,7 +55,7 @@ case object SweepValueStore { def apply( validResult: ValidNewtonRaphsonPFResult, nodes: Seq[NodeModel], - nodeUuidToIndexMap: Map[UUID, Int] + nodeUuidToIndexMap: Map[UUID, Int], ): SweepValueStore = { val sweepDataValues = nodes.foldLeft(Vector.empty[SweepValueStoreData])( (valueStoreDataElements, node) => { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala index 20902cedd6..3eae4e4a55 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.agent.{SimonaAgent, ValueStore} import edu.ie3.simona.agent.grid.GridAgent.FinishGridSimulationTrigger import edu.ie3.simona.agent.participant.ParticipantAgent.{ StartCalculationTrigger, - getAndCheckNodalVoltage + getAndCheckNodalVoltage, } import edu.ie3.simona.agent.participant.data.Data import edu.ie3.simona.agent.participant.data.Data.PrimaryData.PrimaryDataWithApparentPower @@ -19,19 +19,19 @@ import edu.ie3.simona.agent.participant.data.Data.{PrimaryData, SecondaryData} import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FromOutsideBaseStateData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData._ import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, DataCollectionStateData, - ParticipantStateData + ParticipantStateData, } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.{ Calculate, - HandleInformation + HandleInformation, } import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.notifier.NotifierConfig @@ -41,13 +41,13 @@ import edu.ie3.simona.model.participant.{ CalcRelevantData, FlexChangeIndicator, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexResponse, IssueFlexControl, - RequestFlexOptions + RequestFlexOptions, } import edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation @@ -55,7 +55,7 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResp import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ PrimaryServiceRegistrationMessage, ProvisionMessage, - RegistrationResponseMessage + RegistrationResponseMessage, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.ReactivePower @@ -96,10 +96,10 @@ abstract class ParticipantAgent[ D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD, MS] + M <: SystemParticipant[CD, PD, MS], ]( scheduler: ActorRef, - initStateData: ParticipantInitializeStateData[I, MC, PD] + initStateData: ParticipantInitializeStateData[I, MC, PD], )(implicit val tag: ClassTag[MS]) extends SimonaAgent[ParticipantStateData[PD]] { @@ -113,7 +113,7 @@ abstract class ParticipantAgent[ Long, ParticipantModelBaseStateData[PD, CD, MS, M], MS, - squants.Dimensionless + squants.Dimensionless, ) => PD // general agent states @@ -124,7 +124,7 @@ abstract class ParticipantAgent[ /* Initialize the agent */ case Event( Activation(INIT_SIM_TICK), - _: ParticipantUninitializedStateData[PD] + _: ParticipantUninitializedStateData[PD], ) => /* Ask the primary service proxy for data. If some is available, it will delegate the request to a worker and * that will confirm, otherwise, a failed registration is announced. */ @@ -141,14 +141,14 @@ abstract class ParticipantAgent[ initStateData.resolution, initStateData.requestVoltageDeviationThreshold, initStateData.outputConfig, - initStateData.maybeEmAgent + initStateData.maybeEmAgent, ) } when(Idle) { case Event( Activation(tick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], ) if modelBaseStateData.services.isEmpty => /* An activity start trigger is sent and no data is awaited (neither secondary nor primary). Therefore go straight * ahead to calculations */ @@ -167,35 +167,35 @@ abstract class ParticipantAgent[ modelBaseStateData.requestValueStore, modelBaseStateData.voltageValueStore, additionalActivationTicks, - modelBaseStateData.foreseenDataTicks + modelBaseStateData.foreseenDataTicks, ) case Event( Activation(currentTick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], ) => /* An activation is sent, but I'm not sure yet, if secondary data will arrive. Figure out, if someone * is about to deliver new data and either go to HandleInformation, check and possibly wait for data provision * messages or directly go to Calculate and utilize what is already there */ handleActivationAndGoToHandleInformation( currentTick, - modelBaseStateData + modelBaseStateData, ) case Event( Activation(currentTick), - fromOutsideBaseStateData: FromOutsideBaseStateData[M, PD] + fromOutsideBaseStateData: FromOutsideBaseStateData[M, PD], ) => /* An activation is sent, but I'm still expecting primary data. Go to HandleInformation and wait for * a data provision message */ handleActivationAndGoToHandleInformation( currentTick, - fromOutsideBaseStateData + fromOutsideBaseStateData, ) case Event( msg: ProvisionMessage[Data], - baseStateData: BaseStateData[PD] + baseStateData: BaseStateData[PD], ) => /* Somebody has sent new primary or secondary data. Collect, what is expected for this tick. Go over to data * handling */ @@ -203,7 +203,7 @@ abstract class ParticipantAgent[ case Event( RequestAssetPowerMessage(requestTick, eInPu, fInPu), - baseStateData: BaseStateData[PD] + baseStateData: BaseStateData[PD], ) => /* Determine the reply and stay in this state (or stash the message if the request cannot yet be answered) */ answerPowerRequestAndStayWithUpdatedStateData( @@ -211,19 +211,19 @@ abstract class ParticipantAgent[ requestTick, eInPu, fInPu, - alternativeResult + alternativeResult, ) case Event( FinishGridSimulationTrigger(tick), - baseStateData: BaseStateData[PD] + baseStateData: BaseStateData[PD], ) => // clean up agent result value store finalizeTickAfterPF(baseStateData, tick) case Event( RequestFlexOptions(tick), - baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], ) => val expectedSenders = baseStateData.foreseenDataTicks .collect { @@ -238,7 +238,7 @@ abstract class ParticipantAgent[ val nextStateData = DataCollectionStateData( baseStateData, expectedSenders, - yetTriggered = true + yetTriggered = true, ) /* Do await provision messages in HandleInformation */ @@ -252,7 +252,7 @@ abstract class ParticipantAgent[ case Event( flexCtrl: IssueFlexControl, - baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], ) => handleFlexCtrl(baseStateData, flexCtrl, scheduler) } @@ -270,8 +270,8 @@ abstract class ParticipantAgent[ resolution, requestVoltageDeviationThreshold, outputConfig, - _ - ) + _, + ), ) => log.debug("Will replay primary data") initializeParticipantForPrimaryDataReplay( @@ -283,7 +283,7 @@ abstract class ParticipantAgent[ requestVoltageDeviationThreshold, outputConfig, serviceRef -> maybeNextDataTick, - scheduler + scheduler, ) /* Receive registration refuse from primary data service -> Set up actor for model calculation */ @@ -298,8 +298,8 @@ abstract class ParticipantAgent[ resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent - ) + maybeEmAgent, + ), ) => log.debug("Will perform model calculations") initializeParticipantForModelCalculation( @@ -312,19 +312,19 @@ abstract class ParticipantAgent[ requestVoltageDeviationThreshold, outputConfig, scheduler, - maybeEmAgent + maybeEmAgent, ) /* Receiving the registration replies from services and collect their next data ticks */ case Event( msg: RegistrationResponseMessage, - stateData: CollectRegistrationConfirmMessages[PD] + stateData: CollectRegistrationConfirmMessages[PD], ) => handleRegistrationResponse(scheduler, msg, stateData) case Event( Activation(currentTick), - stateData: DataCollectionStateData[PD] + stateData: DataCollectionStateData[PD], ) => /* The actor received an activation. Check, if there is everything at its place. If so, change state * accordingly, otherwise stay here and wait for the messages */ @@ -333,18 +333,18 @@ abstract class ParticipantAgent[ stateData, isYetTriggered = true, currentTick, - scheduler + scheduler, )(stateData.baseStateData.outputConfig) case Event( RequestFlexOptions(tick), - stateData: DataCollectionStateData[PD] + stateData: DataCollectionStateData[PD], ) => checkForExpectedDataAndChangeState( stateData, isYetTriggered = true, tick, - scheduler + scheduler, )(stateData.baseStateData.outputConfig) case Event( @@ -352,8 +352,8 @@ abstract class ParticipantAgent[ stateData @ DataCollectionStateData( baseStateData: BaseStateData[PD], data, - isYetTriggered - ) + isYetTriggered, + ), ) => /* We yet have received at least one data provision message. Handle all messages, that follow up for this tick, by * adding the received data to the collection state data and checking, if everything is at its place */ @@ -371,7 +371,7 @@ abstract class ParticipantAgent[ scheduler ! ScheduleActivation( self.toTyped, msg.tick, - msg.unlockKey + msg.unlockKey, ) /* Depending on if a next data tick can be foreseen, either update the entry in the base state data or remove @@ -384,18 +384,18 @@ abstract class ParticipantAgent[ baseStateData.requestValueStore, baseStateData.voltageValueStore, baseStateData.additionalActivationTicks, - foreSeenDataTicks + foreSeenDataTicks, ) val updatedStateData: DataCollectionStateData[PD] = stateData .copy( baseStateData = updatedBaseStateData, - data = updatedData + data = updatedData, ) checkForExpectedDataAndChangeState( updatedStateData, isYetTriggered, msg.tick, - scheduler + scheduler, )(updatedBaseStateData.outputConfig) } else throw new IllegalStateException( @@ -404,7 +404,7 @@ abstract class ParticipantAgent[ case Event( RequestAssetPowerMessage(currentTick, _, _), - DataCollectionStateData(_, data, yetTriggered) + DataCollectionStateData(_, data, yetTriggered), ) => if (log.isDebugEnabled) { val awaitedSenders = data.filter(_._2.isEmpty).keys @@ -418,7 +418,7 @@ abstract class ParticipantAgent[ s"$currentTick from ${sender()}", awaitedSenders, yetReceivedSenders, - if (yetTriggered) "" else "NOT" + if (yetTriggered) "" else "NOT", ) } stash() @@ -428,7 +428,7 @@ abstract class ParticipantAgent[ when(Calculate) { case Event( StartCalculationTrigger(currentTick), - modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M] + modelBaseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], ) => /* Model calculation without any secondary data needed */ val voltage = getAndCheckNodalVoltage(modelBaseStateData, currentTick) @@ -441,7 +441,7 @@ abstract class ParticipantAgent[ lastModelState, currentTick, scheduler, - voltage + voltage, ) case Event( @@ -449,15 +449,15 @@ abstract class ParticipantAgent[ DataCollectionStateData( participantStateData: ParticipantModelBaseStateData[PD, CD, MS, M], data, - _ - ) + _, + ), ) => val updatedReceivedSecondaryData = ValueStore.updateValueStore( participantStateData.receivedSecondaryDataStore, currentTick, data.map { case (actorRef, Some(data: SecondaryData)) => actorRef -> data - } + }, ) /* At least parts of the needed data has been received or it is an additional activation, that has been triggered. @@ -470,14 +470,14 @@ abstract class ParticipantAgent[ ), lastModelState, currentTick, - scheduler + scheduler, ) case Event(RequestAssetPowerMessage(currentTick, _, _), _) => log.debug( s"Got asset power request for tick {} from '{}'. Will answer it later.", currentTick, - sender() + sender(), ) stash() stay() @@ -528,7 +528,7 @@ abstract class ParticipantAgent[ requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, senderToMaybeTick: (ActorRef, Option[Long]), - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] /** Abstract definition of initialization method, implementation in @@ -566,7 +566,7 @@ abstract class ParticipantAgent[ requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, scheduler: ActorRef, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): FSM.State[AgentState, ParticipantStateData[PD]] /** Handles the responses from service providers, this actor has registered @@ -583,7 +583,7 @@ abstract class ParticipantAgent[ def handleRegistrationResponse( scheduler: ActorRef, registrationResponse: RegistrationResponseMessage, - stateData: CollectRegistrationConfirmMessages[PD] + stateData: CollectRegistrationConfirmMessages[PD], ): FSM.State[AgentState, ParticipantStateData[PD]] /** Handle an [[Activation]] received in [[Idle]]. Prepare the foreseen @@ -599,7 +599,7 @@ abstract class ParticipantAgent[ */ private def handleActivationAndGoToHandleInformation( tick: Long, - baseStateData: BaseStateData[PD] + baseStateData: BaseStateData[PD], ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* Hold tick, as we are about to changes states for a while */ holdTick(tick) @@ -617,7 +617,7 @@ abstract class ParticipantAgent[ val nextStateData = DataCollectionStateData( baseStateData, expectedSenders, - yetTriggered = true + yetTriggered = true, ) if (expectedSenders.nonEmpty || unforeseenPossible) { @@ -632,7 +632,7 @@ abstract class ParticipantAgent[ protected def getLastOrInitialStateData( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): MS = ConstantState match { case constantState: MS => @@ -662,7 +662,7 @@ abstract class ParticipantAgent[ def handleDataProvisionAndGoToHandleInformation( msg: ProvisionMessage[Data], baseStateData: BaseStateData[PD], - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] /** Checks, if all data is available and change state accordingly. Three cases @@ -692,7 +692,7 @@ abstract class ParticipantAgent[ stateData: DataCollectionStateData[PD], isYetTriggered: Boolean, tick: Long, - scheduler: ActorRef + scheduler: ActorRef, )(implicit outputConfig: NotifierConfig ): FSM.State[AgentState, ParticipantStateData[PD]] @@ -721,7 +721,7 @@ abstract class ParticipantAgent[ lastModelState: MS, currentTick: Long, scheduler: ActorRef, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): FSM.State[AgentState, ParticipantStateData[PD]] /** Abstractly calculate the power output of the participant utilising @@ -751,7 +751,7 @@ abstract class ParticipantAgent[ baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], lastModelState: MS, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] protected def createInitialState( @@ -760,23 +760,23 @@ abstract class ParticipantAgent[ protected def handleFlexRequest( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): ParticipantModelBaseStateData[PD, CD, MS, M] protected def calculateFlexOptions( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): ParticipantModelBaseStateData[PD, CD, MS, M] protected def createCalcRelevantData( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): CD protected def handleFlexCtrl( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], flexCtrl: IssueFlexControl, - scheduler: ActorRef + scheduler: ActorRef, ): State /** Handle an active power change by flex control. @@ -798,7 +798,7 @@ abstract class ParticipantAgent[ baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], data: CD, lastState: MS, - setPower: squants.Power + setPower: squants.Power, ): (MS, PD, FlexChangeIndicator) /** Determining the reply to an @@ -833,7 +833,7 @@ abstract class ParticipantAgent[ requestTick: Long, eInPu: Dimensionless, fInPu: Dimensionless, - alternativeResult: PD + alternativeResult: PD, ): FSM.State[AgentState, ParticipantStateData[PD]] /** Abstract definition to notify result listeners from every participant @@ -848,7 +848,7 @@ abstract class ParticipantAgent[ baseStateData: BaseStateData[_], currentTick: Long, activePower: Power, - reactivePower: ReactivePower + reactivePower: ReactivePower, )(implicit outputConfig: NotifierConfig): Unit /** Abstract definition to clean up agent value stores after power flow @@ -864,7 +864,7 @@ abstract class ParticipantAgent[ */ def finalizeTickAfterPF( baseStateData: BaseStateData[PD], - currentTick: Long + currentTick: Long, ): FSM.State[AgentState, ParticipantStateData[PD]] } @@ -885,7 +885,7 @@ object ParticipantAgent { */ def getAndCheckNodalVoltage( baseStateData: BaseStateData[_ <: PrimaryData], - currentTick: Long + currentTick: Long, ): Dimensionless = { baseStateData.voltageValueStore.last(currentTick) match { case Some((_, voltage)) => voltage diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala index ecb7dce11a..894c0e1c2e 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentals.scala @@ -11,7 +11,7 @@ import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.datamodel.models.result.system.{ FlexOptionsResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.ValueStore @@ -22,35 +22,35 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, ApparentPowerAndHeat, EnrichableData, - PrimaryDataWithApparentPower + PrimaryDataWithApparentPower, } import edu.ie3.simona.agent.participant.data.Data.{PrimaryData, SecondaryData} import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FromOutsideBaseStateData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ CollectRegistrationConfirmMessages, - InputModelContainer + InputModelContainer, } import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, DataCollectionStateData, - ParticipantStateData + ParticipantStateData, } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.{ Calculate, - HandleInformation + HandleInformation, } import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.event.ResultEvent.{ FlexOptionsResultEvent, ParticipantResultEvent, - ThermalResultEvent + ThermalResultEvent, } import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.CriticalFailureException @@ -58,29 +58,29 @@ import edu.ie3.simona.exceptions.agent.{ ActorNotRegisteredException, AgentInitializationException, InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.io.result.AccompaniedSimulationResult import edu.ie3.simona.model.em.EmTools import edu.ie3.simona.model.participant.{ CalcRelevantData, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, - AssetPowerUnchangedMessage + AssetPowerUnchangedMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ProvisionMessage, - RegistrationResponseMessage + RegistrationResponseMessage, } import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.quantities.PowerSystemUnits._ @@ -111,7 +111,7 @@ protected trait ParticipantAgentFundamentals[ D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD, MS] + M <: SystemParticipant[CD, PD, MS], ] extends ServiceRegistration[PD, CD, MS, D, I, MC, M] { this: ParticipantAgent[PD, CD, MS, D, I, MC, M] => protected val pdClassTag: ClassTag[PD] @@ -126,7 +126,7 @@ protected trait ParticipantAgentFundamentals[ requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, senderToMaybeTick: (ActorRef, Option[Long]), - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] = { val stateData = determineFromOutsideBaseStateData( inputModel, @@ -136,7 +136,7 @@ protected trait ParticipantAgentFundamentals[ resolution, requestVoltageDeviationThreshold, outputConfig, - senderToMaybeTick + senderToMaybeTick, ) /* Confirm final initialization */ @@ -178,13 +178,13 @@ protected trait ParticipantAgentFundamentals[ resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - senderToMaybeTick: (ActorRef, Option[Long]) + senderToMaybeTick: (ActorRef, Option[Long]), ): FromOutsideBaseStateData[M, PD] = { val model = buildModel( inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) FromOutsideBaseStateData( model, @@ -203,10 +203,10 @@ protected trait ParticipantAgentFundamentals[ .to(PU) .getValue .doubleValue - ) + ), ), ValueStore.forResult[PD](resolution, 2), - ValueStore(resolution) + ValueStore(resolution), ) } @@ -226,7 +226,7 @@ protected trait ParticipantAgentFundamentals[ inputModel: InputModelContainer[I], modelConfig: MC, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): M /** Initializing the agent based on the uninitialized state and additional @@ -267,7 +267,7 @@ protected trait ParticipantAgentFundamentals[ requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, scheduler: ActorRef, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): FSM.State[AgentState, ParticipantStateData[PD]] = try { /* Register for services */ @@ -279,7 +279,7 @@ protected trait ParticipantAgentFundamentals[ emAgent ! RegisterParticipant( inputModel.electricalInputModel.getUuid, self.toTyped[FlexRequest], - inputModel.electricalInputModel + inputModel.electricalInputModel, ) } @@ -292,7 +292,7 @@ protected trait ParticipantAgentFundamentals[ resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) /* If we do have registered with secondary data providers, wait for their responses. If not, the agent does not @@ -300,7 +300,7 @@ protected trait ParticipantAgentFundamentals[ if (awaitRegistrationResponsesFrom.nonEmpty) { goto(HandleInformation) using CollectRegistrationConfirmMessages( baseStateData, - awaitRegistrationResponsesFrom + awaitRegistrationResponsesFrom, ) } else { /* Determine the next activation tick, create a ScheduleTriggerMessage and remove the recently triggered tick */ @@ -313,7 +313,7 @@ protected trait ParticipantAgentFundamentals[ // flex is scheduled for tick 0, if no first tick available emAgent ! ScheduleFlexRequest( inputModel.electricalInputModel.getUuid, - newTick.getOrElse(0) + newTick.getOrElse(0), ) } @@ -321,7 +321,7 @@ protected trait ParticipantAgentFundamentals[ // scheduler, since we are activated by the EmAgent from now on scheduler ! Completion( self.toTyped, - newTick.filterNot(_ => baseStateData.isEmManaged) + newTick.filterNot(_ => baseStateData.isEmManaged), ) log.debug(s"Going to {}, using {}", Idle, nextBaseStateData) @@ -346,7 +346,7 @@ protected trait ParticipantAgentFundamentals[ resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[PD, CD, MS, M] /** Determine all ticks between the operation start and end of the @@ -368,7 +368,7 @@ protected trait ParticipantAgentFundamentals[ simulationStartDate: ZonedDateTime, resolution: Long, operationStart: Long, - operationEnd: Long + operationEnd: Long, ): SortedSet[Long] = { /* The profile load model holds values in the specified resolution (e.g. for each full quarter hour (00:00, * 00:15, ...)). As the simulation might not start at an integer multiple of the resolution, we have to @@ -404,7 +404,7 @@ protected trait ParticipantAgentFundamentals[ */ def firstFullResolutionInSimulation( simulationStartDate: ZonedDateTime, - resolution: Long + resolution: Long, ): Long = { if (3600L % resolution != 0) throw new AgentInitializationException( @@ -430,12 +430,12 @@ protected trait ParticipantAgentFundamentals[ def handleRegistrationResponse( scheduler: ActorRef, registrationResponse: RegistrationResponseMessage, - stateData: CollectRegistrationConfirmMessages[PD] + stateData: CollectRegistrationConfirmMessages[PD], ): FSM.State[AgentState, ParticipantStateData[PD]] = registrationResponse match { case RegistrationResponseMessage.RegistrationSuccessfulMessage( serviceRef, - maybeNextTick + maybeNextTick, ) => val remainingResponses = stateData.pendingResponses.filter(_ != serviceRef) @@ -452,12 +452,12 @@ protected trait ParticipantAgentFundamentals[ stateData.baseStateData.requestValueStore, stateData.baseStateData.voltageValueStore, stateData.baseStateData.additionalActivationTicks, - foreseenDataTicks + foreseenDataTicks, ) goToIdleReplyCompletionAndScheduleTriggerForNextAction( complementedBaseStateData, - scheduler + scheduler, ) } else { val foreseenDataTicksFlattened = foreseenDataTicks.collect { @@ -467,7 +467,7 @@ protected trait ParticipantAgentFundamentals[ /* We not have yet received all responses. Wait here a bit for next messages. */ stay() using stateData.copy( pendingResponses = remainingResponses, - foreseenNextDataTicks = foreseenDataTicksFlattened + foreseenNextDataTicks = foreseenDataTicksFlattened, ) } case RegistrationResponseMessage.RegistrationFailedMessage(serviceRef) => @@ -493,7 +493,7 @@ protected trait ParticipantAgentFundamentals[ override def handleDataProvisionAndGoToHandleInformation( msg: ProvisionMessage[Data], baseStateData: BaseStateData[PD], - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* Figure out, who is going to send data in this tick */ val expectedSenders = baseStateData.foreseenDataTicks @@ -529,13 +529,13 @@ protected trait ParticipantAgentFundamentals[ emAgent ! ScheduleFlexRequest( modelStateData.model.getUuid, msg.tick, - msg.unlockKey + msg.unlockKey, ) case None => scheduler ! ScheduleActivation( self.toTyped, msg.tick, - msg.unlockKey + msg.unlockKey, ) } case _ => @@ -555,10 +555,10 @@ protected trait ParticipantAgentFundamentals[ baseStateData.requestValueStore, baseStateData.voltageValueStore, baseStateData.additionalActivationTicks, - foreseenDataTicks + foreseenDataTicks, ), expectedSenders, - yetTriggered = false + yetTriggered = false, ) goto(HandleInformation) using nextStateData } @@ -590,7 +590,7 @@ protected trait ParticipantAgentFundamentals[ stateData: DataCollectionStateData[PD], isYetTriggered: Boolean, tick: Long, - scheduler: ActorRef + scheduler: ActorRef, )(implicit outputConfig: NotifierConfig ): FSM.State[AgentState, ParticipantStateData[PD]] = { @@ -599,7 +599,7 @@ protected trait ParticipantAgentFundamentals[ stateData.baseStateData match { case fromOutsideBaseStateData: BaseStateData.FromOutsideBaseStateData[ M, - PD + PD, ] => /* Determine the way, the reactive power may be filled up */ val reactivePowerFunc = @@ -613,14 +613,14 @@ protected trait ParticipantAgentFundamentals[ announceSimulationResult( stateData.baseStateData, tick, - AccompaniedSimulationResult(mostRecentData) + AccompaniedSimulationResult(mostRecentData), ) val resultValueStore = fromOutsideBaseStateData.resultValueStore val updatedResultValueStore = ValueStore.updateValueStore( resultValueStore, tick, - mostRecentData + mostRecentData, ) val baseStateDataWithUpdatedResults = BaseStateData.updateBaseStateData( @@ -629,17 +629,17 @@ protected trait ParticipantAgentFundamentals[ stateData.baseStateData.requestValueStore, stateData.baseStateData.voltageValueStore, stateData.baseStateData.additionalActivationTicks, - stateData.baseStateData.foreseenDataTicks + stateData.baseStateData.foreseenDataTicks, ) goToIdleReplyCompletionAndScheduleTriggerForNextAction( baseStateDataWithUpdatedResults, - scheduler + scheduler, ) case Failure(exception) => log.error( "Was not able to extract received primary data correctly. Tear down the simulation. Failed with", - exception + exception, ) throw exception } @@ -648,14 +648,14 @@ protected trait ParticipantAgentFundamentals[ PD, CD, MS, - M + M, ] if modelStateData.isEmManaged => val updatedReceivedSecondaryData = ValueStore.updateValueStore( modelStateData.receivedSecondaryDataStore, tick, stateData.data.map { case (actorRef, Some(data: SecondaryData)) => actorRef -> data - } + }, ) // we don't go to calculate state, but return to idle directly @@ -663,7 +663,7 @@ protected trait ParticipantAgentFundamentals[ modelStateData.copy( receivedSecondaryDataStore = updatedReceivedSecondaryData ), - tick + tick, ) goto(Idle) using updatedStateData @@ -684,11 +684,11 @@ protected trait ParticipantAgentFundamentals[ override protected def handleFlexRequest( participantStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): ParticipantModelBaseStateData[PD, CD, MS, M] = { val updatedBaseStateData = calculateFlexOptions( participantStateData, - tick + tick, ) val updatedFlexData = updatedBaseStateData.flexStateData.getOrElse( @@ -709,7 +709,7 @@ protected trait ParticipantAgentFundamentals[ override protected def calculateFlexOptions( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], - tick: Long + tick: Long, ): ParticipantModelBaseStateData[PD, CD, MS, M] = { implicit val startDateTime: ZonedDateTime = baseStateData.startDate @@ -717,7 +717,7 @@ protected trait ParticipantAgentFundamentals[ val relevantData = createCalcRelevantData( baseStateData, - tick + tick, ) val lastState = getLastOrInitialStateData(baseStateData, tick) @@ -733,14 +733,14 @@ protected trait ParticipantAgentFundamentals[ modelUuid, referencePower, minPower, - maxPower + maxPower, ) => new FlexOptionsResult( tick.toDateTime, modelUuid, referencePower.toMegawatts.asMegaWatt, minPower.toMegawatts.asMegaWatt, - maxPower.toMegawatts.asMegaWatt + maxPower.toMegawatts.asMegaWatt, ) } @@ -757,7 +757,7 @@ protected trait ParticipantAgentFundamentals[ override protected def handleFlexCtrl( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], flexCtrl: IssueFlexControl, - scheduler: ActorRef + scheduler: ActorRef, ): State = { /* Collect all needed information */ val flexStateData = baseStateData.flexStateData.getOrElse( @@ -767,7 +767,7 @@ protected trait ParticipantAgentFundamentals[ ) val relevantData = createCalcRelevantData( baseStateData, - flexCtrl.tick + flexCtrl.tick, ) val lastState = getLastOrInitialStateData(baseStateData, flexCtrl.tick) @@ -788,7 +788,7 @@ protected trait ParticipantAgentFundamentals[ baseStateData, relevantData, lastState, - setPointActivePower + setPointActivePower, ) // sanity check, simulation would hang if this matches @@ -807,7 +807,7 @@ protected trait ParticipantAgentFundamentals[ stateDataStore = ValueStore.updateValueStore( baseStateData.stateDataStore, flexCtrl.tick, - updatedState + updatedState, ) ) @@ -815,7 +815,7 @@ protected trait ParticipantAgentFundamentals[ val stateDataWithResults = handleCalculatedResult( updatedStateData, result, - flexCtrl.tick + flexCtrl.tick, ) // determine next tick @@ -833,7 +833,7 @@ protected trait ParticipantAgentFundamentals[ baseStateData.modelUuid, result.toApparentPower, flexChangeIndicator.changesAtNextActivation, - nextActivation + nextActivation, ) stay() using stateDataFinal @@ -854,21 +854,21 @@ protected trait ParticipantAgentFundamentals[ protected def handleCalculatedResult( baseStateData: ParticipantModelBaseStateData[PD, CD, MS, M], result: PD, - currentTick: Long + currentTick: Long, ): ParticipantModelBaseStateData[PD, CD, MS, M] = { // announce last result to listeners announceSimulationResult( baseStateData, currentTick, - AccompaniedSimulationResult(result) + AccompaniedSimulationResult(result), )(baseStateData.outputConfig) baseStateData.copy( resultValueStore = ValueStore.updateValueStore( baseStateData.resultValueStore, currentTick, - result + result, ) ) } @@ -893,7 +893,7 @@ protected trait ParticipantAgentFundamentals[ lastModelState: MS, currentTick: Long, scheduler: ActorRef, - nodalVoltage: squants.Dimensionless + nodalVoltage: squants.Dimensionless, ): FSM.State[AgentState, ParticipantStateData[PD]] = { val calcRelevantData = createCalcRelevantData(baseStateData, currentTick) @@ -904,34 +904,34 @@ protected trait ParticipantAgentFundamentals[ lastModelState, calcRelevantData, nodalVoltage, - baseStateData.model + baseStateData.model, ) val result = calculateModelPowerFunc( currentTick, baseStateData, updatedState, - nodalVoltage + nodalVoltage, ) val updatedResultValueStore = ValueStore.updateValueStore( baseStateData.resultValueStore, currentTick, - result + result, ) /* Inform the listeners about new result */ announceSimulationResult( baseStateData, currentTick, - AccompaniedSimulationResult(result) + AccompaniedSimulationResult(result), )(baseStateData.outputConfig) val updatedStateDataStore = ValueStore.updateValueStore( baseStateData.stateDataStore, currentTick, - updatedState + updatedState, ) /* In this case, without secondary data, the agent has been triggered by an ActivityStartTrigger by itself, @@ -939,12 +939,12 @@ protected trait ParticipantAgentFundamentals[ val baseStateDataWithUpdatedResultStore = baseStateData.copy( resultValueStore = updatedResultValueStore, - stateDataStore = updatedStateDataStore + stateDataStore = updatedStateDataStore, ) goToIdleReplyCompletionAndScheduleTriggerForNextAction( baseStateDataWithUpdatedResultStore, - scheduler + scheduler, ) } @@ -969,7 +969,7 @@ protected trait ParticipantAgentFundamentals[ modelState: MS, calcRelevantData: CD, nodalVoltage: squants.Dimensionless, - model: M + model: M, ): MS /** Determining the active to reactive power function to apply @@ -983,7 +983,7 @@ protected trait ParticipantAgentFundamentals[ */ def getReactivePowerFunction( tick: Long, - baseStateData: FromOutsideBaseStateData[M, PD] + baseStateData: FromOutsideBaseStateData[M, PD], ): Power => ReactivePower = if (baseStateData.fillUpReactivePowerWithModelFunc) { /* Use the model's active to reactive power function */ @@ -1015,7 +1015,7 @@ protected trait ParticipantAgentFundamentals[ */ def prepareData( data: Map[ActorRef, Option[_ <: Data]], - reactivePowerFunction: Power => ReactivePower + reactivePowerFunction: Power => ReactivePower, ): Try[PD] = data.headOption .flatMap { case (_, maybeData) => @@ -1073,7 +1073,7 @@ protected trait ParticipantAgentFundamentals[ */ def goToIdleReplyCompletionAndScheduleTriggerForNextAction( baseStateData: BaseStateData[PD], - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* Determine the very next tick, where activation is required */ val (maybeNextTick, updatedBaseStateData) = @@ -1088,7 +1088,7 @@ protected trait ParticipantAgentFundamentals[ maybeEmAgent.foreach { _ ! ScheduleFlexRequest( modelStateData.model.getUuid, - maybeNextTick.getOrElse(0) + maybeNextTick.getOrElse(0), ) } @@ -1102,7 +1102,7 @@ protected trait ParticipantAgentFundamentals[ // scheduler, since we are activated by the EmAgent from now on scheduler ! Completion( self.toTyped, - maybeNextTick.filterNot(_ => emManaged) + maybeNextTick.filterNot(_ => emManaged), ) unstashAll() goto(Idle) using updatedBaseStateData @@ -1157,7 +1157,7 @@ protected trait ParticipantAgentFundamentals[ /* There is only a data tick available */ ( Some(dataTick), - baseStateData + baseStateData, ) case (Some(additionalTick), Some(dataTick)) if dataTick < additionalTick => @@ -1165,7 +1165,7 @@ protected trait ParticipantAgentFundamentals[ * trigger. */ ( Some(dataTick), - baseStateData + baseStateData, ) case (Some(additionalTick), _) => /* The next activation is additional (either there is no foreseen data tick or it is after the additional tick. @@ -1178,12 +1178,12 @@ protected trait ParticipantAgentFundamentals[ baseStateData.requestValueStore, baseStateData.voltageValueStore, upcomingActivationTicks, - baseStateData.foreseenDataTicks + baseStateData.foreseenDataTicks, ) ( Some(additionalTick), - updatedBaseStateData + updatedBaseStateData, ) case (None, None) => /* We don't know nothing about either additional activation nor new incoming data */ @@ -1223,7 +1223,7 @@ protected trait ParticipantAgentFundamentals[ requestTick: Long, eInPu: Dimensionless, fInPu: Dimensionless, - alternativeResult: PD + alternativeResult: PD, ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* Check, if there is any calculation foreseen for this tick. If so, wait with the response. */ val activationExpected = @@ -1235,7 +1235,7 @@ protected trait ParticipantAgentFundamentals[ s"Received power request from '{}' for tick '{}', but I'm still waiting for new results before " + s"this tick. Waiting with the response.", sender(), - requestTick + requestTick, ) stash() stay() using baseStateData @@ -1246,7 +1246,7 @@ protected trait ParticipantAgentFundamentals[ sqrt( pow(eInPu.toEach, 2) + pow( fInPu.toEach, - 2 + 2, ) ) ) @@ -1256,7 +1256,7 @@ protected trait ParticipantAgentFundamentals[ ValueStore.updateValueStore( baseStateData.voltageValueStore, requestTick, - nodalVoltage + nodalVoltage, ) /* Determine the most recent request */ val mostRecentRequest = @@ -1269,7 +1269,7 @@ protected trait ParticipantAgentFundamentals[ requestTick, updatedVoltageStore, nodalVoltage, - lastNodalVoltage + lastNodalVoltage, ).getOrElse { /* If a fast reply is not possible, determine it the old fashioned way */ determineReply( @@ -1278,7 +1278,7 @@ protected trait ParticipantAgentFundamentals[ mostRecentRequest, nodalVoltage, updatedVoltageStore, - alternativeResult + alternativeResult, ) } } @@ -1311,7 +1311,7 @@ protected trait ParticipantAgentFundamentals[ requestTick: Long, voltageValueStore: ValueStore[Dimensionless], nodalVoltage: Dimensionless, - lastNodalVoltage: Option[(Long, Dimensionless)] + lastNodalVoltage: Option[(Long, Dimensionless)], ): Option[FSM.State[AgentState, ParticipantStateData[PD]]] = { implicit val outputConfig: NotifierConfig = baseStateData.outputConfig @@ -1330,14 +1330,14 @@ protected trait ParticipantAgentFundamentals[ voltageValueStore = voltageValueStore ) replying AssetPowerUnchangedMessage( latestProvidedValues.p, - latestProvidedValues.q + latestProvidedValues.q, ) ) case modelBaseStateData: ParticipantModelBaseStateData[ PD, CD, MS, - M + M, ] => /* Check, if the last request has been made with the same nodal voltage. If not, recalculate the reactive * power. */ @@ -1353,7 +1353,7 @@ protected trait ParticipantAgentFundamentals[ Some( stay() using modelBaseStateData replying AssetPowerUnchangedMessage( latestProvidedValues.p, - latestProvidedValues.q + latestProvidedValues.q, ) ) } else { @@ -1398,7 +1398,7 @@ protected trait ParticipantAgentFundamentals[ mostRecentRequest: Option[(Long, PD)], nodalVoltage: Dimensionless, updatedVoltageValueStore: ValueStore[Dimensionless], - alternativeResult: PD + alternativeResult: PD, ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* No fast reply possible --> Some calculations have to be made */ mostRecentRequest match { @@ -1414,7 +1414,7 @@ protected trait ParticipantAgentFundamentals[ PD, CD, MS, - M + M, ] => /* Active power is yet calculated, but reactive power needs update */ val nextReactivePower = modelBaseStateData.model @@ -1425,17 +1425,17 @@ protected trait ParticipantAgentFundamentals[ ValueStore.updateValueStore( baseStateData.requestValueStore, requestTick, - lastResult.withReactivePower(nextReactivePower) + lastResult.withReactivePower(nextReactivePower), ) val nextStateData = modelBaseStateData.copy( requestValueStore = updatedRequestValueStore, - voltageValueStore = updatedVoltageValueStore + voltageValueStore = updatedVoltageValueStore, ) stay() using nextStateData replying AssetPowerChangedMessage( lastResult.p, - nextReactivePower + nextReactivePower, ) case unexpectedStateData => throw new IllegalStateException( @@ -1450,7 +1450,7 @@ protected trait ParticipantAgentFundamentals[ getRelevantResultData( requestTick, baseStateData.resultValueStore, - baseStateData.requestValueStore + baseStateData.requestValueStore, ) match { case Some(relevantData) => /* There is at least one relevant simulation result apparent, which might also be the most recent one @@ -1461,7 +1461,7 @@ protected trait ParticipantAgentFundamentals[ requestTick, nodalVoltage, updatedVoltageValueStore, - alternativeResult + alternativeResult, ) case None => /* There is no simulation result at all. Reply with zero power */ @@ -1469,7 +1469,7 @@ protected trait ParticipantAgentFundamentals[ baseStateData, alternativeResult, requestTick, - updatedVoltageValueStore + updatedVoltageValueStore, ) } } @@ -1495,7 +1495,7 @@ protected trait ParticipantAgentFundamentals[ def getRelevantResultData( requestTick: Long, resultValueStore: ValueStore[PD], - requestValueStore: ValueStore[PD] + requestValueStore: ValueStore[PD], ): Option[RelevantResultValues[PD]] = { /* The actual tick window for averaging is the last request tick and this request tick (both including) */ val (averagingWindowStart, averagingWindowEnd) = @@ -1505,7 +1505,7 @@ protected trait ParticipantAgentFundamentals[ * averaging window and it's end (both including) are relevant for averaging the simulated primary data */ val firstRelevantTick = determineFirstRelevantTick( averagingWindowStart, - resultValueStore + resultValueStore, ) /* Let's see, if we got some simulation results between the first relevant simulation tick and this request's tick */ @@ -1518,7 +1518,7 @@ protected trait ParticipantAgentFundamentals[ RelevantResultValues( averagingWindowStart, averagingWindowEnd, - simulationResults + simulationResults, ) ) } else { @@ -1538,7 +1538,7 @@ protected trait ParticipantAgentFundamentals[ */ private def determineTickWindow( requestTick: Long, - requestValueStore: ValueStore[_] + requestValueStore: ValueStore[_], ): (Long, Long) = requestValueStore.lastKnownTick(requestTick - 1) match { case Some(lastRequestTick) => (lastRequestTick, requestTick) @@ -1559,7 +1559,7 @@ protected trait ParticipantAgentFundamentals[ */ private def determineFirstRelevantTick( lastRequestTick: Long, - resultValueStore: ValueStore[_] + resultValueStore: ValueStore[_], ): Long = resultValueStore.lastKnownTick(lastRequestTick) match { case Some(firstRelevantDataTick) => firstRelevantDataTick @@ -1592,7 +1592,7 @@ protected trait ParticipantAgentFundamentals[ requestTick: Long, nodalVoltage: Dimensionless, voltageValueStore: ValueStore[Dimensionless], - alternativeResult: PD + alternativeResult: PD, ): FSM.State[AgentState, ParticipantStateData[PD]] = { if (relevantResults.relevantData.nonEmpty) { averagePowerAndStay( @@ -1602,18 +1602,18 @@ protected trait ParticipantAgentFundamentals[ relevantResults.windowStart, relevantResults.windowEnd, nodalVoltage, - voltageValueStore + voltageValueStore, ) } else { log.debug( s"No relevant data apparent, stay and reply with alternative result {}.", - alternativeResult + alternativeResult, ) stayWithUpdatedRequestValueStore( baseData, alternativeResult, requestTick, - voltageValueStore + voltageValueStore, ) } } @@ -1648,20 +1648,20 @@ protected trait ParticipantAgentFundamentals[ windowStartTick: Long, windowEndTick: Long, nodalVoltage: Dimensionless, - voltageValueStore: ValueStore[Dimensionless] + voltageValueStore: ValueStore[Dimensionless], ): FSM.State[AgentState, ParticipantStateData[PD]] = { val averageResult = determineAverageResult( baseData, tickToResult, windowStartTick, windowEndTick, - nodalVoltage + nodalVoltage, ) stayWithUpdatedRequestValueStore( baseData, averageResult, requestTick, - voltageValueStore + voltageValueStore, ) } @@ -1687,7 +1687,7 @@ protected trait ParticipantAgentFundamentals[ tickToResult: Map[Long, PD], windowStartTick: Long, windowEndTick: Long, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): PD = { /* Determine, how the single model would transfer the active into reactive power */ val activeToReactivePowerFunction = baseStateData match { @@ -1702,7 +1702,7 @@ protected trait ParticipantAgentFundamentals[ tickToResult, windowStartTick, windowEndTick, - activeToReactivePowerFunction + activeToReactivePowerFunction, ) } @@ -1725,7 +1725,7 @@ protected trait ParticipantAgentFundamentals[ windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] = None + ] = None, ): PD /** Updates the given base state data by inserting updated request value store @@ -1749,13 +1749,13 @@ protected trait ParticipantAgentFundamentals[ baseStateData: BaseStateData[PD], averageResult: PD, requestTick: Long, - voltageValueStore: ValueStore[Dimensionless] + voltageValueStore: ValueStore[Dimensionless], ): FSM.State[AgentState, ParticipantStateData[PD]] = { val updatedRequestValueStore = ValueStore.updateValueStore( baseStateData.requestValueStore, requestTick, - averageResult + averageResult, ) val nextStateData = BaseStateData.updateBaseStateData( baseStateData, @@ -1763,7 +1763,7 @@ protected trait ParticipantAgentFundamentals[ updatedRequestValueStore, voltageValueStore, baseStateData.additionalActivationTicks, - baseStateData.foreseenDataTicks + baseStateData.foreseenDataTicks, ) averageResult.toApparentPower match { @@ -1787,7 +1787,7 @@ protected trait ParticipantAgentFundamentals[ protected def announceSimulationResult( baseStateData: BaseStateData[PD], tick: Long, - result: AccompaniedSimulationResult[PD] + result: AccompaniedSimulationResult[PD], )(implicit outputConfig: NotifierConfig): Unit = if (outputConfig.simulationResultInfo) { notifyListener( @@ -1816,20 +1816,20 @@ protected trait ParticipantAgentFundamentals[ scheduler: ActorRef, baseStateData: BaseStateData[PD], result: AccompaniedSimulationResult[PD], - relevantData: CD + relevantData: CD, ): FSM.State[AgentState, ParticipantStateData[PD]] = { /* Update the value stores */ val updatedValueStore = ValueStore.updateValueStore( baseStateData.resultValueStore, currentTick, - result.primaryData + result.primaryData, ) /* Inform the listeners about new result */ announceSimulationResult( baseStateData, currentTick, - result + result, )(baseStateData.outputConfig) /* Update the base state data */ @@ -1847,7 +1847,7 @@ protected trait ParticipantAgentFundamentals[ goToIdleReplyCompletionAndScheduleTriggerForNextAction( baseStateDateWithUpdatedResults, - scheduler + scheduler, ) } @@ -1869,7 +1869,7 @@ protected trait ParticipantAgentFundamentals[ baseStateData: BaseStateData[_], tick: Long, activePower: Power, - reactivePower: ReactivePower + reactivePower: ReactivePower, )(implicit outputConfig: NotifierConfig): Unit = if (outputConfig.powerRequestReply) { log.warning( @@ -1889,7 +1889,7 @@ protected trait ParticipantAgentFundamentals[ */ override def finalizeTickAfterPF( baseStateData: BaseStateData[PD], - currentTick: Long + currentTick: Long, ): FSM.State[AgentState, ParticipantStateData[PD]] = { baseStateData.requestValueStore.last(currentTick).foreach { case (_, data) => @@ -1898,7 +1898,7 @@ protected trait ParticipantAgentFundamentals[ baseStateData, currentTick, data.p, - data.q + data.q, )(baseStateData.outputConfig) } goto(Idle) using baseStateData @@ -1918,7 +1918,7 @@ protected trait ParticipantAgentFundamentals[ def buildResultEvent( baseStateData: BaseStateData[PD], tick: Long, - result: PD + result: PD, ): ParticipantResultEvent = { val uuid = baseStateData.modelUuid val dateTime = tick.toDateTime(baseStateData.startDate) @@ -1962,7 +1962,7 @@ protected trait ParticipantAgentFundamentals[ protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: PD + result: PD, ): SystemParticipantResult /** Returns secondary service of type T or throws exception @@ -2012,7 +2012,7 @@ object ParticipantAgentFundamentals { final case class RelevantResultValues[+PD <: PrimaryData]( windowStart: Long, windowEnd: Long, - relevantData: Map[Long, PD] + relevantData: Map[Long, PD], ) /** Determine the average apparent power within the given tick window @@ -2035,21 +2035,21 @@ object ParticipantAgentFundamentals { activeToReactivePowerFuncOpt: Option[ Power => ReactivePower ] = None, - log: LoggingAdapter + log: LoggingAdapter, ): ApparentPower = { val p = QuantityUtil.average[Power, Energy]( tickToResults.map { case (tick, pd) => tick -> pd.p }, windowStart, - windowEnd + windowEnd, ) match { case Success(pSuccess) => pSuccess case Failure(exception) => log.warning( "Unable to determine average active power. Apply 0 instead. Cause:\n\t{}", - exception + exception, ) Megawatts(0d) } @@ -2065,14 +2065,14 @@ object ParticipantAgentFundamentals { } }, windowStart, - windowEnd + windowEnd, ) match { case Success(pSuccess) => Megavars(pSuccess.toMegawatts) case Failure(exception) => log.warning( "Unable to determine average reactive power. Apply 0 instead. Cause:\n\t{}", - exception + exception, ) Megavars(0d) } @@ -2100,14 +2100,14 @@ object ParticipantAgentFundamentals { activeToReactivePowerFuncOpt: Option[ Power => ReactivePower ] = None, - log: LoggingAdapter + log: LoggingAdapter, ): ApparentPowerAndHeat = { val tickToResultsApparentPower: Map[Long, ApparentPower] = tickToResults.map { case (tick, pd) => ( tick, - ApparentPower(Megawatts(pd.p.toMegawatts), Megavars(pd.q.toMegavars)) + ApparentPower(Megawatts(pd.p.toMegawatts), Megavars(pd.q.toMegavars)), ) } @@ -2116,7 +2116,7 @@ object ParticipantAgentFundamentals { windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) val qDot = QuantityUtil.average[Power, Energy]( @@ -2124,13 +2124,13 @@ object ParticipantAgentFundamentals { tick -> Megawatts(pd.qDot.toMegawatts) }, windowStart, - windowEnd + windowEnd, ) match { case Success(qDotSuccess) => qDotSuccess case Failure(exception) => log.warning( "Unable to determine average thermal power. Apply 0 instead. Cause:\n\t{}", - exception + exception, ) Megawatts(0d) } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala index bca34cc95f..b8b2ef33ad 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ServiceRegistration.scala @@ -14,7 +14,7 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.{ ActorEvMovementsService, ActorPriceService, - ActorWeatherService + ActorWeatherService, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.config.SimonaConfig @@ -22,7 +22,7 @@ import edu.ie3.simona.exceptions.agent.ServiceRegistrationException import edu.ie3.simona.model.participant.{ CalcRelevantData, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.services.EvMessage.RegisterForEvDataMessage import edu.ie3.simona.ontology.messages.services.WeatherMessage.RegisterForWeatherMessage @@ -34,7 +34,7 @@ trait ServiceRegistration[ D <: ParticipantStateData[PD], I <: SystemParticipantInput, MC <: SimonaConfig.BaseRuntimeConfig, - M <: SystemParticipant[CD, PD, MS] + M <: SystemParticipant[CD, PD, MS], ] { this: ParticipantAgent[PD, CD, MS, D, I, MC, M] => @@ -50,7 +50,7 @@ trait ServiceRegistration[ */ def registerForServices( inputModel: I, - services: Iterable[SecondaryDataService[_ <: SecondaryData]] + services: Iterable[SecondaryDataService[_ <: SecondaryData]], ): Iterable[ActorRef] = services.flatMap(service => registerForSecondaryService(service, inputModel) @@ -72,12 +72,12 @@ trait ServiceRegistration[ S <: SecondaryData ]( serviceDefinition: SecondaryDataService[S], - inputModel: I + inputModel: I, ): Option[ActorRef] = serviceDefinition match { case SecondaryDataService.ActorPriceService(_) => log.debug( s"Attempt to register for {}. This is currently not supported.", - ActorPriceService + ActorPriceService, ) None case ActorWeatherService(serviceRef) => @@ -98,7 +98,7 @@ trait ServiceRegistration[ */ private def registerForWeather( actorRef: ActorRef, - inputModel: I + inputModel: I, ): Unit = { /* If we are asked to register for weather, determine the proper geo position */ val geoPosition = inputModel.getNode.getGeoPosition @@ -126,7 +126,7 @@ trait ServiceRegistration[ */ private def registerForEvMovements( serviceRef: ActorRef, - inputModel: I + inputModel: I, ): Unit = { inputModel match { case evcsInput: EvcsInput => diff --git a/src/main/scala/edu/ie3/simona/agent/participant/data/Data.scala b/src/main/scala/edu/ie3/simona/agent/participant/data/Data.scala index 2bba0f0509..35748f755f 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/data/Data.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/data/Data.scala @@ -62,7 +62,7 @@ object Data { val ZERO_POWER: ApparentPower = ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) /** Active power as participant simulation result @@ -76,7 +76,7 @@ object Data { override def toApparentPower: ApparentPower = ApparentPower( p, - Megavars(0d) + Megavars(0d), ) override def add(q: ReactivePower): ApparentPower = @@ -92,7 +92,7 @@ object Data { */ final case class ApparentPower( override val p: Power, - override val q: ReactivePower + override val q: ReactivePower, ) extends PrimaryDataWithApparentPower[ApparentPower] { override def toApparentPower: ApparentPower = this @@ -109,14 +109,14 @@ object Data { */ final case class ActivePowerAndHeat( override val p: Power, - override val qDot: Power + override val qDot: Power, ) extends PrimaryData with Heat with EnrichableData[ApparentPowerAndHeat] { override def toApparentPower: ApparentPower = ApparentPower( p, - Megavars(0d) + Megavars(0d), ) override def add(q: ReactivePower): ApparentPowerAndHeat = @@ -135,7 +135,7 @@ object Data { final case class ApparentPowerAndHeat( override val p: Power, override val q: ReactivePower, - override val qDot: Power + override val qDot: Power, ) extends PrimaryDataWithApparentPower[ApparentPowerAndHeat] with Heat { override def toApparentPower: ApparentPower = @@ -161,7 +161,7 @@ object Data { ), Kilowatts( qDot.to(PowerSystemUnits.KILOWATT).getValue.doubleValue - ) + ), ) ) case _ => @@ -181,7 +181,7 @@ object Data { ), Kilovars( q.to(PowerSystemUnits.KILOVAR).getValue.doubleValue - ) + ), ) ) case _ => @@ -201,7 +201,7 @@ object Data { ), Kilowatts( qDot.to(PowerSystemUnits.KILOWATT).getValue.doubleValue - ) + ), ) ) case _ => diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala index 59516ff5ab..b2c428242d 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgent.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.participant.evcs import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.ActorEvMovementsService @@ -18,18 +18,18 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.agent.participant.{ ParticipantAgent, - ParticipantAgentFundamentals + ParticipantAgentFundamentals, } import edu.ie3.simona.agent.state.AgentState.Idle import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig import edu.ie3.simona.model.participant.evcs.EvcsModel import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsRelevantData, - EvcsState + EvcsState, } import edu.ie3.simona.ontology.messages.services.EvMessage.{ DepartingEvsRequest, - EvFreeLotsRequest + EvFreeLotsRequest, } import edu.ie3.util.scala.quantities.ReactivePower import org.apache.pekko.actor.{ActorRef, Props} @@ -41,15 +41,15 @@ object EvcsAgent { initStateData: ParticipantInitializeStateData[ EvcsInput, EvcsRuntimeConfig, - ApparentPower + ApparentPower, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props( new EvcsAgent( scheduler, initStateData, - listener + listener, ) ) @@ -63,9 +63,9 @@ class EvcsAgent( initStateData: ParticipantInitializeStateData[ EvcsInput, EvcsRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPower, EvcsRelevantData, @@ -73,7 +73,7 @@ class EvcsAgent( ParticipantStateData[ApparentPower], EvcsInput, EvcsRuntimeConfig, - EvcsModel + EvcsModel, ](scheduler, initStateData) with EvcsAgentFundamentals { override val alternativeResult: ApparentPower = ZERO_POWER @@ -85,8 +85,8 @@ class EvcsAgent( ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ) => handleFreeLotsRequest(tick, modelBaseStateData) stay() @@ -97,8 +97,8 @@ class EvcsAgent( ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ) => val updatedStateData = handleDepartingEvsRequest(tick, departingEvs, modelBaseStateData) @@ -124,13 +124,13 @@ class EvcsAgent( windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] + ], ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala index d91295d5ba..9bf4dde900 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/evcs/EvcsAgentFundamentals.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.participant.evcs import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.datamodel.models.result.system.{ EvcsResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage @@ -21,12 +21,12 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService.Acto import edu.ie3.simona.agent.participant.evcs.EvcsAgent.neededServices import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FlexControlledData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, - ParticipantStateData + ParticipantStateData, } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle @@ -36,18 +36,18 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.model.participant.FlexChangeIndicator import edu.ie3.simona.model.participant.evcs.EvcsModel import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsRelevantData, - EvcsState + EvcsState, } import edu.ie3.simona.ontology.messages.PowerMessage.AssetPowerChangedMessage import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.util.SimonaConstants @@ -74,7 +74,7 @@ protected trait EvcsAgentFundamentals ParticipantStateData[ApparentPower], EvcsInput, EvcsRuntimeConfig, - EvcsModel + EvcsModel, ] { this: EvcsAgent => override protected val pdClassTag: ClassTag[ApparentPower] = @@ -113,12 +113,12 @@ protected trait EvcsAgentFundamentals resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] = { /* Check for needed services */ if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) @@ -132,14 +132,14 @@ protected trait EvcsAgentFundamentals inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ]( simulationStartDate, simulationEndDate, @@ -157,13 +157,13 @@ protected trait EvcsAgentFundamentals .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) } @@ -171,14 +171,14 @@ protected trait EvcsAgentFundamentals inputModel: InputModelContainer[EvcsInput], modelConfig: EvcsRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): EvcsModel = EvcsModel( inputModel.electricalInputModel, modelConfig.scaling, simulationStartDate, simulationEndDate, modelConfig.chargingStrategy, - modelConfig.lowestEvSoc + modelConfig.lowestEvSoc, ) override protected def createInitialState( @@ -186,13 +186,13 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] ): EvcsState = EvcsState( Seq.empty, Map.empty, - SimonaConstants.FIRST_TICK_IN_SIMULATION + SimonaConstants.FIRST_TICK_IN_SIMULATION, ) override protected def createCalcRelevantData( @@ -200,9 +200,9 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ], - tick: Long + tick: Long, ): EvcsRelevantData = { // always only take arrivals for the current tick // or empty sequence if none arrived @@ -239,18 +239,18 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ], data: EvcsRelevantData, lastState: EvcsState, - setPower: squants.Power + setPower: squants.Power, ): (EvcsState, ApparentPower, FlexChangeIndicator) = { /* Calculate the power */ val voltage = getAndCheckNodalVoltage(baseStateData, tick) val reactivePower = baseStateData.model.calculateReactivePower( setPower, - voltage + voltage, ) val result = ApparentPower(setPower, reactivePower) @@ -270,10 +270,10 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ], EvcsState, - Dimensionless + Dimensionless, ) => ApparentPower = (_, _, _, _) => throw new InvalidRequestException( @@ -306,11 +306,11 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ], lastModelState: EvcsState, tick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { /* extract EV data from secondary data, which should have been requested and received before */ baseStateData.receivedSecondaryDataStore @@ -322,7 +322,7 @@ protected trait EvcsAgentFundamentals handleArrivingEvsAndGoIdle( tick, scheduler, - baseStateData + baseStateData, ) } .getOrElse( @@ -347,8 +347,8 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ): Unit = { val evServiceRef = getService[ActorEvMovementsService]( modelBaseStateData.services @@ -359,7 +359,7 @@ protected trait EvcsAgentFundamentals evServiceRef ! FreeLotsResponse( modelBaseStateData.model.uuid, - modelBaseStateData.model.chargingPoints - lastState.evs.size + modelBaseStateData.model.chargingPoints - lastState.evs.size, ) } @@ -381,13 +381,13 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] = { val evServiceRef = getService[ActorEvMovementsService]( baseStateData.services @@ -410,7 +410,7 @@ protected trait EvcsAgentFundamentals val updatedEvs = baseStateData.model.applySchedule( lastState, - tick + tick, ) val (departingEvs, stayingEvs) = updatedEvs.partition { ev => @@ -421,7 +421,7 @@ protected trait EvcsAgentFundamentals if (requestedDepartingEvs.nonEmpty) { evServiceRef ! DepartingEvsResponse( baseStateData.modelUuid, - departingEvs + departingEvs, ) } @@ -430,7 +430,7 @@ protected trait EvcsAgentFundamentals determineResultsAnnounceUpdateValueStore( lastState, tick, - baseStateData + baseStateData, ) val stayingSchedules = @@ -451,9 +451,9 @@ protected trait EvcsAgentFundamentals stateDataStore = ValueStore.updateValueStore( baseStateData.stateDataStore, tick, - newState + newState, ), - resultValueStore = updatedResultValueStore + resultValueStore = updatedResultValueStore, ) } @@ -478,8 +478,8 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { val relevantData = @@ -489,13 +489,13 @@ protected trait EvcsAgentFundamentals val currentEvs = modelBaseStateData.model.determineCurrentEvs( relevantData, - lastState + lastState, ) // if new EVs arrived, a new scheduling must be calculated. val newSchedule = modelBaseStateData.model.calculateNewScheduling( relevantData, - currentEvs + currentEvs, ) // create new current state @@ -504,7 +504,7 @@ protected trait EvcsAgentFundamentals val updatedStateDataStore = ValueStore.updateValueStore( modelBaseStateData.stateDataStore, tick, - newState + newState, ) /* Update the base state data with the updated result value store and relevant data store */ @@ -515,7 +515,7 @@ protected trait EvcsAgentFundamentals // We're only here if we're not flex-controlled, thus sending a Completion is always right goToIdleReplyCompletionAndScheduleTriggerForNextAction( updatedBaseStateData, - scheduler + scheduler, ) } @@ -545,7 +545,7 @@ protected trait EvcsAgentFundamentals mostRecentRequest: Option[(Long, ApparentPower)], nodalVoltage: squants.Dimensionless, updatedVoltageValueStore: ValueStore[squants.Dimensionless], - alternativeResult: ApparentPower + alternativeResult: ApparentPower, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { /* No fast reply possible --> Some calculations have to be made */ mostRecentRequest match { @@ -561,7 +561,7 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] => /* Active power is yet calculated, but reactive power needs update */ val nextReactivePower = modelBaseStateData.model @@ -572,18 +572,18 @@ protected trait EvcsAgentFundamentals ValueStore.updateValueStore( baseStateData.requestValueStore, requestTick, - lastResult.withReactivePower(nextReactivePower) + lastResult.withReactivePower(nextReactivePower), ) val nextStateData = modelBaseStateData.copy( requestValueStore = updatedRequestValueStore, - voltageValueStore = updatedVoltageValueStore + voltageValueStore = updatedVoltageValueStore, ) stay() using nextStateData replying AssetPowerChangedMessage( lastResult.p, - nextReactivePower + nextReactivePower, ) case unexpectedStateData => throw new IllegalStateException( @@ -605,7 +605,7 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] => val lastState = getLastOrInitialStateData(modelBaseStateData, requestTick) @@ -614,7 +614,7 @@ protected trait EvcsAgentFundamentals determineResultsAnnounceUpdateValueStore( lastState, requestTick, - modelBaseStateData + modelBaseStateData, ) modelBaseStateData.copy( @@ -630,7 +630,7 @@ protected trait EvcsAgentFundamentals getRelevantResultData( requestTick, updatedBaseStateData.resultValueStore, - updatedBaseStateData.requestValueStore + updatedBaseStateData.requestValueStore, ) match { case Some(relevantData) => /* There is at least one relevant simulation result apparent, which might also be the most recent one @@ -641,7 +641,7 @@ protected trait EvcsAgentFundamentals requestTick, nodalVoltage, updatedVoltageValueStore, - alternativeResult + alternativeResult, ) case None => /* There is no simulation result at all. Reply with zero power */ @@ -649,7 +649,7 @@ protected trait EvcsAgentFundamentals updatedBaseStateData, alternativeResult, requestTick, - updatedVoltageValueStore + updatedVoltageValueStore, ) } } @@ -672,15 +672,15 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ], result: ApparentPower, - currentTick: Long + currentTick: Long, ): ParticipantModelBaseStateData[ ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] = { // calculate results from last schedule @@ -698,7 +698,7 @@ protected trait EvcsAgentFundamentals determineResultsAnnounceUpdateValueStore( lastState, currentTick, - baseStateData + baseStateData, ) baseStateData.copy( @@ -707,7 +707,7 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel + EvcsModel, ] } } @@ -734,8 +734,8 @@ protected trait EvcsAgentFundamentals ApparentPower, EvcsRelevantData, EvcsState, - EvcsModel - ] + EvcsModel, + ], ): ValueStore[ApparentPower] = { val voltage = modelBaseStateData.voltageValueStore @@ -748,7 +748,7 @@ protected trait EvcsAgentFundamentals val (evResults, evcsResults) = modelBaseStateData.model.createResults( lastState, currentTick, - voltage + voltage, ) // send out EV results @@ -770,8 +770,8 @@ protected trait EvcsAgentFundamentals result.getTime.toTick(modelBaseStateData.startDate), ApparentPower( Megawatts(result.getP.to(MEGAWATT).getValue.doubleValue), - Megavars(result.getQ.to(MEGAVAR).getValue.doubleValue) - ) + Megavars(result.getQ.to(MEGAVAR).getValue.doubleValue), + ), ) } } @@ -790,13 +790,13 @@ protected trait EvcsAgentFundamentals override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new EvcsResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) /** Update the last known model state with the given external, relevant data @@ -820,6 +820,6 @@ protected trait EvcsAgentFundamentals modelState: EvcsState, calcRelevantData: EvcsRelevantData, nodalVoltage: squants.Dimensionless, - model: EvcsModel + model: EvcsModel, ): EvcsState = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala index 3d38db1105..9b5b681f90 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgent.scala @@ -23,9 +23,9 @@ object FixedFeedInAgent { initStateData: ParticipantInitializeStateData[ FixedFeedInInput, FixedFeedInRuntimeConfig, - ApparentPower + ApparentPower, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props(new FixedFeedInAgent(scheduler, initStateData, listener)) } @@ -42,9 +42,9 @@ class FixedFeedInAgent( initStateData: ParticipantInitializeStateData[ FixedFeedInInput, FixedFeedInRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPower, FixedRelevantData.type, @@ -52,7 +52,7 @@ class FixedFeedInAgent( ParticipantStateData[ApparentPower], FixedFeedInInput, FixedFeedInRuntimeConfig, - FixedFeedInModel + FixedFeedInModel, ](scheduler, initStateData) with FixedFeedInAgentFundamentals { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala index c68b8a4b82..cbaabae42e 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/fixedfeedin/FixedFeedInAgentFundamentals.scala @@ -9,20 +9,20 @@ package edu.ie3.simona.agent.participant.fixedfeedin import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.datamodel.models.result.system.{ FixedFeedInResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FlexControlledData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer @@ -32,7 +32,7 @@ import edu.ie3.simona.config.SimonaConfig.FixedFeedInRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData import edu.ie3.simona.model.participant.ModelState.ConstantState @@ -40,11 +40,11 @@ import edu.ie3.simona.model.participant.{ CalcRelevantData, FixedFeedInModel, FlexChangeIndicator, - ModelState + ModelState, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil.RichZonedDateTime @@ -69,7 +69,7 @@ protected trait FixedFeedInAgentFundamentals ParticipantStateData[ApparentPower], FixedFeedInInput, FixedFeedInRuntimeConfig, - FixedFeedInModel + FixedFeedInModel, ] { this: FixedFeedInAgent => override protected val pdClassTag: ClassTag[ApparentPower] = @@ -109,12 +109,12 @@ protected trait FixedFeedInAgentFundamentals resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ] = { /* Build the calculation model */ val model = @@ -122,7 +122,7 @@ protected trait FixedFeedInAgentFundamentals inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) /* Go and collect all ticks, in which new data will be available. Also register for @@ -139,14 +139,14 @@ protected trait FixedFeedInAgentFundamentals SortedSet[Long]( SimonaConstants.FIRST_TICK_IN_SIMULATION, model.operationInterval.start, - model.operationInterval.end + model.operationInterval.end, ).filterNot(_ == lastTickInSimulation) ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ]( simulationStartDate, simulationEndDate, @@ -164,13 +164,13 @@ protected trait FixedFeedInAgentFundamentals .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) } @@ -178,12 +178,12 @@ protected trait FixedFeedInAgentFundamentals inputModel: InputModelContainer[FixedFeedInInput], modelConfig: FixedFeedInRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): FixedFeedInModel = FixedFeedInModel( inputModel.electricalInputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) override protected def createInitialState( @@ -191,7 +191,7 @@ protected trait FixedFeedInAgentFundamentals ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ] ): ModelState.ConstantState.type = ConstantState @@ -200,9 +200,9 @@ protected trait FixedFeedInAgentFundamentals ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ], - tick: Long + tick: Long, ): FixedRelevantData.type = FixedRelevantData @@ -226,18 +226,18 @@ protected trait FixedFeedInAgentFundamentals ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ], data: FixedRelevantData.type, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { /* Calculate result */ val voltage = getAndCheckNodalVoltage(baseStateData, tick) val reactivePower = baseStateData.model.calculateReactivePower( setPower, - voltage + voltage, ) val result = ApparentPower(setPower, reactivePower) @@ -253,20 +253,20 @@ protected trait FixedFeedInAgentFundamentals ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = ( currentTick: Long, baseStateData: ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ], state: ConstantState.type, - voltage: Dimensionless + voltage: Dimensionless, ) => baseStateData.model match { case fixedModel: FixedFeedInModel => @@ -274,7 +274,7 @@ protected trait FixedFeedInAgentFundamentals currentTick, voltage, state, - FixedRelevantData + FixedRelevantData, ) case unsupportedModel => throw new InconsistentStateException( @@ -308,11 +308,11 @@ protected trait FixedFeedInAgentFundamentals ApparentPower, FixedRelevantData.type, ConstantState.type, - FixedFeedInModel + FixedFeedInModel, ], lastModelState: ConstantState.type, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = throw new InvalidRequestException( "Request to calculate power with secondary data cannot be processed in a fixed feed in agent." @@ -337,14 +337,14 @@ protected trait FixedFeedInAgentFundamentals windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] = None + ] = None, ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -361,13 +361,13 @@ protected trait FixedFeedInAgentFundamentals override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new FixedFeedInResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) /** Update the last known model state with the given external, relevant data @@ -391,6 +391,6 @@ protected trait FixedFeedInAgentFundamentals modelState: ModelState.ConstantState.type, calcRelevantData: CalcRelevantData.FixedRelevantData.type, nodalVoltage: squants.Dimensionless, - model: FixedFeedInModel + model: FixedFeedInModel, ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala index 2f587e710a..0be0c2877b 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgent.scala @@ -24,15 +24,15 @@ object HpAgent { initStateData: ParticipantInitializeStateData[ HpInput, HpRuntimeConfig, - ApparentPowerAndHeat + ApparentPowerAndHeat, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props( new HpAgent( scheduler, initStateData, - listener + listener, ) ) @@ -46,9 +46,9 @@ class HpAgent( initStateData: ParticipantInitializeStateData[ HpInput, HpRuntimeConfig, - ApparentPowerAndHeat + ApparentPowerAndHeat, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPowerAndHeat, HpRelevantData, @@ -58,7 +58,7 @@ class HpAgent( ], HpInput, HpRuntimeConfig, - HpModel + HpModel, ](scheduler, initStateData) with HpAgentFundamentals { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 2136bb7776..0fb9103312 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.participant.hp import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.datamodel.models.result.system.{ HpResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage @@ -20,15 +20,15 @@ import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.hp.HpAgent.neededServices import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FlexControlledData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ InputModelContainer, - WithHeatInputContainer + WithHeatInputContainer, } import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, - ParticipantStateData + ParticipantStateData, } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle @@ -37,7 +37,7 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.io.result.AccompaniedSimulationResult import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} @@ -45,7 +45,7 @@ import edu.ie3.simona.model.participant.{FlexChangeIndicator, HpModel} import edu.ie3.simona.model.thermal.ThermalGrid import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.util.quantities.PowerSystemUnits.PU @@ -70,7 +70,7 @@ trait HpAgentFundamentals ParticipantStateData[ApparentPowerAndHeat], HpInput, HpRuntimeConfig, - HpModel + HpModel, ] { this: HpAgent => override protected val pdClassTag: ClassTag[ApparentPowerAndHeat] = @@ -78,7 +78,7 @@ trait HpAgentFundamentals override val alternativeResult: ApparentPowerAndHeat = ApparentPowerAndHeat( Megawatts(0d), Megavars(0d), - Megawatts(0d) + Megawatts(0d), ) /** Partial function, that is able to transfer @@ -91,10 +91,10 @@ trait HpAgentFundamentals ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ], HpState, - Dimensionless + Dimensionless, ) => ApparentPowerAndHeat = (_, _, _, _) => throw new InvalidRequestException( @@ -106,7 +106,7 @@ trait HpAgentFundamentals ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ] ): HpState = startingState(baseStateData.model.thermalGrid) @@ -119,7 +119,7 @@ trait HpAgentFundamentals Megawatts(0d), Megawatts(0d), ThermalGrid.startingState(thermalGrid), - None + None, ) /** Handle an active power change by flex control. @@ -142,11 +142,11 @@ trait HpAgentFundamentals ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ], data: HpRelevantData, lastState: HpState, - setPower: squants.Power + setPower: squants.Power, ): (HpState, ApparentPowerAndHeat, FlexChangeIndicator) = { /* Determine needed information */ val voltage = @@ -180,7 +180,7 @@ trait HpAgentFundamentals tick, voltage, updatedState, - relevantData + relevantData, ) (updatedState, result, flexChangeIndicator) @@ -213,11 +213,11 @@ trait HpAgentFundamentals ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ], lastModelState: HpState, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPowerAndHeat]] = { /* Determine needed information */ @@ -232,7 +232,7 @@ trait HpAgentFundamentals lastModelState, relevantData, voltage, - baseStateData.model + baseStateData.model, ) /* Calculate power results */ @@ -240,7 +240,7 @@ trait HpAgentFundamentals currentTick, voltage, updatedState, - relevantData + relevantData, ) val accompanyingResults = baseStateData.model.thermalGrid.results( lastModelState.thermalGridState @@ -250,7 +250,7 @@ trait HpAgentFundamentals val updatedStateDataStore = ValueStore.updateValueStore( baseStateData.stateDataStore, currentTick, - updatedState + updatedState, ) val updatedBaseStateData = baseStateData.copy(stateDataStore = updatedStateDataStore) @@ -258,7 +258,7 @@ trait HpAgentFundamentals scheduler, updatedBaseStateData, result, - relevantData + relevantData, ) } @@ -283,7 +283,7 @@ trait HpAgentFundamentals modelState: HpState, calcRelevantData: HpRelevantData, nodalVoltage: squants.Dimensionless, - model: HpModel + model: HpModel, ): HpState = model.determineState(modelState, calcRelevantData) /** Abstract definition, individual implementations found in individual agent @@ -298,12 +298,12 @@ trait HpAgentFundamentals resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): BaseStateData.ParticipantModelBaseStateData[ ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ] = { if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) throw new AgentInitializationException( @@ -317,7 +317,7 @@ trait HpAgentFundamentals withHeatContainer, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) /* Determine a proper starting model state and save it into the base state data */ @@ -325,14 +325,14 @@ trait HpAgentFundamentals val stateDataStore = ValueStore.updateValueStore( ValueStore(resolution), -1L, - startingModelState + startingModelState, ) ParticipantModelBaseStateData[ ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ]( simulationStartDate, simulationEndDate, @@ -350,13 +350,13 @@ trait HpAgentFundamentals .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), stateDataStore, - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) case unsupported => throw new AgentInitializationException( @@ -371,9 +371,9 @@ trait HpAgentFundamentals ApparentPowerAndHeat, HpRelevantData, HpState, - HpModel + HpModel, ], - tick: Long + tick: Long, ): HpRelevantData = { /* extract weather data from secondary data, which should have been requested and received before */ val weatherData = @@ -398,7 +398,7 @@ trait HpAgentFundamentals HpRelevantData( tick, - weatherData.temp.inKelvin + weatherData.temp.inKelvin, ) } @@ -418,7 +418,7 @@ trait HpAgentFundamentals inputModel: InputModelContainer[HpInput], modelConfig: HpRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): HpModel = inputModel match { case ParticipantStateData.SimpleInputContainer(_) => throw new AgentInitializationException( @@ -431,7 +431,7 @@ trait HpAgentFundamentals modelConfig.scaling, simulationStartDate, simulationEndDate, - ThermalGrid(thermalGrid) + ThermalGrid(thermalGrid), ) } @@ -454,14 +454,14 @@ trait HpAgentFundamentals windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] + ], ): ApparentPowerAndHeat = ParticipantAgentFundamentals.averageApparentPowerAndHeat( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -478,12 +478,12 @@ trait HpAgentFundamentals override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPowerAndHeat + result: ApparentPowerAndHeat, ): SystemParticipantResult = new HpResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, result.q.toMegavars.asMegaVar, - result.qDot.toMegawatts.asMegaWatt + result.qDot.toMegawatts.asMegaWatt, ) } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala index ed432fb4be..338547efbc 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgent.scala @@ -12,7 +12,7 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.load.LoadAgentFundamentals.{ FixedLoadAgentFundamentals, ProfileLoadAgentFundamentals, - RandomLoadAgentFundamentals + RandomLoadAgentFundamentals, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData @@ -26,7 +26,7 @@ import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomReleva import edu.ie3.simona.model.participant.load.{ FixedLoadModel, LoadModel, - LoadModelBehaviour + LoadModelBehaviour, } import org.apache.pekko.actor.{ActorRef, Props} @@ -36,9 +36,9 @@ object LoadAgent { initStateData: ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = LoadModelBehaviour(initStateData.modelConfig.modelBehaviour) match { case LoadModelBehaviour.FIX => @@ -58,12 +58,12 @@ object LoadAgent { initStateData: ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends LoadAgent[ FixedLoadModel.FixedLoadRelevantData.type, - FixedLoadModel + FixedLoadModel, ](scheduler, initStateData, listener) with FixedLoadAgentFundamentals @@ -72,12 +72,12 @@ object LoadAgent { initStateData: ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends LoadAgent[ ProfileRelevantData, - ProfileLoadModel + ProfileLoadModel, ](scheduler, initStateData, listener) with ProfileLoadAgentFundamentals @@ -86,12 +86,12 @@ object LoadAgent { initStateData: ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends LoadAgent[ RandomRelevantData, - RandomLoadModel + RandomLoadModel, ](scheduler, initStateData, listener) with RandomLoadAgentFundamentals } @@ -108,9 +108,9 @@ abstract class LoadAgent[LD <: LoadRelevantData, LM <: LoadModel[LD]]( initStateData: ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPower, LD, @@ -118,7 +118,7 @@ abstract class LoadAgent[LD <: LoadRelevantData, LM <: LoadModel[LD]]( ParticipantStateData[ApparentPower], LoadInput, LoadRuntimeConfig, - LM + LM, ](scheduler, initStateData) with LoadAgentFundamentals[LD, LM] { /* diff --git a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala index a419ea5fb7..79df65997c 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/load/LoadAgentFundamentals.scala @@ -9,20 +9,20 @@ package edu.ie3.simona.agent.participant.load import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.result.system.{ LoadResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FlexControlledData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer @@ -38,22 +38,22 @@ import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantDat import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel.ProfileRelevantData import edu.ie3.simona.model.participant.load.profile.{ LoadProfileStore, - ProfileLoadModel + ProfileLoadModel, } import edu.ie3.simona.model.participant.load.random.RandomLoadModel.RandomRelevantData import edu.ie3.simona.model.participant.load.random.{ RandomLoadModel, - RandomLoadParamStore + RandomLoadParamStore, } import edu.ie3.simona.model.participant.load.{ FixedLoadModel, LoadModel, - LoadReference + LoadReference, } import edu.ie3.simona.model.participant.{FlexChangeIndicator, ModelState} import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil._ @@ -80,7 +80,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ ParticipantStateData[ApparentPower], LoadInput, LoadRuntimeConfig, - LM + LM, ] { this: LoadAgent[LD, LM] => override protected val pdClassTag: ClassTag[ApparentPower] = @@ -120,12 +120,12 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, LD, ConstantState.type, - LM + LM, ] = { /* Build the calculation model */ val model = @@ -133,7 +133,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) /* Go and collect all ticks, in which activation is needed in addition to the activations made by incoming data. @@ -152,21 +152,21 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ SortedSet[Long]( SimonaConstants.FIRST_TICK_IN_SIMULATION, fixedLoadModel.operationInterval.start, - fixedLoadModel.operationInterval.end + fixedLoadModel.operationInterval.end, ).filterNot(_ == lastTickInSimulation) case profileLoadModel: ProfileLoadModel => activationTicksInOperationTime( simulationStartDate, LoadProfileStore.resolution.getSeconds, profileLoadModel.operationInterval.start, - profileLoadModel.operationInterval.end + profileLoadModel.operationInterval.end, ) case randomLoadModel: RandomLoadModel => activationTicksInOperationTime( simulationStartDate, RandomLoadParamStore.resolution.getSeconds, randomLoadModel.operationInterval.start, - randomLoadModel.operationInterval.end + randomLoadModel.operationInterval.end, ) case _ => SortedSet.empty[Long] @@ -189,13 +189,13 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) } @@ -203,20 +203,20 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ inputModel: InputModelContainer[LoadInput], modelConfig: LoadRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): LM = { val operationInterval: OperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.electricalInputModel.getOperationTime + inputModel.electricalInputModel.getOperationTime, ) val reference = LoadReference(inputModel.electricalInputModel, modelConfig) buildModel( inputModel.electricalInputModel, operationInterval, modelConfig, - reference + reference, ) } @@ -224,7 +224,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ inputModel: LoadInput, operationInterval: OperationInterval, modelConfig: LoadRuntimeConfig, - reference: LoadReference + reference: LoadReference, ): LM override protected def createInitialState( @@ -232,7 +232,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ ApparentPower, LD, ConstantState.type, - LM + LM, ] ): ModelState.ConstantState.type = ConstantState @@ -256,18 +256,18 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ ApparentPower, LD, ConstantState.type, - LM + LM, ], data: LD, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { /* Calculate result */ val voltage = getAndCheckNodalVoltage(baseStateData, tick) val reactivePower = baseStateData.model.calculateReactivePower( setPower, - voltage + voltage, ) val result = ApparentPower(setPower, reactivePower) @@ -303,11 +303,11 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ ApparentPower, LD, ConstantState.type, - LM + LM, ], lastModelState: ConstantState.type, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = throw new InconsistentStateException( s"Load model is not able to calculate power with secondary data." @@ -332,14 +332,14 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] = None + ] = None, ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -356,13 +356,13 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new LoadResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) override protected def updateState( @@ -370,7 +370,7 @@ protected trait LoadAgentFundamentals[LD <: LoadRelevantData, LM <: LoadModel[ modelState: ModelState.ConstantState.type, calcRelevantData: LD, nodalVoltage: squants.Dimensionless, - model: LM + model: LM, ): ModelState.ConstantState.type = modelState } @@ -378,7 +378,7 @@ object LoadAgentFundamentals { trait FixedLoadAgentFundamentals extends LoadAgentFundamentals[ FixedLoadModel.FixedLoadRelevantData.type, - FixedLoadModel + FixedLoadModel, ] { this: LoadAgent.FixedLoadAgent => @@ -386,13 +386,13 @@ object LoadAgentFundamentals { inputModel: LoadInput, operationInterval: OperationInterval, modelConfig: LoadRuntimeConfig, - reference: LoadReference + reference: LoadReference, ): FixedLoadModel = FixedLoadModel( inputModel, modelConfig.scaling, operationInterval, - reference + reference, ) override protected def createCalcRelevantData( @@ -400,9 +400,9 @@ object LoadAgentFundamentals { ApparentPower, FixedLoadRelevantData.type, ConstantState.type, - FixedLoadModel + FixedLoadModel, ], - tick: Long + tick: Long, ): FixedLoadRelevantData.type = FixedLoadRelevantData @@ -416,33 +416,33 @@ object LoadAgentFundamentals { ApparentPower, FixedLoadRelevantData.type, ConstantState.type, - FixedLoadModel + FixedLoadModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = ( tick: Long, baseStateData: ParticipantModelBaseStateData[ ApparentPower, FixedLoadRelevantData.type, ConstantState.type, - FixedLoadModel + FixedLoadModel, ], state: ConstantState.type, - voltage: Dimensionless + voltage: Dimensionless, ) => baseStateData.model.calculatePower( tick, voltage, state, - FixedLoadRelevantData + FixedLoadRelevantData, ) } trait ProfileLoadAgentFundamentals extends LoadAgentFundamentals[ ProfileRelevantData, - ProfileLoadModel + ProfileLoadModel, ] { this: LoadAgent.ProfileLoadAgent => @@ -450,13 +450,13 @@ object LoadAgentFundamentals { inputModel: LoadInput, operationInterval: OperationInterval, modelConfig: LoadRuntimeConfig, - reference: LoadReference + reference: LoadReference, ): ProfileLoadModel = ProfileLoadModel( inputModel, operationInterval, modelConfig.scaling, - reference + reference, ) override protected def createCalcRelevantData( @@ -464,9 +464,9 @@ object LoadAgentFundamentals { ApparentPower, ProfileRelevantData, ConstantState.type, - ProfileLoadModel + ProfileLoadModel, ], - currentTick: Long + currentTick: Long, ): ProfileRelevantData = ProfileRelevantData( currentTick.toDateTime(baseStateData.startDate) @@ -482,10 +482,10 @@ object LoadAgentFundamentals { ApparentPower, ProfileRelevantData, ConstantState.type, - ProfileLoadModel + ProfileLoadModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = (tick, baseStateData, _, voltage) => { val profileRelevantData = createCalcRelevantData(baseStateData, tick) @@ -494,7 +494,7 @@ object LoadAgentFundamentals { currentTick, voltage, ConstantState, - profileRelevantData + profileRelevantData, ) } } @@ -502,7 +502,7 @@ object LoadAgentFundamentals { trait RandomLoadAgentFundamentals extends LoadAgentFundamentals[ RandomRelevantData, - RandomLoadModel + RandomLoadModel, ] { this: LoadAgent.RandomLoadAgent => @@ -510,13 +510,13 @@ object LoadAgentFundamentals { inputModel: LoadInput, operationInterval: OperationInterval, modelConfig: LoadRuntimeConfig, - reference: LoadReference + reference: LoadReference, ): RandomLoadModel = RandomLoadModel( inputModel, operationInterval, modelConfig.scaling, - reference + reference, ) override protected def createCalcRelevantData( @@ -524,9 +524,9 @@ object LoadAgentFundamentals { ApparentPower, RandomRelevantData, ConstantState.type, - RandomLoadModel + RandomLoadModel, ], - tick: Long + tick: Long, ): RandomRelevantData = RandomRelevantData( tick.toDateTime(baseStateData.startDate) @@ -542,10 +542,10 @@ object LoadAgentFundamentals { ApparentPower, RandomRelevantData, ConstantState.type, - RandomLoadModel + RandomLoadModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = (tick, baseStateData, _, voltage) => { val profileRelevantData = createCalcRelevantData(baseStateData, tick) @@ -554,7 +554,7 @@ object LoadAgentFundamentals { currentTick, voltage, ConstantState, - profileRelevantData + profileRelevantData, ) } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala index 68cc7aa485..bf6f5db3b7 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgent.scala @@ -25,15 +25,15 @@ object PvAgent { initStateData: ParticipantInitializeStateData[ PvInput, PvRuntimeConfig, - ApparentPower + ApparentPower, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props( new PvAgent( scheduler, initStateData, - listener + listener, ) ) @@ -54,9 +54,9 @@ class PvAgent( initStateData: ParticipantInitializeStateData[ PvInput, PvRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPower, PvRelevantData, @@ -64,10 +64,10 @@ class PvAgent( ParticipantStateData[ApparentPower], PvInput, PvRuntimeConfig, - PvModel + PvModel, ]( scheduler, - initStateData + initStateData, ) with PvAgentFundamentals { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala index 03f8060ebe..a60fa87b63 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/pv/PvAgentFundamentals.scala @@ -9,21 +9,21 @@ package edu.ie3.simona.agent.participant.pv import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.datamodel.models.result.system.{ PvResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent.getAndCheckNodalVoltage import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.pv.PvAgent.neededServices import edu.ie3.simona.agent.participant.statedata.BaseStateData.{ FlexControlledData, - ParticipantModelBaseStateData + ParticipantModelBaseStateData, } import edu.ie3.simona.agent.participant.statedata.ParticipantStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.InputModelContainer @@ -34,7 +34,7 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.io.result.AccompaniedSimulationResult import edu.ie3.simona.model.participant.ModelState.ConstantState @@ -42,11 +42,11 @@ import edu.ie3.simona.model.participant.PvModel.PvRelevantData import edu.ie3.simona.model.participant.{ FlexChangeIndicator, ModelState, - PvModel + PvModel, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherService.FALLBACK_WEATHER_STEM_DISTANCE @@ -72,7 +72,7 @@ protected trait PvAgentFundamentals ParticipantStateData[ApparentPower], PvInput, PvRuntimeConfig, - PvModel + PvModel, ] { this: PvAgent => override protected val pdClassTag: ClassTag[ApparentPower] = @@ -112,12 +112,12 @@ protected trait PvAgentFundamentals resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ] = { /* Check for needed services */ if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) @@ -131,14 +131,14 @@ protected trait PvAgentFundamentals inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) ParticipantModelBaseStateData[ ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ]( simulationStartDate, simulationEndDate, @@ -156,13 +156,13 @@ protected trait PvAgentFundamentals .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) } @@ -170,12 +170,12 @@ protected trait PvAgentFundamentals inputModel: InputModelContainer[PvInput], modelConfig: PvRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): PvModel = PvModel( inputModel.electricalInputModel, modelConfig.scaling, simulationStartDate, - simulationEndDate + simulationEndDate, ) override protected def createInitialState( @@ -183,7 +183,7 @@ protected trait PvAgentFundamentals ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ] ): ModelState.ConstantState.type = ConstantState @@ -193,9 +193,9 @@ protected trait PvAgentFundamentals ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ], - tick: Long + tick: Long, ): PvRelevantData = { /* convert current tick to a datetime */ implicit val startDateTime: ZonedDateTime = @@ -241,7 +241,7 @@ protected trait PvAgentFundamentals dateTime, tickInterval, weatherData.diffIrr, - weatherData.dirIrr + weatherData.dirIrr, ) } @@ -265,18 +265,18 @@ protected trait PvAgentFundamentals ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ], data: PvRelevantData, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { /* Calculate result */ val voltage = getAndCheckNodalVoltage(baseStateData, tick) val reactivePower = baseStateData.model.calculateReactivePower( setPower, - voltage + voltage, ) val result = ApparentPower(setPower, reactivePower) @@ -296,10 +296,10 @@ protected trait PvAgentFundamentals ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = (_, _, _, _) => throw new InvalidRequestException( @@ -332,11 +332,11 @@ protected trait PvAgentFundamentals ApparentPower, PvRelevantData, ConstantState.type, - PvModel + PvModel, ], lastModelState: ConstantState.type, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { val voltage = getAndCheckNodalVoltage(baseStateData, currentTick) @@ -344,21 +344,21 @@ protected trait PvAgentFundamentals val relevantData = createCalcRelevantData( baseStateData, - currentTick + currentTick, ) val result = baseStateData.model.calculatePower( currentTick, voltage, ConstantState, - relevantData + relevantData, ) updateValueStoresInformListenersAndGoToIdleWithUpdatedBaseStateData( scheduler, baseStateData, AccompaniedSimulationResult(result), - relevantData + relevantData, ) } @@ -381,14 +381,14 @@ protected trait PvAgentFundamentals windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] = None + ] = None, ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -405,13 +405,13 @@ protected trait PvAgentFundamentals override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new PvResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) /** Update the last known model state with the given external, relevant data @@ -435,6 +435,6 @@ protected trait PvAgentFundamentals modelState: ModelState.ConstantState.type, calcRelevantData: PvRelevantData, nodalVoltage: squants.Dimensionless, - model: PvModel + model: PvModel, ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala index 0f3a72a881..96758a2d16 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/BaseStateData.scala @@ -14,12 +14,12 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.model.participant.{ CalcRelevantData, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, FlexResponse, - ProvideFlexOptions + ProvideFlexOptions, } import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.{ActorRef => ClassicActorRef} @@ -100,7 +100,7 @@ object BaseStateData { +PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, MS <: ModelState, - +M <: SystemParticipant[_ <: CalcRelevantData, PD, MS] + +M <: SystemParticipant[_ <: CalcRelevantData, PD, MS], ] extends BaseStateData[PD] { /** The physical system model @@ -154,7 +154,7 @@ object BaseStateData { final case class FromOutsideBaseStateData[M <: SystemParticipant[ _ <: CalcRelevantData, P, - _ + _, ], +P <: PrimaryDataWithApparentPower[P]]( model: M, override val startDate: ZonedDateTime, @@ -168,7 +168,7 @@ object BaseStateData { Dimensionless ], override val resultValueStore: ValueStore[P], - override val requestValueStore: ValueStore[P] + override val requestValueStore: ValueStore[P], ) extends BaseStateData[P] { override val modelUuid: UUID = model.getUuid } @@ -209,7 +209,7 @@ object BaseStateData { +PD <: PrimaryDataWithApparentPower[PD], CD <: CalcRelevantData, MS <: ModelState, - M <: SystemParticipant[_ <: CalcRelevantData, PD, MS] + M <: SystemParticipant[_ <: CalcRelevantData, PD, MS], ]( override val startDate: ZonedDateTime, override val endDate: ZonedDateTime, @@ -228,7 +228,7 @@ object BaseStateData { Map[ClassicActorRef, _ <: SecondaryData] ], override val stateDataStore: ValueStore[MS], - override val flexStateData: Option[FlexControlledData] + override val flexStateData: Option[FlexControlledData], ) extends ModelBaseStateData[PD, CD, MS, M] { /** Unique identifier of the simulation model @@ -249,7 +249,7 @@ object BaseStateData { final case class FlexControlledData( emAgent: ActorRef[FlexResponse], flexAdapter: ActorRef[FlexRequest], - lastFlexOptions: Option[ProvideFlexOptions] = None + lastFlexOptions: Option[ProvideFlexOptions] = None, ) /** Updates the base state data with the given value stores @@ -277,7 +277,7 @@ object BaseStateData { updatedRequestValueStore: ValueStore[PD], updatedVoltageValueStore: ValueStore[Dimensionless], updatedAdditionalActivationTicks: SortedSet[Long], - updatedForeseenTicks: Map[ClassicActorRef, Option[Long]] + updatedForeseenTicks: Map[ClassicActorRef, Option[Long]], ): BaseStateData[PD] = { baseStateData match { case external: FromOutsideBaseStateData[_, PD] => @@ -286,7 +286,7 @@ object BaseStateData { requestValueStore = updatedRequestValueStore, voltageValueStore = updatedVoltageValueStore, additionalActivationTicks = updatedAdditionalActivationTicks, - foreseenDataTicks = updatedForeseenTicks + foreseenDataTicks = updatedForeseenTicks, ) case model: ParticipantModelBaseStateData[PD, _, _, _] => model.copy( @@ -294,7 +294,7 @@ object BaseStateData { requestValueStore = updatedRequestValueStore, voltageValueStore = updatedVoltageValueStore, additionalActivationTicks = updatedAdditionalActivationTicks, - foreseenDataTicks = updatedForeseenTicks + foreseenDataTicks = updatedForeseenTicks, ) } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/DataCollectionStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/DataCollectionStateData.scala index d9b7f63de2..1ce8cf9352 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/DataCollectionStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/DataCollectionStateData.scala @@ -32,7 +32,7 @@ final case class DataCollectionStateData[+PD <: PrimaryDataWithApparentPower[ ]]( baseStateData: BaseStateData[PD], data: Map[ActorRef, Option[_ <: Data]], - yetTriggered: Boolean + yetTriggered: Boolean, ) extends ParticipantStateData[PD] { /** Extract the given type of [[Data]] from the list of secondary data diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala index 08a291afce..de01009850 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/InitializeStateData.scala @@ -27,7 +27,7 @@ object InitializeStateData { val outputConfig: NotifierConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = true, - flexResult = false + flexResult = false, ) } } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala index f7c3312a59..95d8df3fcf 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/statedata/ParticipantStateData.scala @@ -67,7 +67,7 @@ object ParticipantStateData { final case class ParticipantInitializingStateData[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: InputModelContainer[I], modelConfig: C, @@ -77,7 +77,7 @@ object ParticipantStateData { resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[ActorRef[FlexResponse]] + maybeEmAgent: Option[ActorRef[FlexResponse]], ) extends ParticipantStateData[PD] /** State data to use, when initializing the participant agent @@ -111,7 +111,7 @@ object ParticipantStateData { final case class ParticipantInitializeStateData[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: InputModelContainer[I], modelConfig: C, @@ -122,7 +122,7 @@ object ParticipantStateData { resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[ActorRef[FlexResponse]] = None + maybeEmAgent: Option[ActorRef[FlexResponse]] = None, ) extends InitializeStateData[PD] object ParticipantInitializeStateData { @@ -130,7 +130,7 @@ object ParticipantStateData { def apply[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: I, modelConfig: C, @@ -142,7 +142,7 @@ object ParticipantStateData { simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ParticipantInitializeStateData[I, C, PD] = new ParticipantInitializeStateData[I, C, PD]( SimpleInputContainer(inputModel), @@ -154,12 +154,12 @@ object ParticipantStateData { resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent = None + maybeEmAgent = None, ) def apply[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: I, modelConfig: C, @@ -172,7 +172,7 @@ object ParticipantStateData { resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[ActorRef[FlexResponse]] + maybeEmAgent: Option[ActorRef[FlexResponse]], ): ParticipantInitializeStateData[I, C, PD] = new ParticipantInitializeStateData[I, C, PD]( SimpleInputContainer(inputModel), @@ -184,13 +184,13 @@ object ParticipantStateData { resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) def apply[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: I, thermalGrid: ThermalGrid, @@ -203,7 +203,7 @@ object ParticipantStateData { simulationEndDate: ZonedDateTime, resolution: Long, requestVoltageDeviationThreshold: Double, - outputConfig: NotifierConfig + outputConfig: NotifierConfig, ): ParticipantInitializeStateData[I, C, PD] = new ParticipantInitializeStateData[I, C, PD]( WithHeatInputContainer(inputModel, thermalGrid), @@ -215,13 +215,13 @@ object ParticipantStateData { resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent = None + maybeEmAgent = None, ) def apply[ I <: SystemParticipantInput, C <: SimonaConfig.BaseRuntimeConfig, - PD <: PrimaryData + PD <: PrimaryData, ]( inputModel: I, thermalGrid: ThermalGrid, @@ -235,7 +235,7 @@ object ParticipantStateData { resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[ActorRef[FlexResponse]] + maybeEmAgent: Option[ActorRef[FlexResponse]], ): ParticipantInitializeStateData[I, C, PD] = new ParticipantInitializeStateData[I, C, PD]( WithHeatInputContainer(inputModel, thermalGrid), @@ -247,7 +247,7 @@ object ParticipantStateData { resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) } @@ -269,7 +269,7 @@ object ParticipantStateData { ]( baseStateData: BaseStateData[PD], pendingResponses: Iterable[ClassicActorRef], - foreseenNextDataTicks: Map[ClassicActorRef, Long] = Map.empty + foreseenNextDataTicks: Map[ClassicActorRef, Long] = Map.empty, ) extends ParticipantStateData[PD] sealed trait InputModelContainer[+I <: SystemParticipantInput] { @@ -282,6 +282,6 @@ object ParticipantStateData { final case class WithHeatInputContainer[+I <: SystemParticipantInput]( override val electricalInputModel: I, - thermalGrid: ThermalGrid + thermalGrid: ThermalGrid, ) extends InputModelContainer[I] } diff --git a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala index 9f65245c4c..957d48a28f 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgent.scala @@ -25,15 +25,15 @@ object WecAgent { initStateData: ParticipantInitializeStateData[ WecInput, WecRuntimeConfig, - ApparentPower + ApparentPower, ], - listener: Iterable[ActorRef] + listener: Iterable[ActorRef], ): Props = Props( new WecAgent( scheduler, initStateData, - listener + listener, ) ) @@ -54,9 +54,9 @@ class WecAgent( initStateData: ParticipantInitializeStateData[ WecInput, WecRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] + override val listener: Iterable[ActorRef], ) extends ParticipantAgent[ ApparentPower, WecRelevantData, @@ -64,7 +64,7 @@ class WecAgent( ParticipantStateData[ApparentPower], WecInput, WecRuntimeConfig, - WecModel + WecModel, ](scheduler, initStateData) with WecAgentFundamentals { diff --git a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala index f39fbd8d3b..955131bafc 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/wec/WecAgentFundamentals.scala @@ -9,14 +9,14 @@ package edu.ie3.simona.agent.participant.wec import edu.ie3.datamodel.models.input.system.WecInput import edu.ie3.datamodel.models.result.system.{ SystemParticipantResult, - WecResult + WecResult, } import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.ParticipantAgent._ import edu.ie3.simona.agent.participant.ParticipantAgentFundamentals import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService @@ -31,7 +31,7 @@ import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, InconsistentStateException, - InvalidRequestException + InvalidRequestException, } import edu.ie3.simona.io.result.AccompaniedSimulationResult import edu.ie3.simona.model.participant.ModelState.ConstantState @@ -39,11 +39,11 @@ import edu.ie3.simona.model.participant.WecModel.WecRelevantData import edu.ie3.simona.model.participant.{ FlexChangeIndicator, ModelState, - WecModel + WecModel, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexRequest, - FlexResponse + FlexResponse, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.util.quantities.PowerSystemUnits._ @@ -67,7 +67,7 @@ protected trait WecAgentFundamentals ParticipantStateData[ApparentPower], WecInput, WecRuntimeConfig, - WecModel + WecModel, ] { this: WecAgent => override protected val pdClassTag: ClassTag[ApparentPower] = @@ -107,12 +107,12 @@ protected trait WecAgentFundamentals resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] = { /* Check for needed services */ if (!services.toSeq.map(_.getClass).containsSlice(neededServices)) @@ -126,14 +126,14 @@ protected trait WecAgentFundamentals inputModel, modelConfig, simulationStartDate, - simulationEndDate + simulationEndDate, ) ParticipantModelBaseStateData[ ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ]( simulationStartDate, simulationEndDate, @@ -151,13 +151,13 @@ protected trait WecAgentFundamentals .to(PU) .getValue .doubleValue - ) + ), ), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])) + maybeEmAgent.map(FlexControlledData(_, self.toTyped[FlexRequest])), ) } @@ -165,12 +165,12 @@ protected trait WecAgentFundamentals inputModel: InputModelContainer[WecInput], modelConfig: WecRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): WecModel = WecModel( inputModel.electricalInputModel, modelConfig.scaling, simulationStartDate, - simulationEndDate + simulationEndDate, ) override protected def createInitialState( @@ -178,7 +178,7 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] ): ModelState.ConstantState.type = ConstantState @@ -188,9 +188,9 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], - tick: Long + tick: Long, ): WecRelevantData = { // take the last weather data, not necessarily the one for the current tick: // we might receive flex control messages for irregular ticks @@ -217,7 +217,7 @@ protected trait WecAgentFundamentals WecRelevantData( weatherData.windVel, weatherData.temp, - None + None, ) } @@ -241,18 +241,18 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], data: WecRelevantData, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, ApparentPower, FlexChangeIndicator) = { /* Calculate result */ val voltage = getAndCheckNodalVoltage(baseStateData, tick) val reactivePower = baseStateData.model.calculateReactivePower( setPower, - voltage + voltage, ) val result = ApparentPower(setPower, reactivePower) @@ -272,10 +272,10 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], ConstantState.type, - Dimensionless + Dimensionless, ) => ApparentPower = ( _: Long, @@ -283,10 +283,10 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], _, - _: Dimensionless + _: Dimensionless, ) => throw new InvalidRequestException( "WEC model cannot be run without secondary data." @@ -318,11 +318,11 @@ protected trait WecAgentFundamentals ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], lastModelState: ConstantState.type, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = { val voltage = getAndCheckNodalVoltage(baseStateData, currentTick) @@ -330,21 +330,21 @@ protected trait WecAgentFundamentals val relevantData = createCalcRelevantData( baseStateData, - currentTick + currentTick, ) val result = baseStateData.model.calculatePower( currentTick, voltage, ConstantState, - relevantData + relevantData, ) updateValueStoresInformListenersAndGoToIdleWithUpdatedBaseStateData( scheduler, baseStateData, AccompaniedSimulationResult(result), - relevantData + relevantData, ) } @@ -367,14 +367,14 @@ protected trait WecAgentFundamentals windowEnd: Long, activeToReactivePowerFuncOpt: Option[ Power => ReactivePower - ] = None + ] = None, ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -391,13 +391,13 @@ protected trait WecAgentFundamentals override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new WecResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) /** Update the last known model state with the given external, relevant data @@ -421,6 +421,6 @@ protected trait WecAgentFundamentals modelState: ModelState.ConstantState.type, calcRelevantData: WecRelevantData, nodalVoltage: squants.Dimensionless, - model: WecModel + model: WecModel, ): ModelState.ConstantState.type = modelState } diff --git a/src/main/scala/edu/ie3/simona/agent/state/AgentState.scala b/src/main/scala/edu/ie3/simona/agent/state/AgentState.scala index 0261a7a210..fc4497b77b 100644 --- a/src/main/scala/edu/ie3/simona/agent/state/AgentState.scala +++ b/src/main/scala/edu/ie3/simona/agent/state/AgentState.scala @@ -19,7 +19,7 @@ object AgentState { final case class TerminatedPrematurelyEvent( actorRef: ActorRef, reason: FSM.Reason, - tick: Option[Int] + tick: Option[Int], ) case object Uninitialized extends AgentState diff --git a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala index bce029ea33..be3d434a8a 100644 --- a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala +++ b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala @@ -15,12 +15,12 @@ import edu.ie3.simona.api.simulation.ontology.{ ActivationMessage, TerminationCompleted, TerminationMessage, - CompletionMessage => ExtCompletionMessage + CompletionMessage => ExtCompletionMessage, } import edu.ie3.simona.logging.SimonaActorLogging import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.ScheduleServiceActivation import edu.ie3.simona.ontology.messages.{Activation, StopMessage} @@ -47,7 +47,7 @@ object ExtSimAdapter { final case class ExtSimAdapterStateData( extSimData: ExtSimAdapterData, - currentTick: Option[Long] = None + currentTick: Option[Long] = None, ) } @@ -59,7 +59,7 @@ final case class ExtSimAdapter(scheduler: ActorRef) scheduler ! ScheduleActivation( self.toTyped, INIT_SIM_TICK, - Some(unlockKey) + Some(unlockKey), ) context become receiveIdle( ExtSimAdapterStateData(extSimAdapterData) @@ -75,7 +75,7 @@ final case class ExtSimAdapter(scheduler: ActorRef) ) log.debug( "Tick {} has been activated in external simulation", - tick + tick, ) context become receiveIdle( @@ -91,7 +91,7 @@ final case class ExtSimAdapter(scheduler: ActorRef) scheduler ! Completion(self.toTyped, newTick) log.debug( "Tick {} has been completed in external simulation", - stateData.currentTick + stateData.currentTick, ) context become receiveIdle(stateData.copy(currentTick = None)) @@ -104,7 +104,7 @@ final case class ExtSimAdapter(scheduler: ActorRef) scheduleDataService.getDataService ! ScheduleServiceActivation( tick, - key + key, ) case StopMessage(simulationSuccessful) => diff --git a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala index 132b2f4c50..183aa8149c 100644 --- a/src/main/scala/edu/ie3/simona/config/ArgsParser.scala +++ b/src/main/scala/edu/ie3/simona/config/ArgsParser.scala @@ -30,7 +30,7 @@ object ArgsParser extends LazyLogging { nodePort: Option[String] = None, seedAddress: Option[String] = None, useLocalWorker: Option[Boolean] = None, - tArgs: Map[String, String] = Map.empty + tArgs: Map[String, String] = Map.empty, ) { val useCluster: Boolean = clusterType.isDefined } @@ -42,7 +42,7 @@ object ArgsParser extends LazyLogging { .action((value, args) => { args.copy( config = Some(parseTypesafeConfig(value)), - configLocation = Option(value) + configLocation = Option(value), ) }) .validate(value => @@ -122,7 +122,7 @@ object ArgsParser extends LazyLogging { private def parse( parser: scoptOptionParser[Arguments], - args: Array[String] + args: Array[String], ): Option[Arguments] = parser.parse(args, init = Arguments(args)) diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index ab3b3895a9..e2ca6a0cb6 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -12,7 +12,7 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.InfluxDb1x import edu.ie3.simona.config.SimonaConfig.{ BaseOutputConfig, RefSystemConfig, - ResultKafkaParams + ResultKafkaParams, } import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.io.result.ResultSinkType @@ -22,7 +22,7 @@ import edu.ie3.simona.service.weather.WeatherSource import edu.ie3.simona.util.CollectionUtils import edu.ie3.simona.util.ConfigUtil.DatabaseConfigUtil.{ checkInfluxDb1xParams, - checkKafkaParams + checkKafkaParams, } import edu.ie3.simona.util.ConfigUtil.{CsvConfigUtil, NotifierIdentifier} import edu.ie3.util.scala.ReflectionTools @@ -74,7 +74,7 @@ case object ConfigFailFast extends LazyLogging { case Failure(exception) => throw new InvalidConfigParameterException( "Checking of pekko config failed due to unhandled error.", - exception + exception, ) case Success(_) => } @@ -94,7 +94,7 @@ case object ConfigFailFast extends LazyLogging { case Failure(exception) => throw new InvalidConfigParameterException( "Checking of pekko logging config failed due to unhandled error.", - exception + exception, ) case _ => } @@ -191,7 +191,7 @@ case object ConfigFailFast extends LazyLogging { checkInfluxDb1xParams( "Sink", ResultSinkType.buildInfluxDb1xUrl(influxDb1x), - influxDb1x.database + influxDb1x.database, ) case Some(Some(kafka: ResultKafkaParams)) => checkKafkaParams(kafka, Seq(kafka.topicNodeRes)) @@ -235,7 +235,7 @@ case object ConfigFailFast extends LazyLogging { throw new InvalidConfigParameterException( s"Invalid dateTimeString: $dateTimeString." + s"Please ensure that your date/time parameter match the following pattern: 'yyyy-MM-dd HH:mm:ss'", - e + e, ) } } @@ -256,27 +256,27 @@ case object ConfigFailFast extends LazyLogging { /* Check basic model configuration parameters common to each participant */ checkBaseRuntimeConfigs( subConfig.load.defaultConfig, - subConfig.load.individualConfigs + subConfig.load.individualConfigs, ) checkBaseRuntimeConfigs( subConfig.fixedFeedIn.defaultConfig, - subConfig.fixedFeedIn.individualConfigs + subConfig.fixedFeedIn.individualConfigs, ) checkBaseRuntimeConfigs( subConfig.evcs.defaultConfig, - subConfig.evcs.individualConfigs + subConfig.evcs.individualConfigs, ) checkBaseRuntimeConfigs( subConfig.pv.defaultConfig, - subConfig.pv.individualConfigs + subConfig.pv.individualConfigs, ) checkBaseRuntimeConfigs( subConfig.wec.defaultConfig, - subConfig.wec.individualConfigs + subConfig.wec.individualConfigs, ) /* check model configuration parameters specific to participants */ @@ -304,7 +304,7 @@ case object ConfigFailFast extends LazyLogging { private def checkBaseRuntimeConfigs( defaultConfig: SimonaConfig.BaseRuntimeConfig, individualConfigs: List[SimonaConfig.BaseRuntimeConfig], - defaultString: String = "default" + defaultString: String = "default", ): Unit = { // special default config check val uuidString = defaultConfig.uuids.mkString(",") @@ -346,7 +346,7 @@ case object ConfigFailFast extends LazyLogging { case e: IllegalArgumentException => throw new InvalidConfigParameterException( s"The UUID '$uuid' cannot be parsed as it is invalid.", - e + e, ) } ) @@ -369,7 +369,7 @@ case object ConfigFailFast extends LazyLogging { */ private def checkSingleString( singleString: String, - uuids: List[String] + uuids: List[String], ): Unit = { if (uuids.toVector.size != 1) throw new InvalidConfigParameterException( @@ -388,7 +388,7 @@ case object ConfigFailFast extends LazyLogging { case e: IllegalArgumentException => throw new InvalidConfigParameterException( s"Found invalid UUID '$singleEntry' it was meant to be the string '$singleString' or a valid UUID.", - e + e, ) } case None => @@ -449,7 +449,7 @@ case object ConfigFailFast extends LazyLogging { case Failure(exception) => throw new InvalidConfigParameterException( s"The given nominal voltage '${voltLvl.vNom}' cannot be parsed to a quantity. Did you provide the volt level with it's unit (e.g. \"20 kV\")?", - exception + exception, ) } } @@ -548,7 +548,7 @@ case object ConfigFailFast extends LazyLogging { checkDefaultBaseOutputConfig( subConfig.defaultConfig, - defaultString = "default" + defaultString = "default", ) checkIndividualParticipantsOutputConfigs(subConfig.individualConfigs) } @@ -592,7 +592,7 @@ case object ConfigFailFast extends LazyLogging { */ private def checkDefaultBaseOutputConfig( config: SimonaConfig.BaseOutputConfig, - defaultString: String + defaultString: String, ): Unit = { if ( StringUtils @@ -649,7 +649,7 @@ case object ConfigFailFast extends LazyLogging { case e: NoSuchElementException => throw new InvalidConfigParameterException( s"The identifier '$id' you provided is not valid. Valid input: ${NotifierIdentifier.values.map(_.toString).mkString(",")}", - e + e, ) } } diff --git a/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala b/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala index 66bf1100c1..d299dc16d7 100644 --- a/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala +++ b/src/main/scala/edu/ie3/simona/config/RefSystemParser.scala @@ -18,7 +18,7 @@ object RefSystemParser { final case class ConfigRefSystems( private val gridIdRefSystems: Map[Int, RefSystem], - private val voltLvLRefSystems: Map[VoltageLevel, RefSystem] + private val voltLvLRefSystems: Map[VoltageLevel, RefSystem], ) { /** Returns a [[RefSystem]] based on the provided gridId or the voltLvl as @@ -33,7 +33,7 @@ object RefSystemParser { */ def find( gridId: Int, - voltLvl: Option[VoltageLevel] = None + voltLvl: Option[VoltageLevel] = None, ): Option[RefSystem] = gridIdRefSystems .get(gridId) diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 1079b2b932..e437569147 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -13,26 +13,26 @@ object SimonaConfig { final case class BaseCsvParams( override val csvSep: java.lang.String, override val directoryPath: java.lang.String, - override val isHierarchic: scala.Boolean + override val isHierarchic: scala.Boolean, ) extends CsvParams(csvSep, directoryPath, isHierarchic) object BaseCsvParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.BaseCsvParams = { SimonaConfig.BaseCsvParams( csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), - isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) + isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -48,7 +48,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -64,19 +64,19 @@ object SimonaConfig { sealed abstract class BaseOutputConfig( val notifier: java.lang.String, - val simulationResult: scala.Boolean + val simulationResult: scala.Boolean, ) sealed abstract class BaseRuntimeConfig( val calculateMissingReactivePowerWithModel: scala.Boolean, val scaling: scala.Double, - val uuids: scala.List[java.lang.String] + val uuids: scala.List[java.lang.String], ) extends java.io.Serializable sealed abstract class CsvParams( val csvSep: java.lang.String, val directoryPath: java.lang.String, - val isHierarchic: scala.Boolean + val isHierarchic: scala.Boolean, ) final case class EvcsRuntimeConfig( @@ -84,17 +84,17 @@ object SimonaConfig { override val scaling: scala.Double, override val uuids: scala.List[java.lang.String], chargingStrategy: java.lang.String, - lowestEvSoc: scala.Double + lowestEvSoc: scala.Double, ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object EvcsRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.EvcsRuntimeConfig = { SimonaConfig.EvcsRuntimeConfig( chargingStrategy = @@ -108,17 +108,17 @@ object SimonaConfig { parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -134,7 +134,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -151,34 +151,34 @@ object SimonaConfig { final case class FixedFeedInRuntimeConfig( override val calculateMissingReactivePowerWithModel: scala.Boolean, override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] + override val uuids: scala.List[java.lang.String], ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object FixedFeedInRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.FixedFeedInRuntimeConfig = { SimonaConfig.FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel = $_reqBln( parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -194,7 +194,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -214,13 +214,13 @@ object SimonaConfig { notifier: java.lang.String, switches: scala.Boolean, transformers2w: scala.Boolean, - transformers3w: scala.Boolean + transformers3w: scala.Boolean, ) object GridOutputConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.GridOutputConfig = { SimonaConfig.GridOutputConfig( lines = c.hasPathOrNull("lines") && c.getBoolean("lines"), @@ -230,14 +230,14 @@ object SimonaConfig { transformers2w = c.hasPathOrNull("transformers2w") && c.getBoolean("transformers2w"), transformers3w = - c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w") + c.hasPathOrNull("transformers3w") && c.getBoolean("transformers3w"), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -254,34 +254,34 @@ object SimonaConfig { final case class HpRuntimeConfig( override val calculateMissingReactivePowerWithModel: scala.Boolean, override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] + override val uuids: scala.List[java.lang.String], ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object HpRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.HpRuntimeConfig = { SimonaConfig.HpRuntimeConfig( calculateMissingReactivePowerWithModel = $_reqBln( parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -297,7 +297,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -315,7 +315,7 @@ object SimonaConfig { val bootstrapServers: java.lang.String, val linger: scala.Int, val runId: java.lang.String, - val schemaRegistryUrl: java.lang.String + val schemaRegistryUrl: java.lang.String, ) final case class LoadRuntimeConfig( @@ -323,17 +323,17 @@ object SimonaConfig { override val scaling: scala.Double, override val uuids: scala.List[java.lang.String], modelBehaviour: java.lang.String, - reference: java.lang.String + reference: java.lang.String, ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object LoadRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.LoadRuntimeConfig = { SimonaConfig.LoadRuntimeConfig( modelBehaviour = @@ -343,17 +343,17 @@ object SimonaConfig { parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -369,7 +369,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -385,7 +385,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -403,13 +403,13 @@ object SimonaConfig { override val notifier: java.lang.String, override val simulationResult: scala.Boolean, flexResult: scala.Boolean, - powerRequestReply: scala.Boolean + powerRequestReply: scala.Boolean, ) extends BaseOutputConfig(notifier, simulationResult) object ParticipantBaseOutputConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.ParticipantBaseOutputConfig = { SimonaConfig.ParticipantBaseOutputConfig( flexResult = @@ -418,14 +418,14 @@ object SimonaConfig { $_reqBln(parentPath, c, "powerRequestReply", $tsCfgValidator), notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), simulationResult = - $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -441,7 +441,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -459,13 +459,13 @@ object SimonaConfig { override val csvSep: java.lang.String, override val directoryPath: java.lang.String, override val isHierarchic: scala.Boolean, - timePattern: java.lang.String + timePattern: java.lang.String, ) extends CsvParams(csvSep, directoryPath, isHierarchic) object PrimaryDataCsvParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.PrimaryDataCsvParams = { SimonaConfig.PrimaryDataCsvParams( timePattern = @@ -474,14 +474,14 @@ object SimonaConfig { csvSep = $_reqStr(parentPath, c, "csvSep", $tsCfgValidator), directoryPath = $_reqStr(parentPath, c, "directoryPath", $tsCfgValidator), - isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator) + isHierarchic = $_reqBln(parentPath, c, "isHierarchic", $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -497,7 +497,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -514,34 +514,34 @@ object SimonaConfig { final case class PvRuntimeConfig( override val calculateMissingReactivePowerWithModel: scala.Boolean, override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] + override val uuids: scala.List[java.lang.String], ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object PvRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.PvRuntimeConfig = { SimonaConfig.PvRuntimeConfig( calculateMissingReactivePowerWithModel = $_reqBln( parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -557,7 +557,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -575,13 +575,13 @@ object SimonaConfig { gridIds: scala.Option[scala.List[java.lang.String]], sNom: java.lang.String, vNom: java.lang.String, - voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + voltLvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]], ) object RefSystemConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.RefSystemConfig = { SimonaConfig.RefSystemConfig( gridIds = @@ -598,16 +598,16 @@ object SimonaConfig { $_LSimonaConfig_VoltLvlConfig( c.getList("voltLvls"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } private def $_LSimonaConfig_VoltLvlConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -615,7 +615,7 @@ object SimonaConfig { SimonaConfig.VoltLvlConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -624,7 +624,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -643,13 +643,13 @@ object SimonaConfig { override val linger: scala.Int, override val runId: java.lang.String, override val schemaRegistryUrl: java.lang.String, - topicNodeRes: java.lang.String + topicNodeRes: java.lang.String, ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) object ResultKafkaParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.ResultKafkaParams = { SimonaConfig.ResultKafkaParams( topicNodeRes = $_reqStr(parentPath, c, "topicNodeRes", $tsCfgValidator), @@ -658,14 +658,14 @@ object SimonaConfig { linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), schemaRegistryUrl = - $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -681,7 +681,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -700,13 +700,13 @@ object SimonaConfig { override val linger: scala.Int, override val runId: java.lang.String, override val schemaRegistryUrl: java.lang.String, - topic: java.lang.String + topic: java.lang.String, ) extends KafkaParams(bootstrapServers, linger, runId, schemaRegistryUrl) object RuntimeKafkaParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.RuntimeKafkaParams = { SimonaConfig.RuntimeKafkaParams( topic = $_reqStr(parentPath, c, "topic", $tsCfgValidator), @@ -715,14 +715,14 @@ object SimonaConfig { linger = $_reqInt(parentPath, c, "linger", $tsCfgValidator), runId = $_reqStr(parentPath, c, "runId", $tsCfgValidator), schemaRegistryUrl = - $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator) + $_reqStr(parentPath, c, "schemaRegistryUrl", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -738,7 +738,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -754,25 +754,25 @@ object SimonaConfig { final case class SimpleOutputConfig( override val notifier: java.lang.String, - override val simulationResult: scala.Boolean + override val simulationResult: scala.Boolean, ) extends BaseOutputConfig(notifier, simulationResult) object SimpleOutputConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.SimpleOutputConfig = { SimonaConfig.SimpleOutputConfig( notifier = $_reqStr(parentPath, c, "notifier", $tsCfgValidator), simulationResult = - $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator) + $_reqBln(parentPath, c, "simulationResult", $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -788,7 +788,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -804,24 +804,24 @@ object SimonaConfig { final case class VoltLvlConfig( id: java.lang.String, - vNom: java.lang.String + vNom: java.lang.String, ) object VoltLvlConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.VoltLvlConfig = { SimonaConfig.VoltLvlConfig( id = $_reqStr(parentPath, c, "id", $tsCfgValidator), - vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator) + vNom = $_reqStr(parentPath, c, "vNom", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -838,34 +838,34 @@ object SimonaConfig { final case class WecRuntimeConfig( override val calculateMissingReactivePowerWithModel: scala.Boolean, override val scaling: scala.Double, - override val uuids: scala.List[java.lang.String] + override val uuids: scala.List[java.lang.String], ) extends BaseRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) object WecRuntimeConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.WecRuntimeConfig = { SimonaConfig.WecRuntimeConfig( calculateMissingReactivePowerWithModel = $_reqBln( parentPath, c, "calculateMissingReactivePowerWithModel", - $tsCfgValidator + $tsCfgValidator, ), scaling = $_reqDbl(parentPath, c, "scaling", $tsCfgValidator), - uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator) + uuids = $_L$_str(c.getList("uuids"), parentPath, $tsCfgValidator), ) } private def $_reqBln( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Boolean = { if (c == null) false else @@ -881,7 +881,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -903,7 +903,7 @@ object SimonaConfig { powerflow: SimonaConfig.Simona.Powerflow, runtime: SimonaConfig.Simona.Runtime, simulationName: java.lang.String, - time: SimonaConfig.Simona.Time + time: SimonaConfig.Simona.Time, ) object Simona { final case class Event( @@ -914,13 +914,13 @@ object SimonaConfig { object Event { final case class Listener$Elm( eventsToProcess: scala.Option[scala.List[java.lang.String]], - fullClassPath: java.lang.String + fullClassPath: java.lang.String, ) object Listener$Elm { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Event.Listener$Elm = { SimonaConfig.Simona.Event.Listener$Elm( eventsToProcess = @@ -929,19 +929,19 @@ object SimonaConfig { $_L$_str( c.getList("eventsToProcess"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) else None, fullClassPath = - $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator) + $_reqStr(parentPath, c, "fullClassPath", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -958,7 +958,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Event = { SimonaConfig.Simona.Event( listener = @@ -967,7 +967,7 @@ object SimonaConfig { $_LSimonaConfig_Simona_Event_Listener$Elm( c.getList("listener"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) else None @@ -976,7 +976,7 @@ object SimonaConfig { private def $_LSimonaConfig_Simona_Event_Listener$Elm( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.Simona.Event.Listener$Elm] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -984,7 +984,7 @@ object SimonaConfig { SimonaConfig.Simona.Event.Listener$Elm( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -998,20 +998,20 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.GridConfig = { SimonaConfig.Simona.GridConfig( refSystems = $_LSimonaConfig_RefSystemConfig( c.getList("refSystems"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) } private def $_LSimonaConfig_RefSystemConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.RefSystemConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -1019,7 +1019,7 @@ object SimonaConfig { SimonaConfig.RefSystemConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -1029,7 +1029,7 @@ object SimonaConfig { final case class Input( grid: SimonaConfig.Simona.Input.Grid, primary: SimonaConfig.Simona.Input.Primary, - weather: SimonaConfig.Simona.Input.Weather + weather: SimonaConfig.Simona.Input.Weather, ) object Input { final case class Grid( @@ -1038,13 +1038,13 @@ object SimonaConfig { object Grid { final case class Datasource( csvParams: scala.Option[SimonaConfig.BaseCsvParams], - id: java.lang.String + id: java.lang.String, ) object Datasource { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Grid.Datasource = { SimonaConfig.Simona.Input.Grid.Datasource( csvParams = @@ -1053,18 +1053,18 @@ object SimonaConfig { SimonaConfig.BaseCsvParams( c.getConfig("csvParams"), parentPath + "csvParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, - id = $_reqStr(parentPath, c, "id", $tsCfgValidator) + id = $_reqStr(parentPath, c, "id", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1081,7 +1081,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Grid = { SimonaConfig.Simona.Input.Grid( datasource = SimonaConfig.Simona.Input.Grid.Datasource( @@ -1089,7 +1089,7 @@ object SimonaConfig { else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", - $tsCfgValidator + $tsCfgValidator, ) ) } @@ -1103,7 +1103,7 @@ object SimonaConfig { influxDb1xParams: scala.Option[ SimonaConfig.Simona.Input.Primary.InfluxDb1xParams ], - sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams] + sqlParams: scala.Option[SimonaConfig.Simona.Input.Primary.SqlParams], ) object Primary { final case class CouchbaseParams( @@ -1113,13 +1113,13 @@ object SimonaConfig { password: java.lang.String, timePattern: java.lang.String, url: java.lang.String, - userName: java.lang.String + userName: java.lang.String, ) object CouchbaseParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Primary.CouchbaseParams = { SimonaConfig.Simona.Input.Primary.CouchbaseParams( bucketName = @@ -1128,7 +1128,7 @@ object SimonaConfig { parentPath, c, "coordinateColumnName", - $tsCfgValidator + $tsCfgValidator, ), keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), password = $_reqStr(parentPath, c, "password", $tsCfgValidator), @@ -1136,14 +1136,14 @@ object SimonaConfig { if (c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1161,13 +1161,13 @@ object SimonaConfig { database: java.lang.String, port: scala.Int, timePattern: java.lang.String, - url: java.lang.String + url: java.lang.String, ) object InfluxDb1xParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Primary.InfluxDb1xParams = { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), @@ -1175,14 +1175,14 @@ object SimonaConfig { timePattern = if (c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -1198,7 +1198,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1217,13 +1217,13 @@ object SimonaConfig { password: java.lang.String, schemaName: java.lang.String, timePattern: java.lang.String, - userName: java.lang.String + userName: java.lang.String, ) object SqlParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Primary.SqlParams = { SimonaConfig.Simona.Input.Primary.SqlParams( jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), @@ -1234,14 +1234,14 @@ object SimonaConfig { timePattern = if (c.hasPathOrNull("timePattern")) c.getString("timePattern") else "yyyy-MM-dd'T'HH:mm:ss[.S[S][S]]'Z'", - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1258,7 +1258,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Primary = { SimonaConfig.Simona.Input.Primary( couchbaseParams = @@ -1267,7 +1267,7 @@ object SimonaConfig { SimonaConfig.Simona.Input.Primary.CouchbaseParams( c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1277,7 +1277,7 @@ object SimonaConfig { SimonaConfig.PrimaryDataCsvParams( c.getConfig("csvParams"), parentPath + "csvParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1287,7 +1287,7 @@ object SimonaConfig { SimonaConfig.Simona.Input.Primary.InfluxDb1xParams( c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1297,10 +1297,10 @@ object SimonaConfig { SimonaConfig.Simona.Input.Primary.SqlParams( c.getConfig("sqlParams"), parentPath + "sqlParams.", - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } } @@ -1327,7 +1327,7 @@ object SimonaConfig { sqlParams: scala.Option[ SimonaConfig.Simona.Input.Weather.Datasource.SqlParams ], - timestampPattern: scala.Option[java.lang.String] + timestampPattern: scala.Option[java.lang.String], ) object Datasource { final case class CoordinateSource( @@ -1338,7 +1338,7 @@ object SimonaConfig { ], sqlParams: scala.Option[ SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams - ] + ], ) object CoordinateSource { final case class SampleParams( @@ -1348,7 +1348,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource .SampleParams( @@ -1362,13 +1362,13 @@ object SimonaConfig { password: java.lang.String, schemaName: java.lang.String, tableName: java.lang.String, - userName: java.lang.String + userName: java.lang.String, ) object SqlParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource .SqlParams( @@ -1383,14 +1383,14 @@ object SimonaConfig { tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), userName = - $_reqStr(parentPath, c, "userName", $tsCfgValidator) + $_reqStr(parentPath, c, "userName", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1407,7 +1407,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource = { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource( csvParams = @@ -1416,7 +1416,7 @@ object SimonaConfig { SimonaConfig.BaseCsvParams( c.getConfig("csvParams"), parentPath + "csvParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1430,7 +1430,7 @@ object SimonaConfig { .SampleParams( c.getConfig("sampleParams"), parentPath + "sampleParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1441,10 +1441,10 @@ object SimonaConfig { .SqlParams( c.getConfig("sqlParams"), parentPath + "sqlParams.", - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } } @@ -1455,13 +1455,13 @@ object SimonaConfig { keyPrefix: java.lang.String, password: java.lang.String, url: java.lang.String, - userName: java.lang.String + userName: java.lang.String, ) object CouchbaseParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams = { SimonaConfig.Simona.Input.Weather.Datasource.CouchbaseParams( bucketName = @@ -1470,20 +1470,20 @@ object SimonaConfig { parentPath, c, "coordinateColumnName", - $tsCfgValidator + $tsCfgValidator, ), keyPrefix = $_reqStr(parentPath, c, "keyPrefix", $tsCfgValidator), password = $_reqStr(parentPath, c, "password", $tsCfgValidator), url = $_reqStr(parentPath, c, "url", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1500,25 +1500,25 @@ object SimonaConfig { final case class InfluxDb1xParams( database: java.lang.String, port: scala.Int, - url: java.lang.String + url: java.lang.String, ) object InfluxDb1xParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams = { SimonaConfig.Simona.Input.Weather.Datasource.InfluxDb1xParams( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -1534,7 +1534,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1555,7 +1555,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.SampleParams = { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( use = !c.hasPathOrNull("use") || c.getBoolean("use") @@ -1568,13 +1568,13 @@ object SimonaConfig { password: java.lang.String, schemaName: java.lang.String, tableName: java.lang.String, - userName: java.lang.String + userName: java.lang.String, ) object SqlParams { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource.SqlParams = { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( jdbcUrl = $_reqStr(parentPath, c, "jdbcUrl", $tsCfgValidator), @@ -1584,14 +1584,14 @@ object SimonaConfig { else "public", tableName = $_reqStr(parentPath, c, "tableName", $tsCfgValidator), - userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator) + userName = $_reqStr(parentPath, c, "userName", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1608,7 +1608,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather.Datasource = { SimonaConfig.Simona.Input.Weather.Datasource( coordinateSource = @@ -1619,7 +1619,7 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("coordinateSource{}"), parentPath + "coordinateSource.", - $tsCfgValidator + $tsCfgValidator, ), couchbaseParams = if (c.hasPathOrNull("couchbaseParams")) @@ -1628,7 +1628,7 @@ object SimonaConfig { .CouchbaseParams( c.getConfig("couchbaseParams"), parentPath + "couchbaseParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1638,7 +1638,7 @@ object SimonaConfig { SimonaConfig.BaseCsvParams( c.getConfig("csvParams"), parentPath + "csvParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1649,7 +1649,7 @@ object SimonaConfig { .InfluxDb1xParams( c.getConfig("influxDb1xParams"), parentPath + "influxDb1xParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1667,7 +1667,7 @@ object SimonaConfig { SimonaConfig.Simona.Input.Weather.Datasource.SampleParams( c.getConfig("sampleParams"), parentPath + "sampleParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1680,14 +1680,14 @@ object SimonaConfig { SimonaConfig.Simona.Input.Weather.Datasource.SqlParams( c.getConfig("sqlParams"), parentPath + "sqlParams.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, timestampPattern = if (c.hasPathOrNull("timestampPattern")) Some(c.getString("timestampPattern")) - else None + else None, ) } } @@ -1695,7 +1695,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input.Weather = { SimonaConfig.Simona.Input.Weather( datasource = SimonaConfig.Simona.Input.Weather.Datasource( @@ -1703,7 +1703,7 @@ object SimonaConfig { else com.typesafe.config.ConfigFactory.parseString("datasource{}"), parentPath + "datasource.", - $tsCfgValidator + $tsCfgValidator, ) ) } @@ -1712,27 +1712,27 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Input = { SimonaConfig.Simona.Input( grid = SimonaConfig.Simona.Input.Grid( if (c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", - $tsCfgValidator + $tsCfgValidator, ), primary = SimonaConfig.Simona.Input.Primary( if (c.hasPathOrNull("primary")) c.getConfig("primary") else com.typesafe.config.ConfigFactory.parseString("primary{}"), parentPath + "primary.", - $tsCfgValidator + $tsCfgValidator, ), weather = SimonaConfig.Simona.Input.Weather( if (c.hasPathOrNull("weather")) c.getConfig("weather") else com.typesafe.config.ConfigFactory.parseString("weather{}"), parentPath + "weather.", - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } } @@ -1743,31 +1743,31 @@ object SimonaConfig { grid: SimonaConfig.GridOutputConfig, participant: SimonaConfig.Simona.Output.Participant, sink: SimonaConfig.Simona.Output.Sink, - thermal: SimonaConfig.Simona.Output.Thermal + thermal: SimonaConfig.Simona.Output.Thermal, ) object Output { final case class Base( addTimestampToOutputDir: scala.Boolean, - dir: java.lang.String + dir: java.lang.String, ) object Base { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Base = { SimonaConfig.Simona.Output.Base( addTimestampToOutputDir = !c.hasPathOrNull( "addTimestampToOutputDir" ) || c.getBoolean("addTimestampToOutputDir"), - dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator) + dir = $_reqStr(parentPath, c, "dir", $tsCfgValidator), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1785,13 +1785,13 @@ object SimonaConfig { defaultConfig: SimonaConfig.ParticipantBaseOutputConfig, individualConfigs: scala.List[ SimonaConfig.ParticipantBaseOutputConfig - ] + ], ) object Participant { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Participant = { SimonaConfig.Simona.Output.Participant( defaultConfig = SimonaConfig.ParticipantBaseOutputConfig( @@ -1800,19 +1800,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_ParticipantBaseOutputConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_ParticipantBaseOutputConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.ParticipantBaseOutputConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -1820,7 +1820,7 @@ object SimonaConfig { SimonaConfig.ParticipantBaseOutputConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -1830,20 +1830,20 @@ object SimonaConfig { final case class Sink( csv: scala.Option[SimonaConfig.Simona.Output.Sink.Csv], influxDb1x: scala.Option[SimonaConfig.Simona.Output.Sink.InfluxDb1x], - kafka: scala.Option[SimonaConfig.ResultKafkaParams] + kafka: scala.Option[SimonaConfig.ResultKafkaParams], ) object Sink { final case class Csv( fileFormat: java.lang.String, filePrefix: java.lang.String, fileSuffix: java.lang.String, - isHierarchic: scala.Boolean + isHierarchic: scala.Boolean, ) object Csv { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Sink.Csv = { SimonaConfig.Simona.Output.Sink.Csv( fileFormat = @@ -1856,7 +1856,7 @@ object SimonaConfig { if (c.hasPathOrNull("fileSuffix")) c.getString("fileSuffix") else "", isHierarchic = - c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic") + c.hasPathOrNull("isHierarchic") && c.getBoolean("isHierarchic"), ) } } @@ -1864,25 +1864,25 @@ object SimonaConfig { final case class InfluxDb1x( database: java.lang.String, port: scala.Int, - url: java.lang.String + url: java.lang.String, ) object InfluxDb1x { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Sink.InfluxDb1x = { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = $_reqStr(parentPath, c, "database", $tsCfgValidator), port = $_reqInt(parentPath, c, "port", $tsCfgValidator), - url = $_reqStr(parentPath, c, "url", $tsCfgValidator) + url = $_reqStr(parentPath, c, "url", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -1898,7 +1898,7 @@ object SimonaConfig { parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -1915,7 +1915,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Sink = { SimonaConfig.Simona.Output.Sink( csv = @@ -1924,7 +1924,7 @@ object SimonaConfig { SimonaConfig.Simona.Output.Sink.Csv( c.getConfig("csv"), parentPath + "csv.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1934,7 +1934,7 @@ object SimonaConfig { SimonaConfig.Simona.Output.Sink.InfluxDb1x( c.getConfig("influxDb1x"), parentPath + "influxDb1x.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -1944,23 +1944,23 @@ object SimonaConfig { SimonaConfig.ResultKafkaParams( c.getConfig("kafka"), parentPath + "kafka.", - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } } final case class Thermal( defaultConfig: SimonaConfig.SimpleOutputConfig, - individualConfigs: scala.List[SimonaConfig.SimpleOutputConfig] + individualConfigs: scala.List[SimonaConfig.SimpleOutputConfig], ) object Thermal { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output.Thermal = { SimonaConfig.Simona.Output.Thermal( defaultConfig = SimonaConfig.SimpleOutputConfig( @@ -1969,19 +1969,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_SimpleOutputConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_SimpleOutputConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.SimpleOutputConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -1989,7 +1989,7 @@ object SimonaConfig { SimonaConfig.SimpleOutputConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -1999,40 +1999,40 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Output = { SimonaConfig.Simona.Output( base = SimonaConfig.Simona.Output.Base( if (c.hasPathOrNull("base")) c.getConfig("base") else com.typesafe.config.ConfigFactory.parseString("base{}"), parentPath + "base.", - $tsCfgValidator + $tsCfgValidator, ), flex = c.hasPathOrNull("flex") && c.getBoolean("flex"), grid = SimonaConfig.GridOutputConfig( if (c.hasPathOrNull("grid")) c.getConfig("grid") else com.typesafe.config.ConfigFactory.parseString("grid{}"), parentPath + "grid.", - $tsCfgValidator + $tsCfgValidator, ), participant = SimonaConfig.Simona.Output.Participant( if (c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", - $tsCfgValidator + $tsCfgValidator, ), sink = SimonaConfig.Simona.Output.Sink( if (c.hasPathOrNull("sink")) c.getConfig("sink") else com.typesafe.config.ConfigFactory.parseString("sink{}"), parentPath + "sink.", - $tsCfgValidator + $tsCfgValidator, ), thermal = SimonaConfig.Simona.Output.Thermal( if (c.hasPathOrNull("thermal")) c.getConfig("thermal") else com.typesafe.config.ConfigFactory.parseString("thermal{}"), parentPath + "thermal.", - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } } @@ -2042,30 +2042,30 @@ object SimonaConfig { newtonraphson: SimonaConfig.Simona.Powerflow.Newtonraphson, resolution: java.time.Duration, stopOnFailure: scala.Boolean, - sweepTimeout: java.time.Duration + sweepTimeout: java.time.Duration, ) object Powerflow { final case class Newtonraphson( epsilon: scala.List[scala.Double], - iterations: scala.Int + iterations: scala.Int, ) object Newtonraphson { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Powerflow.Newtonraphson = { SimonaConfig.Simona.Powerflow.Newtonraphson( epsilon = $_L$_dbl(c.getList("epsilon"), parentPath, $tsCfgValidator), - iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator) + iterations = $_reqInt(parentPath, c, "iterations", $tsCfgValidator), ) } private def $_reqInt( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Int = { if (c == null) 0 else @@ -2082,7 +2082,7 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Powerflow = { SimonaConfig.Simona.Powerflow( maxSweepPowerDeviation = @@ -2092,7 +2092,7 @@ object SimonaConfig { else com.typesafe.config.ConfigFactory.parseString("newtonraphson{}"), parentPath + "newtonraphson.", - $tsCfgValidator + $tsCfgValidator, ), resolution = if (c.hasPathOrNull("resolution")) c.getDuration("resolution") @@ -2101,14 +2101,14 @@ object SimonaConfig { c.hasPathOrNull("stopOnFailure") && c.getBoolean("stopOnFailure"), sweepTimeout = if (c.hasPathOrNull("sweepTimeout")) c.getDuration("sweepTimeout") - else java.time.Duration.parse("PT30S") + else java.time.Duration.parse("PT30S"), ) } private def $_reqDbl( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -2126,18 +2126,18 @@ object SimonaConfig { listener: SimonaConfig.Simona.Runtime.Listener, participant: SimonaConfig.Simona.Runtime.Participant, selected_subgrids: scala.Option[scala.List[scala.Int]], - selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]] + selected_volt_lvls: scala.Option[scala.List[SimonaConfig.VoltLvlConfig]], ) object Runtime { final case class Listener( eventsToProcess: scala.Option[scala.List[java.lang.String]], - kafka: scala.Option[SimonaConfig.RuntimeKafkaParams] + kafka: scala.Option[SimonaConfig.RuntimeKafkaParams], ) object Listener { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Listener = { SimonaConfig.Simona.Runtime.Listener( eventsToProcess = @@ -2146,7 +2146,7 @@ object SimonaConfig { $_L$_str( c.getList("eventsToProcess"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -2156,10 +2156,10 @@ object SimonaConfig { SimonaConfig.RuntimeKafkaParams( c.getConfig("kafka"), parentPath + "kafka.", - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } } @@ -2171,18 +2171,18 @@ object SimonaConfig { load: SimonaConfig.Simona.Runtime.Participant.Load, pv: SimonaConfig.Simona.Runtime.Participant.Pv, requestVoltageDeviationThreshold: scala.Double, - wec: SimonaConfig.Simona.Runtime.Participant.Wec + wec: SimonaConfig.Simona.Runtime.Participant.Wec, ) object Participant { final case class Evcs( defaultConfig: SimonaConfig.EvcsRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.EvcsRuntimeConfig], ) object Evcs { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.Evcs = { SimonaConfig.Simona.Runtime.Participant.Evcs( defaultConfig = SimonaConfig.EvcsRuntimeConfig( @@ -2192,19 +2192,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_EvcsRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_EvcsRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.EvcsRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2212,7 +2212,7 @@ object SimonaConfig { SimonaConfig.EvcsRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2221,13 +2221,13 @@ object SimonaConfig { final case class FixedFeedIn( defaultConfig: SimonaConfig.FixedFeedInRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.FixedFeedInRuntimeConfig], ) object FixedFeedIn { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.FixedFeedIn = { SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( defaultConfig = SimonaConfig.FixedFeedInRuntimeConfig( @@ -2237,19 +2237,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_FixedFeedInRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_FixedFeedInRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.FixedFeedInRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2257,7 +2257,7 @@ object SimonaConfig { SimonaConfig.FixedFeedInRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2266,13 +2266,13 @@ object SimonaConfig { final case class Hp( defaultConfig: SimonaConfig.HpRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.HpRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.HpRuntimeConfig], ) object Hp { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.Hp = { SimonaConfig.Simona.Runtime.Participant.Hp( defaultConfig = SimonaConfig.HpRuntimeConfig( @@ -2282,19 +2282,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_HpRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_HpRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.HpRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2302,7 +2302,7 @@ object SimonaConfig { SimonaConfig.HpRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2311,13 +2311,13 @@ object SimonaConfig { final case class Load( defaultConfig: SimonaConfig.LoadRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.LoadRuntimeConfig], ) object Load { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.Load = { SimonaConfig.Simona.Runtime.Participant.Load( defaultConfig = SimonaConfig.LoadRuntimeConfig( @@ -2327,19 +2327,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_LoadRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_LoadRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.LoadRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2347,7 +2347,7 @@ object SimonaConfig { SimonaConfig.LoadRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2356,13 +2356,13 @@ object SimonaConfig { final case class Pv( defaultConfig: SimonaConfig.PvRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.PvRuntimeConfig], ) object Pv { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.Pv = { SimonaConfig.Simona.Runtime.Participant.Pv( defaultConfig = SimonaConfig.PvRuntimeConfig( @@ -2372,19 +2372,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_PvRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_PvRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.PvRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2392,7 +2392,7 @@ object SimonaConfig { SimonaConfig.PvRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2401,13 +2401,13 @@ object SimonaConfig { final case class Wec( defaultConfig: SimonaConfig.WecRuntimeConfig, - individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig] + individualConfigs: scala.List[SimonaConfig.WecRuntimeConfig], ) object Wec { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant.Wec = { SimonaConfig.Simona.Runtime.Participant.Wec( defaultConfig = SimonaConfig.WecRuntimeConfig( @@ -2417,19 +2417,19 @@ object SimonaConfig { com.typesafe.config.ConfigFactory .parseString("defaultConfig{}"), parentPath + "defaultConfig.", - $tsCfgValidator + $tsCfgValidator, ), individualConfigs = $_LSimonaConfig_WecRuntimeConfig( c.getList("individualConfigs"), parentPath, - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_LSimonaConfig_WecRuntimeConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.WecRuntimeConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2437,7 +2437,7 @@ object SimonaConfig { SimonaConfig.WecRuntimeConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2447,39 +2447,39 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime.Participant = { SimonaConfig.Simona.Runtime.Participant( evcs = SimonaConfig.Simona.Runtime.Participant.Evcs( if (c.hasPathOrNull("evcs")) c.getConfig("evcs") else com.typesafe.config.ConfigFactory.parseString("evcs{}"), parentPath + "evcs.", - $tsCfgValidator + $tsCfgValidator, ), fixedFeedIn = SimonaConfig.Simona.Runtime.Participant.FixedFeedIn( if (c.hasPathOrNull("fixedFeedIn")) c.getConfig("fixedFeedIn") else com.typesafe.config.ConfigFactory.parseString("fixedFeedIn{}"), parentPath + "fixedFeedIn.", - $tsCfgValidator + $tsCfgValidator, ), hp = SimonaConfig.Simona.Runtime.Participant.Hp( if (c.hasPathOrNull("hp")) c.getConfig("hp") else com.typesafe.config.ConfigFactory.parseString("hp{}"), parentPath + "hp.", - $tsCfgValidator + $tsCfgValidator, ), load = SimonaConfig.Simona.Runtime.Participant.Load( if (c.hasPathOrNull("load")) c.getConfig("load") else com.typesafe.config.ConfigFactory.parseString("load{}"), parentPath + "load.", - $tsCfgValidator + $tsCfgValidator, ), pv = SimonaConfig.Simona.Runtime.Participant.Pv( if (c.hasPathOrNull("pv")) c.getConfig("pv") else com.typesafe.config.ConfigFactory.parseString("pv{}"), parentPath + "pv.", - $tsCfgValidator + $tsCfgValidator, ), requestVoltageDeviationThreshold = if (c.hasPathOrNull("requestVoltageDeviationThreshold")) @@ -2489,8 +2489,8 @@ object SimonaConfig { if (c.hasPathOrNull("wec")) c.getConfig("wec") else com.typesafe.config.ConfigFactory.parseString("wec{}"), parentPath + "wec.", - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } } @@ -2498,20 +2498,20 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Runtime = { SimonaConfig.Simona.Runtime( listener = SimonaConfig.Simona.Runtime.Listener( if (c.hasPathOrNull("listener")) c.getConfig("listener") else com.typesafe.config.ConfigFactory.parseString("listener{}"), parentPath + "listener.", - $tsCfgValidator + $tsCfgValidator, ), participant = SimonaConfig.Simona.Runtime.Participant( if (c.hasPathOrNull("participant")) c.getConfig("participant") else com.typesafe.config.ConfigFactory.parseString("participant{}"), parentPath + "participant.", - $tsCfgValidator + $tsCfgValidator, ), selected_subgrids = if (c.hasPathOrNull("selected_subgrids")) @@ -2519,7 +2519,7 @@ object SimonaConfig { $_L$_int( c.getList("selected_subgrids"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) else None, @@ -2529,16 +2529,16 @@ object SimonaConfig { $_LSimonaConfig_VoltLvlConfig( c.getList("selected_volt_lvls"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) - else None + else None, ) } private def $_LSimonaConfig_VoltLvlConfig( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.VoltLvlConfig] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -2546,7 +2546,7 @@ object SimonaConfig { SimonaConfig.VoltLvlConfig( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2556,13 +2556,13 @@ object SimonaConfig { final case class Time( endDateTime: java.lang.String, schedulerReadyCheckWindow: scala.Option[scala.Int], - startDateTime: java.lang.String + startDateTime: java.lang.String, ) object Time { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Time = { SimonaConfig.Simona.Time( endDateTime = @@ -2574,7 +2574,7 @@ object SimonaConfig { else None, startDateTime = if (c.hasPathOrNull("startDateTime")) c.getString("startDateTime") - else "2011-05-01 00:00:00" + else "2011-05-01 00:00:00", ) } } @@ -2582,44 +2582,44 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona = { SimonaConfig.Simona( event = SimonaConfig.Simona.Event( if (c.hasPathOrNull("event")) c.getConfig("event") else com.typesafe.config.ConfigFactory.parseString("event{}"), parentPath + "event.", - $tsCfgValidator + $tsCfgValidator, ), gridConfig = SimonaConfig.Simona.GridConfig( if (c.hasPathOrNull("gridConfig")) c.getConfig("gridConfig") else com.typesafe.config.ConfigFactory.parseString("gridConfig{}"), parentPath + "gridConfig.", - $tsCfgValidator + $tsCfgValidator, ), input = SimonaConfig.Simona.Input( if (c.hasPathOrNull("input")) c.getConfig("input") else com.typesafe.config.ConfigFactory.parseString("input{}"), parentPath + "input.", - $tsCfgValidator + $tsCfgValidator, ), output = SimonaConfig.Simona.Output( if (c.hasPathOrNull("output")) c.getConfig("output") else com.typesafe.config.ConfigFactory.parseString("output{}"), parentPath + "output.", - $tsCfgValidator + $tsCfgValidator, ), powerflow = SimonaConfig.Simona.Powerflow( if (c.hasPathOrNull("powerflow")) c.getConfig("powerflow") else com.typesafe.config.ConfigFactory.parseString("powerflow{}"), parentPath + "powerflow.", - $tsCfgValidator + $tsCfgValidator, ), runtime = SimonaConfig.Simona.Runtime( if (c.hasPathOrNull("runtime")) c.getConfig("runtime") else com.typesafe.config.ConfigFactory.parseString("runtime{}"), parentPath + "runtime.", - $tsCfgValidator + $tsCfgValidator, ), simulationName = $_reqStr(parentPath, c, "simulationName", $tsCfgValidator), @@ -2627,15 +2627,15 @@ object SimonaConfig { if (c.hasPathOrNull("time")) c.getConfig("time") else com.typesafe.config.ConfigFactory.parseString("time{}"), parentPath + "time.", - $tsCfgValidator - ) + $tsCfgValidator, + ), ) } private def $_reqStr( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): java.lang.String = { if (c == null) null else @@ -2657,7 +2657,7 @@ object SimonaConfig { if (c.hasPathOrNull("simona")) c.getConfig("simona") else com.typesafe.config.ConfigFactory.parseString("simona{}"), parentPath + "simona.", - $tsCfgValidator + $tsCfgValidator, ) ) $tsCfgValidator.validate() @@ -2667,7 +2667,7 @@ object SimonaConfig { private def $_L$_dbl( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[scala.Double] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_dbl(cv)).toList @@ -2675,7 +2675,7 @@ object SimonaConfig { private def $_L$_int( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[scala.Int] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_int(cv)).toList @@ -2683,7 +2683,7 @@ object SimonaConfig { private def $_L$_str( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[java.lang.String] = { import scala.jdk.CollectionConverters._ cl.asScala.map(cv => $_str(cv)).toList @@ -2699,7 +2699,7 @@ object SimonaConfig { private def $_expE( cv: com.typesafe.config.ConfigValue, - exp: java.lang.String + exp: java.lang.String, ) = { val u: Any = cv.unwrapped new java.lang.RuntimeException( @@ -2728,7 +2728,7 @@ object SimonaConfig { def addBadPath( path: java.lang.String, - e: com.typesafe.config.ConfigException + e: com.typesafe.config.ConfigException, ): Unit = { badPaths += s"'$path': ${e.getClass.getName}(${e.getMessage})" } @@ -2736,7 +2736,7 @@ object SimonaConfig { def addInvalidEnumValue( path: java.lang.String, value: java.lang.String, - enumName: java.lang.String + enumName: java.lang.String, ): Unit = { badPaths += s"'$path': invalid value $value for enumeration $enumName" } diff --git a/src/main/scala/edu/ie3/simona/config/VoltLvlParser.scala b/src/main/scala/edu/ie3/simona/config/VoltLvlParser.scala index 3d3ce38920..885adae81e 100644 --- a/src/main/scala/edu/ie3/simona/config/VoltLvlParser.scala +++ b/src/main/scala/edu/ie3/simona/config/VoltLvlParser.scala @@ -10,7 +10,7 @@ import edu.ie3.datamodel.exceptions.VoltageLevelException import edu.ie3.datamodel.models.voltagelevels.{ CommonVoltageLevel, GermanVoltageLevelUtils, - VoltageLevel + VoltageLevel, } import edu.ie3.simona.config.SimonaConfig.VoltLvlConfig import edu.ie3.simona.exceptions.InvalidConfigParameterException @@ -46,7 +46,7 @@ object VoltLvlParser { */ private def parse( id: String, - vNominal: ComparableQuantity[ElectricPotential] + vNominal: ComparableQuantity[ElectricPotential], ): CommonVoltageLevel = try { GermanVoltageLevelUtils.parse(id, vNominal) @@ -54,7 +54,7 @@ object VoltLvlParser { case vle: VoltageLevelException => throw new InvalidConfigParameterException( s"Cannot find a common voltage level with id $id and nominal voltage $vNominal", - vle + vle, ) } @@ -76,12 +76,12 @@ object VoltLvlParser { case iae: IllegalArgumentException => throw new InvalidConfigParameterException( s"Cannot parse the nominal voltage $quantString", - iae + iae, ) case cce: ClassCastException => throw new InvalidConfigParameterException( s"Cannot parse $quantString to nominal voltage, as it is no voltage.", - cce + cce, ) } } diff --git a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala index 81512e9a9d..6c3b55b8af 100644 --- a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala @@ -10,11 +10,11 @@ import edu.ie3.datamodel.models.result.NodeResult import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, - Transformer2WResult + Transformer2WResult, } import edu.ie3.datamodel.models.result.system.{ FlexOptionsResult, - SystemParticipantResult + SystemParticipantResult, } import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult @@ -65,7 +65,7 @@ object ResultEvent { switchResults: Iterable[SwitchResult], lineResults: Iterable[LineResult], transformer2wResults: Iterable[Transformer2WResult], - transformer3wResults: Iterable[PartialTransformer3wResult] + transformer3wResults: Iterable[PartialTransformer3wResult], ) extends ResultEvent /** Event that holds the flexibility options result of a diff --git a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala index 23a3352e19..c7e793a9a2 100644 --- a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala @@ -80,7 +80,7 @@ object RuntimeEvent { final case class Done( tick: Long, duration: Long, - errorInSim: Boolean + errorInSim: Boolean, ) extends RuntimeEvent /** Indicates that a power flow calculation has failed. This event is not diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index 3abe4d831e..fcd820db4c 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -16,11 +16,11 @@ import edu.ie3.simona.event.ResultEvent.{ FlexOptionsResultEvent, ParticipantResultEvent, PowerFlowResultEvent, - ThermalResultEvent + ThermalResultEvent, } import edu.ie3.simona.exceptions.{ FileHierarchyException, - ProcessResultEventException + ProcessResultEventException, } import edu.ie3.simona.io.result._ import edu.ie3.simona.ontology.messages.StopMessage @@ -55,8 +55,8 @@ object ResultEventListener extends Transformer3wResultSupport { classToSink: Map[Class[_], ResultEntitySink], threeWindingResults: Map[ Transformer3wKey, - AggregatedTransformer3wResult - ] = Map.empty + AggregatedTransformer3wResult, + ] = Map.empty, ) /** Initialize the sinks for this listener based on the provided collection @@ -94,8 +94,8 @@ object ResultEventListener extends Transformer3wResultSupport { ResultEntityCsvSink( fileName.replace(".gz", ""), new ResultEntityProcessor(resultClass), - fileName.endsWith(".gz") - ) + fileName.endsWith(".gz"), + ), ) } } else { @@ -121,7 +121,7 @@ object ResultEventListener extends Transformer3wResultSupport { runId, bootstrapServers, schemaRegistryUrl, - linger + linger, ) => val classes: Iterable[Class[_ <: ResultEntity]] = Set( classOf[NodeResult] // currently, only NodeResults are sent out @@ -135,8 +135,8 @@ object ResultEventListener extends Transformer3wResultSupport { runId, bootstrapServers, schemaRegistryUrl, - linger - ) + linger, + ), ) ) ) @@ -155,7 +155,7 @@ object ResultEventListener extends Transformer3wResultSupport { private def handleResult( resultEntity: ResultEntity, baseData: BaseData, - log: Logger + log: Logger, ): BaseData = { handOverToSink(resultEntity, baseData.classToSink, log) baseData @@ -175,14 +175,14 @@ object ResultEventListener extends Transformer3wResultSupport { private def handlePartialTransformer3wResult( result: PartialTransformer3wResult, baseData: BaseData, - log: Logger + log: Logger, ): BaseData = { val key = Transformer3wKey(result.input, result.time) // retrieve existing partial result or use empty one val partialResult = baseData.threeWindingResults.getOrElse( key, - AggregatedTransformer3wResult.EMPTY + AggregatedTransformer3wResult.EMPTY, ) // add partial result val updatedResults = partialResult.add(result).map { updatedResult => @@ -202,7 +202,7 @@ object ResultEventListener extends Transformer3wResultSupport { case Failure(exception) => log.warn( "Failure when handling partial Transformer3w result", - exception + exception, ) // on failure, we just continue with previous results baseData.threeWindingResults @@ -222,7 +222,7 @@ object ResultEventListener extends Transformer3wResultSupport { private def handOverToSink( resultEntity: ResultEntity, classToSink: Map[Class[_], ResultEntitySink], - log: Logger + log: Logger, ): Unit = Try { classToSink @@ -244,7 +244,7 @@ object ResultEventListener extends Transformer3wResultSupport { s"Events that will be processed: {}", resultFileHierarchy.resultEntitiesToConsider .map(_.getSimpleName) - .mkString(",") + .mkString(","), ) } @@ -295,8 +295,8 @@ object ResultEventListener extends Transformer3wResultSupport { switchResults, lineResults, transformer2wResults, - transformer3wResults - ) + transformer3wResults, + ), ) => val updatedBaseData = (nodeResults ++ switchResults ++ lineResults ++ transformer2wResults ++ transformer3wResults) @@ -305,12 +305,12 @@ object ResultEventListener extends Transformer3wResultSupport { handleResult(resultEntity, currentBaseData, ctx.log) case ( currentBaseData, - partialTransformerResult: PartialTransformer3wResult + partialTransformerResult: PartialTransformer3wResult, ) => handlePartialTransformer3wResult( partialTransformerResult, currentBaseData, - ctx.log + ctx.log, ) } idle(updatedBaseData) @@ -341,7 +341,7 @@ object ResultEventListener extends Transformer3wResultSupport { .map { case Transformer3wKey(model, zdt) => s"model '$model' at $zdt" } - .mkString("\n\t\t") + .mkString("\n\t\t"), ) // close sinks concurrently to speed up closing (closing calls might be blocking) @@ -353,7 +353,7 @@ object ResultEventListener extends Transformer3wResultSupport { } ) ), - 5.minutes + 5.minutes, ) ctx.log.debug("Result I/O completed.") diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index a45fdd5f86..3b12951688 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.io.runtime.{ RuntimeEventKafkaSink, RuntimeEventLogSink, RuntimeEventQueueSink, - RuntimeEventSink + RuntimeEventSink, } import edu.ie3.util.TimeUtil import org.slf4j.Logger @@ -42,7 +42,7 @@ object RuntimeEventListener { def apply( listenerConf: SimonaConfig.Simona.Runtime.Listener, queue: Option[BlockingQueue[RuntimeEvent]], - startDateTimeString: String + startDateTimeString: String, ): Behavior[RuntimeEvent] = { val listeners = Iterable( Some( @@ -51,19 +51,19 @@ object RuntimeEventListener { ) ), queue.map(qu => RuntimeEventQueueSink(qu)), - listenerConf.kafka.map(kafkaConf => RuntimeEventKafkaSink(kafkaConf)) + listenerConf.kafka.map(kafkaConf => RuntimeEventKafkaSink(kafkaConf)), ).flatten RuntimeEventListener( listeners, - listenerConf.eventsToProcess + listenerConf.eventsToProcess, ) } def apply( listeners: Iterable[RuntimeEventSink], eventsToProcess: Option[List[String]] = None, - runtimeStats: RuntimeStats = RuntimeStats() + runtimeStats: RuntimeStats = RuntimeStats(), ): Behavior[RuntimeEvent] = Behaviors .receive[RuntimeEvent] { case (_, PowerFlowFailed) => @@ -79,7 +79,7 @@ object RuntimeEventListener { else ctx.log.debug( "Skipping event {} as it is not in the list of events to process.", - event.id + event.id, ) Behaviors.same } @@ -92,7 +92,7 @@ object RuntimeEventListener { listeners: Iterable[RuntimeEventSink], event: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger + log: Logger, ): Unit = listeners.foreach(_.handleRuntimeEvent(event, runtimeStats, log)) diff --git a/src/main/scala/edu/ie3/simona/event/listener/SimonaListenerWithFilter.scala b/src/main/scala/edu/ie3/simona/event/listener/SimonaListenerWithFilter.scala index 8d09e63c0a..666120e80e 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/SimonaListenerWithFilter.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/SimonaListenerWithFilter.scala @@ -49,7 +49,7 @@ abstract class SimonaListenerWithFilter(eventsToProcess: Option[List[String]]) case _ => log.debug( "Skipping event {} as it is not in the list of events to process.", - event.id + event.id, ) } } diff --git a/src/main/scala/edu/ie3/simona/event/listener/Transformer3wResultSupport.scala b/src/main/scala/edu/ie3/simona/event/listener/Transformer3wResultSupport.scala index 5eb68a5653..97e443a2b0 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/Transformer3wResultSupport.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/Transformer3wResultSupport.scala @@ -27,7 +27,7 @@ private[listener] trait Transformer3wResultSupport { */ final case class Transformer3wKey( model: UUID, - zdt: ZonedDateTime + zdt: ZonedDateTime, ) /** Holding the result values of all three ports of a transformer @@ -42,7 +42,7 @@ private[listener] trait Transformer3wResultSupport { final case class AggregatedTransformer3wResult( a: Option[PartialTransformer3wResult.PortA], b: Option[PartialTransformer3wResult.PortB], - c: Option[PartialTransformer3wResult.PortC] + c: Option[PartialTransformer3wResult.PortC], ) { /** Check, if the results can be consolidated @@ -65,29 +65,29 @@ private[listener] trait Transformer3wResultSupport { aResult.input, Quantities.getQuantity( aResult.currentMagnitude.toAmperes, - Units.AMPERE + Units.AMPERE, ), Quantities.getQuantity( aResult.currentAngle.toDegrees, - PowerSystemUnits.DEGREE_GEOM + PowerSystemUnits.DEGREE_GEOM, ), Quantities.getQuantity( bResult.currentMagnitude.toAmperes, - Units.AMPERE + Units.AMPERE, ), Quantities.getQuantity( bResult.currentAngle.toDegrees, - PowerSystemUnits.DEGREE_GEOM + PowerSystemUnits.DEGREE_GEOM, ), Quantities.getQuantity( cResult.currentMagnitude.toAmperes, - Units.AMPERE + Units.AMPERE, ), Quantities.getQuantity( cResult.currentAngle.toDegrees, - PowerSystemUnits.DEGREE_GEOM + PowerSystemUnits.DEGREE_GEOM, ), - aResult.tapPos + aResult.tapPos, ) ) case _ => diff --git a/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala b/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala index dfcf9c9e65..bacd0be34d 100644 --- a/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala +++ b/src/main/scala/edu/ie3/simona/event/notifier/NotifierConfig.scala @@ -15,5 +15,5 @@ package edu.ie3.simona.event.notifier final case class NotifierConfig( simulationResultInfo: Boolean, powerRequestReply: Boolean, - flexResult: Boolean + flexResult: Boolean, ) diff --git a/src/main/scala/edu/ie3/simona/exceptions/WeatherServiceException.scala b/src/main/scala/edu/ie3/simona/exceptions/WeatherServiceException.scala index 5dcdaab211..08d109a2a6 100644 --- a/src/main/scala/edu/ie3/simona/exceptions/WeatherServiceException.scala +++ b/src/main/scala/edu/ie3/simona/exceptions/WeatherServiceException.scala @@ -15,7 +15,7 @@ package edu.ie3.simona.exceptions */ abstract class WeatherServiceException( private val msg: String = "", - private val cause: Throwable = None.orNull + private val cause: Throwable = None.orNull, ) extends Exception(msg, cause) object WeatherServiceException { @@ -30,7 +30,7 @@ object WeatherServiceException { */ final case class WeatherServiceInitializationException( private val msg: String = "", - private val cause: Throwable = None.orNull + private val cause: Throwable = None.orNull, ) extends WeatherServiceException(msg, cause) /** Exception to be thrown, if looking up of weather fails @@ -42,7 +42,7 @@ object WeatherServiceException { */ final case class WeatherLookupException( private val msg: String = "", - private val cause: Throwable = None.orNull + private val cause: Throwable = None.orNull, ) extends WeatherServiceException(msg, cause) /** Exception to be thrown if the registration of the an agent fails @@ -53,7 +53,7 @@ object WeatherServiceException { */ final case class InvalidRegistrationRequestException( private val msg: String = "", - private val cause: Throwable = None.orNull + private val cause: Throwable = None.orNull, ) extends WeatherServiceException(msg, cause) } diff --git a/src/main/scala/edu/ie3/simona/io/grid/CsvGridSource.scala b/src/main/scala/edu/ie3/simona/io/grid/CsvGridSource.scala index fa7016a09a..7726640c1f 100644 --- a/src/main/scala/edu/ie3/simona/io/grid/CsvGridSource.scala +++ b/src/main/scala/edu/ie3/simona/io/grid/CsvGridSource.scala @@ -13,7 +13,7 @@ import edu.ie3.datamodel.models.input.container._ import edu.ie3.datamodel.models.input.thermal.{ ThermalBusInput, ThermalHouseInput, - ThermalStorageInput + ThermalStorageInput, } import java.nio.file.Path @@ -23,7 +23,7 @@ object CsvGridSource { def readThermalGrids( csvSep: String, baseFolder: Path, - fileNamingStrategy: FileNamingStrategy + fileNamingStrategy: FileNamingStrategy, ): Map[ThermalBusInput, ThermalGrid] = { val csvDataSource = new CsvDataSource(csvSep, baseFolder, fileNamingStrategy) @@ -56,7 +56,7 @@ object CsvGridSource { bus -> new ThermalGrid( bus, h, - s + s, ) }.toMap } diff --git a/src/main/scala/edu/ie3/simona/io/grid/GridProvider.scala b/src/main/scala/edu/ie3/simona/io/grid/GridProvider.scala index 4818b95fb1..24277fcd7c 100644 --- a/src/main/scala/edu/ie3/simona/io/grid/GridProvider.scala +++ b/src/main/scala/edu/ie3/simona/io/grid/GridProvider.scala @@ -11,7 +11,7 @@ import edu.ie3.datamodel.io.naming.FileNamingStrategy import edu.ie3.datamodel.io.source.csv.CsvJointGridContainerSource import edu.ie3.datamodel.models.input.container.{ JointGridContainer, - ThermalGrid + ThermalGrid, } import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.utils.validation.ValidationUtils @@ -31,7 +31,7 @@ object GridProvider extends LazyLogging { def gridFromConfig( simulationName: String, - gridDataSource: SimonaConfig.Simona.Input.Grid.Datasource + gridDataSource: SimonaConfig.Simona.Input.Grid.Datasource, ): JointGridContainer = { GridSourceType(gridDataSource.id.toLowerCase) match { case GridSourceType.CSV => @@ -41,14 +41,14 @@ object GridProvider extends LazyLogging { simulationName, params.csvSep, Path.of(params.directoryPath), - params.isHierarchic + params.isHierarchic, ) Try(ValidationUtils.check(jointGridContainer)) match { case Failure(exception) => logger.warn( s"Validation of grid ${jointGridContainer.getGridName} failed: \n\t{}", - exception.getMessage + exception.getMessage, ) case Success(_) => logger.debug( @@ -85,7 +85,7 @@ object GridProvider extends LazyLogging { .readThermalGrids( params.csvSep, Path.of(params.directoryPath), - new FileNamingStrategy() + new FileNamingStrategy(), ) case None => throw new RuntimeException( diff --git a/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala b/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala index 0b41aebbe0..88e6d5a080 100644 --- a/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala +++ b/src/main/scala/edu/ie3/simona/io/result/ResultEntityCsvSink.scala @@ -41,7 +41,7 @@ final case class ResultEntityCsvSink private ( fileWriter: Writer, resultEntityProcessor: ResultEntityProcessor, compressOutputFiles: Boolean, - delimiter: String + delimiter: String, ) extends ResultEntitySink with LazyLogging { @@ -159,7 +159,7 @@ object ResultEntityCsvSink { outfileName: String, resultEntityProcessor: ResultEntityProcessor, compressOutputFiles: Boolean, - delimiter: String = "," + delimiter: String = ",", ): ResultEntityCsvSink = { val file = new File(outfileName) @@ -172,7 +172,7 @@ object ResultEntityCsvSink { writer, resultEntityProcessor, compressOutputFiles, - delimiter + delimiter, ) if (!existedBefore) diff --git a/src/main/scala/edu/ie3/simona/io/result/ResultEntityInfluxDbSink.scala b/src/main/scala/edu/ie3/simona/io/result/ResultEntityInfluxDbSink.scala index 3b101064b5..a8d0ec4a5d 100644 --- a/src/main/scala/edu/ie3/simona/io/result/ResultEntityInfluxDbSink.scala +++ b/src/main/scala/edu/ie3/simona/io/result/ResultEntityInfluxDbSink.scala @@ -48,7 +48,7 @@ object ResultEntityInfluxDbSink { def apply( databaseUrl: String, databaseName: String, - scenarioName: String + scenarioName: String, ): Future[ResultEntityInfluxDbSink] = Future.successful( new ResultEntityInfluxDbSink( diff --git a/src/main/scala/edu/ie3/simona/io/result/ResultEntityKafkaSink.scala b/src/main/scala/edu/ie3/simona/io/result/ResultEntityKafkaSink.scala index b9d8f1f272..3effd9dd2d 100644 --- a/src/main/scala/edu/ie3/simona/io/result/ResultEntityKafkaSink.scala +++ b/src/main/scala/edu/ie3/simona/io/result/ResultEntityKafkaSink.scala @@ -16,7 +16,7 @@ import io.confluent.kafka.serializers.AbstractKafkaSchemaSerDeConfig.SCHEMA_REGI import org.apache.kafka.clients.producer.{ KafkaProducer, ProducerConfig, - ProducerRecord + ProducerRecord, } import org.apache.kafka.common.serialization.{Serdes, Serializer} @@ -26,11 +26,11 @@ import scala.reflect.ClassTag final case class ResultEntityKafkaSink[ V <: ResultEntity, - P <: PlainResult + P <: PlainResult, ] private ( producer: KafkaProducer[String, P], plainWriter: PlainWriter[V, P], - topic: String + topic: String, ) extends ResultEntitySink { override def handleResultEntity(resultEntity: ResultEntity): Unit = { @@ -53,7 +53,7 @@ object ResultEntityKafkaSink { simRunId: UUID, bootstrapServers: String, schemaRegistryUrl: String, - linger: Int + linger: Int, )(implicit tag: ClassTag[R] ): ResultEntityKafkaSink[_ <: ResultEntity, _ <: PlainResult] = { @@ -62,7 +62,7 @@ object ResultEntityKafkaSink { props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers) props.put( ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, - true + true, ) // exactly once delivery val NodeResClass = classOf[NodeResult] @@ -79,24 +79,24 @@ object ResultEntityKafkaSink { schemaRegistryUrl: String, props: Properties, topic: String, - writer: PlainWriter[F, P] + writer: PlainWriter[F, P], ): ResultEntityKafkaSink[F, P] = { val keySerializer = Serdes.String().serializer() val valueSerializer: Serializer[P] = reflectionSerializer4S[P] valueSerializer.configure( Map(SCHEMA_REGISTRY_URL_CONFIG -> schemaRegistryUrl).asJava, - false + false, ) ResultEntityKafkaSink( new KafkaProducer[String, P]( props, keySerializer, - valueSerializer + valueSerializer, ), writer, - topic + topic, ) } } diff --git a/src/main/scala/edu/ie3/simona/io/result/ResultSinkType.scala b/src/main/scala/edu/ie3/simona/io/result/ResultSinkType.scala index d4c444fdd7..3510810062 100644 --- a/src/main/scala/edu/ie3/simona/io/result/ResultSinkType.scala +++ b/src/main/scala/edu/ie3/simona/io/result/ResultSinkType.scala @@ -20,7 +20,7 @@ object ResultSinkType { final case class Csv( fileFormat: String = ".csv", filePrefix: String = "", - fileSuffix: String = "" + fileSuffix: String = "", ) extends ResultSinkType final case class InfluxDb1x(url: String, database: String, scenario: String) @@ -31,12 +31,12 @@ object ResultSinkType { runId: UUID, bootstrapServers: String, schemaRegistryUrl: String, - linger: Int + linger: Int, ) extends ResultSinkType def apply( sinkConfig: SimonaConfig.Simona.Output.Sink, - runName: String + runName: String, ): ResultSinkType = { val sink: Seq[Any] = Seq(sinkConfig.csv, sinkConfig.influxDb1x, sinkConfig.kafka).flatten @@ -57,7 +57,7 @@ object ResultSinkType { UUID.fromString(params.runId), params.bootstrapServers, params.schemaRegistryUrl, - params.linger + params.linger, ) case None => throw new IllegalArgumentException( diff --git a/src/main/scala/edu/ie3/simona/io/result/plain/PlainResult.scala b/src/main/scala/edu/ie3/simona/io/result/plain/PlainResult.scala index a590441007..19bb41283d 100644 --- a/src/main/scala/edu/ie3/simona/io/result/plain/PlainResult.scala +++ b/src/main/scala/edu/ie3/simona/io/result/plain/PlainResult.scala @@ -40,6 +40,6 @@ object PlainResult { uuid: UUID, inputModel: UUID, vMag: Double, - vAng: Double + vAng: Double, ) extends PlainResult } diff --git a/src/main/scala/edu/ie3/simona/io/result/plain/PlainWriter.scala b/src/main/scala/edu/ie3/simona/io/result/plain/PlainWriter.scala index 993f43d0c9..597dff5ac1 100644 --- a/src/main/scala/edu/ie3/simona/io/result/plain/PlainWriter.scala +++ b/src/main/scala/edu/ie3/simona/io/result/plain/PlainWriter.scala @@ -62,7 +62,7 @@ object PlainWriter { full.getUuid, full.getInputModel, full.getvMag.getValue.doubleValue(), - full.getvAng.getValue.doubleValue() + full.getvAng.getValue.doubleValue(), ) } @@ -72,7 +72,7 @@ object PlainWriter { ZonedDateTime.parse(plain.time, timeFormatter), plain.inputModel, Quantities.getQuantity(plain.vMag, PowerSystemUnits.PU), - Quantities.getQuantity(plain.vAng, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(plain.vAng, PowerSystemUnits.DEGREE_GEOM), ) } } diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala index dea2b50642..b38e3c252d 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala @@ -16,7 +16,7 @@ import io.confluent.kafka.serializers.AbstractKafkaSchemaSerDeConfig.SCHEMA_REGI import org.apache.kafka.clients.producer.{ KafkaProducer, ProducerConfig, - ProducerRecord + ProducerRecord, } import org.apache.kafka.common.serialization.{Serdes, Serializer} import org.slf4j.Logger @@ -36,13 +36,13 @@ import scala.jdk.CollectionConverters._ final case class RuntimeEventKafkaSink( producer: KafkaProducer[String, SimonaEndMessage], simRunId: UUID, - topic: String + topic: String, ) extends RuntimeEventSink { override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger + log: Logger, ): Unit = { (runtimeEvent match { case Done(_, _, errorInSim) => @@ -83,7 +83,7 @@ object RuntimeEventKafkaSink { props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, config.bootstrapServers) props.put( ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, - true + true, ) // exactly once delivery implicit val recordFormat: RecordFormat[SimonaEndMessage] = @@ -95,23 +95,23 @@ object RuntimeEventKafkaSink { valueSerializer.configure( Map(SCHEMA_REGISTRY_URL_CONFIG -> config.schemaRegistryUrl).asJava, - false + false, ) RuntimeEventKafkaSink( new KafkaProducer[String, SimonaEndMessage]( props, keySerializer, - valueSerializer + valueSerializer, ), simRunId, - config.topic + config.topic, ) } final case class SimonaEndMessage( simRunId: UUID, failedPowerFlows: Int, - error: Boolean + error: Boolean, ) } diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala index 833b5907dd..6117ebccb9 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala @@ -26,7 +26,7 @@ final case class RuntimeEventLogSink( override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger + log: Logger, ): Unit = runtimeEvent match { case Initializing => diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala index dad7a65686..202f13f0d9 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala @@ -21,7 +21,7 @@ final case class RuntimeEventQueueSink(queue: BlockingQueue[RuntimeEvent]) override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger + log: Logger, ): Unit = queue.put(runtimeEvent) diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala index 496a2166e3..4a526788be 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala @@ -28,7 +28,7 @@ trait RuntimeEventSink { def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger + log: Logger, ): Unit /** Contains all cleanup operations before closing this sink. Should be diff --git a/src/main/scala/edu/ie3/simona/logging/SimonaFSMActorLogging.scala b/src/main/scala/edu/ie3/simona/logging/SimonaFSMActorLogging.scala index cfc618bc85..9a4b58b069 100644 --- a/src/main/scala/edu/ie3/simona/logging/SimonaFSMActorLogging.scala +++ b/src/main/scala/edu/ie3/simona/logging/SimonaFSMActorLogging.scala @@ -17,7 +17,7 @@ trait SimonaFSMActorLogging extends ActorLogging with SimonaLogging { context.system, () => stateName, this, - actorName + actorName, ) } diff --git a/src/main/scala/edu/ie3/simona/logging/SimonaLogging.scala b/src/main/scala/edu/ie3/simona/logging/SimonaLogging.scala index 5cb449ab3d..933eed80a7 100644 --- a/src/main/scala/edu/ie3/simona/logging/SimonaLogging.scala +++ b/src/main/scala/edu/ie3/simona/logging/SimonaLogging.scala @@ -11,7 +11,7 @@ import org.apache.pekko.event.{ LogSource, LoggingAdapter, LoggingBus, - LoggingFilter + LoggingFilter, } import edu.ie3.simona.actor.SimonaActorNaming @@ -33,7 +33,7 @@ object SimonaLogging { system: ActorSystem, state: () => S, logSource: T, - agentName: String + agentName: String, ): LoggingAdapter = { val (str, clazz) = LogSource(logSource, system) SimonaBusLogging( @@ -41,14 +41,14 @@ object SimonaLogging { str, clazz, logFilter(system), - () => fsmPrefix(agentName, state) + () => fsmPrefix(agentName, state), ) } private[logging] def createAdapter[T: LogSource]( system: ActorSystem, logSource: T, - agentName: String + agentName: String, ): LoggingAdapter = { val (str, clazz) = LogSource(logSource, system) SimonaBusLogging( @@ -56,7 +56,7 @@ object SimonaLogging { str, clazz, logFilter(system), - () => actorPrefix(agentName) + () => actorPrefix(agentName), ) } @@ -79,7 +79,7 @@ object SimonaLogging { logSource: String, logClass: Class[_], loggingFilter: LoggingFilter, - prefix: () => String + prefix: () => String, ) extends LoggingAdapter { import org.apache.pekko.event.Logging._ diff --git a/src/main/scala/edu/ie3/simona/logging/logback/LogbackConfiguration.scala b/src/main/scala/edu/ie3/simona/logging/logback/LogbackConfiguration.scala index 8aa16d5174..3d236a1f41 100644 --- a/src/main/scala/edu/ie3/simona/logging/logback/LogbackConfiguration.scala +++ b/src/main/scala/edu/ie3/simona/logging/logback/LogbackConfiguration.scala @@ -39,7 +39,7 @@ object LogbackConfiguration extends LazyLogging { log, "simona-default", fileLoggerFilterList, - loggerContext + loggerContext, ) ) @@ -61,7 +61,7 @@ object LogbackConfiguration extends LazyLogging { logPath: String, appenderName: String, maybeFilterList: Option[Seq[Filter[ILoggingEvent]]], - loggerContext: LoggerContext + loggerContext: LoggerContext, ): FileAppender[ILoggingEvent] = { val layoutEncoder = new PatternLayoutEncoder diff --git a/src/main/scala/edu/ie3/simona/main/RunSimona.scala b/src/main/scala/edu/ie3/simona/main/RunSimona.scala index 449a16df25..df011e6614 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimona.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimona.scala @@ -68,7 +68,7 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging { "\"Assimiliert das!\" - Worf (in Star Trek: Der erste Kontakt)", "\"Lebe lang und erfolgreich.\" - Gruppe von Vulkanier (in Star Trek: Der erste Kontakt)", "\"Ich bin der Anfang, das Ende, die Eine, die Viele ist. Ich bin die Borg.\" - Borg-Königin (in Star Trek: Der erste Kontakt)", - "\"A horse! A horse! My kingdom for a horse!\" - King Richard III (in Shakespeare's Richard III, 1594)" + "\"A horse! A horse! My kingdom for a horse!\" - King Richard III (in Shakespeare's Richard III, 1594)", ) val rand = new Random diff --git a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala index 5a8bee6d2e..1fe37611a5 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.sim.SimMessage.{ InitSim, SimulationFailure, SimulationSuccessful, - StartSimulation + StartSimulation, } import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.sim.setup.SimonaStandaloneSetup @@ -46,7 +46,7 @@ object RunSimonaStandalone extends RunSimona[SimonaStandaloneSetup] { SimonaStandaloneSetup( parsedConfig, SimonaStandaloneSetup.buildResultFileHierarchy(parsedConfig), - mainArgs = arguments.mainArgs + mainArgs = arguments.mainArgs, ) ) } diff --git a/src/main/scala/edu/ie3/simona/model/SystemComponent.scala b/src/main/scala/edu/ie3/simona/model/SystemComponent.scala index a81c235bf9..623e5a58c3 100644 --- a/src/main/scala/edu/ie3/simona/model/SystemComponent.scala +++ b/src/main/scala/edu/ie3/simona/model/SystemComponent.scala @@ -13,7 +13,7 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.OperationTime import edu.ie3.simona.exceptions.{ InvalidActionRequestException, - InvalidParameterException + InvalidParameterException, } import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.scala.OperationInterval @@ -35,7 +35,7 @@ import scala.util.{Failure, Success, Try} abstract class SystemComponent( uuid: UUID, id: String, - operationInterval: OperationInterval + operationInterval: OperationInterval, ) extends LazyLogging { private val elementType: String = this.getClass.getSimpleName @@ -107,7 +107,7 @@ case object SystemComponent { def determineOperationInterval( startDate: ZonedDateTime, endDate: ZonedDateTime, - operationTime: OperationTime + operationTime: OperationTime, ): OperationInterval = { val operationStartOpt = operationTime.getStartDate.toScala val operationEndOpt = operationTime.getEndDate.toScala diff --git a/src/main/scala/edu/ie3/simona/model/em/EmTools.scala b/src/main/scala/edu/ie3/simona/model/em/EmTools.scala index 1eecffa22d..8a10b9c335 100644 --- a/src/main/scala/edu/ie3/simona/model/em/EmTools.scala +++ b/src/main/scala/edu/ie3/simona/model/em/EmTools.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ IssueFlexControl, IssueNoControl, IssuePowerControl, - ProvideFlexOptions + ProvideFlexOptions, } import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import squants.Power @@ -32,7 +32,7 @@ object EmTools { */ def determineFlexPower( flexOptionsMsg: ProvideFlexOptions, - flexCtrl: IssueFlexControl + flexCtrl: IssueFlexControl, ): Power = flexOptionsMsg match { case flexOptions: ProvideMinMaxFlexOptions => @@ -64,7 +64,7 @@ object EmTools { */ def checkSetPower( flexOptions: ProvideMinMaxFlexOptions, - setPower: Power + setPower: Power, ): Unit = { if (setPower < flexOptions.min) throw new CriticalFailureException( diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index fd1ea11df2..27a3f556ea 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -17,7 +17,7 @@ import edu.ie3.simona.model.grid.GridModel.GridComponents import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, - PowerFlowCaseC + PowerFlowCaseC, } import edu.ie3.simona.util.CollectionUtils import org.jgrapht.Graph @@ -36,7 +36,7 @@ import scala.jdk.CollectionConverters._ final case class GridModel( subnetNo: Int, mainRefSystem: RefSystem, - gridComponents: GridComponents + gridComponents: GridComponents, ) { // init nodeUuidToIndexMap @@ -50,7 +50,7 @@ final case class GridModel( nodeModel.uuid, throw new InvalidGridException( s"Requested slack node with uuid ${nodeModel.uuid} is not part of nodeToIndexMap!" - ) + ), ) ) .toVector @@ -64,7 +64,7 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, ): GridModel = { buildAndValidate(subGridContainer, refSystem, startDate, endDate) } @@ -77,7 +77,7 @@ case object GridModel { lines: Set[LineModel], transformers: Set[TransformerModel], transformers3w: Set[Transformer3wModel], - switches: Set[SwitchModel] + switches: Set[SwitchModel], ) /** Checks the availability of node calculation models, that are connected by @@ -93,7 +93,7 @@ case object GridModel { */ private def getConnectedNodes( connector: ConnectorInput, - nodes: Seq[NodeModel] + nodes: Seq[NodeModel], ): (NodeModel, NodeModel) = { val nodeAOpt: Option[NodeModel] = nodes.find(_.uuid.equals(connector.getNodeA.getUuid)) @@ -131,7 +131,7 @@ case object GridModel { */ private def getConnectedNodes( transformerInput: Transformer3WInput, - nodes: Seq[NodeModel] + nodes: Seq[NodeModel], ): (NodeModel, NodeModel, NodeModel) = { val (nodeA, nodeB) = getConnectedNodes(transformerInput.asInstanceOf[ConnectorInput], nodes) @@ -165,7 +165,7 @@ case object GridModel { def composeAdmittanceMatrix( nodeUuidToIndexMap: Map[UUID, Int], - gridComponents: GridComponents + gridComponents: GridComponents, ): DenseMatrix[Complex] = { val _returnAdmittanceMatrixIfValid @@ -176,7 +176,7 @@ case object GridModel { { entry: Complex => !entry.imag.isNaN & !entry.real.isNaN & entry.imag.isFinite & entry.real.isFinite }, - admittanceMatrix + admittanceMatrix, ) ) throw new RuntimeException(s"Admittance matrix is illegal.") @@ -191,17 +191,17 @@ case object GridModel { val linesAdmittanceMatrix = buildAssetAdmittanceMatrix( nodeUuidToIndexMap, gridComponents.lines, - getLinesAdmittance + getLinesAdmittance, ) val trafoAdmittanceMatrix = buildAssetAdmittanceMatrix( nodeUuidToIndexMap, gridComponents.transformers, - getTransformerAdmittance + getTransformerAdmittance, ) val trafo3wAdmittanceMatrix = buildAssetAdmittanceMatrix( nodeUuidToIndexMap, gridComponents.transformers3w, - getTransformer3wAdmittance + getTransformer3wAdmittance, ) _returnAdmittanceMatrixIfValid( @@ -214,8 +214,8 @@ case object GridModel { assets: Set[C], getAssetAdmittance: ( Map[UUID, Int], - C - ) => (Int, Int, Complex, Complex, Complex) + C, + ) => (Int, Int, Complex, Complex, Complex), ): DenseMatrix[Complex] = { val matrixDimension = nodeUuidToIndexMap.values.toSeq.distinct.size @@ -237,20 +237,20 @@ case object GridModel { private def getLinesAdmittance( nodeUuidToIndexMap: Map[UUID, Int], - line: LineModel + line: LineModel, ): (Int, Int, Complex, Complex, Complex) = { val (i: Int, j: Int) = ( nodeUuidToIndexMap.getOrElse( line.nodeAUuid, - throwNodeNotFoundException(line.nodeAUuid) + throwNodeNotFoundException(line.nodeAUuid), ), nodeUuidToIndexMap .getOrElse( line.nodeBUuid, - throwNodeNotFoundException(line.nodeBUuid) - ) + throwNodeNotFoundException(line.nodeBUuid), + ), ) // yaa == ybb => we use yaa only @@ -261,25 +261,25 @@ case object GridModel { private def getTransformerAdmittance( nodeUuidToIndexMap: Map[UUID, Int], - trafo: TransformerModel + trafo: TransformerModel, ): (Int, Int, Complex, Complex, Complex) = { val (i: Int, j: Int) = ( nodeUuidToIndexMap.getOrElse( trafo.hvNodeUuid, - throwNodeNotFoundException(trafo.hvNodeUuid) + throwNodeNotFoundException(trafo.hvNodeUuid), ), nodeUuidToIndexMap.getOrElse( trafo.lvNodeUuid, - throwNodeNotFoundException(trafo.lvNodeUuid) - ) + throwNodeNotFoundException(trafo.lvNodeUuid), + ), ) val (yab, yaa, ybb) = ( TransformerModel.yij(trafo), TransformerModel.y0(trafo, ConnectorPort.A), - TransformerModel.y0(trafo, ConnectorPort.B) + TransformerModel.y0(trafo, ConnectorPort.B), ) (i, j, yab, yaa, ybb) @@ -287,7 +287,7 @@ case object GridModel { private def getTransformer3wAdmittance( nodeUuidToIndexMap: Map[UUID, Int], - trafo3w: Transformer3wModel + trafo3w: Transformer3wModel, ): (Int, Int, Complex, Complex, Complex) = { // start with power flow case specific parameters @@ -298,7 +298,7 @@ case object GridModel { trafo3w.hvNodeUuid, trafo3w.nodeInternalUuid, Transformer3wModel - .y0(trafo3w, Transformer3wModel.Transformer3wPort.INTERNAL) + .y0(trafo3w, Transformer3wModel.Transformer3wPort.INTERNAL), ) case PowerFlowCaseB => @@ -313,7 +313,7 @@ case object GridModel { nodeUuidToIndexMap .getOrElse(nodeAUuid, throwNodeNotFoundException(nodeAUuid)), nodeUuidToIndexMap - .getOrElse(nodeBUuid, throwNodeNotFoundException(nodeBUuid)) + .getOrElse(nodeBUuid, throwNodeNotFoundException(nodeBUuid)), ) // these parameters are the same for all cases @@ -450,7 +450,7 @@ case object GridModel { subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, ): GridModel = { // build @@ -479,7 +479,7 @@ case object GridModel { transformer2wInput, refSystem, startDate, - endDate + endDate, ) } else { throw new InvalidGridException( @@ -498,7 +498,7 @@ case object GridModel { refSystem, subGridContainer.getSubnet, startDate, - endDate + endDate, ) }.toSet @@ -531,7 +531,7 @@ case object GridModel { lines, transformers, transformer3ws, - switches + switches, ) val gridModel = @@ -574,7 +574,7 @@ case object GridModel { case switchModel: SwitchModel => map ++ Map( switchModel.nodeAUuid -> componentId, - switchModel.nodeBUuid -> componentId + switchModel.nodeBUuid -> componentId, ) case nodeModel: NodeModel => diff --git a/src/main/scala/edu/ie3/simona/model/grid/LineModel.scala b/src/main/scala/edu/ie3/simona/model/grid/LineModel.scala index 8ca2b2f0a9..60a2621630 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/LineModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/LineModel.scala @@ -63,11 +63,11 @@ final case class LineModel( protected val r: squants.Dimensionless, protected val x: squants.Dimensionless, protected val g: squants.Dimensionless, - protected val b: squants.Dimensionless + protected val b: squants.Dimensionless, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) with PiEquivalentCircuit { @@ -111,7 +111,7 @@ case object LineModel extends LazyLogging { lineInput: LineInput, refSystem: RefSystem, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): LineModel = { // validate the input model first validateInputModel(lineInput) @@ -121,7 +121,7 @@ case object LineModel extends LazyLogging { lineInput, refSystem, simulationStartDate, - simulationEndDate + simulationEndDate, ) } @@ -143,7 +143,7 @@ case object LineModel extends LazyLogging { lineInput: LineInput, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, ): LineModel = { val lineType = lineInput.getType @@ -183,14 +183,14 @@ case object LineModel extends LazyLogging { .getValue .doubleValue() ) - ) + ), ) val operationInterval = SystemComponent.determineOperationInterval( startDate, endDate, - lineInput.getOperationTime + lineInput.getOperationTime, ) val lineModel = new LineModel( @@ -206,7 +206,7 @@ case object LineModel extends LazyLogging { r, x, g, - b + b, ) // if the line input model is in operation, enable the model @@ -321,7 +321,7 @@ case object LineModel extends LazyLogging { def y0(lineModel: LineModel): Complex = { new Complex( lineModel.g0().value.doubleValue(), - lineModel.b0().value.doubleValue() + lineModel.b0().value.doubleValue(), ) } @@ -335,7 +335,7 @@ case object LineModel extends LazyLogging { */ def yij(lineModel: LineModel): Complex = new Complex( lineModel.gij().value.doubleValue(), - lineModel.bij().value.doubleValue() + lineModel.bij().value.doubleValue(), ) /** Calculates the utilisation of a given line model @@ -352,12 +352,12 @@ case object LineModel extends LazyLogging { def utilisation( lineModel: LineModel, iNodeA: squants.electro.ElectricCurrent, - iNodeB: squants.electro.ElectricCurrent + iNodeB: squants.electro.ElectricCurrent, ): squants.Dimensionless = { Each( Math.max( iNodeA.toAmperes, - iNodeB.toAmperes + iNodeB.toAmperes, ) / lineModel.iNom.toAmperes * 100 / lineModel.amount ) } diff --git a/src/main/scala/edu/ie3/simona/model/grid/NodeModel.scala b/src/main/scala/edu/ie3/simona/model/grid/NodeModel.scala index 67acac7d8b..506ea804a1 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/NodeModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/NodeModel.scala @@ -39,18 +39,18 @@ final case class NodeModel( operationInterval: OperationInterval, isSlack: Boolean, vTarget: squants.Dimensionless, - voltLvl: VoltageLevel + voltLvl: VoltageLevel, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) case object NodeModel { def apply( nodeInput: NodeInput, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): NodeModel = { // validate the input model @@ -60,7 +60,7 @@ case object NodeModel { SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - nodeInput.getOperationTime + nodeInput.getOperationTime, ) val nodeModel = new NodeModel( @@ -69,7 +69,7 @@ case object NodeModel { operationInterval, nodeInput.isSlack, Each(nodeInput.getvTarget.to(PowerSystemUnits.PU).getValue.doubleValue()), - nodeInput.getVoltLvl + nodeInput.getVoltLvl, ) /* Checks, if the participant is in operation right from the start */ diff --git a/src/main/scala/edu/ie3/simona/model/grid/PiEquivalentCircuit.scala b/src/main/scala/edu/ie3/simona/model/grid/PiEquivalentCircuit.scala index d1d85d7177..0583d37d74 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/PiEquivalentCircuit.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/PiEquivalentCircuit.scala @@ -125,7 +125,7 @@ trait PiEquivalentCircuit extends LazyLogging { r, x, g, - b + b, ) } diff --git a/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala b/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala index 53ee866930..e6826546d3 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/RefSystem.scala @@ -24,7 +24,7 @@ final case class RefSystem private ( nominalVoltage: squants.electro.ElectricPotential, nominalCurrent: squants.electro.ElectricCurrent, nominalPower: squants.Power, - nominalImpedance: squants.electro.ElectricalResistance + nominalImpedance: squants.electro.ElectricalResistance, ) { /** Calculates the referenced resistance r (real part of impedance z) of a @@ -146,11 +146,11 @@ final case class RefSystem private ( def vInSi(vInPu: Complex): ( squants.electro.ElectricPotential, - squants.electro.ElectricPotential + squants.electro.ElectricPotential, ) = ( vInSi(Each(vInPu.real)), - vInSi(Each(vInPu.imag)) + vInSi(Each(vInPu.imag)), ) /** Converts a provided voltage value from physical SI value into p.u. value @@ -170,7 +170,7 @@ case object RefSystem { def apply( nominalPower: squants.Power, - nominalVoltage: squants.electro.ElectricPotential + nominalVoltage: squants.electro.ElectricPotential, ): RefSystem = { val nominalCurrent: squants.electro.ElectricCurrent = @@ -183,7 +183,7 @@ case object RefSystem { nominalVoltage, nominalCurrent, nominalPower, - nominalImpedance + nominalImpedance, ) } @@ -227,7 +227,7 @@ case object RefSystem { def transferImpedance( impedance: squants.Dimensionless, from: RefSystem, - to: RefSystem + to: RefSystem, ): squants.Dimensionless = { val ratio = from.nominalImpedance.toOhms / to.nominalImpedance.toOhms Each(impedance.toEach * ratio) @@ -248,7 +248,7 @@ case object RefSystem { def transferAdmittance( admittance: squants.Dimensionless, from: RefSystem, - to: RefSystem + to: RefSystem, ): squants.Dimensionless = { val ratio = to.nominalImpedance.toOhms / from.nominalImpedance.toOhms diff --git a/src/main/scala/edu/ie3/simona/model/grid/SwitchModel.scala b/src/main/scala/edu/ie3/simona/model/grid/SwitchModel.scala index 49d1d73402..5a5a457a5f 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/SwitchModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/SwitchModel.scala @@ -35,11 +35,11 @@ final case class SwitchModel( id: String, operationInterval: OperationInterval, nodeAUuid: UUID, - nodeBUuid: UUID + nodeBUuid: UUID, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) { private var _isClosed = true @@ -86,7 +86,7 @@ case object SwitchModel { def apply( switchInput: SwitchInput, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): SwitchModel = { // validate the input model @@ -96,7 +96,7 @@ case object SwitchModel { SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - switchInput.getOperationTime + switchInput.getOperationTime, ) val switchModel = new SwitchModel( @@ -104,7 +104,7 @@ case object SwitchModel { switchInput.getId, operationInterval, switchInput.getNodeA.getUuid, - switchInput.getNodeB.getUuid + switchInput.getNodeB.getUuid, ) if (!switchInput.isClosed) switchModel.open() diff --git a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala index 25e1ffeca4..8f61c2a897 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wModel.scala @@ -16,13 +16,13 @@ import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.datamodel.models.input.connector.`type`.Transformer3WTypeInput import edu.ie3.simona.exceptions.{ InvalidActionRequestException, - InvalidParameterException + InvalidParameterException, } import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, - PowerFlowCaseC + PowerFlowCaseC, } import edu.ie3.simona.util.SimonaConstants import edu.ie3.util.quantities.PowerSystemUnits._ @@ -94,11 +94,11 @@ final case class Transformer3wModel( protected val r: squants.Dimensionless, protected val x: squants.Dimensionless, protected val g: squants.Dimensionless, - protected val b: squants.Dimensionless + protected val b: squants.Dimensionless, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) with PiEquivalentCircuit with TransformerTapping { @@ -171,7 +171,7 @@ case object Transformer3wModel extends LazyLogging { refSystem: RefSystem, subnetNo: Int, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): Transformer3wModel = { // validate the input model first validateInputModel(transformer3wInput) @@ -182,7 +182,7 @@ case object Transformer3wModel extends LazyLogging { refSystem, subnetNo, simulationStartDate, - simulationEndDate + simulationEndDate, ) } @@ -213,7 +213,7 @@ case object Transformer3wModel extends LazyLogging { gridRefSystem: RefSystem, subnetNo: Int, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, ): Transformer3wModel = { // build the model val trafo3wType = transformer3wInput.getType @@ -238,7 +238,7 @@ case object Transformer3wModel extends LazyLogging { trafo3wType.getTapMax, trafo3wType.getTapMin, trafo3wType.getTapNeutr, - transformer3wInput.isAutoTap + transformer3wInput.isAutoTap, ) val voltRatioNominal = powerFlowCase match { @@ -262,7 +262,7 @@ case object Transformer3wModel extends LazyLogging { SystemComponent.determineOperationInterval( startDate, endDate, - transformer3wInput.getOperationTime + transformer3wInput.getOperationTime, ) val transformer3wModel = new Transformer3wModel( @@ -280,7 +280,7 @@ case object Transformer3wModel extends LazyLogging { r, x, g, - b + b, ) // if the transformer3w input model is in operation, enable the model @@ -314,12 +314,12 @@ case object Transformer3wModel extends LazyLogging { private def rxgbInPu( transformerType: Transformer3WTypeInput, refSystem: RefSystem, - powerFlowCase: Transformer3wPowerFlowCase + powerFlowCase: Transformer3wPowerFlowCase, ): ( squants.Dimensionless, squants.Dimensionless, squants.Dimensionless, - squants.Dimensionless + squants.Dimensionless, ) = { val transformerRefSystem = RefSystem( @@ -328,7 +328,7 @@ case object Transformer3wModel extends LazyLogging { ), Kilovolts( transformerType.getvRatedA.to(KILOVOLT).getValue.doubleValue() - ) + ), ) /* Get the physical equivalent circuit diagram parameters from type. They come with reference to the highest @@ -339,7 +339,7 @@ case object Transformer3wModel extends LazyLogging { transformerType.getrScA, transformerType.getxScA, transformerType.getgM, - transformerType.getbM + transformerType.getbM, ) case PowerFlowCaseB => val nominalRatio = transformerType @@ -353,7 +353,7 @@ case object Transformer3wModel extends LazyLogging { transformerType.getrScB.divide(pow(nominalRatio, 2)), transformerType.getxScB.divide(pow(nominalRatio, 2)), Quantities.getQuantity(0d, StandardUnits.CONDUCTANCE), - Quantities.getQuantity(0d, StandardUnits.SUSCEPTANCE) + Quantities.getQuantity(0d, StandardUnits.SUSCEPTANCE), ) case PowerFlowCaseC => val nominalRatio = transformerType @@ -367,7 +367,7 @@ case object Transformer3wModel extends LazyLogging { transformerType.getrScC.divide(pow(nominalRatio, 2)), transformerType.getxScC.divide(pow(nominalRatio, 2)), Quantities.getQuantity(0d, StandardUnits.CONDUCTANCE), - Quantities.getQuantity(0d, StandardUnits.SUSCEPTANCE) + Quantities.getQuantity(0d, StandardUnits.SUSCEPTANCE), ) } @@ -380,7 +380,7 @@ case object Transformer3wModel extends LazyLogging { /* g */ refSystem.gInPu(Siemens(gTrafo.to(SIEMENS).getValue.doubleValue())), /* b */ - refSystem.bInPu(Siemens(bTrafo.to(SIEMENS).getValue.doubleValue())) + refSystem.bInPu(Siemens(bTrafo.to(SIEMENS).getValue.doubleValue())), ) } @@ -400,17 +400,17 @@ case object Transformer3wModel extends LazyLogging { val (vNodeAVal, vTypeAVal) = ( transformer3wInput.getNodeA.getVoltLvl.getNominalVoltage.getValue.doubleValue, - trafo3wType.getvRatedA.getValue.doubleValue + trafo3wType.getvRatedA.getValue.doubleValue, ) val (vNodeBVal, vTypeBVal) = ( transformer3wInput.getNodeB.getVoltLvl.getNominalVoltage.getValue.doubleValue, - trafo3wType.getvRatedB.getValue.doubleValue + trafo3wType.getvRatedB.getValue.doubleValue, ) val (vNodeCVal, vTypeCVal) = ( transformer3wInput.getNodeC.getVoltLvl.getNominalVoltage.getValue.doubleValue, - trafo3wType.getvRatedC.getValue.doubleValue + trafo3wType.getvRatedC.getValue.doubleValue, ) val nomVoltDevA = vNodeAVal - vTypeAVal @@ -435,7 +435,7 @@ case object Transformer3wModel extends LazyLogging { // check for wrong positioning by comparing node{A,B,C} voltage and transformer type v{A,B,C} val transformerWrongPositionExceptionString: ( Quantity[ElectricPotential], - Quantity[ElectricPotential] + Quantity[ElectricPotential], ) => String = { (vRatedNodeX, typeVNodeX) => s"The rated voltage of node A is $vRatedNodeX, " + s"but the winding A is only rated for $typeVNodeX. Is the transformer connected correctly?" @@ -444,21 +444,21 @@ case object Transformer3wModel extends LazyLogging { throw new InvalidGridException( transformerWrongPositionExceptionString( transformer3wInput.getNodeA.getVoltLvl.getNominalVoltage, - trafo3wType.getvRatedA + trafo3wType.getvRatedA, ) ) if (vNodeBVal < vTypeBVal) throw new InvalidGridException( transformerWrongPositionExceptionString( transformer3wInput.getNodeB.getVoltLvl.getNominalVoltage, - trafo3wType.getvRatedB + trafo3wType.getvRatedB, ) ) if (vNodeCVal < vTypeCVal) throw new InvalidGridException( transformerWrongPositionExceptionString( transformer3wInput.getNodeC.getVoltLvl.getNominalVoltage, - trafo3wType.getvRatedC + trafo3wType.getvRatedC, ) ) @@ -481,7 +481,7 @@ case object Transformer3wModel extends LazyLogging { trafo3wType.getsRatedA(), trafo3wType.getsRatedB(), trafo3wType.getsRatedC(), - trafo3wType.getsRatedB().add(trafo3wType.getsRatedC()) + trafo3wType.getsRatedB().add(trafo3wType.getsRatedC()), ) } } @@ -526,7 +526,7 @@ case object Transformer3wModel extends LazyLogging { */ def y0( transformer3wModel: Transformer3wModel, - port: Transformer3wPort.Value + port: Transformer3wPort.Value, ): Complex = { val amount = transformer3wModel.amount transformer3wModel.powerFlowCase match { @@ -537,10 +537,10 @@ case object Transformer3wModel extends LazyLogging { val bii = transformer3wModel.b0().value.doubleValue() amount * ((1 - 1 / transformer3wModel.tapRatio) * Complex( gij, - bij + bij, ) + Complex( gii, - bii + bii, )) case _ => Complex.zero } diff --git a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wPowerFlowCase.scala b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wPowerFlowCase.scala index 0b3e88252f..cad400df8f 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/Transformer3wPowerFlowCase.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/Transformer3wPowerFlowCase.scala @@ -34,7 +34,7 @@ object Transformer3wPowerFlowCase { def apply( trafo3wInput: Transformer3WInput, - subnetNo: Int + subnetNo: Int, ): Transformer3wPowerFlowCase = { if (trafo3wInput.getNodeA.getSubnet == subnetNo) PowerFlowCaseA diff --git a/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala b/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala index a34e2f3abc..7a63cbf489 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/TransformerModel.scala @@ -11,7 +11,7 @@ import breeze.numerics.pow import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, - Transformer2WInput + Transformer2WInput, } import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.util.SimonaConstants @@ -77,11 +77,11 @@ final case class TransformerModel( protected val r: squants.Dimensionless, protected val x: squants.Dimensionless, protected val g: squants.Dimensionless, - protected val b: squants.Dimensionless + protected val b: squants.Dimensionless, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) with PiEquivalentCircuit with TransformerTapping { @@ -95,7 +95,7 @@ case object TransformerModel { transformerInput: Transformer2WInput, refSystem: RefSystem, startDate: ZonedDateTime, - endDate: ZonedDateTime + endDate: ZonedDateTime, ): TransformerModel = { // validate the input model first @@ -125,7 +125,7 @@ case object TransformerModel { transformerInput: Transformer2WInput, gridRefSystem: RefSystem, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): TransformerModel = { // get referenced electric values @@ -167,7 +167,7 @@ case object TransformerModel { .multiply(squaredNominalVoltRatio) .getValue .doubleValue() - ) + ), ) /* Transfer the dimensionless parameters into the grid reference system */ @@ -175,7 +175,7 @@ case object TransformerModel { gridRefSystem.rInPu(rTrafo), gridRefSystem.xInPu(xTrafo), gridRefSystem.gInPu(gTrafo), - gridRefSystem.bInPu(bTrafo) + gridRefSystem.bInPu(bTrafo), ) // iNomHv, iNomLv @@ -201,7 +201,7 @@ case object TransformerModel { Kilovolts( trafoType.getvRatedB.to(KILOVOLT).getValue.doubleValue() ) - ) + ), ) // get the element port, where the transformer tap is located @@ -216,14 +216,14 @@ case object TransformerModel { trafoType.getTapMin, trafoType.getTapNeutr, transformerInput.isAutoTap, - tapSide + tapSide, ) val operationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - transformerInput.getOperationTime + transformerInput.getOperationTime, ) val transformerModel = new TransformerModel( @@ -240,7 +240,7 @@ case object TransformerModel { r, x, g, - b + b, ) // if the transformer input model is in operation, enable the model @@ -268,7 +268,7 @@ case object TransformerModel { */ def validateInputModel( transformerInput: Transformer2WInput, - refSystem: RefSystem + refSystem: RefSystem, ): Unit = { val trafoType = transformerInput.getType @@ -371,7 +371,7 @@ case object TransformerModel { new Complex( transformerModel.gij().value.doubleValue(), - transformerModel.bij().value.doubleValue() + transformerModel.bij().value.doubleValue(), ) * amount / tapRatio } @@ -390,14 +390,14 @@ case object TransformerModel { def utilisation( transformerModel: TransformerModel, iNodeHv: Quantity[ElectricCurrent], - iNodeLv: Quantity[ElectricCurrent] + iNodeLv: Quantity[ElectricCurrent], ): squants.Dimensionless = { Each( Math.max( iNodeHv.getValue.doubleValue() / transformerModel.iNomHv.value .doubleValue(), iNodeLv.getValue.doubleValue() / transformerModel.iNomLv.value - .doubleValue() + .doubleValue(), ) * 100 ) } diff --git a/src/main/scala/edu/ie3/simona/model/grid/TransformerTapping.scala b/src/main/scala/edu/ie3/simona/model/grid/TransformerTapping.scala index 5337e0c829..809e7c5f8f 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/TransformerTapping.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/TransformerTapping.scala @@ -72,7 +72,7 @@ trait TransformerTapping { */ def computeDeltaTap( vChangeRequest: Quantity[Dimensionless], - deadBand: Quantity[Dimensionless] = Quantities.getQuantity(0.75, PU) + deadBand: Quantity[Dimensionless] = Quantities.getQuantity(0.75, PU), ): Int = transformerTappingModel.computeDeltaTap(vChangeRequest, deadBand) diff --git a/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala b/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala index a04b3548e2..602259cec2 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/TransformerTappingModel.scala @@ -43,7 +43,7 @@ final case class TransformerTappingModel( tapMin: Int, tapNeutr: Int, autoTap: Boolean, - tapSide: ConnectorPort = ConnectorPort.A + tapSide: ConnectorPort = ConnectorPort.A, ) extends LazyLogging { private val deltaVval = deltaV.to(PU).getValue.doubleValue() @@ -130,7 +130,7 @@ final case class TransformerTappingModel( */ def computeDeltaTap( vChangeRequest: Quantity[Dimensionless], - deadBandPerTap: Quantity[Dimensionless] = Quantities.getQuantity(0.75, PU) + deadBandPerTap: Quantity[Dimensionless] = Quantities.getQuantity(0.75, PU), ): Int = { /* Determine the tap change, that has to be done in any case, as well as the remainder to fully * fulfill the voltage change request */ @@ -169,7 +169,7 @@ case object TransformerTappingModel { tapMin: Int, tapNeutr: Int, autoTap: Boolean, - elementPort: ConnectorPort = ConnectorPort.A + elementPort: ConnectorPort = ConnectorPort.A, ): TransformerTappingModel = { val tapModel = new TransformerTappingModel( @@ -179,7 +179,7 @@ case object TransformerTappingModel { tapMin, tapNeutr, autoTap, - elementPort + elementPort, ) // update internal state variables diff --git a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala index 253518577e..205704bf41 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatParticipant.scala @@ -12,14 +12,14 @@ import squants.{Dimensionless, Power} trait ApparentPowerAndHeatParticipant[ CD <: CalcRelevantData, - MS <: ModelState + MS <: ModelState, ] { this: SystemParticipant[CD, ApparentPowerAndHeat, MS] => override def calculatePower( tick: Long, voltage: Dimensionless, modelState: MS, - data: CD + data: CD, ): ApparentPowerAndHeat = { val apparentPower = calculateApparentPower(tick, voltage, modelState, data) @@ -46,6 +46,6 @@ trait ApparentPowerAndHeatParticipant[ def calculateHeat( tick: Long, modelState: MS, - data: CD + data: CD, ): Power } diff --git a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala index 1819e2d2a0..d1d71a58ac 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ApparentPowerParticipant.scala @@ -15,7 +15,7 @@ trait ApparentPowerParticipant[CD <: CalcRelevantData, MS <: ModelState] { tick: Long, voltage: Dimensionless, modelState: MS, - data: CD + data: CD, ): ApparentPower = calculateApparentPower(tick, voltage, modelState, data) } diff --git a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala index c3a5e3a9ad..40b149bf95 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/BMModel.scala @@ -35,11 +35,11 @@ final case class BMModel( private val isCostControlled: Boolean, private val opex: Money, private val feedInTariff: EnergyPrice, - private val loadGradient: Double + private val loadGradient: Double, ) extends SystemParticipant[ BMCalcRelevantData, ApparentPower, - ConstantState.type + ConstantState.type, ]( uuid, id, @@ -47,7 +47,7 @@ final case class BMModel( scalingFactor, qControl, sRated, - cosPhi + cosPhi, ) with ApparentPowerParticipant[BMCalcRelevantData, ConstantState.type] { @@ -59,7 +59,7 @@ final case class BMModel( tick: Long, voltage: Dimensionless, modelState: ConstantState.type, - data: BMCalcRelevantData + data: BMCalcRelevantData, ): ApparentPower = { val result = super.calculatePower(tick, voltage, modelState, data) _lastPower = Some(result.p) @@ -76,7 +76,7 @@ final case class BMModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - data: BMCalcRelevantData + data: BMCalcRelevantData, ): Power = { // Calculate heat demand // val (k1, k2) = (calculateK1(data.date), calculateK2(data.date)) @@ -142,7 +142,7 @@ final case class BMModel( private def calculatePTh( temp: Temperature, k1: Double, - k2: Double + k2: Double, ): Power = { // linear regression: Heat-demand in relation to temperature (above 19.28°C: independent of temperature) val pTh = temp.toCelsiusScale match { @@ -187,7 +187,7 @@ final case class BMModel( */ private def calculateElOutput( usage: Double, - eff: Double + eff: Double, ): Power = { val currOpex = opex.divide(eff) val avgOpex = (currOpex + opex).divide(2) @@ -228,7 +228,7 @@ final case class BMModel( override def determineFlexOptions( data: BMCalcRelevantData, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = { val power = calculateActivePower(lastState, data) @@ -238,7 +238,7 @@ final case class BMModel( override def handleControlledPowerChange( data: BMCalcRelevantData, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } @@ -254,6 +254,6 @@ object BMModel { */ final case class BMCalcRelevantData( date: ZonedDateTime, - temperature: Temperature + temperature: Temperature, ) extends CalcRelevantData } diff --git a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala index 89349c4c91..302fa02229 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/ChpModel.scala @@ -56,7 +56,7 @@ final case class ChpModel( sRated: Power, cosPhiRated: Double, pThermal: Power, - storage: ThermalStorage with MutableStorage + storage: ThermalStorage with MutableStorage, ) extends SystemParticipant[ChpRelevantData, ApparentPower, ConstantState.type]( uuid, id, @@ -64,7 +64,7 @@ final case class ChpModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerParticipant[ChpRelevantData, ConstantState.type] { @@ -83,7 +83,7 @@ final case class ChpModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - chpData: ChpRelevantData + chpData: ChpRelevantData, ): Power = chpData.chpState.activePower @@ -149,7 +149,7 @@ final case class ChpModel( isRunning = false, chpData.currentTimeTick, DefaultQuantities.zeroKW, - DefaultQuantities.zeroKWH + DefaultQuantities.zeroKWH, ) /** The demand cannot be covered, therefore this function sets storage level @@ -186,7 +186,7 @@ final case class ChpModel( isRunning = false, chpData.currentTimeTick, DefaultQuantities.zeroKW, - DefaultQuantities.zeroKWH + DefaultQuantities.zeroKWH, ) } @@ -226,7 +226,7 @@ final case class ChpModel( */ private def calculateStateRunningSurplus( chpData: ChpRelevantData, - surplus: Option[Energy] = None + surplus: Option[Energy] = None, ): ChpState = { surplus match { case Some(surplusEnergy) => @@ -234,14 +234,14 @@ final case class ChpModel( isRunning = false, chpData.currentTimeTick, pRated, - chpEnergy(chpData) - surplusEnergy + chpEnergy(chpData) - surplusEnergy, ) case None => ChpState( isRunning = true, chpData.currentTimeTick, pRated, - chpEnergy(chpData) + chpEnergy(chpData), ) } } @@ -255,7 +255,7 @@ final case class ChpModel( */ private def powerToEnergy( chpData: ChpRelevantData, - power: Power + power: Power, ): Energy = power * timeRunning(chpData) @@ -294,17 +294,17 @@ final case class ChpModel( override def determineFlexOptions( data: ChpRelevantData, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = ProvideMinMaxFlexOptions.noFlexOption( uuid, - calculateActivePower(lastState, data) + calculateActivePower(lastState, data), ) override def handleControlledPowerChange( data: ChpRelevantData, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) @@ -331,7 +331,7 @@ object ChpModel { isRunning: Boolean, lastTimeTick: Long, activePower: Power, - thermalEnergy: Energy + thermalEnergy: Energy, ) /** Main data required for simulation/calculation, containing a [[ChpState]], @@ -350,7 +350,7 @@ object ChpModel { final case class ChpRelevantData( chpState: ChpState, heatDemand: Energy, - currentTimeTick: Long + currentTimeTick: Long, ) extends CalcRelevantData /** Function to construct a new [[ChpModel]] based on a provided [[ChpInput]] @@ -376,12 +376,12 @@ object ChpModel { simulationEndDate: ZonedDateTime, qControl: QControl, scalingFactor: Double, - thermalStorage: ThermalStorage with MutableStorage + thermalStorage: ThermalStorage with MutableStorage, ): ChpModel = { val operationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - chpInput.getOperationTime + chpInput.getOperationTime, ) val model = new ChpModel( @@ -403,7 +403,7 @@ object ChpModel { .getValue .doubleValue ), - thermalStorage + thermalStorage, ) model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala index 4229ee5496..a348923bb5 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FixedFeedInModel.scala @@ -48,11 +48,11 @@ final case class FixedFeedInModel( override val scalingFactor: Double, qControl: QControl, sRated: Power, - cosPhiRated: Double + cosPhiRated: Double, ) extends SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ]( uuid, id, @@ -60,7 +60,7 @@ final case class FixedFeedInModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerParticipant[FixedRelevantData.type, ConstantState.type] { @@ -74,23 +74,23 @@ final case class FixedFeedInModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - data: FixedRelevantData.type = FixedRelevantData + data: FixedRelevantData.type = FixedRelevantData, ): Power = sRated * (-1) * cosPhiRated override def determineFlexOptions( data: FixedRelevantData.type, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = ProvideMinMaxFlexOptions.noFlexOption( uuid, - calculateActivePower(lastState, data) + calculateActivePower(lastState, data), ) override def handleControlledPowerChange( data: FixedRelevantData.type, lastState: ConstantState.type, - setPower: Power + setPower: Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } @@ -100,14 +100,14 @@ object FixedFeedInModel extends LazyLogging { inputModel: FixedFeedInInput, modelConfiguration: SimonaConfig.FixedFeedInRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): FixedFeedInModel = { /* Determine the operation interval */ val operationInterval: OperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.getOperationTime + inputModel.getOperationTime, ) // build the fixed feed in model @@ -123,7 +123,7 @@ object FixedFeedInModel extends LazyLogging { .getValue .doubleValue ), - inputModel.getCosPhiRated + inputModel.getCosPhiRated, ) model.enable() model diff --git a/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala b/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala index 5a4b7d0839..dda77c2f06 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/FlexChangeIndicator.scala @@ -8,5 +8,5 @@ package edu.ie3.simona.model.participant final case class FlexChangeIndicator( changesAtNextActivation: Boolean = false, - changesAtTick: Option[Long] = None + changesAtTick: Option[Long] = None, ) diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index bd4eedb911..ec2ad37b5e 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -58,11 +58,11 @@ final case class HpModel( sRated: Power, cosPhiRated: Double, pThermal: Power, - thermalGrid: ThermalGrid + thermalGrid: ThermalGrid, ) extends SystemParticipant[ HpRelevantData, ApparentPowerAndHeat, - HpState + HpState, ]( uuid, id, @@ -70,7 +70,7 @@ final case class HpModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerAndHeatParticipant[HpRelevantData, HpState] { @@ -92,7 +92,7 @@ final case class HpModel( */ override protected def calculateActivePower( modelState: HpState, - relevantData: HpRelevantData + relevantData: HpRelevantData, ): Power = modelState.activePower /** "Calculate" the heat output of the heat pump. The hp's state is already @@ -112,7 +112,7 @@ final case class HpModel( override def calculateHeat( tick: Long, modelState: HpState, - data: HpRelevantData + data: HpRelevantData, ): Power = modelState.qDot /** Given a [[HpRelevantData]] object and the current [[HpState]], this @@ -128,7 +128,7 @@ final case class HpModel( */ def determineState( state: HpState, - relevantData: HpRelevantData + relevantData: HpRelevantData, ): HpState = { val turnOn = operatesInNextState(state, relevantData) calcState(state, relevantData, turnOn) @@ -149,12 +149,12 @@ final case class HpModel( */ private def operatesInNextState( state: HpState, - relevantData: HpRelevantData + relevantData: HpRelevantData, ): Boolean = { val demand = thermalGrid.energyDemand( relevantData.currentTick, relevantData.ambientTemperature, - state.thermalGridState + state.thermalGridState, ) demand.hasRequiredDemand || (state.isRunning && demand.hasAdditionalDemand) } @@ -175,7 +175,7 @@ final case class HpModel( private def calcState( state: HpState, relevantData: HpRelevantData, - isRunning: Boolean + isRunning: Boolean, ): HpState = { val (newActivePower, newThermalPower) = if (isRunning) @@ -188,7 +188,7 @@ final case class HpModel( relevantData.currentTick, state.thermalGridState, state.ambientTemperature.getOrElse(relevantData.ambientTemperature), - newThermalPower + newThermalPower, ) HpState( @@ -198,13 +198,13 @@ final case class HpModel( newActivePower, newThermalPower, thermalGridState, - maybeThreshold + maybeThreshold, ) } override def determineFlexOptions( data: HpRelevantData, - lastState: HpState + lastState: HpState, ): ProvideFlexOptions = { /* Determine the operating state in the given tick */ val updatedState = determineState(lastState, data) @@ -213,7 +213,7 @@ final case class HpModel( val thermalEnergyDemand = thermalGrid.energyDemand( data.currentTick, data.ambientTemperature, - lastState.thermalGridState + lastState.thermalGridState, ) val canOperate = thermalEnergyDemand.hasRequiredDemand || thermalEnergyDemand.hasAdditionalDemand @@ -234,7 +234,7 @@ final case class HpModel( uuid, updatedState.activePower, lowerBoundary, - upperBoundary + upperBoundary, ) } @@ -258,7 +258,7 @@ final case class HpModel( override def handleControlledPowerChange( data: HpRelevantData, lastState: HpState, - setPower: Power + setPower: Power, ): (HpState, FlexChangeIndicator) = { /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ val turnOn = setPower > (sRated * cosPhiRated * 0.5) @@ -268,8 +268,8 @@ final case class HpModel( updatedState, FlexChangeIndicator( changesAtNextActivation = true, - updatedState.maybeThermalThreshold.map(_.tick) - ) + updatedState.maybeThermalThreshold.map(_.tick), + ), ) } } @@ -283,14 +283,14 @@ object HpModel { scaling: Double, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, - thermalGrid: ThermalGrid + thermalGrid: ThermalGrid, ): HpModel = { /* Determine the operation interval */ val operationInterval: OperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.getOperationTime + inputModel.getOperationTime, ) val qControl = QControl(inputModel.getqCharacteristics()) @@ -314,7 +314,7 @@ object HpModel { .getValue .doubleValue ), - thermalGrid + thermalGrid, ) model.enable() @@ -348,7 +348,7 @@ object HpModel { activePower: Power, qDot: Power, thermalGridState: ThermalGridState, - maybeThermalThreshold: Option[ThermalThreshold] + maybeThermalThreshold: Option[ThermalThreshold], ) extends ModelState /** Main data required for simulation/calculation, containing a [[HpState]] @@ -362,7 +362,7 @@ object HpModel { */ final case class HpRelevantData( currentTick: Long, - ambientTemperature: Temperature + ambientTemperature: Temperature, ) extends CalcRelevantData /** Internal method to construct a new [[HpModel]] based on a provided @@ -389,12 +389,12 @@ object HpModel { simulationEndDate: ZonedDateTime, qControl: QControl, scalingFactor: Double, - thermalGrid: ThermalGrid + thermalGrid: ThermalGrid, ): HpModel = { val operationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - hpInput.getOperationTime + hpInput.getOperationTime, ) val model = new HpModel( @@ -416,7 +416,7 @@ object HpModel { .getValue .doubleValue ), - thermalGrid + thermalGrid, ) model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala index 30fd1df579..3aca7332d9 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/PvModel.scala @@ -42,7 +42,7 @@ final case class PvModel private ( private val etaConv: Dimensionless, private val alphaE: Angle, private val gammaE: Angle, - private val moduleSurface: Area = SquareMeters(1d) + private val moduleSurface: Area = SquareMeters(1d), ) extends SystemParticipant[PvRelevantData, ApparentPower, ConstantState.type]( uuid, id, @@ -50,7 +50,7 @@ final case class PvModel private ( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerParticipant[PvRelevantData, ConstantState.type] { @@ -76,7 +76,7 @@ final case class PvModel private ( */ override protected def calculateActivePower( modelState: ConstantState.type, - data: PvRelevantData + data: PvRelevantData, ): Power = { // === Weather Base Data === // /* The pv model calculates the power in-feed based on the solar irradiance that is received over a specific @@ -114,7 +114,7 @@ final case class PvModel private ( delta, lat, gammaE, - alphaE + alphaE, ) // === Diffuse Radiation Parameters ===// @@ -130,7 +130,7 @@ final case class PvModel private ( extraterrestrialRadiationI0, thetaZ, thetaG, - gammaE + gammaE, ) // === Reflected Radiation ===// @@ -144,7 +144,7 @@ final case class PvModel private ( calcOutput( eTotal, data.dateTime, - irraditionSTC + irraditionSTC, ) } @@ -203,7 +203,7 @@ final case class PvModel private ( private def calcHourAngleOmega( time: ZonedDateTime, angleJ: Angle, - longitude: Angle + longitude: Angle, ): Angle = { val jInRad = angleJ.toRadians val lambda = longitude.toDegrees @@ -232,7 +232,7 @@ final case class PvModel private ( */ private def calcSunsetAngleOmegaSS( latitude: Angle, - delta: Angle + delta: Angle, ): Angle = { val latInRad = latitude.toRadians val deltaInRad = delta.toRadians @@ -261,7 +261,7 @@ final case class PvModel private ( private def calcSolarAltitudeAngleAlphaS( omega: Angle, delta: Angle, - latitude: Angle + latitude: Angle, ): Angle = { val latInRad = latitude.toRadians val deltaInRad = delta.toRadians @@ -271,9 +271,9 @@ final case class PvModel private ( max( cos(omegaInRad) * cos(latInRad) * cos(deltaInRad) + sin(latInRad) * sin(deltaInRad), - -1 + -1, ), - 1 + 1, ) Radians(asin(sinAlphaS)) } @@ -368,7 +368,7 @@ final case class PvModel private ( latitude: Angle, gammaE: Angle, alphaE: Angle, - omega: Angle + omega: Angle, ): Angle = { val deltaInRad = delta.toRadians val omegaInRad = omega.toRadians @@ -407,7 +407,7 @@ final case class PvModel private ( thetaG: Angle, omega: Angle, omegaSS: Angle, - omegaSR: Angle + omegaSR: Angle, ): Option[(Angle, Angle)] = { val thetaGInRad = thetaG.toRadians val omegaSSInRad = omegaSS.toRadians @@ -470,7 +470,7 @@ final case class PvModel private ( delta: Angle, latitude: Angle, gammaE: Angle, - alphaE: Angle + alphaE: Angle, ): Irradiation = { omegas match { @@ -540,7 +540,7 @@ final case class PvModel private ( extraterrestrialRadiationI0: Irradiation, thetaZ: Angle, thetaG: Angle, - gammaE: Angle + gammaE: Angle, ): Irradiation = { val thetaZInRad = thetaZ.toRadians val thetaGInRad = thetaG.toRadians @@ -558,10 +558,10 @@ final case class PvModel private ( var epsilon = ((eDifH + eBeamH) / eDifH + (5.535d * 1.0e-6) * pow( thetaZInRad, - 3 + 3, )) / (1d + (5.535d * 1.0e-6) * pow( thetaZInRad, - 3 + 3, )) // get the corresponding bin if epsilon is smaller than 6.2 @@ -573,7 +573,7 @@ final case class PvModel private ( Array(1.500, 1.950), Array(1.950, 2.800), Array(2.800, 4.500), - Array(4.500, 6.200) + Array(4.500, 6.200), ) // adapt the epsilon as we have no bin < 1 epsilon = max(1, epsilon) @@ -599,7 +599,7 @@ final case class PvModel private ( val f11 = -0.0161 * pow(x, 3) + 0.1840 * pow(x, 2) - 0.3806 * x + 0.2324 val f12 = 0.0134 * pow(x, 4) - 0.1938 * pow(x, 3) + 0.8410 * pow( x, - 2 + 2, ) - 1.4018 * x + 1.3579 val f13 = 0.0032 * pow(x, 3) - 0.0280 * pow(x, 2) - 0.0056 * x - 0.0385 val f21 = -0.0048 * pow(x, 3) + 0.0536 * pow(x, 2) - 0.1049 * x + 0.0034 @@ -640,7 +640,7 @@ final case class PvModel private ( eBeamH: Irradiation, eDifH: Irradiation, gammaE: Angle, - albedo: Double + albedo: Double, ): Irradiation = { val gammaEInRad = gammaE.toRadians (eBeamH + eDifH) * (albedo * 0.5 * (1 - cos(gammaEInRad))) @@ -648,7 +648,7 @@ final case class PvModel private ( private def generatorCorrectionFactor( time: ZonedDateTime, - gammaE: Angle + gammaE: Angle, ): Double = { val gammaEValInDeg = gammaE.toDegrees @@ -682,7 +682,7 @@ final case class PvModel private ( private def calcOutput( eTotalInWhPerSM: Irradiation, time: ZonedDateTime, - irradiationSTC: Irradiation + irradiationSTC: Irradiation, ): Power = { val genCorr = generatorCorrectionFactor(time, gammaE) val tempCorr = temperatureCorrectionFactor(time) @@ -703,7 +703,7 @@ final case class PvModel private ( "The fed in active power is higher than the estimated maximum active power of this plant ({} < {}). " + "Did you provide wrong weather input data?", proposal, - pMax + pMax, ) /* If the output is marginally small, suppress the output, as we are likely to be in night and then only produce incorrect output */ @@ -714,7 +714,7 @@ final case class PvModel private ( override def determineFlexOptions( data: PvRelevantData, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = { val power = calculateActivePower(ConstantState, data) @@ -724,7 +724,7 @@ final case class PvModel private ( override def handleControlledPowerChange( data: PvRelevantData, lastState: ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } @@ -747,21 +747,21 @@ object PvModel { dateTime: ZonedDateTime, weatherDataFrameLength: Long, diffIrradiance: Irradiance, - dirIrradiance: Irradiance + dirIrradiance: Irradiance, ) extends CalcRelevantData def apply( inputModel: PvInput, scalingFactor: Double, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): PvModel = { /* Determine the operation interval */ val operationInterval: OperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.getOperationTime + inputModel.getOperationTime, ) // moduleSurface and yieldSTC are left out for now @@ -798,7 +798,7 @@ object PvModel { .to(RADIAN) .getValue .doubleValue - ) + ), ) model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala index 84f1ed4296..92d47f8ae0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/SystemParticipant.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.model.participant import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - PrimaryDataWithApparentPower + PrimaryDataWithApparentPower, } import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl @@ -17,7 +17,7 @@ import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.{ DefaultQuantities, Megavars, - ReactivePower + ReactivePower, } import squants.Dimensionless import squants.energy.{Kilowatts, Power} @@ -50,7 +50,7 @@ import java.util.UUID abstract class SystemParticipant[ CD <: CalcRelevantData, +PD <: PrimaryDataWithApparentPower[PD], - MS <: ModelState + MS <: ModelState, ]( uuid: UUID, id: String, @@ -58,7 +58,7 @@ abstract class SystemParticipant[ val scalingFactor: Double, qControl: QControl, sRated: Power, - cosPhiRated: Double + cosPhiRated: Double, ) extends SystemComponent(uuid, id, operationInterval) { /** Maximum allowed apparent power output of this system participant. Used to @@ -85,7 +85,7 @@ abstract class SystemParticipant[ tick: Long, voltage: Dimensionless, modelState: MS, - data: CD + data: CD, ): PD /** Calculate the apparent power behaviour based on the given data. @@ -103,7 +103,7 @@ abstract class SystemParticipant[ tick: Long, voltage: Dimensionless, modelState: MS, - data: CD + data: CD, ): ApparentPower = { if (isInOperation(tick)) { val activePower = calculateActivePower(modelState, data) @@ -111,12 +111,12 @@ abstract class SystemParticipant[ calculateReactivePower(activePower, voltage) ApparentPower( activePower * scalingFactor, - reactivePower * scalingFactor + reactivePower * scalingFactor, ) } else { ApparentPower( DefaultQuantities.zeroMW, - DefaultQuantities.zeroMVAr + DefaultQuantities.zeroMVAr, ) } } @@ -132,7 +132,7 @@ abstract class SystemParticipant[ */ protected def calculateActivePower( modelState: MS, - data: CD + data: CD, ): Power /** @param data @@ -142,7 +142,7 @@ abstract class SystemParticipant[ */ def determineFlexOptions( data: CD, - lastState: MS + lastState: MS, ): ProvideFlexOptions /** @param data @@ -156,7 +156,7 @@ abstract class SystemParticipant[ def handleControlledPowerChange( data: CD, lastState: MS, - setPower: Power + setPower: Power, ): (MS, FlexChangeIndicator) /** Get a partial function, that transfers the current active into reactive @@ -173,7 +173,7 @@ abstract class SystemParticipant[ qControl.activeToReactivePowerFunc( sRated, cosPhiRated, - nodalVoltage + nodalVoltage, ) /** Calculate the reactive power of the model @@ -187,11 +187,11 @@ abstract class SystemParticipant[ */ def calculateReactivePower( activePower: Power, - voltage: Dimensionless + voltage: Dimensionless, ): ReactivePower = { limitReactivePower( activePower, - activeToReactivePowerFunc(voltage)(activePower) + activeToReactivePowerFunc(voltage)(activePower), ) } @@ -207,7 +207,7 @@ abstract class SystemParticipant[ */ private def limitReactivePower( activePower: Power, - reactivePower: ReactivePower + reactivePower: ReactivePower, ): ReactivePower = { { val apparentPower: Power = Kilowatts( diff --git a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala index 795507a621..2154f03d03 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/WecModel.scala @@ -13,7 +13,7 @@ import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.WecModel.{ WecCharacteristic, - WecRelevantData + WecRelevantData, } import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.system.Characteristic @@ -65,7 +65,7 @@ final case class WecModel( sRated: Power, cosPhiRated: Double, rotorArea: Area, - betzCurve: WecCharacteristic + betzCurve: WecCharacteristic, ) extends SystemParticipant[WecRelevantData, ApparentPower, ConstantState.type]( uuid, id, @@ -73,7 +73,7 @@ final case class WecModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerParticipant[WecRelevantData, ConstantState.type] { @@ -95,7 +95,7 @@ final case class WecModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - wecData: WecRelevantData + wecData: WecRelevantData, ): Power = { val activePower = determinePower(wecData) val pMax = sMax * cosPhiRated @@ -105,7 +105,7 @@ final case class WecModel( "The fed in active power is higher than the estimated maximum active power of this plant ({} > {}). " + "Did you provide wrong weather input data?", activePower, - pMax + pMax, ) pMax } else { @@ -134,7 +134,7 @@ final case class WecModel( val airDensity = calculateAirDensity( wecData.temperature, - wecData.airPressure + wecData.airPressure, ).toKilogramsPerCubicMeter val v = wecData.windVelocity.toMetersPerSecond @@ -179,7 +179,7 @@ final case class WecModel( */ private def calculateAirDensity( temperature: Temperature, - airPressure: Option[Pressure] + airPressure: Option[Pressure], ): Density = { airPressure match { case None => @@ -195,7 +195,7 @@ final case class WecModel( override def determineFlexOptions( data: WecRelevantData, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = { val power = calculateActivePower(ConstantState, data) @@ -205,7 +205,7 @@ final case class WecModel( override def handleControlledPowerChange( data: WecRelevantData, lastState: ConstantState.type, - setPower: Power + setPower: Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } @@ -236,7 +236,7 @@ object WecModel { input.getPoints.asScala.map(p => XYPair[Velocity, Dimensionless]( MetersPerSecond(p.getX.to(METRE_PER_SECOND).getValue.doubleValue), - Each(p.getY.to(PU).getValue.doubleValue) + Each(p.getY.to(PU).getValue.doubleValue), ) ) ) @@ -255,19 +255,19 @@ object WecModel { final case class WecRelevantData( windVelocity: Velocity, temperature: Temperature, - airPressure: Option[Pressure] + airPressure: Option[Pressure], ) extends CalcRelevantData def apply( inputModel: WecInput, scalingFactor: Double, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): WecModel = { val operationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.getOperationTime + inputModel.getOperationTime, ) val model = new WecModel( @@ -281,7 +281,7 @@ object WecModel { SquareMeters( inputModel.getType.getRotorArea.to(SQUARE_METRE).getValue.doubleValue ), - WecCharacteristic(inputModel.getType.getCpCharacteristic) + WecCharacteristic(inputModel.getType.getCpCharacteristic), ) model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala b/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala index 02c42be94f..37355d55b4 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/control/QControl.scala @@ -45,7 +45,7 @@ sealed trait QControl { def activeToReactivePowerFunc( sRated: Power, cosPhiRated: Double, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): Power => ReactivePower } @@ -73,7 +73,7 @@ object QControl { cosPhiP.getPoints.asScala.map(point => XYPair[Dimensionless, Dimensionless]( Each(point.getX.getValue.doubleValue()), - Each(point.getY.getValue.doubleValue()) + Each(point.getY.getValue.doubleValue()), ) ) ) @@ -85,7 +85,7 @@ object QControl { .map(point => XYPair[Dimensionless, Dimensionless]( Each(point.getX.getValue.doubleValue()), - Each(point.getY.getValue.doubleValue()) + Each(point.getY.getValue.doubleValue()), ) ) .toSeq @@ -118,7 +118,7 @@ object QControl { override def activeToReactivePowerFunc( sRated: Power, cosPhiRated: Double, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): Power => ReactivePower = { activePower: Power => _cosPhiMultiplication(cosPhi, activePower) } @@ -151,7 +151,7 @@ object QControl { */ def q( vInPu: Dimensionless, - qMax: ReactivePower + qMax: ReactivePower, ): ReactivePower = { qMax * interpolateXy(vInPu)._2.toEach } @@ -170,7 +170,7 @@ object QControl { override def activeToReactivePowerFunc( sRated: Power, cosPhiRated: Double, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): Power => ReactivePower = { activePower: Power => val qMaxFromP = Megavars( sqrt( @@ -197,7 +197,7 @@ object QControl { */ private def qMaxPossible( qMaxFromP: ReactivePower, - qFromCharacteristic: ReactivePower + qFromCharacteristic: ReactivePower, ): ReactivePower = if (qFromCharacteristic.abs >= qMaxFromP.abs) qMaxFromP * copySign(1, qFromCharacteristic.toMegavars) @@ -245,7 +245,7 @@ object QControl { override def activeToReactivePowerFunc( sRated: Power, cosPhiRated: Double, - nodalVoltage: Dimensionless + nodalVoltage: Dimensionless, ): Power => ReactivePower = { activePower: Power => /* cosphi( P / P_N ) = cosphi( P / (S_N * cosphi_rated) ) */ val pInPu = diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala index 80cdcf8a9a..f928af2fcf 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvModelWrapper.scala @@ -27,7 +27,7 @@ import java.util.UUID */ final case class EvModelWrapper( storedEnergy: squants.Energy, - private val original: EvModel + private val original: EvModel, ) { def uuid: UUID = original.getUuid @@ -61,7 +61,7 @@ object EvModelWrapper { KilowattHours( evModel.getStoredEnergy.to(KILOWATTHOUR).getValue.doubleValue ), - evModel + evModel, ) } diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala index 0e127f6e6a..c6445dd0ea 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/EvcsModel.scala @@ -17,13 +17,13 @@ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.evcs.EvcsModel._ import edu.ie3.simona.model.participant.evcs.uncontrolled.{ ConstantPowerCharging, - MaximumPowerCharging + MaximumPowerCharging, } import edu.ie3.simona.model.participant.{ CalcRelevantData, FlexChangeIndicator, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -82,7 +82,7 @@ final case class EvcsModel( locationType: EvcsLocationType, vehicle2grid: Boolean, strategy: ChargingStrategy.Value, - lowestEvSoc: Double + lowestEvSoc: Double, ) extends SystemParticipant[EvcsRelevantData, ApparentPower, EvcsState]( uuid, id, @@ -90,7 +90,7 @@ final case class EvcsModel( scalingFactor, qControl, sRated * chargingPoints, - cosPhiRated + cosPhiRated, ) with LazyLogging with MaximumPowerCharging @@ -107,7 +107,7 @@ final case class EvcsModel( */ def calculateNewScheduling( data: EvcsRelevantData, - evs: Seq[EvModelWrapper] + evs: Seq[EvModelWrapper], ): ScheduleMap = { if ( locationType == EvcsLocationType.CHARGING_HUB_TOWN || locationType == EvcsLocationType.CHARGING_HUB_HIGHWAY @@ -115,13 +115,13 @@ final case class EvcsModel( /* Cars at charging hubs always charge eagerly */ chargeWithMaximumPower( data.tick, - evs + evs, ) } else scheduleByStrategy( strategy, data.tick, - evs + evs, ) } @@ -139,17 +139,17 @@ final case class EvcsModel( private def scheduleByStrategy( strategy: ChargingStrategy.Value, currentTick: Long, - evs: Seq[EvModelWrapper] + evs: Seq[EvModelWrapper], ): ScheduleMap = strategy match { case ChargingStrategy.MAX_POWER => chargeWithMaximumPower( currentTick, - evs + evs, ) case ChargingStrategy.CONSTANT_POWER => chargeWithConstantPower( currentTick, - evs + evs, ) case ChargingStrategy.GRID_ORIENTED => throw new NotImplementedError( @@ -173,7 +173,7 @@ final case class EvcsModel( */ def applySchedule( state: EvcsState, - currentTick: Long + currentTick: Long, ): Seq[EvModelWrapper] = if (state.schedule.nonEmpty) { state.evs .map(ev => @@ -184,7 +184,7 @@ final case class EvcsModel( ev, _, state.tick, - currentTick + currentTick, ) } .getOrElse(ev) @@ -214,7 +214,7 @@ final case class EvcsModel( ev: EvModelWrapper, schedule: ChargingSchedule, lastSchedulingTick: Long, - currentTick: Long + currentTick: Long, ): EvModelWrapper = { /* Determine charged energy in the charging interval */ val chargedEnergySinceLastScheduling = @@ -231,7 +231,7 @@ final case class EvcsModel( val trimmedEntry = trimScheduleEntry( scheduleEntry, lastSchedulingTick, - currentTick + currentTick, ) /* Determine the energy charged within this slice of the schedule and accumulate it */ @@ -263,7 +263,7 @@ final case class EvcsModel( def createResults( lastState: EvcsState, currentTick: Long, - voltageMagnitude: Dimensionless + voltageMagnitude: Dimensionless, ): (Iterable[EvResult], Iterable[EvcsResult]) = { val lastTick = lastState.tick @@ -292,7 +292,7 @@ final case class EvcsModel( evUuid -> trimScheduleEntry( entry, lastTick, - currentTick + currentTick, ) } } @@ -324,7 +324,7 @@ final case class EvcsModel( lastEvMap, startingSchedules, Seq.empty[EvResult], - Seq.empty[EvcsResult] + Seq.empty[EvcsResult], ) { case ((evMap, lastActiveEntries, evResults, evcsResults), tick) => val time = tick.toDateTime(simulationStartDate) @@ -353,7 +353,7 @@ final case class EvcsModel( ev, tick, Kilowatts(0d), - voltageMagnitude + voltageMagnitude, ) } @@ -368,7 +368,7 @@ final case class EvcsModel( ev, entry.tickStart, entry.chargingPower, - voltageMagnitude + voltageMagnitude, ) // update EV @@ -378,7 +378,7 @@ final case class EvcsModel( ( evMap.updated(evUuid, newEv), - results.appended(result) + results.appended(result), ) } @@ -391,20 +391,20 @@ final case class EvcsModel( } val evcsQ = calculateReactivePower( evcsP, - voltageMagnitude + voltageMagnitude, ) val evcsResult = new EvcsResult( time, uuid, evcsP.toMegawatts.asMegaWatt, - evcsQ.toMegavars.asMegaVar + evcsQ.toMegavars.asMegaVar, ) ( updatedEvMap, currentActiveEntries, evResults ++ chargingEvResults ++ noChargingEvResults, - evcsResults :+ evcsResult + evcsResults :+ evcsResult, ) } @@ -423,7 +423,7 @@ final case class EvcsModel( _, currentTick, Kilowatts(0d), - voltageMagnitude + voltageMagnitude, ) } @@ -434,11 +434,11 @@ final case class EvcsModel( ev: EvModelWrapper, tick: Long, p: Power, - voltageMagnitude: Dimensionless + voltageMagnitude: Dimensionless, ) = { val q = calculateReactivePower( p, - voltageMagnitude + voltageMagnitude, ) val soc = (ev.storedEnergy / ev.eStorage).asPu .to(PERCENT) @@ -448,7 +448,7 @@ final case class EvcsModel( ev.uuid, p.toMegawatts.asMegaWatt, q.toMegavars.asMegaVar, - soc + soc, ) } @@ -469,11 +469,11 @@ final case class EvcsModel( private def trimScheduleEntry( scheduleEntry: ScheduleEntry, lastSchedulingTick: Long, - currentTick: Long + currentTick: Long, ): ScheduleEntry = scheduleEntry.copy( tickStart = math.max(scheduleEntry.tickStart, lastSchedulingTick), - tickStop = math.min(scheduleEntry.tickStop, currentTick) + tickStop = math.min(scheduleEntry.tickStop, currentTick), ) /** Determine the energy, that has been charged during the schedule entry time @@ -516,19 +516,19 @@ final case class EvcsModel( tick: Long, voltage: Dimensionless, modelState: EvcsState, - data: EvcsRelevantData + data: EvcsRelevantData, ): ApparentPower = throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") override protected def calculateActivePower( modelState: EvcsState, - data: EvcsRelevantData + data: EvcsRelevantData, ): Power = throw new NotImplementedError("Use calculatePowerAndEvSoc() instead.") override def determineFlexOptions( data: EvcsRelevantData, - lastState: EvcsState + lastState: EvcsState, ): FlexibilityMessage.ProvideFlexOptions = { val currentEvs = determineCurrentEvs(data, lastState) @@ -541,7 +541,7 @@ final case class EvcsModel( ) { case ( (chargingSum, preferredSum, forcedSum, dischargingSum), - ev + ev, ) => val maxPower = getMaxAvailableChargingPower(ev) @@ -575,7 +575,7 @@ final case class EvcsModel( chargingSum + maxCharging, preferredSum + preferred.getOrElse(Kilowatts(0d)), forcedSum + forced, - dischargingSum + maxDischarging + dischargingSum + maxDischarging, ) } @@ -590,7 +590,7 @@ final case class EvcsModel( uuid, adaptedPreferred, adaptedMaxDischarging, - maxCharging + maxCharging, ) } @@ -599,7 +599,7 @@ final case class EvcsModel( override def handleControlledPowerChange( data: EvcsRelevantData, lastState: EvcsState, - setPower: Power + setPower: Power, ): (EvcsState, FlexChangeIndicator) = { val currentEvs = determineCurrentEvs(data, lastState) @@ -608,9 +608,9 @@ final case class EvcsModel( EvcsState( evs = currentEvs, schedule = Map.empty, - tick = data.tick + tick = data.tick, ), - FlexChangeIndicator() + FlexChangeIndicator(), ) // applicable evs can be charged/discharged, other evs cannot @@ -646,9 +646,9 @@ final case class EvcsModel( EvcsState( evs = currentEvs, schedule = allSchedules, - tick = data.tick + tick = data.tick, ), - aggregateFlexChange(combinedSchedules) + aggregateFlexChange(combinedSchedules), ) } @@ -677,7 +677,7 @@ final case class EvcsModel( FlexChangeIndicator( scheduleAtNextActivation, - nextScheduledTick + nextScheduledTick, ) } @@ -698,10 +698,10 @@ final case class EvcsModel( private def createScheduleWithSetPower( currentTick: Long, evs: Seq[EvModelWrapper], - setPower: Power + setPower: Power, ): ( Seq[(UUID, (ChargingSchedule, Long, Boolean))], - Power + Power, ) = { if (evs.isEmpty) return (Seq.empty, setPower) @@ -734,8 +734,8 @@ final case class EvcsModel( ScheduleEntry(currentTick, endTick, proposedPower) ), endTick, - isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) - ) + isFull(ev) || isEmpty(ev) || isInLowerMargin(ev), + ), ) } @@ -764,8 +764,8 @@ final case class EvcsModel( ( SortedSet(ScheduleEntry(currentTick, endTick, power)), endTick, - isFull(ev) || isEmpty(ev) || isInLowerMargin(ev) - ) + isFull(ev) || isEmpty(ev) || isInLowerMargin(ev), + ), ) } @@ -782,7 +782,7 @@ final case class EvcsModel( createScheduleWithSetPower( currentTick, fittingPowerEvs, - remainingAfterAllocation + remainingAfterAllocation, ) val combinedResults = maxChargedResults ++ nextIterationResults @@ -805,7 +805,7 @@ final case class EvcsModel( */ private def calcFlexOptionsChange( ev: EvModelWrapper, - power: Power + power: Power, ): Long = { val timeUntilFullOrEmpty = if (power > Kilowatts(0d)) { @@ -876,7 +876,7 @@ final case class EvcsModel( */ def determineCurrentEvs( data: EvcsRelevantData, - lastState: EvcsState + lastState: EvcsState, ): Seq[EvModelWrapper] = { // If last state is outdated, determine @@ -890,7 +890,7 @@ final case class EvcsModel( validateArrivals( lastState.evs, data.arrivals, - chargingPoints + chargingPoints, ) currentEVs ++ data.arrivals @@ -906,7 +906,7 @@ final case class EvcsModel( */ def validateDepartures( lastEvs: Seq[EvModelWrapper], - departures: Seq[UUID] + departures: Seq[UUID], ): Unit = { departures.foreach { ev => if (!lastEvs.exists(_.uuid == ev)) @@ -931,7 +931,7 @@ final case class EvcsModel( def validateArrivals( lastEvs: Seq[EvModelWrapper], arrivals: Seq[EvModelWrapper], - chargingPoints: Int + chargingPoints: Int, ): Unit = { arrivals.foreach { ev => @@ -974,7 +974,7 @@ object EvcsModel { */ final case class EvcsRelevantData( tick: Long, - arrivals: Seq[EvModelWrapper] + arrivals: Seq[EvModelWrapper], ) extends CalcRelevantData /** Class that represents the state of the charging station (including @@ -991,7 +991,7 @@ object EvcsModel { final case class EvcsState( evs: Seq[EvModelWrapper], schedule: ScheduleMap, - tick: Long + tick: Long, ) extends ModelState /** Schedule entry specifying a time interval in which the EV should be @@ -1007,7 +1007,7 @@ object EvcsModel { final case class ScheduleEntry( tickStart: Long, tickStop: Long, - chargingPower: squants.Power + chargingPower: squants.Power, ) extends Ordered[ScheduleEntry] { override def compare(that: ScheduleEntry): Int = { val startComp = tickStart.compare(that.tickStart) @@ -1047,14 +1047,14 @@ object EvcsModel { simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, chargingStrategy: String, - lowestEvSoc: Double + lowestEvSoc: Double, ): EvcsModel = { /* Determine the operation interval */ val operationInterval: OperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - inputModel.getOperationTime + inputModel.getOperationTime, ) val model = EvcsModel( @@ -1071,7 +1071,7 @@ object EvcsModel { inputModel.getLocationType, inputModel.getV2gSupport, ChargingStrategy(chargingStrategy), - lowestEvSoc + lowestEvSoc, ) model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala index 4e2a56135e..20106c77af 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerCharging.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled import edu.ie3.simona.model.participant.evcs.EvcsModel.{ ScheduleMap, - ScheduleEntry + ScheduleEntry, } import edu.ie3.simona.model.participant.evcs.{EvModelWrapper, EvcsModel} import squants.Seconds @@ -32,7 +32,7 @@ trait ConstantPowerCharging { */ def chargeWithConstantPower( currentTick: Long, - evs: Seq[EvModelWrapper] + evs: Seq[EvModelWrapper], ): ScheduleMap = evs .filter(ev => ev.storedEnergy < ev.eStorage) .map { ev => diff --git a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala index babbc580ac..eac55d9fcc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerCharging.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.model.participant.evcs.uncontrolled import edu.ie3.simona.model.participant.evcs.EvcsModel.{ ScheduleMap, - ScheduleEntry + ScheduleEntry, } import edu.ie3.simona.model.participant.evcs.{EvModelWrapper, EvcsModel} import squants.Seconds @@ -32,7 +32,7 @@ trait MaximumPowerCharging { */ def chargeWithMaximumPower( currentTick: Long, - evs: Seq[EvModelWrapper] + evs: Seq[EvModelWrapper], ): ScheduleMap = evs .filter(ev => ev.storedEnergy < ev.eStorage) .map { ev => diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala index 0f2e4f4b9e..b74e154b61 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/FixedLoadModel.scala @@ -13,7 +13,7 @@ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.FixedLoadModel.FixedLoadRelevantData import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, - EnergyConsumption + EnergyConsumption, } import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval @@ -50,7 +50,7 @@ final case class FixedLoadModel( qControl: QControl, sRated: Power, cosPhiRated: Double, - reference: LoadReference + reference: LoadReference, ) extends LoadModel[FixedLoadRelevantData.type]( uuid, id, @@ -58,7 +58,7 @@ final case class FixedLoadModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) { val activePower: Power = reference match { @@ -78,7 +78,7 @@ final case class FixedLoadModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - data: FixedLoadRelevantData.type = FixedLoadRelevantData + data: FixedLoadRelevantData.type = FixedLoadRelevantData, ): Power = activePower } @@ -89,7 +89,7 @@ object FixedLoadModel { input: LoadInput, scalingFactor: Double, operationInterval: OperationInterval, - reference: LoadReference + reference: LoadReference, ): FixedLoadModel = { val model = FixedLoadModel( input.getUuid, @@ -104,7 +104,7 @@ object FixedLoadModel { .doubleValue ), input.getCosPhiRated, - reference + reference, ) model.enable() model diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala index 4d0e81c322..874b5a5038 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadModel.scala @@ -15,7 +15,7 @@ import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.{ ApparentPowerParticipant, FlexChangeIndicator, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -38,7 +38,7 @@ abstract class LoadModel[D <: LoadRelevantData]( scalingFactor: Double, qControl: QControl, sRated: Power, - cosPhiRated: Double + cosPhiRated: Double, ) extends SystemParticipant[D, ApparentPower, ConstantState.type]( uuid, id, @@ -46,23 +46,23 @@ abstract class LoadModel[D <: LoadRelevantData]( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) with ApparentPowerParticipant[D, ConstantState.type] { override def determineFlexOptions( data: D, - lastState: ConstantState.type + lastState: ConstantState.type, ): ProvideFlexOptions = ProvideMinMaxFlexOptions.noFlexOption( uuid, - calculateActivePower(lastState, data) + calculateActivePower(lastState, data), ) override def handleControlledPowerChange( data: D, lastState: ConstantState.type, - setPower: Power + setPower: Power, ): (ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } @@ -90,7 +90,7 @@ case object LoadModel extends LazyLogging { def scaleSRatedActivePower( inputModel: LoadInput, activePower: Power, - safetyFactor: Double = 1d + safetyFactor: Double = 1d, ): Power = { val sRated = Megawatts( inputModel.getsRated @@ -133,7 +133,7 @@ case object LoadModel extends LazyLogging { energyConsumption: Energy, profileMaxPower: Power, profileEnergyScaling: Energy, - safetyFactor: Double = 1d + safetyFactor: Double = 1d, ): Power = { (profileMaxPower / inputModel.getCosPhiRated) * ( energyConsumption / profileEnergyScaling diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala b/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala index 4fbfd67821..5a795673c5 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/LoadReference.scala @@ -61,7 +61,7 @@ object LoadReference { */ def apply( inputModel: LoadInput, - modelConfig: SimonaConfig.LoadRuntimeConfig + modelConfig: SimonaConfig.LoadRuntimeConfig, ): LoadReference = StringUtils.cleanString(modelConfig.reference).toLowerCase match { case "power" => diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileKey.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileKey.scala index cb3cb60e90..af77c3fa55 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileKey.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileKey.scala @@ -25,7 +25,7 @@ import edu.ie3.simona.model.participant.load.{DayType, profile} final case class LoadProfileKey( standardLoadProfile: StandardLoadProfile, season: Season.Value, - dayType: DayType.Value + dayType: DayType.Value, ) case object LoadProfileKey { @@ -64,19 +64,19 @@ case object LoadProfileKey { def apply( loadProfile: String, season: String, - dayType: String + dayType: String, ): LoadProfileKey = { try { new LoadProfileKey( StandardLoadProfile.parse(loadProfile), Season(season), - DayType(dayType) + DayType(dayType), ) } catch { case e: ParsingException => throw new IllegalArgumentException( s"Cannot parse '$loadProfile' to a now StandardLoadProfile.", - e + e, ) } } @@ -93,12 +93,12 @@ case object LoadProfileKey { */ def apply( loadProfile: StandardLoadProfile, - time: ZonedDateTime + time: ZonedDateTime, ): LoadProfileKey = { new LoadProfileKey( loadProfile, profile.Season(time), - load.DayType(time.getDayOfWeek) + load.DayType(time.getDayOfWeek), ) } } diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala index e2f66635cd..f1e7d54f62 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/LoadProfileStore.scala @@ -10,11 +10,11 @@ import breeze.numerics.round import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.profile.{ BdewStandardLoadProfile, - StandardLoadProfile + StandardLoadProfile, } import edu.ie3.simona.model.participant.load.profile.LoadProfileStore.{ initializeMaxConsumptionPerProfile, - initializeTypeDayValues + initializeTypeDayValues, } import edu.ie3.simona.model.participant.load.{DayType, profile} import org.apache.commons.csv.CSVFormat @@ -56,7 +56,7 @@ class LoadProfileStore private (val reader: Reader) { */ def entry( time: ZonedDateTime, - loadProfile: StandardLoadProfile + loadProfile: StandardLoadProfile, ): squants.Power = { val key = LoadProfileKey(loadProfile, time) profileMap.get(key) match { diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala index 15b0a4f141..8fd4128996 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/profile/ProfileLoadModel.scala @@ -50,7 +50,7 @@ final case class ProfileLoadModel( sRated: Power, cosPhiRated: Double, loadProfile: StandardLoadProfile, - reference: LoadReference + reference: LoadReference, ) extends LoadModel[ProfileRelevantData]( uuid, id, @@ -58,7 +58,7 @@ final case class ProfileLoadModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) { private val loadProfileStore: LoadProfileStore = LoadProfileStore() @@ -86,7 +86,7 @@ final case class ProfileLoadModel( */ override protected def calculateActivePower( modelState: ConstantState.type, - data: ProfileRelevantData + data: ProfileRelevantData, ): Power = { /* The power comes in W and is delivered all 15 minutes */ val averagePower: Power = loadProfileStore @@ -114,7 +114,7 @@ object ProfileLoadModel { input: LoadInput, operationInterval: OperationInterval, scalingFactor: Double, - reference: LoadReference + reference: LoadReference, ): ProfileLoadModel = { val model = reference match { case LoadReference.ActivePower(power) => @@ -128,7 +128,7 @@ object ProfileLoadModel { sRatedPowerScaled, input.getCosPhiRated, input.getLoadProfile.asInstanceOf[StandardLoadProfile], - reference + reference, ) case LoadReference.EnergyConsumption(energyConsumption) => @@ -140,7 +140,7 @@ object ProfileLoadModel { input, energyConsumption, loadProfileMax, - LoadProfileStore.defaultLoadProfileEnergyScaling + LoadProfileStore.defaultLoadProfileEnergyScaling, ) ProfileLoadModel( input.getUuid, @@ -151,7 +151,7 @@ object ProfileLoadModel { sRatedEnergy, input.getCosPhiRated, input.getLoadProfile.asInstanceOf[StandardLoadProfile], - reference + reference, ) } model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala index 6d62344fe0..4897530a1e 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadModel.scala @@ -55,7 +55,7 @@ final case class RandomLoadModel( qControl: QControl, sRated: Power, cosPhiRated: Double, - reference: LoadReference + reference: LoadReference, ) extends LoadModel[RandomRelevantData]( uuid, id, @@ -63,7 +63,7 @@ final case class RandomLoadModel( scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) { private lazy val energyReferenceScalingFactor = reference match { @@ -91,7 +91,7 @@ final case class RandomLoadModel( @tailrec override protected def calculateActivePower( modelState: ConstantState.type, - data: RandomRelevantData + data: RandomRelevantData, ): Power = { val gev = getGevDistribution(data.date) @@ -130,7 +130,7 @@ final case class RandomLoadModel( * available, yet, instantiate one. */ val key: GevKey = ( DayType(dateTime.getDayOfWeek), - TimeUtil.withDefaults.getQuarterHourOfDay(dateTime) + TimeUtil.withDefaults.getQuarterHourOfDay(dateTime), ) gevStorage.get(key) match { case Some(foundIt) => foundIt @@ -142,7 +142,7 @@ final case class RandomLoadModel( gevParameters.my, gevParameters.sigma, gevParameters.k, - randomFactory + randomFactory, ) gevStorage += (key -> newGev) newGev @@ -180,7 +180,7 @@ object RandomLoadModel { input: LoadInput, operationInterval: OperationInterval, scalingFactor: Double, - reference: LoadReference + reference: LoadReference, ): RandomLoadModel = { val model = reference match { case ActivePower(power) => @@ -195,7 +195,7 @@ object RandomLoadModel { QControl.apply(input.getqCharacteristics()), sRatedPowerScaled, input.getCosPhiRated, - reference + reference, ) case EnergyConsumption(energyConsumption) => val sRatedEnergy = LoadModel.scaleSRatedEnergy( @@ -203,7 +203,7 @@ object RandomLoadModel { energyConsumption, randomMaxPower, randomProfileEnergyScaling, - 1.1 + 1.1, ) RandomLoadModel( @@ -214,7 +214,7 @@ object RandomLoadModel { QControl.apply(input.getqCharacteristics()), sRatedEnergy, input.getCosPhiRated, - reference + reference, ) } model.enable() diff --git a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala index c83620ef84..36635ae940 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/load/random/RandomLoadParamStore.scala @@ -36,7 +36,7 @@ final case class RandomLoadParamStore private (reader: Reader) { dayType, throw new RuntimeException( s"Cannot determine the random load parameters for '$time' (day type '$dayType')." - ) + ), ) .getQuarterHourParameters(time) } @@ -106,7 +106,7 @@ case object RandomLoadParamStore extends LazyLogging { case e: FileIOException => throw new FileIOException( s"Cannot determine random load parameters for day type '$dayType' and quarter hour '$quartHour'", - e + e, ) } } @@ -180,7 +180,7 @@ case object RandomLoadParamStore extends LazyLogging { */ private def assembleParameters( record: CSVRecord, - parameterToCol: Map[RandomLoadParameters.Value, Int] + parameterToCol: Map[RandomLoadParameters.Value, Int], ): RandomLoadParameters = { val k = record .get( @@ -188,7 +188,7 @@ case object RandomLoadParamStore extends LazyLogging { RandomLoadParameters.K, throw new FileIOException( s"Cannot determine column index for random load parameter ${RandomLoadParameters.K}." - ) + ), ) ) .toDouble @@ -198,7 +198,7 @@ case object RandomLoadParamStore extends LazyLogging { RandomLoadParameters.MY, throw new FileIOException( s"Cannot determine column index for random load parameter ${RandomLoadParameters.MY}." - ) + ), ) ) .toDouble @@ -208,7 +208,7 @@ case object RandomLoadParamStore extends LazyLogging { RandomLoadParameters.SIGMA, throw new FileIOException( s"Cannot determine column index for random load parameter ${RandomLoadParameters.SIGMA}." - ) + ), ) ) .toDouble diff --git a/src/main/scala/edu/ie3/simona/model/system/Characteristic.scala b/src/main/scala/edu/ie3/simona/model/system/Characteristic.scala index 2be558d535..2088ca6cdc 100644 --- a/src/main/scala/edu/ie3/simona/model/system/Characteristic.scala +++ b/src/main/scala/edu/ie3/simona/model/system/Characteristic.scala @@ -38,7 +38,7 @@ trait Characteristic[A <: Quantity[A], O <: Quantity[O]] { xyCoordinates.toSeq .map(xyPair => xyPair.x -> xyPair.y) .toMap, - requestedAbscissaQuantity + requestedAbscissaQuantity, ) xyCoords.foldLeft( @@ -56,7 +56,7 @@ trait Characteristic[A <: Quantity[A], O <: Quantity[O]] { Some(requestedAbscissaQuantity), Some( b.map(_ + (m * deltaX).value) - ) + ), ) case _ => throw new CharacteristicsException( @@ -75,7 +75,7 @@ trait Characteristic[A <: Quantity[A], O <: Quantity[O]] { object Characteristic { final case class XYPair[A <: Quantity[A], O <: Quantity[O]]( x: A, - y: O + y: O, ) extends Ordered[XYPair[A, O]] { /** The pairs are ordered by their x value first. If two pairs have the same diff --git a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala index c3f7ee83b4..b6828f7dc5 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/CylindricalThermalStorage.scala @@ -10,19 +10,19 @@ import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.{ CylindricalStorageInput, - ThermalBusInput + ThermalBusInput, } import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.{ StorageEmpty, - StorageFull + StorageFull, } import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.SquantsUtils.RichEnergy import edu.ie3.util.scala.quantities.{ DefaultQuantities, KilowattHoursPerKelvinCubicMeters, - SpecificHeatCapacity + SpecificHeatCapacity, } import squants.energy.{Kilowatts, Megawatts} import squants.space.{CubicMeters, Volume} @@ -63,7 +63,7 @@ final case class CylindricalThermalStorage( minEnergyThreshold: Energy, maxEnergyThreshold: Energy, chargingPower: Power, - override protected var _storedEnergy: Energy + override protected var _storedEnergy: Energy, ) extends ThermalStorage( uuid, id, @@ -72,7 +72,7 @@ final case class CylindricalThermalStorage( bus, minEnergyThreshold, maxEnergyThreshold, - chargingPower + chargingPower, ) with MutableStorage { @@ -93,7 +93,7 @@ final case class CylindricalThermalStorage( override def updateState( tick: Long, qDot: Power, - lastState: ThermalStorageState + lastState: ThermalStorageState, ): (ThermalStorageState, Option[ThermalThreshold]) = { /* Determine new state based on time difference and given state */ val energyBalance = lastState.qDot * Seconds(tick - lastState.tick) @@ -132,7 +132,7 @@ final case class CylindricalThermalStorage( override def startingState: ThermalStorageState = ThermalStorageState( -1L, getMinEnergyThreshold, - Kilowatts(0d) + Kilowatts(0d), ) @deprecated("Use thermal storage state instead") @@ -185,7 +185,7 @@ object CylindricalThermalStorage { */ def apply( input: CylindricalStorageInput, - initialStoredEnergy: Energy = DefaultQuantities.zeroKWH + initialStoredEnergy: Energy = DefaultQuantities.zeroKWH, ): CylindricalThermalStorage = { val minEnergyThreshold: Energy = CylindricalThermalStorage.volumeToEnergy( @@ -202,7 +202,7 @@ object CylindricalThermalStorage { .doubleValue ), Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue()), - Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()) + Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()), ) val maxEnergyThreshold: Energy = @@ -217,7 +217,7 @@ object CylindricalThermalStorage { .doubleValue ), Celsius(input.getInletTemp.to(Units.CELSIUS).getValue.doubleValue()), - Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()) + Celsius(input.getReturnTemp.to(Units.CELSIUS).getValue.doubleValue()), ) /* TODO: Currently, the input model does not define any maximum charge power. Assume, that the usable energy can @@ -233,7 +233,7 @@ object CylindricalThermalStorage { minEnergyThreshold, maxEnergyThreshold, chargingPower, - initialStoredEnergy + initialStoredEnergy, ) } @@ -254,7 +254,7 @@ object CylindricalThermalStorage { volume: Volume, c: SpecificHeatCapacity, inletTemp: Temperature, - returnTemp: Temperature + returnTemp: Temperature, ): Energy = { c.calcEnergy(returnTemp, inletTemp, volume) } @@ -276,7 +276,7 @@ object CylindricalThermalStorage { energy: Energy, c: SpecificHeatCapacity, inletTemp: Temperature, - returnTemp: Temperature + returnTemp: Temperature, ): Volume = { val energyDensity = c.calcEnergyDensity(returnTemp, inletTemp) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala index 1ccb5cc024..c447a5bf73 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/RandomStorageState.scala @@ -24,7 +24,7 @@ trait RandomStorageState { ThermalStorageState( -1L, storedEnergy, - Kilowatts(0d) + Kilowatts(0d), ) } } diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala index e213a902ed..0586a20ee7 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -11,12 +11,12 @@ import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.datamodel.models.result.thermal.{ CylindricalStorageResult, - ThermalHouseResult + ThermalHouseResult, } import edu.ie3.simona.exceptions.agent.InconsistentStateException import edu.ie3.simona.model.thermal.ThermalGrid.{ ThermalEnergyDemand, - ThermalGridState + ThermalGridState, } import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState @@ -38,7 +38,7 @@ import scala.jdk.CollectionConverters.SetHasAsScala */ final case class ThermalGrid( house: Option[ThermalHouse], - storage: Option[ThermalStorage] + storage: Option[ThermalStorage], ) extends LazyLogging { /** Determine the energy demand of the total grid at the given instance in @@ -55,7 +55,7 @@ final case class ThermalGrid( def energyDemand( tick: Long, ambientTemperature: Temperature, - state: ThermalGridState + state: ThermalGridState, ): ThermalEnergyDemand = { /* First get the energy demand of the houses */ val houseDemand = house @@ -64,7 +64,7 @@ final case class ThermalGrid( house.energyDemand( tick, ambientTemperature, - state + state, ) } .getOrElse(ThermalEnergyDemand.noDemand) @@ -78,7 +78,7 @@ final case class ThermalGrid( val remaining = storage.getMaxEnergyThreshold - usableEnergy ( usableEnergy, - remaining + remaining, ) } .getOrElse( @@ -95,7 +95,7 @@ final case class ThermalGrid( ThermalEnergyDemand( houseDemand.required - usedEnergy, - houseDemand.possible + finallyRemaining + houseDemand.possible + finallyRemaining, ) } @@ -115,7 +115,7 @@ final case class ThermalGrid( tick: Long, state: ThermalGridState, ambientTemperature: Temperature, - qDot: Power + qDot: Power, ): (ThermalGridState, Option[ThermalThreshold]) = if (qDot > Kilowatts(0d)) handleInfeed(tick, ambientTemperature, state, qDot) else @@ -138,7 +138,7 @@ final case class ThermalGrid( tick: Long, ambientTemperature: Temperature, state: ThermalGridState, - qDot: Power + qDot: Power, ): (ThermalGridState, Option[ThermalThreshold]) = house.zip(state.houseState) match { case Some((thermalHouse, lastHouseState)) => @@ -151,7 +151,7 @@ final case class ThermalGrid( .updateState( tick, Kilowatts(0d), - storageState + storageState, ) ._1 ) @@ -163,7 +163,7 @@ final case class ThermalGrid( tick, lastHouseState, ambientTemperature, - qDot + qDot, ) if ( @@ -177,7 +177,7 @@ final case class ThermalGrid( tick, lastHouseState, ambientTemperature, - Kilowatts(0d) + Kilowatts(0d), ) storage.zip(updatedStorageState) match { case Some((thermalStorage, storageState)) => @@ -187,28 +187,28 @@ final case class ThermalGrid( /* Both house and storage are updated. Determine what reaches the next threshold */ val nextThreshold = determineMostRecentThreshold( maybeFullHouseThreshold, - maybeStorageThreshold + maybeStorageThreshold, ) ( state.copy( houseState = Some(fullHouseState), - storageState = Some(updatedStorageState) + storageState = Some(updatedStorageState), ), - nextThreshold + nextThreshold, ) case None => /* There is no storage, house determines the next activation */ ( state.copy(houseState = Some(fullHouseState)), - maybeFullHouseThreshold + maybeFullHouseThreshold, ) } } else { /* The house can handle the infeed */ ( state.copy(houseState = Some(updatedHouseState)), - maybeHouseThreshold + maybeHouseThreshold, ) } @@ -219,7 +219,7 @@ final case class ThermalGrid( thermalStorage.updateState(tick, qDot, storageState) ( state.copy(storageState = Some(updatedStorageState)), - maybeStorageThreshold + maybeStorageThreshold, ) case None => throw new InconsistentStateException( @@ -230,7 +230,7 @@ final case class ThermalGrid( private def determineMostRecentThreshold( maybeHouseThreshold: Option[ThermalThreshold], - maybeStorageThreshold: Option[ThermalThreshold] + maybeStorageThreshold: Option[ThermalThreshold], ): Option[ThermalThreshold] = (maybeHouseThreshold, maybeStorageThreshold) match { case (Some(houseThreshold), Some(storageThreshold)) => @@ -260,7 +260,7 @@ final case class ThermalGrid( tick: Long, ambientTemperature: Temperature, state: ThermalGridState, - qDot: Power + qDot: Power, ): (ThermalGridState, Option[ThermalThreshold]) = { /* House will be left with no influx in all cases. Determine if and when a threshold is reached */ val maybeUpdatedHouseState = @@ -269,7 +269,7 @@ final case class ThermalGrid( tick, houseState, ambientTemperature, - Megawatts(0d) + Megawatts(0d), ) } @@ -287,20 +287,20 @@ final case class ThermalGrid( state.houseState, state.storageState, ambientTemperature, - qDot + qDot, ) val nextThreshold = determineMostRecentThreshold( revisedHouseState.flatMap(_._2), - revisedStorageState.flatMap(_._2) + revisedStorageState.flatMap(_._2), ) ( state.copy( houseState = revisedHouseState.map(_._1), - storageState = revisedStorageState.map(_._1) + storageState = revisedStorageState.map(_._1), ), - nextThreshold + nextThreshold, ) } @@ -334,15 +334,15 @@ final case class ThermalGrid( formerHouseState: Option[ThermalHouseState], formerStorageState: Option[ThermalStorageState], ambientTemperature: Temperature, - qDot: Power + qDot: Power, ): ( Option[(ThermalHouseState, Option[ThermalThreshold])], - Option[(ThermalStorageState, Option[ThermalThreshold])] + Option[(ThermalStorageState, Option[ThermalThreshold])], ) = house.zip(maybeHouseState).zip(storage.zip(maybeStorageState)) match { case Some( ( (thermalHouse, (houseState, _)), - (thermalStorage, (storageState, _)) + (thermalStorage, (storageState, _)), ) ) if qDot.~=(Kilowatts(0d))(Kilowatts(10e-3)) && @@ -357,7 +357,7 @@ final case class ThermalGrid( throw new InconsistentStateException( "Impossible to find no storage state" ) - ) + ), ) val revisedHouseState = thermalHouse.determineState( tick, @@ -367,7 +367,7 @@ final case class ThermalGrid( ) ), ambientTemperature, - thermalStorage.getChargingPower + thermalStorage.getChargingPower, ) (Some(revisedHouseState), Some(revisedStorageState)) case _ => (maybeHouseState, maybeStorageState) @@ -390,13 +390,13 @@ final case class ThermalGrid( .map { case ( thermalHouse, - ThermalHouseState(tick, innerTemperature, thermalInfeed) + ThermalHouseState(tick, innerTemperature, thermalInfeed), ) => Seq.empty[ResultEntity] :+ new ThermalHouseResult( tick.toDateTime, thermalHouse.uuid, thermalInfeed.toMegawatts.asMegaWatt, - innerTemperature.toKelvinScale.asKelvin + innerTemperature.toKelvinScale.asKelvin, ) } .getOrElse(Seq.empty[ResultEntity]) @@ -406,14 +406,14 @@ final case class ThermalGrid( .map { case ( storage: CylindricalThermalStorage, - ThermalStorageState(tick, storedEnergy, qDot) + ThermalStorageState(tick, storedEnergy, qDot), ) => houseResults :+ new CylindricalStorageResult( tick.toDateTime, storage.uuid, storedEnergy.toMegawattHours.asMegaWattHour, qDot.toMegawatts.asMegaWatt, - (storage.maxEnergyThreshold / storedEnergy).asPu + (storage.maxEnergyThreshold / storedEnergy).asPu, ) case _ => throw new NotImplementedError( @@ -440,7 +440,7 @@ object ThermalGrid { .toSet new ThermalGrid( houses.headOption, - storages.headOption + storages.headOption, ) } @@ -452,13 +452,13 @@ object ThermalGrid { */ final case class ThermalGridState( houseState: Option[ThermalHouseState], - storageState: Option[ThermalStorageState] + storageState: Option[ThermalStorageState], ) def startingState(thermalGrid: ThermalGrid): ThermalGridState = ThermalGridState( thermalGrid.house.map(house => ThermalHouse.startingState(house)), - thermalGrid.storage.map(_.startingState) + thermalGrid.storage.map(_.startingState), ) /** Defines the thermal energy demand of a thermal grid. It comprises the @@ -473,11 +473,11 @@ object ThermalGrid { */ final case class ThermalEnergyDemand private ( required: Energy, - possible: Energy + possible: Energy, ) { def +(rhs: ThermalEnergyDemand): ThermalEnergyDemand = ThermalEnergyDemand( required + rhs.required, - possible + rhs.possible + possible + rhs.possible, ) def hasRequiredDemand: Boolean = required > MegawattHours(0d) @@ -498,7 +498,7 @@ object ThermalGrid { */ def apply( required: Energy, - possible: Energy + possible: Energy, ): ThermalEnergyDemand = { if (possible < required) new ThermalEnergyDemand(possible, possible) @@ -508,7 +508,7 @@ object ThermalGrid { def noDemand: ThermalEnergyDemand = ThermalEnergyDemand( MegawattHours(0d), - MegawattHours(0d) + MegawattHours(0d), ) } } diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala index 874b7c10e3..b702102080 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -10,16 +10,16 @@ import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.{ ThermalBusInput, - ThermalHouseInput + ThermalHouseInput, } import edu.ie3.simona.model.thermal.ThermalGrid.ThermalEnergyDemand import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureLowerBoundaryReached, - HouseTemperatureUpperBoundaryReached + HouseTemperatureUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalHouse.{ ThermalHouseState, - temperatureTolerance + temperatureTolerance, } import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.quantities.{ThermalConductance, WattsPerKelvin} @@ -64,13 +64,13 @@ final case class ThermalHouse( ethCapa: ThermalCapacity, targetTemperature: Temperature, lowerBoundaryTemperature: Temperature, - upperBoundaryTemperature: Temperature + upperBoundaryTemperature: Temperature, ) extends ThermalSink( uuid, id, operatorInput, operationTime, - bus + bus, ) { /** Calculate the energy demand at the instance in question. If the inner @@ -93,7 +93,7 @@ final case class ThermalHouse( def energyDemand( tick: Long, ambientTemperature: Temperature, - state: ThermalHouseState + state: ThermalHouseState, ): ThermalEnergyDemand = { /* Calculate the inner temperature of the house, at the questioned instance in time */ val duration = Seconds(tick - state.tick) @@ -101,7 +101,7 @@ final case class ThermalHouse( state.qDot, duration, state.innerTemperature, - ambientTemperature + ambientTemperature, ) /* Determine, which temperature boundary triggers a needed energy to reach the temperature constraints */ @@ -118,7 +118,7 @@ final case class ThermalHouse( if ( isInnerTemperatureTooLow( currentInnerTemp, - temperatureToTriggerRequiredEnergy + temperatureToTriggerRequiredEnergy, ) ) energy(targetTemperature, currentInnerTemp) else @@ -146,7 +146,7 @@ final case class ThermalHouse( */ private def energy( targetTemperature: Temperature, - startTemperature: Temperature + startTemperature: Temperature, ): Energy = { ethCapa * Kelvin( targetTemperature.toKelvinScale - startTemperature.toKelvinScale @@ -172,7 +172,7 @@ final case class ThermalHouse( */ def isInnerTemperatureTooLow( innerTemperature: Temperature, - boundaryTemperature: Temperature = lowerBoundaryTemperature + boundaryTemperature: Temperature = lowerBoundaryTemperature, ): Boolean = innerTemperature < Kelvin( boundaryTemperature.toKelvinScale + temperatureTolerance.toKelvinScale @@ -195,19 +195,19 @@ final case class ThermalHouse( thermalPower: Power, duration: Time, currentInnerTemperature: Temperature, - ambientTemperature: Temperature + ambientTemperature: Temperature, ): Temperature = { val thermalEnergyChange = calcThermalEnergyChange( calcThermalEnergyGain(thermalPower, duration), calcThermalEnergyLoss( currentInnerTemperature, ambientTemperature, - duration - ) + duration, + ), ) calcNewInnerTemperature( currentInnerTemperature, - calcInnerTemperatureChange(thermalEnergyChange) + calcInnerTemperatureChange(thermalEnergyChange), ) } @@ -222,7 +222,7 @@ final case class ThermalHouse( */ private def calcNewInnerTemperature( oldInnerTemperature: Temperature, - temperatureChange: Temperature + temperatureChange: Temperature, ): Temperature = oldInnerTemperature + temperatureChange @@ -251,7 +251,7 @@ final case class ThermalHouse( */ private def calcThermalEnergyChange( thermalEnergyGain: Energy, - thermalEnergyLoss: Energy + thermalEnergyLoss: Energy, ): Energy = thermalEnergyGain - thermalEnergyLoss @@ -266,7 +266,7 @@ final case class ThermalHouse( */ private def calcThermalEnergyGain( pThermal: Power, - time: Time + time: Time, ): Energy = pThermal * time /** Calculate the thermal energy loss due to the temperature deviation over @@ -284,12 +284,12 @@ final case class ThermalHouse( private def calcThermalEnergyLoss( innerTemperature: Temperature, ambientTemperature: Temperature, - time: Time + time: Time, ): Energy = { ethLosses.thermalConductanceToEnergy( innerTemperature, ambientTemperature, - time + time, ) } @@ -310,14 +310,14 @@ final case class ThermalHouse( tick: Long, state: ThermalHouseState, ambientTemperature: Temperature, - qDot: Power + qDot: Power, ): (ThermalHouseState, Option[ThermalThreshold]) = { val duration = Seconds(tick - state.tick) val updatedInnerTemperature = newInnerTemperature( state.qDot, duration, state.innerTemperature, - ambientTemperature + ambientTemperature, ) /* Calculate the next given threshold */ @@ -328,9 +328,9 @@ final case class ThermalHouse( state.copy( tick = tick, innerTemperature = updatedInnerTemperature, - qDot = qDot + qDot = qDot, ), - threshold + threshold, ) } @@ -350,13 +350,13 @@ final case class ThermalHouse( tick: Long, qDotExternal: Power, innerTemperature: Temperature, - ambientTemperature: Temperature + ambientTemperature: Temperature, ): Option[ThermalThreshold] = { val artificialDuration = Hours(1d) val loss = calcThermalEnergyLoss( innerTemperature, ambientTemperature, - artificialDuration + artificialDuration, ) / artificialDuration val resultingQDot = qDotExternal - loss if ( @@ -369,7 +369,7 @@ final case class ThermalHouse( tick, innerTemperature, lowerBoundaryTemperature, - resultingQDot + resultingQDot, ).map(HouseTemperatureLowerBoundaryReached) } else if ( resultingQDot > Megawatts(0d) && !isInnerTemperatureTooHigh( @@ -381,7 +381,7 @@ final case class ThermalHouse( tick, upperBoundaryTemperature, innerTemperature, - resultingQDot + resultingQDot, ).map(HouseTemperatureUpperBoundaryReached) } else { /* House is in perfect balance */ @@ -393,7 +393,7 @@ final case class ThermalHouse( tick: Long, higherTemperature: Temperature, lowerTemperature: Temperature, - qDot: Power + qDot: Power, ): Option[Long] = { val flexibleEnergy = energy(higherTemperature, lowerTemperature) if (flexibleEnergy < MegawattHours(0d)) @@ -437,7 +437,7 @@ object ThermalHouse { ), Kelvin( input.getUpperTemperatureLimit.to(Units.KELVIN).getValue.doubleValue - ) + ), ) /** State of a thermal house @@ -452,14 +452,14 @@ object ThermalHouse { final case class ThermalHouseState( tick: Long, innerTemperature: Temperature, - qDot: Power + qDot: Power, ) def startingState(house: ThermalHouse): ThermalHouseState = ThermalHouseState( -1L, house.targetTemperature, - Megawatts(0d) + Megawatts(0d), ) object ThermalHouseThreshold { diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalSink.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalSink.scala index 9b46902d8f..97661b0201 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalSink.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalSink.scala @@ -30,5 +30,5 @@ abstract class ThermalSink( id: String, operatorInput: OperatorInput, operationTime: OperationTime, - bus: ThermalBusInput + bus: ThermalBusInput, ) diff --git a/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala b/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala index 33304c8974..03460fee5e 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalStorage.scala @@ -42,7 +42,7 @@ abstract class ThermalStorage( bus: ThermalBusInput, minEnergyThreshold: Energy, maxEnergyThreshold: Energy, - chargingPower: Power + chargingPower: Power, ) { protected val zeroEnergy: Energy = KilowattHours(0d) @@ -70,7 +70,7 @@ abstract class ThermalStorage( def updateState( tick: Long, qDot: Power, - lastState: ThermalStorageState + lastState: ThermalStorageState, ): (ThermalStorageState, Option[ThermalThreshold]) } @@ -78,7 +78,7 @@ object ThermalStorage { final case class ThermalStorageState( tick: Long, storedEnergy: Energy, - qDot: Power + qDot: Power, ) object ThermalStorageThreshold { diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala index d82961cd5a..3d10fe3f5a 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/PowerMessage.scala @@ -41,7 +41,7 @@ object PowerMessage { final case class RequestAssetPowerMessage( currentTick: Long, eInPu: Dimensionless, - fInPu: Dimensionless + fInPu: Dimensionless, ) extends PowerRequestMessage /** Provide power values as a reply to a [[RequestAssetPowerMessage]] @@ -53,7 +53,7 @@ object PowerMessage { */ final case class AssetPowerChangedMessage( override val p: Power, - override val q: ReactivePower + override val q: ReactivePower, ) extends ProvidePowerMessage /** Provide values as a reply to a [[RequestAssetPowerMessage]]. In contrast @@ -67,7 +67,7 @@ object PowerMessage { */ final case class AssetPowerUnchangedMessage( override val p: Power, - override val q: ReactivePower + override val q: ReactivePower, ) extends ProvidePowerMessage /** Request complex power at the nodes that the inferior sub grid shares with @@ -79,7 +79,7 @@ object PowerMessage { */ final case class RequestGridPowerMessage( currentSweepNo: Int, - nodeUuids: Seq[UUID] + nodeUuids: Seq[UUID], ) extends PowerRequestMessage /** Provide complex power at the nodes that the sender's sub grid shares with @@ -105,7 +105,7 @@ object PowerMessage { final case class ExchangePower( nodeUuid: UUID, override val p: Power, - override val q: ReactivePower + override val q: ReactivePower, ) extends ProvidePowerMessage } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala index 866cae63a8..02c1918fc1 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala @@ -15,13 +15,13 @@ trait SchedulerMessage extends Scheduler.Incoming with TimeAdvancer.Incoming object SchedulerMessage { final case class Completion( actor: ActorRef[Activation], - newTick: Option[Long] = None + newTick: Option[Long] = None, ) extends SchedulerMessage final case class ScheduleActivation( actor: ActorRef[Activation], tick: Long, - unlockKey: Option[ScheduleKey] = None + unlockKey: Option[ScheduleKey] = None, ) extends SchedulerMessage } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala index 3c836b599d..eea6675941 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala @@ -27,7 +27,7 @@ object VoltageMessage { */ final case class RequestSlackVoltageMessage( currentSweepNo: Int, - nodeUuids: Seq[UUID] + nodeUuids: Seq[UUID], ) extends VoltageMessage /** Provide complex voltage at the nodes that the sender's sub grid shares @@ -38,7 +38,7 @@ object VoltageMessage { */ final case class ProvideSlackVoltageMessage( currentSweepNo: Int, - nodalSlackVoltages: Seq[ExchangeVoltage] + nodalSlackVoltages: Seq[ExchangeVoltage], ) extends VoltageMessage object ProvideSlackVoltageMessage { @@ -55,7 +55,7 @@ object VoltageMessage { final case class ExchangeVoltage( nodeUuid: UUID, e: ElectricPotential, - f: ElectricPotential + f: ElectricPotential, ) } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala index 7a4706c3c4..f6994db75c 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/FlexibilityMessage.scala @@ -49,7 +49,7 @@ object FlexibilityMessage { final case class RegisterParticipant( override val modelUuid: UUID, participant: ActorRef[FlexRequest], - inputModel: AssetInput + inputModel: AssetInput, ) extends FlexResponse /** Message that schedules a flex request for a flex options provider at given @@ -66,7 +66,7 @@ object FlexibilityMessage { final case class ScheduleFlexRequest( override val modelUuid: UUID, tick: Long, - scheduleKey: Option[ScheduleKey] = None + scheduleKey: Option[ScheduleKey] = None, ) extends FlexResponse /** Message that requests flex options from a flex options provider for given @@ -101,7 +101,7 @@ object FlexibilityMessage { */ final case class IssuePowerControl( override val tick: Long, - setPower: Power + setPower: Power, ) extends IssueFlexControl /** Message sent by [[edu.ie3.simona.agent.em.EmAgent]] indicating that no @@ -137,7 +137,7 @@ object FlexibilityMessage { override val modelUuid: UUID, result: ApparentPower, requestAtNextActivation: Boolean = false, - requestAtTick: Option[Long] = None + requestAtTick: Option[Long] = None, ) extends FlexResponse } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala index 59fc3b0935..c814b14ef0 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessage.scala @@ -38,7 +38,7 @@ object MinMaxFlexibilityMessage { override val modelUuid: UUID, ref: Power, min: Power, - max: Power + max: Power, ) extends ProvideFlexOptions { /** Checks whether given power fits within the min-max interval and thus @@ -76,7 +76,7 @@ object MinMaxFlexibilityMessage { modelUuid: UUID, ref: Power, min: Power, - max: Power + max: Power, ): ProvideMinMaxFlexOptions = { if (min > ref) throw new CriticalFailureException( @@ -103,7 +103,7 @@ object MinMaxFlexibilityMessage { */ def noFlexOption( modelUuid: UUID, - power: Power + power: Power, ): ProvideMinMaxFlexOptions = ProvideMinMaxFlexOptions(modelUuid, power, power, power) } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala index 404cf9e8aa..05a5be6886 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/EvMessage.scala @@ -10,7 +10,7 @@ import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ProvisionMessage, - ServiceRegistrationMessage + ServiceRegistrationMessage, } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import org.apache.pekko.actor.ActorRef @@ -49,7 +49,7 @@ object EvMessage { override val serviceRef: ActorRef, override val data: EvData, override val nextDataTick: Option[Long] = None, - override val unlockKey: Option[ScheduleKey] = None + override val unlockKey: Option[ScheduleKey] = None, ) extends EvMessage with ProvisionMessage[EvData] @@ -82,12 +82,12 @@ object EvMessage { final case class FreeLotsResponse( evcs: UUID, - freeLots: Int + freeLots: Int, ) extends EvResponseMessage final case class DepartingEvsResponse( evcs: UUID, - evModels: Seq[EvModelWrapper] + evModels: Seq[EvModelWrapper], ) extends EvResponseMessage } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala index 6bd8f79b72..73aa482b64 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/PrimaryDataMessage.scala @@ -30,7 +30,7 @@ object PrimaryDataMessage { override val serviceRef: ActorRef, override val data: ApparentPower, override val nextDataTick: Option[Long], - override val unlockKey: Option[ScheduleKey] = None + override val unlockKey: Option[ScheduleKey] = None, ) extends ProvisionMessage[ApparentPower] with PrimaryDataMessage } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala index 3f061c201c..33946b669f 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/ServiceMessage.scala @@ -51,7 +51,7 @@ case object ServiceMessage { */ final case class RegistrationSuccessfulMessage( override val serviceRef: ActorRef, - nextDataTick: Option[Long] + nextDataTick: Option[Long], ) extends RegistrationResponseMessage /** Message, that is used to announce a failed registration @@ -62,7 +62,7 @@ case object ServiceMessage { final case class ScheduleServiceActivation( tick: Long, - unlockKey: ScheduleKey + unlockKey: ScheduleKey, ) } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala index 1af4f8ae43..9d17284d63 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/services/WeatherMessage.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.ontology.messages.services import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ ProvisionMessage, - ServiceRegistrationMessage + ServiceRegistrationMessage, } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.util.scala.quantities.Irradiance @@ -36,7 +36,7 @@ object WeatherMessage { */ final case class RegisterForWeatherMessage( latitude: Double, - longitude: Double + longitude: Double, ) extends WeatherMessage with ServiceRegistrationMessage @@ -54,7 +54,7 @@ object WeatherMessage { override val serviceRef: ActorRef, override val data: WeatherData, override val nextDataTick: Option[Long], - override val unlockKey: Option[ScheduleKey] = None + override val unlockKey: Option[ScheduleKey] = None, ) extends WeatherMessage with ProvisionMessage[WeatherData] @@ -74,7 +74,7 @@ object WeatherMessage { diffIrr: Irradiance, dirIrr: Irradiance, temp: Temperature, - windVel: Velocity + windVel: Velocity, ) extends SecondaryData } diff --git a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala index 4e11d597e2..844021c530 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/RuntimeNotifier.scala @@ -36,7 +36,7 @@ final case class RuntimeNotifier( private val lastCheck: Option[Long] = None, private val simStartTime: Option[Long] = None, private val lastStartTime: Option[Long] = None, - private val lastCheckWindowTime: Option[Long] = None + private val lastCheckWindowTime: Option[Long] = None, ) { /** Notifier listeners that simulation has started or continued with given @@ -53,7 +53,7 @@ final case class RuntimeNotifier( def starting( tick: Long, pauseTick: Option[Long], - endTick: Long + endTick: Long, ): RuntimeNotifier = { val nowTime = now() @@ -72,7 +72,7 @@ final case class RuntimeNotifier( copy( simStartTime = Some(nowTime), lastStartTime = Some(nowTime), - lastCheckWindowTime = Some(nowTime) + lastCheckWindowTime = Some(nowTime), ) } @@ -119,7 +119,7 @@ final case class RuntimeNotifier( .map { lastPassedCheck => copy( lastCheck = Some(lastPassedCheck), - lastCheckWindowTime = Some(nowTime) + lastCheckWindowTime = Some(nowTime), ) } } @@ -139,7 +139,7 @@ final case class RuntimeNotifier( Done( endTick, duration(simStartTime), - errorInSim = false + errorInSim = false, ) ) } @@ -160,7 +160,7 @@ final case class RuntimeNotifier( Done( endTick, duration(simStartTime), - errorInSim = true + errorInSim = true, ) ) } @@ -185,7 +185,7 @@ object RuntimeNotifier { */ private def duration( intervalStart: Option[Long], - intervalEnd: Long = now() + intervalEnd: Long = now(), ): Long = intervalStart.map(intervalEnd - _).getOrElse(0) diff --git a/src/main/scala/edu/ie3/simona/scheduler/ScheduleLock.scala b/src/main/scala/edu/ie3/simona/scheduler/ScheduleLock.scala index e9ca91c0d1..803d223987 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/ScheduleLock.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/ScheduleLock.scala @@ -11,7 +11,7 @@ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior, Scheduler} import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} @@ -38,7 +38,7 @@ object ScheduleLock { private def lockAdapter( lock: ActorRef[LockMsg], - expectedTick: Long + expectedTick: Long, ): Behavior[Activation] = Behaviors.receive { case (ctx, Activation(tick)) => if (tick == expectedTick) @@ -95,7 +95,7 @@ object ScheduleLock { def singleKey( ctx: ActorContext[_], scheduler: ActorRef[SchedulerMessage], - tick: Long + tick: Long, ): ScheduleKey = singleKey(TypedSpawner(ctx), scheduler, tick) @@ -114,7 +114,7 @@ object ScheduleLock { def singleKey( ctx: org.apache.pekko.actor.ActorContext, scheduler: ActorRef[SchedulerMessage], - tick: Long + tick: Long, ): ScheduleKey = singleKey(ClassicSpawner(ctx), scheduler, tick) @@ -133,7 +133,7 @@ object ScheduleLock { def singleKey( spawner: Spawner, scheduler: ActorRef[SchedulerMessage], - tick: Long + tick: Long, ): ScheduleKey = multiKey(spawner, scheduler, tick, 1).headOption.getOrElse( throw new RuntimeException("Should not happen") @@ -157,7 +157,7 @@ object ScheduleLock { ctx: ActorContext[_], scheduler: ActorRef[SchedulerMessage], tick: Long, - count: Int + count: Int, ): Iterable[ScheduleKey] = multiKey(TypedSpawner(ctx), scheduler, tick, count) @@ -179,7 +179,7 @@ object ScheduleLock { ctx: org.apache.pekko.actor.ActorContext, scheduler: ActorRef[SchedulerMessage], tick: Long, - count: Int + count: Int, ): Iterable[ScheduleKey] = multiKey(ClassicSpawner(ctx), scheduler, tick, count) @@ -201,7 +201,7 @@ object ScheduleLock { spawner: Spawner, scheduler: ActorRef[SchedulerMessage], tick: Long, - count: Int + count: Int, ): Iterable[ScheduleKey] = { val keys = (1 to count).map(_ => UUID.randomUUID()) @@ -227,7 +227,7 @@ object ScheduleLock { */ private def apply( scheduler: ActorRef[SchedulerMessage], - awaitedKeys: Set[UUID] + awaitedKeys: Set[UUID], ): Behavior[LockMsg] = Behaviors.withStash(100) { buffer => Behaviors.receiveMessage { @@ -244,7 +244,7 @@ object ScheduleLock { private def uninitialized( scheduler: ActorRef[SchedulerMessage], awaitedKeys: Set[UUID], - adapter: ActorRef[Activation] + adapter: ActorRef[Activation], ): Behavior[LockMsg] = Behaviors.withStash(100) { buffer => Behaviors.receiveMessage { @@ -261,7 +261,7 @@ object ScheduleLock { private def active( scheduler: ActorRef[SchedulerMessage], awaitedKeys: Set[UUID], - adapter: ActorRef[Activation] + adapter: ActorRef[Activation], ): Behavior[LockMsg] = Behaviors.receiveMessage { case Unlock(key) => val updatedKeys = awaitedKeys - key diff --git a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala index bac0df01ae..1c5f37ad2f 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala @@ -11,13 +11,13 @@ import org.apache.pekko.actor.typed.{ActorRef, Behavior} import edu.ie3.simona.actor.ActorUtil.stopOnError import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.core.Core.{ ActiveCore, CoreFactory, - InactiveCore + InactiveCore, } import edu.ie3.simona.scheduler.core.RegularSchedulerCore @@ -42,20 +42,20 @@ object Scheduler { */ def apply( parent: ActorRef[SchedulerMessage], - coreFactory: CoreFactory = RegularSchedulerCore + coreFactory: CoreFactory = RegularSchedulerCore, ): Behavior[Incoming] = Behaviors.setup { ctx => val adapter = ctx.messageAdapter[Activation](msg => WrappedActivation(msg)) inactive( SchedulerData(parent, adapter), - coreFactory.create() + coreFactory.create(), ) } private def inactive( data: SchedulerData, - core: InactiveCore + core: InactiveCore, ): Behavior[Incoming] = Behaviors.receive { case (ctx, WrappedActivation(Activation(tick))) => @@ -71,7 +71,7 @@ object Scheduler { case ( ctx, - ScheduleActivation(actor, newTick, unlockKey) + ScheduleActivation(actor, newTick, unlockKey), ) => if (core.checkSchedule(newTick)) { val (maybeSchedule, newCore) = core.handleSchedule(actor, newTick) @@ -84,7 +84,7 @@ object Scheduler { data.parent ! ScheduleActivation( data.activationAdapter, scheduleTick, - unlockKey + unlockKey, ) case None => // we don't need to escalate to the parent, this means that we can release the lock (if applicable) @@ -100,18 +100,18 @@ object Scheduler { case (ctx, unexpected) => stopOnError( ctx, - s"Received unexpected message $unexpected when inactive" + s"Received unexpected message $unexpected when inactive", ) } private def active( data: SchedulerData, - core: ActiveCore + core: ActiveCore, ): Behavior[Incoming] = Behaviors.receive { case ( ctx, - ScheduleActivation(actor, newTick, unlockKey) + ScheduleActivation(actor, newTick, unlockKey), ) => if (core.checkSchedule(actor, newTick)) { val (toActivate, newCore) = @@ -138,7 +138,7 @@ object Scheduler { .cond( core.checkCompletion(actor), core.handleCompletion(actor), - s"Actor $actor is not part of the expected completing actors" + s"Actor $actor is not part of the expected completing actors", ) .flatMap { newCore => // if successful @@ -148,7 +148,7 @@ object Scheduler { .cond( newCore.checkSchedule(actor, newTick), newCore.handleSchedule(actor, newTick), - s"Cannot schedule an event at tick $newTick for completing actor $actor" + s"Cannot schedule an event at tick $newTick for completing actor $actor", ) } .getOrElse(Right(newCore)) @@ -167,7 +167,7 @@ object Scheduler { .map { case (maybeScheduleTick, inactiveCore) => data.parent ! Completion( data.activationAdapter, - maybeScheduleTick + maybeScheduleTick, ) inactive(data, inactiveCore) } @@ -177,7 +177,7 @@ object Scheduler { } .fold( stopOnError(ctx, _), - identity + identity, ) case (ctx, unexpected) => @@ -194,6 +194,6 @@ object Scheduler { parent: ActorRef[ SchedulerMessage ], - activationAdapter: ActorRef[Activation] + activationAdapter: ActorRef[Activation], ) } diff --git a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala index 5931cbb08a..63aac6d223 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala @@ -13,7 +13,7 @@ import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.sim.SimMessage.{SimulationFailure, SimulationSuccessful} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK @@ -56,14 +56,14 @@ object TimeAdvancer { simulation: org.apache.pekko.actor.ActorRef, eventListener: Option[ActorRef[RuntimeEvent]], checkWindow: Option[Int], - endTick: Long + endTick: Long, ): Behavior[Incoming] = Behaviors.receivePartial { case (_, ScheduleActivation(actor, tick, _)) => inactive( TimeAdvancerData(simulation, actor, endTick), eventListener.map(RuntimeNotifier(_, checkWindow)), tick, - tick + tick, ) case (ctx, Stop(errorMsg: String)) => @@ -86,14 +86,14 @@ object TimeAdvancer { data: TimeAdvancerData, notifier: Option[RuntimeNotifier], startingTick: Long, - nextActiveTick: Long + nextActiveTick: Long, ): Behavior[Incoming] = Behaviors.receivePartial { case (_, StartSimMessage(pauseTick)) => val updatedNotifier = notifier.map { _.starting( startingTick, pauseTick, - data.endTick + data.endTick, ) } @@ -103,7 +103,7 @@ object TimeAdvancer { data, updatedNotifier, nextActiveTick, - pauseTick + pauseTick, ) case (ctx, Stop(errorMsg: String)) => @@ -126,7 +126,7 @@ object TimeAdvancer { data: TimeAdvancerData, notifier: Option[RuntimeNotifier], activeTick: Long, - pauseTick: Option[Long] + pauseTick: Option[Long], ): Behavior[Incoming] = Behaviors.receivePartial { case (ctx, Completion(_, maybeNewTick)) => checkCompletion(activeTick, maybeNewTick) @@ -152,7 +152,7 @@ object TimeAdvancer { data, updatedNotifier, pauseTick + 1, - newTick + newTick, ) case (Some(newTick), _) => @@ -165,7 +165,7 @@ object TimeAdvancer { notifierCompleted.starting( newTick, pauseTick, - data.endTick + data.endTick, ) else notifierCompleted @@ -177,7 +177,7 @@ object TimeAdvancer { data, updatedNotifier, newTick, - pauseTick + pauseTick, ) case (None, _) => @@ -195,7 +195,7 @@ object TimeAdvancer { private def endSuccessfully( data: TimeAdvancerData, - notifier: Option[RuntimeNotifier] + notifier: Option[RuntimeNotifier], ): Behavior[Incoming] = { data.simulation ! SimulationSuccessful @@ -214,7 +214,7 @@ object TimeAdvancer { simulation: org.apache.pekko.actor.ActorRef, notifier: Option[RuntimeNotifier], tick: Long, - errorMsg: String + errorMsg: String, ): Behavior[Incoming] = { simulation ! SimulationFailure notifier.foreach(_.error(tick, errorMsg)) @@ -224,7 +224,7 @@ object TimeAdvancer { private def checkCompletion( activeTick: Long, - maybeNewTick: Option[Long] + maybeNewTick: Option[Long], ): Option[String] = maybeNewTick.filter(_ <= activeTick).map { newTick => s"The next trigger has tick $newTick, although current active tick was $activeTick." @@ -243,6 +243,6 @@ object TimeAdvancer { private final case class TimeAdvancerData( simulation: org.apache.pekko.actor.ActorRef, schedulee: ActorRef[Activation], - endTick: Long + endTick: Long, ) } diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala b/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala index 7fa9220bb5..2735d7f0f4 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/Core.scala @@ -76,7 +76,7 @@ object Core { */ def handleSchedule( actor: Actor, - newTick: Long + newTick: Long, ): (Option[Long], InactiveCore) } diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala b/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala index c6384db107..a1a9ab08e2 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/PhaseSwitchCore.scala @@ -10,7 +10,7 @@ import edu.ie3.simona.scheduler.core.Core.{ ActiveCore, Actor, CoreFactory, - InactiveCore + InactiveCore, } import edu.ie3.util.scala.collection.immutable.PrioritySwitchBiSet @@ -32,7 +32,7 @@ object PhaseSwitchCore extends CoreFactory { final case class PhaseSwitchInactive private ( private val activationQueue: PrioritySwitchBiSet[Long, Actor], - private val lastActiveTick: Option[Long] + private val lastActiveTick: Option[Long], ) extends InactiveCore { override def checkActivation(newTick: Long): Boolean = activationQueue.headKeyOption.contains(newTick) @@ -49,7 +49,7 @@ object PhaseSwitchCore extends CoreFactory { override def handleSchedule( actor: Actor, - newTick: Long + newTick: Long, ): (Option[Long], InactiveCore) = { val oldEarliestTick = activationQueue.headKeyOption @@ -68,7 +68,7 @@ object PhaseSwitchCore extends CoreFactory { private val activationQueue: PrioritySwitchBiSet[Long, Actor], activeTick: Long, private val phase: Int = 0, - private val activeActors: Set[Actor] = Set.empty + private val activeActors: Set[Actor] = Set.empty, ) extends ActiveCore { override def checkCompletion(actor: Actor): Boolean = @@ -85,7 +85,7 @@ object PhaseSwitchCore extends CoreFactory { ) { ( activationQueue.headKeyOption, - PhaseSwitchInactive(activationQueue, Some(activeTick)) + PhaseSwitchInactive(activationQueue, Some(activeTick)), ) } } @@ -123,8 +123,8 @@ object PhaseSwitchCore extends CoreFactory { copy( activationQueue = updatedQueue, phase = newPhase, - activeActors = activeActors.incl(actor) - ) + activeActors = activeActors.incl(actor), + ), ) } .getOrElse((Iterable.empty, this)) diff --git a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala index cdc81cfdff..b7e96b3c6c 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/core/RegularSchedulerCore.scala @@ -10,7 +10,7 @@ import edu.ie3.simona.scheduler.core.Core.{ ActiveCore, Actor, CoreFactory, - InactiveCore + InactiveCore, } import edu.ie3.util.scala.collection.mutable.PriorityMultiBiSet @@ -24,7 +24,7 @@ object RegularSchedulerCore extends CoreFactory { final case class SchedulerInactive private ( private val activationQueue: PriorityMultiBiSet[Long, Actor], - private val lastActiveTick: Option[Long] + private val lastActiveTick: Option[Long], ) extends InactiveCore { override def checkActivation(newTick: Long): Boolean = activationQueue.headKeyOption.contains(newTick) @@ -41,7 +41,7 @@ object RegularSchedulerCore extends CoreFactory { override def handleSchedule( actor: Actor, - newTick: Long + newTick: Long, ): (Option[Long], InactiveCore) = { val oldEarliestTick = activationQueue.headKeyOption @@ -59,7 +59,7 @@ object RegularSchedulerCore extends CoreFactory { private final case class SchedulerActive( private val activationQueue: PriorityMultiBiSet[Long, Actor], private val activeActors: Set[Actor] = Set.empty, - activeTick: Long + activeTick: Long, ) extends ActiveCore { override def checkCompletion(actor: Actor): Boolean = activeActors.contains(actor) @@ -74,7 +74,7 @@ object RegularSchedulerCore extends CoreFactory { ) { ( activationQueue.headKeyOption, - SchedulerInactive(activationQueue, Some(activeTick)) + SchedulerInactive(activationQueue, Some(activeTick)), ) } diff --git a/src/main/scala/edu/ie3/simona/service/SimonaService.scala b/src/main/scala/edu/ie3/simona/service/SimonaService.scala index 89d60e57c4..1b41b30400 100644 --- a/src/main/scala/edu/ie3/simona/service/SimonaService.scala +++ b/src/main/scala/edu/ie3/simona/service/SimonaService.scala @@ -12,14 +12,14 @@ import edu.ie3.simona.logging.SimonaActorLogging import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.ScheduleServiceActivation import edu.ie3.simona.ontology.messages.services.ServiceMessage.ServiceRegistrationMessage import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.service.ServiceStateData.{ InitializeServiceStateData, - ServiceBaseStateData + ServiceBaseStateData, } import edu.ie3.simona.service.SimonaService.Create import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK @@ -35,7 +35,7 @@ object SimonaService { */ final case class Create[+I <: InitializeServiceStateData]( initializeStateData: I, - unlockKey: ScheduleKey + unlockKey: ScheduleKey, ) } @@ -66,12 +66,12 @@ abstract class SimonaService[ case Create( initializeStateData: InitializeServiceStateData, - unlockKey: ScheduleKey + unlockKey: ScheduleKey, ) => scheduler ! ScheduleActivation( self.toTyped, INIT_SIM_TICK, - Some(unlockKey) + Some(unlockKey), ) context become initializing(initializeStateData) @@ -103,7 +103,7 @@ abstract class SimonaService[ s"\nReceivedData: {}" + s"\nException: {}", initializeStateData, - exception + exception, ) throw exception // if a service fails startup we don't want to go on with the simulation } @@ -142,7 +142,7 @@ abstract class SimonaService[ "\nMsg: {}" + "\nException: {}", registrationMsg, - exception + exception, ) unhandled(registrationMsg) } @@ -151,7 +151,7 @@ abstract class SimonaService[ scheduler ! ScheduleActivation( self.toTyped, tick, - Some(unlockKey) + Some(unlockKey), ) // activity start trigger for this service @@ -226,7 +226,7 @@ abstract class SimonaService[ */ protected def announceInformation(tick: Long)(implicit serviceStateData: S, - ctx: ActorContext + ctx: ActorContext, ): (S, Option[Long]) } diff --git a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala index 2ccb45197a..c827cb52fb 100644 --- a/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala +++ b/src/main/scala/edu/ie3/simona/service/ev/ExtEvDataService.scala @@ -21,11 +21,11 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.ServiceRegistrat import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.service.ServiceStateData.{ InitializeServiceStateData, - ServiceBaseStateData + ServiceBaseStateData, } import edu.ie3.simona.service.ev.ExtEvDataService.{ ExtEvStateData, - InitExtEvData + InitExtEvData, } import edu.ie3.simona.service.{ExtDataSupport, ServiceStateData, SimonaService} import edu.ie3.simona.util.ReceiveDataMap @@ -47,7 +47,7 @@ object ExtEvDataService { extEvMessage: Option[EvDataMessageFromExt] = None, freeLots: ReceiveDataMap[UUID, Int] = ReceiveDataMap.empty, departingEvResponses: ReceiveDataMap[UUID, Seq[EvModelWrapper]] = - ReceiveDataMap.empty + ReceiveDataMap.empty, ) extends ServiceBaseStateData final case class InitExtEvData( @@ -65,7 +65,7 @@ class ExtEvDataService(override val scheduler: ActorRef) ): Try[ ( ExtEvStateData, - Option[Long] + Option[Long], ) ] = initServiceData match { @@ -76,7 +76,7 @@ class ExtEvDataService(override val scheduler: ActorRef) Success( evInitializedStateData, - None + None, ) case invalidData => @@ -129,14 +129,14 @@ class ExtEvDataService(override val scheduler: ActorRef) */ private def handleRegistrationRequest( agentToBeRegistered: ActorRef, - evcs: UUID + evcs: UUID, )(implicit serviceStateData: ExtEvStateData ): ExtEvStateData = { log.debug( "Received ev movement service registration from {} for [Evcs:{}]", agentToBeRegistered.path.name, - evcs + evcs, ) serviceStateData.uuidToActorRef.get(evcs) match { @@ -152,7 +152,7 @@ class ExtEvDataService(override val scheduler: ActorRef) // actor is already registered, do nothing log.warning( "Sending actor {} is already registered", - agentToBeRegistered + agentToBeRegistered, ) serviceStateData } @@ -173,7 +173,7 @@ class ExtEvDataService(override val scheduler: ActorRef) tick: Long )(implicit serviceStateData: ExtEvStateData, ctx: ActorContext): ( ExtEvStateData, - Option[Long] + Option[Long], ) = { serviceStateData.extEvMessage.getOrElse( throw ServiceException( @@ -187,7 +187,7 @@ class ExtEvDataService(override val scheduler: ActorRef) case arrivingEvsProvision: ProvideArrivingEvs => handleArrivingEvs(tick, arrivingEvsProvision.arrivals)( serviceStateData, - ctx + ctx, ) } } @@ -211,15 +211,15 @@ class ExtEvDataService(override val scheduler: ActorRef) ( serviceStateData.copy( extEvMessage = None, - freeLots = ReceiveDataMap(freeLots) + freeLots = ReceiveDataMap(freeLots), ), - None + None, ) } private def requestDepartingEvs( tick: Long, - requestedDepartingEvs: java.util.Map[UUID, java.util.List[UUID]] + requestedDepartingEvs: java.util.Map[UUID, java.util.List[UUID]], )(implicit serviceStateData: ExtEvStateData ): (ExtEvStateData, Option[Long]) = { @@ -235,7 +235,7 @@ class ExtEvDataService(override val scheduler: ActorRef) case None => log.warning( "A corresponding actor ref for UUID {} could not be found", - evcs + evcs, ) None @@ -250,18 +250,18 @@ class ExtEvDataService(override val scheduler: ActorRef) ( serviceStateData.copy( extEvMessage = None, - departingEvResponses = ReceiveDataMap(departingEvResponses.toSet) + departingEvResponses = ReceiveDataMap(departingEvResponses.toSet), ), - None + None, ) } private def handleArrivingEvs( tick: Long, - allArrivingEvs: java.util.Map[UUID, java.util.List[EvModel]] + allArrivingEvs: java.util.Map[UUID, java.util.List[EvModel]], )(implicit serviceStateData: ExtEvStateData, - ctx: ActorContext + ctx: ActorContext, ): (ExtEvStateData, Option[Long]) = { val actorToEvs = allArrivingEvs.asScala.flatMap { case (evcs, arrivingEvs) => @@ -271,7 +271,7 @@ class ExtEvDataService(override val scheduler: ActorRef) .orElse { log.warning( "A corresponding actor ref for UUID {} could not be found", - evcs + evcs, ) None } @@ -286,7 +286,7 @@ class ExtEvDataService(override val scheduler: ActorRef) tick, self, ArrivingEvsData(arrivingEvs), - unlockKey = Some(key) + unlockKey = Some(key), ) } @@ -296,7 +296,7 @@ class ExtEvDataService(override val scheduler: ActorRef) serviceStateData.copy( extEvMessage = None ), - None + None, ) } diff --git a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala index 23e28146b1..688ea5c5c3 100644 --- a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala +++ b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceProxy.scala @@ -14,19 +14,19 @@ import edu.ie3.datamodel.io.naming.timeseries.IndividualTimeSeriesMetaInformatio import edu.ie3.datamodel.io.naming.{ DatabaseNamingStrategy, EntityPersistenceNamingStrategy, - FileNamingStrategy + FileNamingStrategy, } import edu.ie3.datamodel.io.source.csv.{ CsvTimeSeriesMappingSource, - CsvTimeSeriesMetaInformationSource + CsvTimeSeriesMetaInformationSource, } import edu.ie3.datamodel.io.source.sql.{ SqlTimeSeriesMappingSource, - SqlTimeSeriesMetaInformationSource + SqlTimeSeriesMetaInformationSource, } import edu.ie3.datamodel.io.source.{ TimeSeriesMappingSource, - TimeSeriesMetaInformationSource + TimeSeriesMetaInformationSource, } import edu.ie3.datamodel.models.value.Value import edu.ie3.simona.config.SimonaConfig.PrimaryDataCsvParams @@ -36,7 +36,7 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Input.{ } import edu.ie3.simona.exceptions.{ InitializationException, - InvalidConfigParameterException + InvalidConfigParameterException, } import edu.ie3.simona.logging.SimonaActorLogging import edu.ie3.simona.ontology.messages.Activation @@ -44,7 +44,7 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationFailedMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ PrimaryServiceRegistrationMessage, - WorkerRegistrationMessage + WorkerRegistrationMessage, } import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.service.{ServiceStateData, SimonaService} @@ -52,12 +52,12 @@ import edu.ie3.simona.service.ServiceStateData.InitializeServiceStateData import edu.ie3.simona.service.primary.PrimaryServiceProxy.{ InitPrimaryServiceProxyStateData, PrimaryServiceStateData, - SourceRef + SourceRef, } import edu.ie3.simona.service.primary.PrimaryServiceWorker.{ CsvInitPrimaryServiceStateData, InitPrimaryServiceStateData, - SqlInitPrimaryServiceStateData + SqlInitPrimaryServiceStateData, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK @@ -84,7 +84,7 @@ import scala.util.{Failure, Success, Try} case class PrimaryServiceProxy( scheduler: ActorRef, initStateData: InitPrimaryServiceProxyStateData, - private implicit val startDateTime: ZonedDateTime + private implicit val startDateTime: ZonedDateTime, ) extends Actor with SimonaActorLogging { @@ -106,7 +106,7 @@ case class PrimaryServiceProxy( * messages */ prepareStateData( initStateData.primaryConfig, - initStateData.simulationStart + initStateData.simulationStart, ) match { case Success(stateData) => scheduler ! Completion(self.toTyped) @@ -114,7 +114,7 @@ case class PrimaryServiceProxy( case Failure(exception) => log.error( exception, - s"Unable to initialize the $actorName. Shut it down." + s"Unable to initialize the $actorName. Shut it down.", ) self ! PoisonPill } @@ -138,7 +138,7 @@ case class PrimaryServiceProxy( */ private def prepareStateData( primaryConfig: PrimaryConfig, - simulationStart: ZonedDateTime + simulationStart: ZonedDateTime, ): Try[PrimaryServiceStateData] = { createSources(primaryConfig).map { case (mappingSource, metaInformationSource) => @@ -161,7 +161,7 @@ case class PrimaryServiceProxy( case None => log.warning( "Unable to acquire meta information for time series '{}'. Leave that out.", - timeSeriesUuid + timeSeriesUuid, ) None } @@ -172,7 +172,7 @@ case class PrimaryServiceProxy( timeSeriesToSourceRef, simulationStart, primaryConfig, - mappingSource + mappingSource, ) } } @@ -184,7 +184,7 @@ case class PrimaryServiceProxy( primaryConfig.sqlParams, primaryConfig.influxDb1xParams, primaryConfig.csvParams, - primaryConfig.couchbaseParams + primaryConfig.couchbaseParams, ).filter(_.isDefined).flatten.headOption match { case Some(PrimaryDataCsvParams(csvSep, directoryPath, _, _)) => val fileNamingStrategy = new FileNamingStrategy() @@ -192,31 +192,31 @@ case class PrimaryServiceProxy( new CsvTimeSeriesMappingSource( csvSep, Paths.get(directoryPath), - fileNamingStrategy + fileNamingStrategy, ), new CsvTimeSeriesMetaInformationSource( csvSep, Paths.get(directoryPath), - fileNamingStrategy - ) + fileNamingStrategy, + ), ) case Some(sqlParams: SqlParams) => val sqlConnector = new SqlConnector( sqlParams.jdbcUrl, sqlParams.userName, - sqlParams.password + sqlParams.password, ) Success( new SqlTimeSeriesMappingSource( sqlConnector, sqlParams.schemaName, - new EntityPersistenceNamingStrategy() + new EntityPersistenceNamingStrategy(), ), new SqlTimeSeriesMetaInformationSource( sqlConnector, sqlParams.schemaName, - new DatabaseNamingStrategy() - ) + new DatabaseNamingStrategy(), + ), ) case Some(x) => Failure( @@ -253,12 +253,12 @@ case class PrimaryServiceProxy( modelUuid, timeSeriesUuid, stateData, - sender() + sender(), ) case None => log.debug( s"There is no time series apparent for the model with uuid '{}'.", - modelUuid + modelUuid, ) sender() ! RegistrationFailedMessage(self) } @@ -284,7 +284,7 @@ case class PrimaryServiceProxy( modelUuid: UUID, timeSeriesUuid: UUID, stateData: PrimaryServiceStateData, - requestingActor: ActorRef + requestingActor: ActorRef, ): Unit = { val timeSeriesToSourceRef = stateData.timeSeriesToSourceRef timeSeriesToSourceRef.get(timeSeriesUuid) match { @@ -297,7 +297,7 @@ case class PrimaryServiceProxy( initializeWorker( metaInformation, stateData.simulationStart, - stateData.primaryConfig + stateData.primaryConfig, ) match { case Success(workerRef) => /* Forward the registration request. The worker will reply about successful registration or not. */ @@ -311,7 +311,7 @@ case class PrimaryServiceProxy( log.warning( s"A failure occurred during spin-off of a primary source for time series '$timeSeriesUuid'. " + s"Will inform the requesting actor, that registration is not possible.", - exception + exception, ) requestingActor ! RegistrationFailedMessage(self) } @@ -340,21 +340,21 @@ case class PrimaryServiceProxy( protected def initializeWorker( metaInformation: IndividualTimeSeriesMetaInformation, simulationStart: ZonedDateTime, - primaryConfig: PrimaryConfig + primaryConfig: PrimaryConfig, ): Try[ActorRef] = { val workerRef = classToWorkerRef( metaInformation.getColumnScheme.getValueClass, - metaInformation.getUuid.toString + metaInformation.getUuid.toString, ) toInitData( metaInformation, simulationStart, - primaryConfig + primaryConfig, ) match { case Success(initData) => workerRef ! SimonaService.Create( initData, - ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK) + ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK), ) Success(workerRef) case Failure(cause) => @@ -362,7 +362,7 @@ case class PrimaryServiceProxy( Failure( new InitializationException( "Unable to build init data for worker. Kill the uninitialized worker. Goodbye my friend!", - cause + cause, ) ) } @@ -382,12 +382,12 @@ case class PrimaryServiceProxy( */ protected def classToWorkerRef[V <: Value]( valueClass: Class[V], - timeSeriesUuid: String + timeSeriesUuid: String, ): ActorRef = { import edu.ie3.simona.actor.SimonaActorNaming._ context.system.simonaActorOf( PrimaryServiceWorker.props(scheduler, valueClass), - timeSeriesUuid + timeSeriesUuid, ) } @@ -404,14 +404,14 @@ case class PrimaryServiceProxy( private def toInitData( metaInformation: IndividualTimeSeriesMetaInformation, simulationStart: ZonedDateTime, - primaryConfig: PrimaryConfig + primaryConfig: PrimaryConfig, ): Try[InitPrimaryServiceStateData] = primaryConfig match { case PrimaryConfig( None, Some(PrimaryDataCsvParams(csvSep, directoryPath, _, timePattern)), None, - None + None, ) => /* The actual data sources are from csv. Meta information have to match */ metaInformation match { @@ -424,7 +424,7 @@ case class PrimaryServiceProxy( Paths.get(directoryPath), csvMetaData.getFullFilePath, new FileNamingStrategy(), - timePattern + timePattern, ) ) case invalidMetaData => @@ -439,14 +439,14 @@ case class PrimaryServiceProxy( None, None, None, - Some(sqlParams: SqlParams) + Some(sqlParams: SqlParams), ) => Success( SqlInitPrimaryServiceStateData( metaInformation.getUuid, simulationStart, sqlParams, - new DatabaseNamingStrategy() + new DatabaseNamingStrategy(), ) ) @@ -472,18 +472,18 @@ case class PrimaryServiceProxy( private def updateStateData( stateData: PrimaryServiceStateData, timeSeriesUuid: UUID, - workerRef: ActorRef + workerRef: ActorRef, ): PrimaryServiceStateData = { val timeSeriesToSourceRef = stateData.timeSeriesToSourceRef val sourceRef = timeSeriesToSourceRef.getOrElse( timeSeriesUuid, throw new IllegalArgumentException( s"Cannot update entry for time series '$timeSeriesUuid', as it hasn't been part of it before." - ) + ), ) val updatedTimeSeriesToSourceRef = timeSeriesToSourceRef.updated( timeSeriesUuid, - sourceRef.copy(worker = Some(workerRef)) + sourceRef.copy(worker = Some(workerRef)), ) stateData.copy(timeSeriesToSourceRef = updatedTimeSeriesToSourceRef) } @@ -494,7 +494,7 @@ object PrimaryServiceProxy { def props( scheduler: ActorRef, initStateData: InitPrimaryServiceProxyStateData, - startDateTime: ZonedDateTime + startDateTime: ZonedDateTime, ): Props = Props( new PrimaryServiceProxy(scheduler, initStateData, startDateTime) ) @@ -509,7 +509,7 @@ object PrimaryServiceProxy { */ final case class InitPrimaryServiceProxyStateData( primaryConfig: PrimaryConfig, - simulationStart: ZonedDateTime + simulationStart: ZonedDateTime, ) extends InitializeServiceStateData /** Holding the state of an initialized proxy. @@ -530,7 +530,7 @@ object PrimaryServiceProxy { timeSeriesToSourceRef: Map[UUID, SourceRef], simulationStart: ZonedDateTime, primaryConfig: PrimaryConfig, - mappingSource: TimeSeriesMappingSource + mappingSource: TimeSeriesMappingSource, ) extends ServiceStateData /** Giving reference to the target time series and source worker. @@ -543,7 +543,7 @@ object PrimaryServiceProxy { */ final case class SourceRef( metaInformation: IndividualTimeSeriesMetaInformation, - worker: Option[ActorRef] + worker: Option[ActorRef], ) /** Check if the config holds correct information to instantiate a mapping @@ -574,7 +574,7 @@ object PrimaryServiceProxy { primaryConfig.couchbaseParams, primaryConfig.csvParams, primaryConfig.influxDb1xParams, - primaryConfig.sqlParams + primaryConfig.sqlParams, ).filter(_.isDefined).flatten if (sourceConfigs.size > 1) throw new InvalidConfigParameterException( diff --git a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala index c9da720690..7e5abcd6f9 100644 --- a/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala +++ b/src/main/scala/edu/ie3/simona/service/primary/PrimaryServiceWorker.scala @@ -25,11 +25,11 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResp import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.service.ServiceStateData.{ InitializeServiceStateData, - ServiceActivationBaseStateData + ServiceActivationBaseStateData, } import edu.ie3.simona.service.primary.PrimaryServiceWorker.{ PrimaryServiceInitializedStateData, - ProvidePrimaryDataMessage + ProvidePrimaryDataMessage, } import edu.ie3.simona.service.{ServiceStateData, SimonaService} import edu.ie3.simona.util.TickUtil.{RichZonedDateTime, TickLong} @@ -44,7 +44,7 @@ import scala.util.{Failure, Success, Try} final case class PrimaryServiceWorker[V <: Value]( override protected val scheduler: ActorRef, - valueClass: Class[V] + valueClass: Class[V], ) extends SimonaService[PrimaryServiceInitializedStateData[V]](scheduler) { /** Initialize the actor with the given information. Try to figure out the @@ -62,7 +62,7 @@ final case class PrimaryServiceWorker[V <: Value]( ): Try[ ( PrimaryServiceInitializedStateData[V], - Option[Long] + Option[Long], ) ] = { (initServiceData match { @@ -73,7 +73,7 @@ final case class PrimaryServiceWorker[V <: Value]( directoryPath, filePath, fileNamingStrategy, - timePattern + timePattern, ) => Try { /* Set up source and acquire information */ @@ -85,7 +85,7 @@ final case class PrimaryServiceWorker[V <: Value]( timeSeriesUuid, filePath, valueClass, - factory + factory, ) (source, simulationStart) } @@ -94,7 +94,7 @@ final case class PrimaryServiceWorker[V <: Value]( timeSeriesUuid: UUID, simulationStart: ZonedDateTime, sqlParams: SqlParams, - namingStrategy: DatabaseNamingStrategy + namingStrategy: DatabaseNamingStrategy, ) => Try { val factory = @@ -103,7 +103,7 @@ final case class PrimaryServiceWorker[V <: Value]( val sqlConnector = new SqlConnector( sqlParams.jdbcUrl, sqlParams.userName, - sqlParams.password + sqlParams.password, ) val source = new SqlTimeSeriesSource( @@ -112,7 +112,7 @@ final case class PrimaryServiceWorker[V <: Value]( namingStrategy, timeSeriesUuid, valueClass, - factory + factory, ) (source, simulationStart) @@ -148,7 +148,7 @@ final case class PrimaryServiceWorker[V <: Value]( maybeNextTick, furtherActivationTicks, simulationStart, - source + source, ) (initializedStateData, maybeNextTick) } @@ -172,7 +172,7 @@ final case class PrimaryServiceWorker[V <: Value]( case ServiceMessage.WorkerRegistrationMessage(requestingActor) => requestingActor ! RegistrationSuccessfulMessage( self, - serviceStateData.maybeNextActivationTick + serviceStateData.maybeNextActivationTick, ) val subscribers = serviceStateData.subscribers :+ requestingActor Success(serviceStateData.copy(subscribers = subscribers)) @@ -200,10 +200,10 @@ final case class PrimaryServiceWorker[V <: Value]( tick: Long )(implicit serviceBaseStateData: PrimaryServiceInitializedStateData[V], - ctx: ActorContext + ctx: ActorContext, ): ( PrimaryServiceInitializedStateData[V], - Option[Long] + Option[Long], ) = { /* Get the information to distribute */ val wallClockTime = tick.toDateTime(serviceBaseStateData.startDateTime) @@ -215,7 +215,7 @@ final case class PrimaryServiceWorker[V <: Value]( log.warning( s"I expected to get data for tick '{}' ({}), but data is not available", tick, - wallClockTime + wallClockTime, ) updateStateDataAndBuildTriggerMessages(serviceBaseStateData) } @@ -234,16 +234,16 @@ final case class PrimaryServiceWorker[V <: Value]( baseStateData: PrimaryServiceInitializedStateData[V] ): ( PrimaryServiceInitializedStateData[V], - Option[Long] + Option[Long], ) = { val (maybeNextActivationTick, remainderActivationTicks) = baseStateData.activationTicks.pop ( baseStateData.copy( maybeNextActivationTick = maybeNextActivationTick, - activationTicks = remainderActivationTicks + activationTicks = remainderActivationTicks, ), - maybeNextActivationTick + maybeNextActivationTick, ) } @@ -262,10 +262,10 @@ final case class PrimaryServiceWorker[V <: Value]( private def processDataAndAnnounce( tick: Long, value: V, - serviceBaseStateData: PrimaryServiceInitializedStateData[V] + serviceBaseStateData: PrimaryServiceInitializedStateData[V], ): ( PrimaryServiceInitializedStateData[V], - Option[Long] + Option[Long], ) = value.toPrimaryData match { case Success(primaryData) => announcePrimaryData(tick, primaryData, serviceBaseStateData) @@ -274,7 +274,7 @@ final case class PrimaryServiceWorker[V <: Value]( log.warning( "Unable to convert received value to primary data. Skipped that data." + "\nException: {}", - exception + exception, ) updateStateDataAndBuildTriggerMessages(serviceBaseStateData) } @@ -294,17 +294,17 @@ final case class PrimaryServiceWorker[V <: Value]( private def announcePrimaryData( tick: Long, primaryData: PrimaryData, - serviceBaseStateData: PrimaryServiceInitializedStateData[V] + serviceBaseStateData: PrimaryServiceInitializedStateData[V], ): ( PrimaryServiceInitializedStateData[V], - Option[Long] + Option[Long], ) = { val (maybeNextTick, remainderActivationTicks) = serviceBaseStateData.activationTicks.pop val updatedStateData = serviceBaseStateData.copy( maybeNextActivationTick = maybeNextTick, - activationTicks = remainderActivationTicks + activationTicks = remainderActivationTicks, ) val provisionMessage = @@ -323,12 +323,12 @@ object PrimaryServiceWorker { ColumnScheme.ACTIVE_POWER, ColumnScheme.ACTIVE_POWER_AND_HEAT_DEMAND, ColumnScheme.APPARENT_POWER, - ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND + ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND, ) def props[V <: Value]( scheduler: ActorRef, - valueClass: Class[V] + valueClass: Class[V], ): Props = Props(new PrimaryServiceWorker(scheduler, valueClass)) @@ -369,7 +369,7 @@ object PrimaryServiceWorker { directoryPath: Path, filePath: Path, fileNamingStrategy: FileNamingStrategy, - timePattern: String + timePattern: String, ) extends InitPrimaryServiceStateData /** Specific implementation of [[InitPrimaryServiceStateData]], if the source @@ -388,7 +388,7 @@ object PrimaryServiceWorker { override val timeSeriesUuid: UUID, override val simulationStart: ZonedDateTime, sqlParams: SqlParams, - databaseNamingStrategy: DatabaseNamingStrategy + databaseNamingStrategy: DatabaseNamingStrategy, ) extends InitPrimaryServiceStateData /** Class carrying the state of a fully initialized [[PrimaryServiceWorker]] @@ -413,7 +413,7 @@ object PrimaryServiceWorker { SortedDistinctSeq.empty, startDateTime: ZonedDateTime, source: TimeSeriesSource[V], - subscribers: Vector[ActorRef] = Vector.empty[ActorRef] + subscribers: Vector[ActorRef] = Vector.empty[ActorRef], ) extends ServiceActivationBaseStateData /** Provide primary data to subscribes @@ -430,6 +430,6 @@ object PrimaryServiceWorker { override val serviceRef: ActorRef, override val data: PrimaryData, override val nextDataTick: Option[Long], - override val unlockKey: Option[ScheduleKey] = None + override val unlockKey: Option[ScheduleKey] = None, ) extends ServiceMessage.ProvisionMessage[PrimaryData] } diff --git a/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala b/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala index 06c62354ba..b4dfa209d4 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/SampleWeatherSource.scala @@ -50,7 +50,7 @@ final class SampleWeatherSource( */ override def getWeather( tick: Long, - weightedCoordinates: WeatherSource.WeightedCoordinates + weightedCoordinates: WeatherSource.WeightedCoordinates, ): WeatherData = getWeather(tick) /** Get the weather data for the given tick and coordinate. Here, the weather @@ -97,7 +97,7 @@ final class SampleWeatherSource( SampleWeatherSource .windVelocity(index) .doubleValue - ) + ), ) } @@ -113,7 +113,7 @@ final class SampleWeatherSource( */ override def getDataTicks( requestFrameStart: Long, - requestFrameEnd: Long + requestFrameEnd: Long, ): Array[Long] = TickUtil.getTicksInBetween(requestFrameStart, requestFrameEnd, resolution) } @@ -137,13 +137,13 @@ object SampleWeatherSource { override def getClosestCoordinates( coordinate: Point, n: Int, - distance: ComparableQuantity[Length] + distance: ComparableQuantity[Length], ): util.List[CoordinateDistance] = { if (coordinate.getY.abs <= 90 && coordinate.getX.abs <= 180) Vector( new CoordinateDistance( coordinate, - coordinate + coordinate, ) ).asJava else @@ -152,13 +152,13 @@ object SampleWeatherSource { override def getNearestCoordinates( coordinate: Point, - i: Int + i: Int, ): util.List[CoordinateDistance] = { if (coordinate.getY.abs <= 90 && coordinate.getX.abs <= 180) Vector( new CoordinateDistance( coordinate, - coordinate + coordinate, ) ).asJava else diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala index 52aa70bd8f..7543dc74c8 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherService.scala @@ -12,22 +12,22 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.WeatherServiceException.InvalidRegistrationRequestException import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.ServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.WeatherMessage._ import edu.ie3.simona.service.SimonaService import edu.ie3.simona.service.ServiceStateData.{ InitializeServiceStateData, - ServiceActivationBaseStateData + ServiceActivationBaseStateData, } import edu.ie3.simona.service.weather.WeatherService.{ InitWeatherServiceStateData, - WeatherInitializedStateData + WeatherInitializedStateData, } import edu.ie3.simona.service.weather.WeatherSource.{ AgentCoordinates, - WeightedCoordinates + WeightedCoordinates, } import edu.ie3.simona.util.SimonaConstants import edu.ie3.simona.util.TickUtil.RichZonedDateTime @@ -42,14 +42,14 @@ object WeatherService { scheduler: ActorRef, startDateTime: ZonedDateTime, simulationEnd: ZonedDateTime, - amountOfInterpolationCoordinates: Int = 4 + amountOfInterpolationCoordinates: Int = 4, ): Props = Props( new WeatherService( scheduler, startDateTime, simulationEnd, - amountOfInterpolationCoordinates + amountOfInterpolationCoordinates, ) ) @@ -74,7 +74,7 @@ object WeatherService { Map.empty[AgentCoordinates, WeightedCoordinates], override val maybeNextActivationTick: Option[Long], override val activationTicks: SortedDistinctSeq[Long] = - SortedDistinctSeq.empty + SortedDistinctSeq.empty, ) extends ServiceActivationBaseStateData /** Weather service state data used for initialization of the weather service @@ -99,7 +99,7 @@ final case class WeatherService( override val scheduler: ActorRef, private implicit val simulationStart: ZonedDateTime, simulationEnd: ZonedDateTime, - private val amountOfInterpolationCoords: Int + private val amountOfInterpolationCoords: Int, ) extends SimonaService[ WeatherInitializedStateData ](scheduler) { @@ -131,7 +131,7 @@ final case class WeatherService( weatherSource .getDataTicks( SimonaConstants.FIRST_TICK_IN_SIMULATION, - simulationEnd.toTick + simulationEnd.toTick, ) .toSeq ).pop @@ -139,12 +139,12 @@ final case class WeatherService( val weatherInitializedStateData = WeatherInitializedStateData( weatherSource, activationTicks = furtherActivationTicks, - maybeNextActivationTick = maybeNextTick + maybeNextActivationTick = maybeNextTick, ) Success( weatherInitializedStateData, - maybeNextTick + maybeNextTick, ) case invalidData => @@ -200,7 +200,7 @@ final case class WeatherService( private def handleRegistrationRequest( agentToBeRegistered: ActorRef, latitude: Double, - longitude: Double + longitude: Double, )(implicit serviceStateData: WeatherInitializedStateData ): WeatherInitializedStateData = { @@ -208,13 +208,13 @@ final case class WeatherService( "Received weather registration from {} for [Lat:{}, Long:{}]", agentToBeRegistered.path.name, latitude, - longitude + longitude, ) // collate the provided coordinates into a single entity val agentCoord = AgentCoordinates( latitude, - longitude + longitude, ) serviceStateData.coordsToActorRefMap.get(agentCoord) match { @@ -222,12 +222,12 @@ final case class WeatherService( /* The coordinate itself is not known yet. Try to figure out, which weather coordinates are relevant */ serviceStateData.weatherSource.getWeightedCoordinates( agentCoord, - amountOfInterpolationCoords + amountOfInterpolationCoords, ) match { case Success(weightedCoordinates) => agentToBeRegistered ! RegistrationSuccessfulMessage( self, - serviceStateData.maybeNextActivationTick + serviceStateData.maybeNextActivationTick, ) /* Enhance the mapping from agent coordinate to requesting actor's ActorRef as well as the necessary @@ -238,12 +238,12 @@ final case class WeatherService( agentToBeRegistered )), weightedWeatherCoordinates = - serviceStateData.weightedWeatherCoordinates + (agentCoord -> weightedCoordinates) + serviceStateData.weightedWeatherCoordinates + (agentCoord -> weightedCoordinates), ) case Failure(exception) => log.error( exception, - s"Unable to obtain necessary information to register for coordinate $agentCoord." + s"Unable to obtain necessary information to register for coordinate $agentCoord.", ) sender() ! RegistrationFailedMessage(self) serviceStateData @@ -253,7 +253,7 @@ final case class WeatherService( // coordinate is already known (= we have data for it), but this actor is not registered yet agentToBeRegistered ! RegistrationSuccessfulMessage( self, - serviceStateData.maybeNextActivationTick + serviceStateData.maybeNextActivationTick, ) serviceStateData.copy( @@ -265,7 +265,7 @@ final case class WeatherService( // actor is already registered, do nothing log.warning( "Sending actor {} is already registered", - agentToBeRegistered + agentToBeRegistered, ) serviceStateData @@ -290,13 +290,13 @@ final case class WeatherService( */ override protected def announceInformation(tick: Long)(implicit serviceStateData: WeatherInitializedStateData, - ctx: ActorContext + ctx: ActorContext, ): (WeatherInitializedStateData, Option[Long]) = { /* Pop the next activation tick and update the state data */ val ( maybeNextTick: Option[Long], - updatedStateData: WeatherInitializedStateData + updatedStateData: WeatherInitializedStateData, ) = { val (nextTick, remainderTicks) = serviceStateData.activationTicks.pop (nextTick, serviceStateData.copy(activationTicks = remainderTicks)) @@ -316,7 +316,7 @@ final case class WeatherService( tick, self, weatherResult, - maybeNextTick + maybeNextTick, ) ) ) @@ -324,7 +324,7 @@ final case class WeatherService( ( updatedStateData, - maybeNextTick + maybeNextTick, ) } diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala index e054b01715..b996d5a475 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherSource.scala @@ -11,7 +11,7 @@ import edu.ie3.datamodel.io.factory.timeseries.{ CosmoIdCoordinateFactory, IconIdCoordinateFactory, IdCoordinateFactory, - SqlIdCoordinateFactory + SqlIdCoordinateFactory, } import edu.ie3.datamodel.io.naming.FileNamingStrategy import edu.ie3.datamodel.io.source.IdCoordinateSource @@ -23,18 +23,18 @@ import edu.ie3.simona.config.SimonaConfig.BaseCsvParams import edu.ie3.simona.config.SimonaConfig.Simona.Input.Weather.Datasource._ import edu.ie3.simona.exceptions.{ InvalidConfigParameterException, - ServiceException + ServiceException, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherSource.{ AgentCoordinates, - WeightedCoordinates + WeightedCoordinates, } import edu.ie3.simona.util.ConfigUtil.CsvConfigUtil.checkBaseCsvParams import edu.ie3.simona.util.ConfigUtil.DatabaseConfigUtil.{ checkCouchbaseParams, checkInfluxDb1xParams, - checkSqlParams + checkSqlParams, } import edu.ie3.simona.util.ParsableEnumeration import edu.ie3.util.geo.{CoordinateDistance, GeoUtils} @@ -72,11 +72,11 @@ trait WeatherSource { */ def getWeightedCoordinates( coordinate: WeatherSource.AgentCoordinates, - amountOfInterpolationCoords: Int + amountOfInterpolationCoords: Int, ): Try[WeatherSource.WeightedCoordinates] = { getNearestCoordinatesWithDistances( coordinate, - amountOfInterpolationCoords + amountOfInterpolationCoords, ) match { case Success(nearestCoordinates) => determineWeights(nearestCoordinates) @@ -84,7 +84,7 @@ trait WeatherSource { Failure( new ServiceException( "Determination of coordinate weights failed.", - exception + exception, ) ) } @@ -104,7 +104,7 @@ trait WeatherSource { */ def getNearestCoordinatesWithDistances( coordinate: WeatherSource.AgentCoordinates, - amountOfInterpolationCoords: Int + amountOfInterpolationCoords: Int, ): Try[Iterable[CoordinateDistance]] = { val queryPoint = coordinate.toPoint @@ -113,7 +113,7 @@ trait WeatherSource { .getClosestCoordinates( queryPoint, amountOfInterpolationCoords, - maxCoordinateDistance + maxCoordinateDistance, ) .asScala @@ -152,7 +152,7 @@ trait WeatherSource { tl || (point.getX < queryPoint.getX && point.getY > queryPoint.getY), tr || (point.getX > queryPoint.getX && point.getY > queryPoint.getY), bl || (point.getX < queryPoint.getX && point.getY < queryPoint.getY), - br || (point.getX > queryPoint.getX && point.getY < queryPoint.getY) + br || (point.getX > queryPoint.getX && point.getY < queryPoint.getY), ) } @@ -252,7 +252,7 @@ trait WeatherSource { */ def getWeather( tick: Long, - weightedCoordinates: WeightedCoordinates + weightedCoordinates: WeightedCoordinates, ): WeatherData /** Get the weather data for the given tick and agent coordinates having a @@ -267,7 +267,7 @@ trait WeatherSource { */ def getWeather( tick: Long, - agentToWeightedCoordinates: Map[AgentCoordinates, WeightedCoordinates] + agentToWeightedCoordinates: Map[AgentCoordinates, WeightedCoordinates], ): Map[AgentCoordinates, WeatherData] = agentToWeightedCoordinates.map { case (agentCoordinates, weightedCoordinates) => agentCoordinates -> getWeather(tick, weightedCoordinates) @@ -286,7 +286,7 @@ trait WeatherSource { */ def getDataTicks( requestFrameStart: Long, - requestFrameEnd: Long + requestFrameEnd: Long, ): Array[Long] } @@ -294,7 +294,7 @@ object WeatherSource { def apply( dataSourceConfig: SimonaConfig.Simona.Input.Weather.Datasource, - simulationStart: ZonedDateTime + simulationStart: ZonedDateTime, ): WeatherSource = checkConfig(dataSourceConfig)(simulationStart) @@ -334,7 +334,7 @@ object WeatherSource { weatherDataSourceCfg.csvParams, weatherDataSourceCfg.influxDb1xParams, weatherDataSourceCfg.couchbaseParams, - weatherDataSourceCfg.sqlParams + weatherDataSourceCfg.sqlParams, ).filter(_.isDefined) val timestampPattern: Option[String] = weatherDataSourceCfg.timestampPattern @@ -343,7 +343,7 @@ object WeatherSource { val distance: ComparableQuantity[Length] = Quantities.getQuantity( weatherDataSourceCfg.maxCoordinateDistance, - Units.METRE + Units.METRE, ) // check that only one source is defined @@ -365,7 +365,7 @@ object WeatherSource { timestampPattern, scheme, resolution, - distance + distance, )(simulationStart) case Some(Some(params: CouchbaseParams)) => checkCouchbaseParams(params) @@ -376,7 +376,7 @@ object WeatherSource { timestampPattern, scheme, resolution, - distance + distance, )(simulationStart) case Some(Some(params @ InfluxDb1xParams(database, _, url))) => checkInfluxDb1xParams("WeatherSource", url, database) @@ -387,7 +387,7 @@ object WeatherSource { timestampPattern, scheme, resolution, - distance + distance, )(simulationStart) case Some(Some(params: SqlParams)) => checkSqlParams(params) @@ -398,7 +398,7 @@ object WeatherSource { timestampPattern, scheme, resolution, - distance + distance, )(simulationStart) case Some(Some(_: SampleParams)) => // sample weather, no check required @@ -444,7 +444,7 @@ object WeatherSource { val definedCoordSources = Vector( coordinateSourceConfig.sampleParams, coordinateSourceConfig.csvParams, - coordinateSourceConfig.sqlParams + coordinateSourceConfig.sqlParams, ).filter(_.isDefined) // check that only one source is defined @@ -469,8 +469,8 @@ object WeatherSource { new CsvDataSource( csvSep, Paths.get(directoryPath), - new FileNamingStrategy() - ) + new FileNamingStrategy(), + ), ) case Some( Some( @@ -479,7 +479,7 @@ object WeatherSource { userName, password, schemaName, - tableName + tableName, ) ) ) => @@ -490,7 +490,7 @@ object WeatherSource { new SqlConnector(jdbcUrl, userName, password), schemaName, tableName, - new SqlIdCoordinateFactory() + new SqlIdCoordinateFactory(), ) case Some( Some( @@ -544,7 +544,7 @@ object WeatherSource { WattsPerSquareMeter(0.0), WattsPerSquareMeter(0.0), Kelvin(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ) def toWeatherData( @@ -590,7 +590,7 @@ object WeatherSource { .doubleValue() ) case None => EMPTY_WEATHER_DATA.windVel - } + }, ) } @@ -600,7 +600,7 @@ object WeatherSource { */ private[weather] final case class AgentCoordinates( latitude: Double, - longitude: Double + longitude: Double, ) { def toPoint: Point = GeoUtils.DEFAULT_GEOMETRY_FACTORY.createPoint( diff --git a/src/main/scala/edu/ie3/simona/service/weather/WeatherSourceWrapper.scala b/src/main/scala/edu/ie3/simona/service/weather/WeatherSourceWrapper.scala index 2fc48cd5f9..dac52742ed 100644 --- a/src/main/scala/edu/ie3/simona/service/weather/WeatherSourceWrapper.scala +++ b/src/main/scala/edu/ie3/simona/service/weather/WeatherSourceWrapper.scala @@ -10,11 +10,11 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.io.connectors.{ CouchbaseConnector, InfluxDbConnector, - SqlConnector + SqlConnector, } import edu.ie3.datamodel.io.factory.timeseries.{ CosmoTimeBasedWeatherValueFactory, - IconTimeBasedWeatherValueFactory + IconTimeBasedWeatherValueFactory, } import edu.ie3.datamodel.io.naming.FileNamingStrategy import edu.ie3.datamodel.io.source.couchbase.CouchbaseWeatherSource @@ -23,12 +23,12 @@ import edu.ie3.datamodel.io.source.influxdb.InfluxDbWeatherSource import edu.ie3.datamodel.io.source.sql.SqlWeatherSource import edu.ie3.datamodel.io.source.{ IdCoordinateSource, - WeatherSource => PsdmWeatherSource + WeatherSource => PsdmWeatherSource, } import edu.ie3.simona.config.SimonaConfig.Simona.Input.Weather.Datasource.{ CouchbaseParams, InfluxDb1xParams, - SqlParams + SqlParams, } import edu.ie3.simona.exceptions.InitializationException import edu.ie3.simona.ontology.messages.services.WeatherMessage @@ -36,7 +36,7 @@ import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherSource.{ EMPTY_WEATHER_DATA, WeatherScheme, - toWeatherData + toWeatherData, } import edu.ie3.simona.service.weather.WeatherSourceWrapper.WeightSum import edu.ie3.simona.service.weather.{WeatherSource => SimonaWeatherSource} @@ -72,7 +72,7 @@ private[weather] final case class WeatherSourceWrapper private ( source: PsdmWeatherSource, override val idCoordinateSource: IdCoordinateSource, resolution: Long, - maxCoordinateDistance: ComparableQuantity[Length] + maxCoordinateDistance: ComparableQuantity[Length], )( private implicit val simulationStart: ZonedDateTime ) extends SimonaWeatherSource @@ -90,7 +90,7 @@ private[weather] final case class WeatherSourceWrapper private ( */ override def getWeather( tick: Long, - weightedCoordinates: WeatherSource.WeightedCoordinates + weightedCoordinates: WeatherSource.WeightedCoordinates, ): WeatherMessage.WeatherData = { val dateTime = tick.toDateTime val interval = new ClosedInterval(dateTime, dateTime) @@ -98,7 +98,7 @@ private[weather] final case class WeatherSourceWrapper private ( val results = source .getWeather( interval, - coordinates + coordinates, ) .asScala .toMap @@ -124,7 +124,7 @@ private[weather] final case class WeatherSourceWrapper private ( point, { logger.warn(s"Received an unexpected point: $point") 0d - } + }, ) /* Sum up weight and contributions */ @@ -169,8 +169,8 @@ private[weather] final case class WeatherSourceWrapper private ( diffIrrWeight, dirIrrWeight, tempWeight, - windVelWeight - ) + windVelWeight, + ), ) } match { case (weatherData: WeatherData, weightSum: WeightSum) => @@ -190,7 +190,7 @@ private[weather] final case class WeatherSourceWrapper private ( */ override def getDataTicks( requestFrameStart: Long, - requestFrameEnd: Long + requestFrameEnd: Long, ): Array[Long] = TickUtil.getTicksInBetween(requestFrameStart, requestFrameEnd, resolution) } @@ -205,7 +205,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { timestampPattern: Option[String], scheme: String, resolution: Option[Long], - maxCoordinateDistance: ComparableQuantity[Length] + maxCoordinateDistance: ComparableQuantity[Length], )(implicit simulationStart: ZonedDateTime): WeatherSourceWrapper = { val idCoordinateSource = idCoordinateSourceFunction() val source = new CsvWeatherSource( @@ -213,7 +213,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { directoryPath, new FileNamingStrategy(), idCoordinateSource, - buildFactory(scheme, timestampPattern) + buildFactory(scheme, timestampPattern), ) logger.info( "Successfully initiated CsvWeatherSource as source for WeatherSourceWrapper." @@ -222,7 +222,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { source, idCoordinateSource, resolution.getOrElse(DEFAULT_RESOLUTION), - maxCoordinateDistance + maxCoordinateDistance, ) } @@ -232,13 +232,13 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { timestampPattern: Option[String], scheme: String, resolution: Option[Long], - maxCoordinateDistance: ComparableQuantity[Length] + maxCoordinateDistance: ComparableQuantity[Length], )(implicit simulationStart: ZonedDateTime): WeatherSourceWrapper = { val couchbaseConnector = new CouchbaseConnector( couchbaseParams.url, couchbaseParams.bucketName, couchbaseParams.userName, - couchbaseParams.password + couchbaseParams.password, ) val idCoordinateSource = idCoordinateSourceFunction() val source = new CouchbaseWeatherSource( @@ -247,7 +247,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { couchbaseParams.coordinateColumnName, couchbaseParams.keyPrefix, buildFactory(scheme, timestampPattern), - "yyyy-MM-dd'T'HH:mm:ssxxx" + "yyyy-MM-dd'T'HH:mm:ssxxx", ) logger.info( "Successfully initiated CouchbaseWeatherSource as source for WeatherSourceWrapper." @@ -256,7 +256,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { source, idCoordinateSource, resolution.getOrElse(DEFAULT_RESOLUTION), - maxCoordinateDistance + maxCoordinateDistance, ) } @@ -266,7 +266,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { timestampPattern: Option[String], scheme: String, resolution: Option[Long], - maxCoordinateDistance: ComparableQuantity[Length] + maxCoordinateDistance: ComparableQuantity[Length], )(implicit simulationStart: ZonedDateTime): WeatherSourceWrapper = { val influxDb1xConnector = new InfluxDbConnector(influxDbParams.url, influxDbParams.database) @@ -274,7 +274,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { val source = new InfluxDbWeatherSource( influxDb1xConnector, idCoordinateSource, - buildFactory(scheme, timestampPattern) + buildFactory(scheme, timestampPattern), ) logger.info( "Successfully initiated InfluxDbWeatherSource as source for WeatherSourceWrapper." @@ -283,7 +283,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { source, idCoordinateSource, resolution.getOrElse(DEFAULT_RESOLUTION), - maxCoordinateDistance + maxCoordinateDistance, ) } @@ -293,12 +293,12 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { timestampPattern: Option[String], scheme: String, resolution: Option[Long], - maxCoordinateDistance: ComparableQuantity[Length] + maxCoordinateDistance: ComparableQuantity[Length], )(implicit simulationStart: ZonedDateTime): WeatherSourceWrapper = { val sqlConnector = new SqlConnector( sqlParams.jdbcUrl, sqlParams.userName, - sqlParams.password + sqlParams.password, ) val idCoordinateSource = idCoordinateSourceFunction() val source = new SqlWeatherSource( @@ -306,7 +306,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { idCoordinateSource, sqlParams.schemaName, sqlParams.tableName, - buildFactory(scheme, timestampPattern) + buildFactory(scheme, timestampPattern), ) logger.info( "Successfully initiated SqlWeatherSource as source for WeatherSourceWrapper." @@ -315,7 +315,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { source, idCoordinateSource, resolution.getOrElse(DEFAULT_RESOLUTION), - maxCoordinateDistance + maxCoordinateDistance, ) } @@ -325,7 +325,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { throw new InitializationException( s"Error while initializing WeatherFactory for weather source wrapper: '$scheme' is not a weather scheme. Supported schemes:\n\t${WeatherScheme.values .mkString("\n\t")}'", - exception + exception, ) case Success(WeatherScheme.ICON) => timestampPattern @@ -358,19 +358,19 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { diffIrr: Double, dirIrr: Double, temp: Double, - windVel: Double + windVel: Double, ) { def add( diffIrr: Double, dirIrr: Double, temp: Double, - windVel: Double + windVel: Double, ): WeightSum = WeightSum( this.diffIrr + diffIrr, this.dirIrr + dirIrr, this.temp + temp, - this.windVel + windVel + this.windVel + windVel, ) /** Scale the given [[WeatherData]] by dividing by the sum of weights per @@ -394,7 +394,7 @@ private[weather] object WeatherSourceWrapper extends LazyLogging { if (this.temp !~= 0d) temp.divide(this.temp) else EMPTY_WEATHER_DATA.temp, if (this.windVel !~= 0d) windVel.divide(this.windVel) - else EMPTY_WEATHER_DATA.windVel + else EMPTY_WEATHER_DATA.windVel, ) } } diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 7a619552eb..5200e39371 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -15,7 +15,7 @@ import org.apache.pekko.actor.{ Props, Stash, SupervisorStrategy, - Terminated + Terminated, } import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.agent.EnvironmentRefs @@ -27,11 +27,11 @@ import edu.ie3.simona.sim.SimMessage.{ InitSim, SimulationFailure, SimulationSuccessful, - StartSimulation + StartSimulation, } import edu.ie3.simona.sim.SimonaSim.{ EmergencyShutdownInitiated, - SimonaSimStateData + SimonaSimStateData, } import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} @@ -63,7 +63,7 @@ class SimonaSim(simonaSetup: SimonaSetup) logger.error( "The simulation's guardian received an uncaught exception. - {}: \"{}\" - Start emergency shutdown.", ex.getClass.getSimpleName, - ex.getMessage + ex.getMessage, ) Stop } @@ -104,9 +104,9 @@ class SimonaSim(simonaSetup: SimonaSetup) runtimeEventListener.toClassic, primaryServiceProxy, weatherService, - extSimulationData.evDataService + extSimulationData.evDataService, ), - systemParticipantsListener + systemParticipantsListener, ) /* watch all actors */ @@ -151,7 +151,7 @@ class SimonaSim(simonaSetup: SimonaSetup) context become waitingForListener( data.initSimSender, simulationSuccessful, - systemParticipantsListener + systemParticipantsListener, ) case EmergencyShutdownInitiated => @@ -165,7 +165,7 @@ class SimonaSim(simonaSetup: SimonaSetup) logger.error( "An actor ({}) unexpectedly terminated. Shut down all children gracefully and report simulation " + "failure. See logs and possible stacktrace for details.", - actorRef + actorRef, ) // stop all children @@ -175,7 +175,7 @@ class SimonaSim(simonaSetup: SimonaSetup) context become waitingForListener( data.initSimSender, successful = false, - systemParticipantsListener + systemParticipantsListener, ) } @@ -190,14 +190,14 @@ class SimonaSim(simonaSetup: SimonaSetup) logger.warn( "Received the following message. Simulation is in emergency shutdown mode. Will neglect that " + "message!\n\t{}", - unsupported + unsupported, ) } def waitingForListener( initSimSender: ActorRef, successful: Boolean, - remainingListeners: Seq[ActorRef] + remainingListeners: Seq[ActorRef], ): Receive = { case Terminated(actor) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) @@ -205,7 +205,7 @@ class SimonaSim(simonaSetup: SimonaSetup) logger.debug( "Listener {} has been terminated. Remaining listeners: {}", actor, - updatedRemainingListeners + updatedRemainingListeners, ) if (updatedRemainingListeners.isEmpty) { @@ -223,7 +223,7 @@ class SimonaSim(simonaSetup: SimonaSetup) context become waitingForListener( initSimSender, successful, - updatedRemainingListeners + updatedRemainingListeners, ) } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/ExtSimSetupData.scala b/src/main/scala/edu/ie3/simona/sim/setup/ExtSimSetupData.scala index 4706a50f09..d5b34606aa 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/ExtSimSetupData.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/ExtSimSetupData.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.service.ev.ExtEvDataService final case class ExtSimSetupData( extSimAdapters: Iterable[ActorRef], - extDataServices: Map[Class[_], ActorRef] + extDataServices: Map[Class[_], ActorRef], ) { def evDataService: Option[ActorRef] = diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala index b7a843ce9a..5aff8bb46a 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SetupHelper.scala @@ -58,12 +58,12 @@ trait SetupHelper extends LazyLogging { subGridToActorRef: Map[Int, ActorRef], gridGates: Set[SubGridGate], configRefSystems: ConfigRefSystems, - thermalGrids: Seq[ThermalGrid] + thermalGrids: Seq[ThermalGrid], ): GridAgentInitData = { val subGridGateToActorRef = buildGateToActorRef( subGridToActorRef, gridGates, - subGridContainer.getSubnet + subGridContainer.getSubnet, ) /* Find the matching reference system */ @@ -79,7 +79,7 @@ trait SetupHelper extends LazyLogging { updatedSubGridContainer, thermalGrids, subGridGateToActorRef, - refSystem + refSystem, ) } @@ -98,7 +98,7 @@ trait SetupHelper extends LazyLogging { def buildGateToActorRef( subGridToActorRefMap: Map[Int, ActorRef], subGridGates: Set[SubGridGate], - currentSubGrid: Int + currentSubGrid: Int, ): Map[SubGridGate, ActorRef] = subGridGates .groupBy(gate => (gate.superiorNode, gate.inferiorNode)) @@ -111,14 +111,14 @@ trait SetupHelper extends LazyLogging { gate -> getActorRef( subGridToActorRefMap, currentSubGrid, - superiorSubGrid + superiorSubGrid, ) } else if (superiorSubGrid == currentSubGrid) { /* This is a gate to an inferior sub grid */ gate -> getActorRef( subGridToActorRefMap, currentSubGrid, - inferiorSubGrid + inferiorSubGrid, ) } else { throw new GridAgentInitializationException( @@ -143,7 +143,7 @@ trait SetupHelper extends LazyLogging { def getActorRef( subGridToActorRefMap: Map[Int, ActorRef], currentSubGrid: Int, - queriedSubGrid: Int + queriedSubGrid: Int, ): ActorRef = { subGridToActorRefMap.get(queriedSubGrid) match { case Some(hit) => hit @@ -166,12 +166,12 @@ trait SetupHelper extends LazyLogging { */ def getRefSystem( configRefSystems: ConfigRefSystems, - subGridContainer: SubGridContainer + subGridContainer: SubGridContainer, ): RefSystem = { val refSystem = configRefSystems .find( subGridContainer.getSubnet, - Some(subGridContainer.getPredominantVoltageLevel) + Some(subGridContainer.getPredominantVoltageLevel), ) .getOrElse( throw new InitializationException( @@ -206,7 +206,7 @@ trait SetupHelper extends LazyLogging { */ def buildResultFileHierarchy( config: TypesafeConfig, - createDirs: Boolean = true + createDirs: Boolean = true, ): ResultFileHierarchy = { val simonaConfig = SimonaConfig(config) @@ -222,12 +222,12 @@ trait SetupHelper extends LazyLogging { modelsToWrite, ResultSinkType( simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName - ) + simonaConfig.simona.simulationName, + ), ), addTimeStampToOutputDir = simonaConfig.simona.output.base.addTimestampToOutputDir, - createDirs = createDirs + createDirs = createDirs, ) // copy config data to output directory diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index caad2d1b7b..e94f782e4c 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -70,7 +70,7 @@ trait SimonaSetup { */ def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef /** Creates a weather service @@ -85,7 +85,7 @@ trait SimonaSetup { */ def weatherService( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef /** Loads external simulations and provides corresponding actors and init data @@ -99,7 +99,7 @@ trait SimonaSetup { */ def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ExtSimSetupData /** Creates the time advancer @@ -116,7 +116,7 @@ trait SimonaSetup { def timeAdvancer( context: ActorContext, simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] + runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] /** Creates a scheduler service @@ -130,7 +130,7 @@ trait SimonaSetup { */ def scheduler( context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], ): ActorRef /** Creates all the needed grid agents @@ -148,7 +148,7 @@ trait SimonaSetup { def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] + systemParticipantListener: Seq[ActorRef], ): Iterable[ActorRef] /** SIMONA links sub grids connected by a three winding transformer a bit @@ -163,7 +163,7 @@ trait SimonaSetup { new SubGridGate( transformer, transformer.getNodeInternal, - gate.inferiorNode + gate.inferiorNode, ) case _ => gate } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index 246fda0101..cf9e78689f 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.sim.setup import org.apache.pekko.actor.typed.scaladsl.adapter.{ ClassicActorContextOps, ClassicActorRefOps, - TypedActorRefOps + TypedActorRefOps, } import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import com.typesafe.config.Config @@ -57,20 +57,20 @@ class SimonaStandaloneSetup( simonaConfig: SimonaConfig, resultFileHierarchy: ResultFileHierarchy, runtimeEventQueue: Option[LinkedBlockingQueue[RuntimeEvent]] = None, - override val args: Array[String] + override val args: Array[String], ) extends SimonaSetup { override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] + systemParticipantListener: Seq[ActorRef], ): Iterable[ActorRef] = { /* get the grid */ val subGridTopologyGraph = GridProvider .gridFromConfig( simonaConfig.simona.simulationName, - simonaConfig.simona.input.grid.datasource + simonaConfig.simona.input.grid.datasource, ) .getSubGridTopologyGraph val thermalGridsByThermalBus = GridProvider.getThermalGridsFromConfig( @@ -86,14 +86,14 @@ class SimonaStandaloneSetup( subGridTopologyGraph, context, environmentRefs, - systemParticipantListener + systemParticipantListener, ) val keys = ScheduleLock.multiKey( context, environmentRefs.scheduler.toTyped, INIT_SIM_TICK, - subGridTopologyGraph.vertexSet().size + subGridTopologyGraph.vertexSet().size, ) /* build the initialization data */ @@ -115,7 +115,7 @@ class SimonaStandaloneSetup( currentSubGrid, throw new GridAgentInitializationException( "Was asked to setup agent for sub grid " + currentSubGrid + ", but did not found it's actor reference." - ) + ), ) val thermalGrids = getThermalGrids(subGridContainer, thermalGridsByThermalBus) @@ -126,7 +126,7 @@ class SimonaStandaloneSetup( subGridToActorRefMap, subGridGates, configRefSystems, - thermalGrids + thermalGrids, ) currentActorRef ! GridAgent.Create(gridAgentInitData, key) @@ -137,7 +137,7 @@ class SimonaStandaloneSetup( override def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = { val simulationStart = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime @@ -147,9 +147,9 @@ class SimonaStandaloneSetup( scheduler, InitPrimaryServiceProxyStateData( simonaConfig.simona.input.primary, - simulationStart + simulationStart, ), - simulationStart + simulationStart, ) ) @@ -159,7 +159,7 @@ class SimonaStandaloneSetup( override def weatherService( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = { val weatherService = context.simonaActorOf( WeatherService.props( @@ -167,14 +167,14 @@ class SimonaStandaloneSetup( TimeUtil.withDefaults .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults - .toZonedDateTime(simonaConfig.simona.time.endDateTime) + .toZonedDateTime(simonaConfig.simona.time.endDateTime), ) ) weatherService ! SimonaService.Create( InitWeatherServiceStateData( simonaConfig.simona.input.weather.datasource ), - ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK) + ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK), ) weatherService @@ -182,7 +182,7 @@ class SimonaStandaloneSetup( override def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ExtSimSetupData = { val jars = ExtSimLoader.scanInputFolder() @@ -193,26 +193,26 @@ class SimonaStandaloneSetup( // external simulation always needs at least an ExtSimAdapter val extSimAdapter = context.simonaActorOf( ExtSimAdapter.props(scheduler), - s"$index" + s"$index", ) val extSimAdapterData = new ExtSimAdapterData(extSimAdapter, args) // send init data right away, init activation is scheduled extSimAdapter ! ExtSimAdapter.Create( extSimAdapterData, - ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK) + ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK), ) // setup data services that belong to this external simulation val (extData, extDataInit): ( Iterable[ExtData], - Iterable[(Class[_ <: SimonaService[_]], ActorRef)] + Iterable[(Class[_ <: SimonaService[_]], ActorRef)], ) = extLink.getExtDataSimulations.asScala.zipWithIndex.map { case (_: ExtEvSimulation, dIndex) => val extEvDataService = context.simonaActorOf( ExtEvDataService.props(scheduler), - s"$index-$dIndex" + s"$index-$dIndex", ) val extEvData = new ExtEvData(extEvDataService, extSimAdapter) @@ -221,8 +221,8 @@ class SimonaStandaloneSetup( ScheduleLock.singleKey( context, scheduler.toTyped, - INIT_SIM_TICK - ) + INIT_SIM_TICK, + ), ) (extEvData, (classOf[ExtEvDataService], extEvDataService)) @@ -230,7 +230,7 @@ class SimonaStandaloneSetup( extLink.getExtSimulation.setup( extSimAdapterData, - extData.toList.asJava + extData.toList.asJava, ) // starting external simulation @@ -246,7 +246,7 @@ class SimonaStandaloneSetup( override def timeAdvancer( context: ActorContext, simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] + runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime @@ -260,22 +260,22 @@ class SimonaStandaloneSetup( simulation, Some(runtimeEventListener), simonaConfig.simona.time.schedulerReadyCheckWindow, - endDateTime.toTick(startDateTime) + endDateTime.toTick(startDateTime), ), - TimeAdvancer.getClass.getSimpleName + TimeAdvancer.getClass.getSimpleName, ) } override def scheduler( context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], ): ActorRef = context .spawn( Scheduler( timeAdvancer ), - Scheduler.getClass.getSimpleName + Scheduler.getClass.getSimpleName, ) .toClassic @@ -287,9 +287,9 @@ class SimonaStandaloneSetup( RuntimeEventListener( simonaConfig.simona.runtime.listener, runtimeEventQueue, - startDateTimeString = simonaConfig.simona.time.startDateTime + startDateTimeString = simonaConfig.simona.time.startDateTime, ), - RuntimeEventListener.getClass.getSimpleName + RuntimeEventListener.getClass.getSimpleName, ) override def systemParticipantsListener( @@ -302,7 +302,7 @@ class SimonaStandaloneSetup( .map { case ((listenerCompanion, events), index) => context.simonaActorOf( listenerCompanion.props(events), - index.toString + index.toString, ) } .toSeq :+ context @@ -310,7 +310,7 @@ class SimonaStandaloneSetup( ResultEventListener( resultFileHierarchy ), - ResultEventListener.getClass.getSimpleName + ResultEventListener.getClass.getSimpleName, ) .toClassic } @@ -319,7 +319,7 @@ class SimonaStandaloneSetup( subGridTopologyGraph: SubGridTopologyGraph, context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] + systemParticipantListener: Seq[ActorRef], ): Map[Int, ActorRef] = { subGridTopologyGraph .vertexSet() @@ -330,9 +330,9 @@ class SimonaStandaloneSetup( GridAgent.props( environmentRefs, simonaConfig, - systemParticipantListener + systemParticipantListener, ), - subGridContainer.getSubnet.toString + subGridContainer.getSubnet.toString, ) subGridContainer.getSubnet -> gridAgentRef }) @@ -349,7 +349,7 @@ class SimonaStandaloneSetup( */ private def getThermalGrids( grid: GridContainer, - thermalGridByBus: Map[ThermalBusInput, ThermalGrid] + thermalGridByBus: Map[ThermalBusInput, ThermalGrid], ): Seq[ThermalGrid] = { grid.getSystemParticipants.getHeatPumps.asScala .flatten(hpInput => thermalGridByBus.get(hpInput.getThermalBus)) @@ -366,13 +366,13 @@ object SimonaStandaloneSetup extends LazyLogging with SetupHelper { typeSafeConfig: Config, resultFileHierarchy: ResultFileHierarchy, runtimeEventQueue: Option[LinkedBlockingQueue[RuntimeEvent]] = None, - mainArgs: Array[String] = Array.empty[String] + mainArgs: Array[String] = Array.empty[String], ): SimonaStandaloneSetup = new SimonaStandaloneSetup( () => ActorSystem("simona", typeSafeConfig), SimonaConfig(typeSafeConfig), resultFileHierarchy, runtimeEventQueue, - mainArgs + mainArgs, ) } diff --git a/src/main/scala/edu/ie3/simona/util/CollectionUtils.scala b/src/main/scala/edu/ie3/simona/util/CollectionUtils.scala index 835f048cf6..6402ea7b2a 100644 --- a/src/main/scala/edu/ie3/simona/util/CollectionUtils.scala +++ b/src/main/scala/edu/ie3/simona/util/CollectionUtils.scala @@ -106,7 +106,7 @@ object CollectionUtils { */ def closestKeyValuePairs[A <: Quantity[A], O <: Quantity[O]]( map: Map[A, O], - key: A + key: A, ): Seq[(A, O)] = { import scala.collection.immutable.TreeMap implicit val ordering: Double.IeeeOrdering.type = @@ -115,7 +115,7 @@ object CollectionUtils { Seq( treeMap.rangeTo(key).lastOption, - treeMap.rangeFrom(key).headOption + treeMap.rangeFrom(key).headOption, ).flatten.distinct .map { case (k, v) => (k, v) } } diff --git a/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala b/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala index ca70e2d7d0..10acb7ddaf 100644 --- a/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala +++ b/src/main/scala/edu/ie3/simona/util/ConfigUtil.scala @@ -10,13 +10,13 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.io.connectors.{ CouchbaseConnector, InfluxDbConnector, - SqlConnector + SqlConnector, } import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, Transformer2WResult, - Transformer3WResult + Transformer3WResult, } import edu.ie3.datamodel.models.result.{NodeResult, ResultEntity} import edu.ie3.simona.config.SimonaConfig @@ -39,7 +39,7 @@ object ConfigUtil { final case class ParticipantConfigUtil private ( private val configs: Map[UUID, SimonaConfig.BaseRuntimeConfig], - private val defaultConfigs: Map[Class[_], BaseRuntimeConfig] + private val defaultConfigs: Map[Class[_], BaseRuntimeConfig], ) { /** Queries for a [[BaseRuntimeConfig]] of type [[T]], that applies for the @@ -88,7 +88,7 @@ object ConfigUtil { subConfig.fixedFeedIn.individualConfigs, subConfig.pv.individualConfigs, subConfig.evcs.individualConfigs, - subConfig.wec.individualConfigs + subConfig.wec.individualConfigs, ).reduceOption(_ ++ _).getOrElse(Seq.empty) ), Seq( @@ -97,8 +97,8 @@ object ConfigUtil { subConfig.pv.defaultConfig, subConfig.evcs.defaultConfig, subConfig.wec.defaultConfig, - subConfig.hp.defaultConfig - ).map { conf => conf.getClass -> conf }.toMap + subConfig.hp.defaultConfig, + ).map { conf => conf.getClass -> conf }.toMap, ) } @@ -127,8 +127,8 @@ object ConfigUtil { private val defaultConfig: NotifierConfig, private val configs: Map[ NotifierIdentifier.Value, - NotifierConfig - ] + NotifierConfig, + ], ) { def getOrDefault( notifierId: NotifierIdentifier.Value @@ -147,7 +147,7 @@ object ConfigUtil { NotifierIdentifier.values -- configs.flatMap { case ( notifierId, - NotifierConfig(resultInfo, _, _) + NotifierConfig(resultInfo, _, _), ) if !resultInfo => Some(notifierId) case _ => None @@ -157,7 +157,7 @@ object ConfigUtil { configs.flatMap { case ( notifierId, - NotifierConfig(resultInfo, _, _) + NotifierConfig(resultInfo, _, _), ) if resultInfo => Some(notifierId) case _ => None @@ -179,7 +179,7 @@ object ConfigUtil { _, simulationResult, flexResult, - powerRequestReply + powerRequestReply, ) => NotifierConfig(simulationResult, powerRequestReply, flexResult) } @@ -188,20 +188,20 @@ object ConfigUtil { notifier, simulationResult, flexResult, - powerRequestReply + powerRequestReply, ) => try { val id = NotifierIdentifier(notifier) id -> NotifierConfig( simulationResult, powerRequestReply, - flexResult + flexResult, ) } catch { case e: NoSuchElementException => throw new InvalidConfigParameterException( s"Cannot parse $notifier to known result event notifier.", - e + e, ) } }.toMap @@ -216,7 +216,7 @@ object ConfigUtil { NotifierConfig( simulationResult, powerRequestReply = false, - flexResult = false + flexResult = false, ) } val configMap = subConfig.individualConfigs.map { @@ -226,13 +226,13 @@ object ConfigUtil { id -> NotifierConfig( simulationResult, powerRequestReply = false, - flexResult = false + flexResult = false, ) } catch { case e: NoSuchElementException => throw new InvalidConfigParameterException( s"Cannot parse $notifier to known result event notifier.", - e + e, ) } }.toMap @@ -295,7 +295,7 @@ object ConfigUtil { */ def checkBaseCsvParams( params: SimonaConfig.BaseCsvParams, - csvParamsName: String + csvParamsName: String, ): Unit = params match { case BaseCsvParams(csvSep, directoryPath, _) => if (!(csvSep.equals(";") || csvSep.equals(","))) @@ -315,7 +315,7 @@ object ConfigUtil { def checkCsvParams( csvParamsName: String, csvSep: String, - folderPath: String + folderPath: String, ): Unit = { if (!(csvSep.equals(";") || csvSep.equals(","))) throw new InvalidConfigParameterException( @@ -370,7 +370,7 @@ object ConfigUtil { case Failure(exception) => throw new IllegalArgumentException( s"Unable to reach configured SQL database with url '${sql.jdbcUrl}' and user name '${sql.userName}'. Exception: $exception", - exception + exception, ) case Success(connection) => val validConnection = connection.isValid(5000) @@ -420,13 +420,13 @@ object ConfigUtil { couchbase.url, couchbase.bucketName, couchbase.userName, - couchbase.password + couchbase.password, ) ) match { case Failure(exception) => throw new IllegalArgumentException( s"Unable to reach configured Couchbase database with url '${couchbase.url}', bucket '${couchbase.bucketName}' and user name '${couchbase.userName}'. Exception: $exception", - exception + exception, ) case Success(connector) => val validConnection = connector.isConnectionValid @@ -445,7 +445,7 @@ object ConfigUtil { def checkInfluxDb1xParams( influxDb1xParamsName: String, url: String, - database: String + database: String, ): Unit = { Try( new InfluxDbConnector(url, database).isConnectionValid @@ -453,7 +453,7 @@ object ConfigUtil { case Failure(exception) => throw new IllegalArgumentException( s"Unable to reach configured influxDb1x with url '$url' for '$influxDb1xParamsName' configuration and database '$database'. Exception: $exception", - exception + exception, ) case Success(validConnection) if !validConnection => throw new IllegalArgumentException( @@ -468,7 +468,7 @@ object ConfigUtil { def checkKafkaParams( kafkaParams: KafkaParams, - topics: Seq[String] + topics: Seq[String], ): Unit = { try { UUID.fromString(kafkaParams.runId) @@ -476,7 +476,7 @@ object ConfigUtil { case e: IllegalArgumentException => throw new InvalidConfigParameterException( s"The UUID '${kafkaParams.runId}' cannot be parsed as it is invalid.", - e + e, ) } @@ -491,17 +491,17 @@ object ConfigUtil { case Failure(ke: KafkaException) => throw new InvalidConfigParameterException( s"Exception creating kafka client for broker ${kafkaParams.bootstrapServers}.", - ke + ke, ) case Failure(ee: ExecutionException) => throw new InvalidConfigParameterException( s"Connection with kafka broker ${kafkaParams.bootstrapServers} failed.", - ee + ee, ) case Failure(other) => throw new InvalidConfigParameterException( s"Checking kafka config failed with unexpected exception.", - other + other, ) case Success(missingTopics) if missingTopics.nonEmpty => throw new InvalidConfigParameterException( diff --git a/src/main/scala/edu/ie3/simona/util/EntityMapperUtil.scala b/src/main/scala/edu/ie3/simona/util/EntityMapperUtil.scala index a6e3398dcc..e52316c88a 100644 --- a/src/main/scala/edu/ie3/simona/util/EntityMapperUtil.scala +++ b/src/main/scala/edu/ie3/simona/util/EntityMapperUtil.scala @@ -25,7 +25,7 @@ case object EntityMapperUtil { ChpPlant -> classOf[ChpResult], Storage -> classOf[StorageResult], Hp -> classOf[HpResult], - House -> classOf[ThermalHouseResult] + House -> classOf[ThermalHouseResult], ) /** Get the classes of [[ResultEntity]], that are issued by the notifier, that @@ -43,6 +43,6 @@ case object EntityMapperUtil { notifierId, throw new NoSuchElementException( s"Cannot determine result entity class of notifier $notifierId" - ) + ), ) } diff --git a/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala b/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala index ba568a043b..1f7fca229e 100644 --- a/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala +++ b/src/main/scala/edu/ie3/simona/util/ReceiveDataMap.scala @@ -19,7 +19,7 @@ package edu.ie3.simona.util */ final case class ReceiveDataMap[K, V]( private val expectedKeys: Set[K], - receivedData: Map[K, V] + receivedData: Map[K, V], ) { def isComplete: Boolean = expectedKeys.isEmpty @@ -27,7 +27,7 @@ final case class ReceiveDataMap[K, V]( def addData( key: K, - value: V + value: V, ): ReceiveDataMap[K, V] = { if (!expectedKeys.contains(key)) @@ -37,7 +37,7 @@ final case class ReceiveDataMap[K, V]( copy( expectedKeys = expectedKeys.excl(key), - receivedData.updated(key, value) + receivedData.updated(key, value), ) } @@ -50,13 +50,13 @@ object ReceiveDataMap { ): ReceiveDataMap[K, V] = ReceiveDataMap( expectedKeys = expectedKeys, - receivedData = Map.empty + receivedData = Map.empty, ) def empty[K, V]: ReceiveDataMap[K, V] = ReceiveDataMap( expectedKeys = Set.empty, - receivedData = Map.empty + receivedData = Map.empty, ) } diff --git a/src/main/scala/edu/ie3/simona/util/ResultFileHierarchy.scala b/src/main/scala/edu/ie3/simona/util/ResultFileHierarchy.scala index 6f27310673..171c5835a2 100644 --- a/src/main/scala/edu/ie3/simona/util/ResultFileHierarchy.scala +++ b/src/main/scala/edu/ie3/simona/util/ResultFileHierarchy.scala @@ -13,7 +13,7 @@ import com.typesafe.config.{ConfigRenderOptions, Config => TypesafeConfig} import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.io.naming.{ EntityPersistenceNamingStrategy, - FileNamingStrategy + FileNamingStrategy, } import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.exceptions.FileHierarchyException @@ -39,7 +39,7 @@ final case class ResultFileHierarchy( private val resultEntityPathConfig: ResultEntityPathConfig, private val configureLogger: String => Unit = LogbackConfiguration.default, private val addTimeStampToOutputDir: Boolean = true, - private val createDirs: Boolean = false + private val createDirs: Boolean = false, ) extends LazyLogging { private val fileSeparator: String = File.separator @@ -76,8 +76,8 @@ final case class ResultFileHierarchy( resultEntityClass, csv, rawOutputDataDir, - fileSeparator - ) + fileSeparator, + ), ) ) .toMap @@ -101,7 +101,7 @@ final case class ResultFileHierarchy( graphOutputDir, kpiOutputDir, tmpDir, - logOutputDir + logOutputDir, ) // needs to be the latest call because otherwise the values are null as they are not initialized yet @@ -152,7 +152,7 @@ object ResultFileHierarchy extends LazyLogging { */ final case class ResultEntityPathConfig( resultEntitiesToConsider: Set[Class[_ <: ResultEntity]], - resultSinkType: ResultSinkType + resultSinkType: ResultSinkType, ) /** @param modelClass @@ -171,7 +171,7 @@ object ResultFileHierarchy extends LazyLogging { modelClass: Class[_ <: ResultEntity], csvSink: Csv, rawOutputDataDir: String, - fileSeparator: String + fileSeparator: String, ): String = { val fileEnding = if (csvSink.fileFormat.startsWith(".")) @@ -180,7 +180,7 @@ object ResultFileHierarchy extends LazyLogging { val namingStrategy = new FileNamingStrategy( new EntityPersistenceNamingStrategy( csvSink.filePrefix, - csvSink.fileSuffix + csvSink.fileSuffix, ) ) val filename = @@ -209,7 +209,7 @@ object ResultFileHierarchy extends LazyLogging { */ def prepareDirectories( config: TypesafeConfig, - resultFileHierarchy: ResultFileHierarchy + resultFileHierarchy: ResultFileHierarchy, ): Unit = { // create output directories if they are not present yet if (!runOutputDirExists(resultFileHierarchy)) @@ -217,7 +217,7 @@ object ResultFileHierarchy extends LazyLogging { logger.info( "Processing configs for simulation: {}.", - config.getString("simona.simulationName") + config.getString("simona.simulationName"), ) val outFile = diff --git a/src/main/scala/edu/ie3/simona/util/TickUtil.scala b/src/main/scala/edu/ie3/simona/util/TickUtil.scala index b705eb63c2..34f16d8e6e 100644 --- a/src/main/scala/edu/ie3/simona/util/TickUtil.scala +++ b/src/main/scala/edu/ie3/simona/util/TickUtil.scala @@ -45,7 +45,7 @@ object TickUtil { /** Calculate the length for the time interval */ def durationUntil( otherTick: Long, - tickDuration: Time = Seconds(1d) + tickDuration: Time = Seconds(1d), ): Time = tickDuration * (otherTick - tick).toDouble diff --git a/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala b/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala index e29a537bea..6ed62dc580 100644 --- a/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala +++ b/src/main/scala/edu/ie3/util/scala/ReflectionTools.scala @@ -51,7 +51,7 @@ object ReflectionTools { */ def classFieldToVal[A](a: A)(implicit tt: TypeTag[A], - ct: ClassTag[A] + ct: ClassTag[A], ): Map[universe.MethodSymbol, Any] = { val members = tt.tpe.members.collect { case m if m.isMethod && m.asMethod.isCaseAccessor => m.asMethod diff --git a/src/main/scala/edu/ie3/util/scala/collection/immutable/PrioritySwitchBiSet.scala b/src/main/scala/edu/ie3/util/scala/collection/immutable/PrioritySwitchBiSet.scala index bdf18abdb2..5aeaf9591a 100644 --- a/src/main/scala/edu/ie3/util/scala/collection/immutable/PrioritySwitchBiSet.scala +++ b/src/main/scala/edu/ie3/util/scala/collection/immutable/PrioritySwitchBiSet.scala @@ -42,7 +42,7 @@ final case class PrioritySwitchBiSet[K, V]( private val orderedValues: immutable.Vector[V], private val valueToIndex: Map[V, Int], private val queue: immutable.SortedMap[K, immutable.SortedSet[Int]], - private val back: Map[V, K] + private val back: Map[V, K], ) { /** Get the first key of the queue, if the queue is not empty. @@ -107,7 +107,7 @@ final case class PrioritySwitchBiSet[K, V]( copy( queue = updatedQueue, - back = updatedBack + back = updatedBack, ) } .getOrElse(this) @@ -120,9 +120,9 @@ final case class PrioritySwitchBiSet[K, V]( ( copy( orderedValues = orderedValues.appended(value), - valueToIndex = valueToIndex.updated(value, newIndex) + valueToIndex = valueToIndex.updated(value, newIndex), ), - newIndex + newIndex, ) case i => (this, i) @@ -134,7 +134,7 @@ final case class PrioritySwitchBiSet[K, V]( updatedStruct.copy( queue = queue.updated(key, updatedSet), - back = back.updated(value, key) + back = back.updated(value, key), ) } @@ -165,7 +165,7 @@ final case class PrioritySwitchBiSet[K, V]( ( firstValue, - copy(queue = updatedQueue, back = back.removed(firstValue)) + copy(queue = updatedQueue, back = back.removed(firstValue)), ) } } @@ -208,6 +208,6 @@ object PrioritySwitchBiSet { Vector.empty, Map.empty, immutable.SortedMap.empty, - Map.empty + Map.empty, ) } diff --git a/src/main/scala/edu/ie3/util/scala/collection/mutable/PriorityMultiBiSet.scala b/src/main/scala/edu/ie3/util/scala/collection/mutable/PriorityMultiBiSet.scala index d25e20a2d1..bd6bd8feab 100644 --- a/src/main/scala/edu/ie3/util/scala/collection/mutable/PriorityMultiBiSet.scala +++ b/src/main/scala/edu/ie3/util/scala/collection/mutable/PriorityMultiBiSet.scala @@ -32,7 +32,7 @@ import scala.collection.{SortedSet, mutable} final case class PriorityMultiBiSet[K, V] private ( private val queue: mutable.SortedSet[K], private val table: mutable.HashMap[K, mutable.Set[V]], - private val back: mutable.HashMap[V, K] + private val back: mutable.HashMap[V, K], ) { /** Get the first key of the queue, if the queue is not empty. Runs in O(1). @@ -161,7 +161,7 @@ object PriorityMultiBiSet { PriorityMultiBiSet( mutable.SortedSet.empty[K], mutable.HashMap[K, mutable.Set[V]](), - mutable.HashMap[V, K]() + mutable.HashMap[V, K](), ) /** Creates and returns an empty PriorityMultiQueue for given types. The @@ -184,17 +184,17 @@ object PriorityMultiBiSet { */ def empty[K: Ordering, V]( initialKeyCapacity: Int, - loadFactor: Double = mutable.HashMap.defaultLoadFactor + loadFactor: Double = mutable.HashMap.defaultLoadFactor, ): PriorityMultiBiSet[K, V] = PriorityMultiBiSet( mutable.SortedSet.empty[K], new mutable.HashMap[K, mutable.Set[V]]( initialKeyCapacity, - loadFactor + loadFactor, ), new mutable.HashMap[V, K]( initialKeyCapacity, - loadFactor - ) + loadFactor, + ), ) } diff --git a/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala b/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala index e4a66cbf5c..0e1515df69 100644 --- a/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala +++ b/src/main/scala/edu/ie3/util/scala/io/GraphicDataCleaner.scala @@ -38,13 +38,13 @@ object GraphicDataCleaner { val csvRawGridSource: RawGridSource = new RawGridSource( csvTypeSource, - dataSource + dataSource, ) val csvGraphicSource: GraphicSource = new GraphicSource( csvTypeSource, csvRawGridSource, - dataSource + dataSource, ) /* read - by default, the csvGraphicSource only returns valid, that means elements with all diff --git a/src/main/scala/edu/ie3/util/scala/io/ScalaReflectionSerde.scala b/src/main/scala/edu/ie3/util/scala/io/ScalaReflectionSerde.scala index e129c8dff6..f7d6707254 100644 --- a/src/main/scala/edu/ie3/util/scala/io/ScalaReflectionSerde.scala +++ b/src/main/scala/edu/ie3/util/scala/io/ScalaReflectionSerde.scala @@ -9,7 +9,7 @@ package edu.ie3.util.scala.io import com.sksamuel.avro4s.RecordFormat import io.confluent.kafka.streams.serdes.avro.{ GenericAvroDeserializer, - GenericAvroSerializer + GenericAvroSerializer, } import org.apache.kafka.common.serialization.{Deserializer, Serializer} @@ -24,7 +24,7 @@ object ScalaReflectionSerde { override def configure( configs: java.util.Map[String, _], - isKey: Boolean + isKey: Boolean, ): Unit = inner.configure(configs, isKey) override def serialize(topic: String, maybeData: T): Array[Byte] = @@ -43,7 +43,7 @@ object ScalaReflectionSerde { override def configure( configs: java.util.Map[String, _], - isKey: Boolean + isKey: Boolean, ): Unit = inner.configure(configs, isKey) override def deserialize(topic: String, maybeData: Array[Byte]): T = diff --git a/src/main/scala/edu/ie3/util/scala/quantities/EnergyDensity.scala b/src/main/scala/edu/ie3/util/scala/quantities/EnergyDensity.scala index 56806ea8da..2f0ae95ff2 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/EnergyDensity.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/EnergyDensity.scala @@ -20,7 +20,7 @@ import scala.util.Try */ final class EnergyDensity private ( val value: Double, - val unit: EnergyDensityUnit + val unit: EnergyDensityUnit, ) extends Quantity[EnergyDensity] { def dimension: EnergyDensity.type = EnergyDensity diff --git a/src/main/scala/edu/ie3/util/scala/quantities/EnergyPrice.scala b/src/main/scala/edu/ie3/util/scala/quantities/EnergyPrice.scala index 96a32d408a..eddd58a99b 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/EnergyPrice.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/EnergyPrice.scala @@ -17,7 +17,7 @@ import scala.util.Try final class EnergyPrice private ( val value: Double, - val unit: EnergyPriceUnit + val unit: EnergyPriceUnit, ) extends squants.Quantity[EnergyPrice] { def dimension: EnergyPrice.type = EnergyPrice diff --git a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala index d5aea08fdd..4ca6d188fb 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/QuantityUtil.scala @@ -61,7 +61,7 @@ object QuantityUtil { ] with TimeIntegral[Q]]( values: Map[Long, Q], windowStart: Long, - windowEnd: Long + windowEnd: Long, ): Try[Q] = { if (windowStart == windowEnd) Failure( @@ -76,7 +76,7 @@ object QuantityUtil { integrate[Q, QI]( values, windowStart, - windowEnd + windowEnd, ) / Seconds(windowEnd - windowStart) } } @@ -102,7 +102,7 @@ object QuantityUtil { ] with TimeIntegral[Q]]( values: Map[Long, Q], windowStart: Long, - windowEnd: Long + windowEnd: Long, ): QI = { /** Case class to hold current state of integration @@ -117,7 +117,7 @@ object QuantityUtil { final case class IntegrationState( currentIntegral: QI, lastTick: Long, - lastValue: Q + lastValue: Q, ) /* Determine the starting and ending value for the integral */ @@ -142,12 +142,12 @@ object QuantityUtil { IntegrationState( startValue * Hours(0), windowStart, - startValue + startValue, ) ) { case ( IntegrationState(currentIntegral, lastTick, lastValue), - (tick, value) + (tick, value), ) => /* Calculate the partial integral over the last know value since it's occurrence and the instance when the newest value comes in */ val duration = Seconds(tick - lastTick) @@ -172,7 +172,7 @@ object QuantityUtil { */ private def startingValue[Q <: squants.Quantity[Q]]( values: Map[Long, Q], - windowStart: Long + windowStart: Long, ): Q = { values .filter { case (tick, _) => @@ -206,7 +206,7 @@ object QuantityUtil { */ private def endingValue[Q <: Quantity[Q]]( values: Map[Long, Q], - windowEnd: Long + windowEnd: Long, ): (Long, Q) = { values .filter { case (tick, _) => diff --git a/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala b/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala index bc696b759c..aaddb36edf 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/ReactivePower.scala @@ -14,7 +14,7 @@ import scala.util.Try final class ReactivePower private ( val value: Double, - val unit: ReactivePowerUnit + val unit: ReactivePowerUnit, ) extends Quantity[ReactivePower] with TimeIntegral[PowerRamp] { diff --git a/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala b/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala index 7440920287..238668e67a 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/ScalaNumberSystem.scala @@ -29,7 +29,7 @@ final class ScalaNumberSystem extends DefaultNumberSystem { override def divideAndRemainder( x: Number, y: Number, - roundRemainderTowardsZero: Boolean + roundRemainderTowardsZero: Boolean, ): Array[Number] = { val signX = signum(x) val signY = signum(y) diff --git a/src/main/scala/edu/ie3/util/scala/quantities/SpecificHeatCapacity.scala b/src/main/scala/edu/ie3/util/scala/quantities/SpecificHeatCapacity.scala index a9e2c24011..e63ec421f5 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/SpecificHeatCapacity.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/SpecificHeatCapacity.scala @@ -20,7 +20,7 @@ import scala.util.Try */ final class SpecificHeatCapacity private ( val value: Double, - val unit: SpecificHeatCapacityUnit + val unit: SpecificHeatCapacityUnit, ) extends Quantity[SpecificHeatCapacity] { def dimension: SpecificHeatCapacity.type = SpecificHeatCapacity @@ -36,7 +36,7 @@ final class SpecificHeatCapacity private ( */ def calcEnergyDensity( temperatureA: Temperature, - temperatureB: Temperature + temperatureB: Temperature, ): EnergyDensity = KilowattHoursPerCubicMeter( this.toKilowattHoursPerKelvinCubicMeters * math.abs( @@ -59,7 +59,7 @@ final class SpecificHeatCapacity private ( def calcEnergy( temperatureA: Temperature, temperatureB: Temperature, - volume: Volume + volume: Volume, ): Energy = KilowattHours( this.toKilowattHoursPerKelvinCubicMeters * math.abs( diff --git a/src/main/scala/edu/ie3/util/scala/quantities/ThermalConductance.scala b/src/main/scala/edu/ie3/util/scala/quantities/ThermalConductance.scala index 1d26ec1f35..ce8f9d4293 100644 --- a/src/main/scala/edu/ie3/util/scala/quantities/ThermalConductance.scala +++ b/src/main/scala/edu/ie3/util/scala/quantities/ThermalConductance.scala @@ -17,7 +17,7 @@ import scala.util.Try */ final class ThermalConductance private ( val value: Double, - val unit: ThermalConductanceUnit + val unit: ThermalConductanceUnit, ) extends Quantity[ThermalConductance] { def dimension: ThermalConductance.type = ThermalConductance @@ -36,7 +36,7 @@ final class ThermalConductance private ( def thermalConductanceToEnergy( temperatureInner: Temperature, temperatureOuter: Temperature, - time: squants.Time + time: squants.Time, ): Energy = WattHours( this.toWattsPerKelvin * (temperatureInner.toKelvinScale - temperatureOuter.toKelvinScale) * time.toHours ) diff --git a/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala b/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala index 870f79064e..ede6b3043b 100644 --- a/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala @@ -44,7 +44,7 @@ class ValueStoreSpec extends UnitSpec with PrivateMethodTester { "A filled value store" should { val filledValueStore: ValueStore[String] = ValueStore[String]( 5, - SortedMap(1L -> "One", 2L -> "Two", 3L -> "Three", 4L -> "Four") + SortedMap(1L -> "One", 2L -> "Two", 3L -> "Three", 4L -> "Four"), ) "be properly instantiated" in { @@ -54,7 +54,7 @@ class ValueStoreSpec extends UnitSpec with PrivateMethodTester { 1L -> "One", 2L -> "Two", 3L -> "Three", - 4L -> "Four" + 4L -> "Four", ) filledValueStore.maxTickSpan shouldBe 5 } @@ -74,7 +74,7 @@ class ValueStoreSpec extends UnitSpec with PrivateMethodTester { "return an empty map on request of tick window" in { filledValueStore.get(2L, 3L) shouldBe Map( 2L -> "Two", - 3L -> "Three" + 3L -> "Three", ) } @@ -88,7 +88,7 @@ class ValueStoreSpec extends UnitSpec with PrivateMethodTester { 3L -> "Three", 4L -> "Four", 5L -> "Five", - 6L -> "Six" + 6L -> "Six", ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index 5beb87d7b0..ace38eb295 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -22,7 +22,7 @@ import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage @@ -31,7 +31,7 @@ import edu.ie3.simona.test.common.model.grid.DbfsTestGrid import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, - TestSpawnerClassic + TestSpawnerClassic, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars @@ -56,7 +56,7 @@ class DBFSAlgorithmCenGridSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with DBFSMockGridAgents @@ -71,7 +71,7 @@ class DBFSAlgorithmCenGridSpec private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), - Seq(supNodeA.getUuid, supNodeB.getUuid) + Seq(supNodeA.getUuid, supNodeB.getUuid), ) private val inferiorGrid11 = @@ -82,7 +82,7 @@ class DBFSAlgorithmCenGridSpec private val inferiorGrid13 = InferiorGA( TestProbe("inferiorGridAgent_13"), - Seq(node3.getUuid, node4.getUuid) + Seq(node3.getUuid, node4.getUuid), ) private val environmentRefs = EnvironmentRefs( @@ -90,7 +90,7 @@ class DBFSAlgorithmCenGridSpec runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, - evDataService = None + evDataService = None, ) val resultListener: TestProbe = TestProbe("resultListener") @@ -102,7 +102,7 @@ class DBFSAlgorithmCenGridSpec GridAgent.props( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref), ) ) @@ -126,7 +126,7 @@ class DBFSAlgorithmCenGridSpec hvGridContainer, Seq.empty[ThermalGrid], subGridGateToActorRef, - RefSystem("2000 MVA", "110 kV") + RefSystem("2000 MVA", "110 kV"), ) val key = @@ -135,7 +135,7 @@ class DBFSAlgorithmCenGridSpec centerGridAgent ! GridAgent.Create( gridAgentInitData, - key + key, ) scheduler.expectMsg( ScheduleActivation(centerGridAgent.toTyped, INIT_SIM_TICK, Some(key)) @@ -145,7 +145,7 @@ class DBFSAlgorithmCenGridSpec scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(3600) + Some(3600), ) ) @@ -155,13 +155,13 @@ class DBFSAlgorithmCenGridSpec scheduler.send( centerGridAgent, - Activation(3600) + Activation(3600), ) scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(3600) + Some(3600), ) ) } @@ -204,9 +204,9 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node1.getUuid, Kilovolts(110d), - Kilovolts(0d) + Kilovolts(0d), ) - ) + ), ) inferiorGrid12.expectSlackVoltageProvision( @@ -215,9 +215,9 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node2.getUuid, Kilovolts(110d), - Kilovolts(0d) + Kilovolts(0d), ) - ) + ), ) inferiorGrid13.expectSlackVoltageProvision( @@ -226,14 +226,14 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node3.getUuid, Kilovolts(110d), - Kilovolts(0d) + Kilovolts(0d), ), ExchangeVoltage( node4.getUuid, Kilovolts(110d), - Kilovolts(0d) - ) - ) + Kilovolts(0d), + ), + ), ) // we now answer the request of our centerGridAgent @@ -246,10 +246,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) inferiorGrid12.gaProbe.send( @@ -259,10 +259,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) inferiorGrid13.gaProbe.send( @@ -272,10 +272,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) superiorGridAgent.gaProbe.send( @@ -286,15 +286,15 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( supNodeA.getUuid, Kilovolts(380d), - Kilovolts(0d) + Kilovolts(0d), ), ExchangeVoltage( supNodeB.getUuid, Kilovolts(380d), - Kilovolts(0d) - ) - ) - ) + Kilovolts(0d), + ), + ), + ), ) // power flow calculation should run now. After it's done, @@ -307,13 +307,13 @@ class DBFSAlgorithmCenGridSpec ExchangePower( supNodeA.getUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), ExchangePower( supNodeB.getUuid, Megawatts(0.160905770717798), - Megavars(-1.4535602349123878) - ) + Megavars(-1.4535602349123878), + ), ) ) @@ -335,15 +335,15 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( supNodeB.getUuid, Kilovolts(374.22694614463d), // 380 kV @ 10° - Kilovolts(65.9863075134335d) // 380 kV @ 10° + Kilovolts(65.9863075134335d), // 380 kV @ 10° ), ExchangeVoltage( // this one should currently be ignored anyways supNodeA.getUuid, Kilovolts(380d), - Kilovolts(0d) - ) - ) - ) + Kilovolts(0d), + ), + ), + ), ) // After the intermediate power flow calculation, we expect one grid power @@ -377,9 +377,9 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node1.getUuid, Kilovolts(108.487669651919932d), - Kilovolts(19.101878551141232d) + Kilovolts(19.101878551141232d), ) - ) + ), ) inferiorGrid12.expectSlackVoltageProvision( @@ -388,9 +388,9 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node2.getUuid, Kilovolts(108.449088870497683d), - Kilovolts(19.10630456834157630d) + Kilovolts(19.10630456834157630d), ) - ) + ), ) inferiorGrid13.expectSlackVoltageProvision( @@ -399,14 +399,14 @@ class DBFSAlgorithmCenGridSpec ExchangeVoltage( node3.getUuid, Kilovolts(108.470028019077087d), - Kilovolts(19.104403047662570d) + Kilovolts(19.104403047662570d), ), ExchangeVoltage( node4.getUuid, Kilovolts(108.482524607256866d), - Kilovolts(19.1025584700935336d) - ) - ) + Kilovolts(19.1025584700935336d), + ), + ), ) // we now answer the requests of our centerGridAgent @@ -418,10 +418,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) inferiorGrid12.gaProbe.send( @@ -431,10 +431,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) inferiorGrid13.gaProbe.send( @@ -444,10 +444,10 @@ class DBFSAlgorithmCenGridSpec ExchangePower( nodeUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) // we expect that the GridAgent unstashes the messages and return a value for our power request @@ -456,13 +456,13 @@ class DBFSAlgorithmCenGridSpec ExchangePower( supNodeA.getUuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), ExchangePower( supNodeB.getUuid, Megawatts(0.16090577067051856), - Megavars(-1.4535602358772026) - ) + Megavars(-1.4535602358772026), + ), ) ) @@ -470,7 +470,7 @@ class DBFSAlgorithmCenGridSpec // connected inferior grids, because the slack node is just a mock, we imitate this behavior superiorGridAgent.gaProbe.send( centerGridAgent, - FinishGridSimulationTrigger(3600) + FinishGridSimulationTrigger(3600), ) // after a FinishGridSimulationTrigger is send the inferior grids, they themselves will send the @@ -484,7 +484,7 @@ class DBFSAlgorithmCenGridSpec scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(7200) + Some(7200), ) ) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index 85b4bb041a..bd677049a2 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -20,11 +20,11 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ FailedPowerFlow, - ProvideGridPowerMessage + ProvideGridPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage @@ -33,7 +33,7 @@ import edu.ie3.simona.test.common.model.grid.DbfsTestGrid import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, - TestSpawnerClassic + TestSpawnerClassic, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars @@ -51,7 +51,7 @@ class DBFSAlgorithmFailedPowerFlowSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with DBFSMockGridAgents @@ -67,7 +67,7 @@ class DBFSAlgorithmFailedPowerFlowSpec private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), - Seq(supNodeA.getUuid) + Seq(supNodeA.getUuid), ) private val inferiorGridAgent = @@ -78,7 +78,7 @@ class DBFSAlgorithmFailedPowerFlowSpec runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, - evDataService = None + evDataService = None, ) val resultListener: TestProbe = TestProbe("resultListener") @@ -90,7 +90,7 @@ class DBFSAlgorithmFailedPowerFlowSpec GridAgent.props( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref), ) ) @@ -111,7 +111,7 @@ class DBFSAlgorithmFailedPowerFlowSpec hvGridContainerPF, Seq.empty[ThermalGrid], subGridGateToActorRef, - RefSystem("2000 MVA", "110 kV") + RefSystem("2000 MVA", "110 kV"), ) val key = @@ -120,7 +120,7 @@ class DBFSAlgorithmFailedPowerFlowSpec centerGridAgent ! GridAgent.Create( gridAgentInitData, - key + key, ) scheduler.expectMsg( ScheduleActivation(centerGridAgent.toTyped, INIT_SIM_TICK, Some(key)) @@ -130,7 +130,7 @@ class DBFSAlgorithmFailedPowerFlowSpec scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(3600) + Some(3600), ) ) @@ -141,14 +141,14 @@ class DBFSAlgorithmFailedPowerFlowSpec // send init data to agent scheduler.send( centerGridAgent, - Activation(3600) + Activation(3600), ) // we expect a completion message scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(3600) + Some(3600), ) ) } @@ -179,9 +179,9 @@ class DBFSAlgorithmFailedPowerFlowSpec ExchangeVoltage( node1.getUuid, Kilovolts(110d), - Kilovolts(0d) + Kilovolts(0d), ) - ) + ), ) // we now answer the request of our centerGridAgent @@ -193,10 +193,10 @@ class DBFSAlgorithmFailedPowerFlowSpec ExchangePower( nodeUuid, Megawatts(1000.0), - Megavars(0.0) + Megavars(0.0), ) ) - ) + ), ) superiorGridAgent.gaProbe.send( @@ -207,10 +207,10 @@ class DBFSAlgorithmFailedPowerFlowSpec ExchangeVoltage( supNodeA.getUuid, Kilovolts(380d), - Kilovolts(0d) + Kilovolts(0d), ) - ) - ) + ), + ), ) // power flow calculation should run now. After it's done, @@ -227,7 +227,7 @@ class DBFSAlgorithmFailedPowerFlowSpec // connected inferior grids, because the slack node is just a mock, we imitate this behavior superiorGridAgent.gaProbe.send( centerGridAgent, - FinishGridSimulationTrigger(3600) + FinishGridSimulationTrigger(3600), ) // after a FinishGridSimulationTrigger is send to the inferior grids, they themselves will @@ -239,7 +239,7 @@ class DBFSAlgorithmFailedPowerFlowSpec scheduler.expectMsg( Completion( centerGridAgent.toTyped, - Some(7200) + Some(7200), ) ) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index 76c91a359f..c15e254661 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.agent.grid import org.apache.pekko.actor.typed.scaladsl.adapter.{ ClassicActorRefOps, - TypedActorRefOps + TypedActorRefOps, } import org.apache.pekko.actor.{ActorRef, ActorSystem} import org.apache.pekko.testkit.{ImplicitSender, TestProbe} @@ -23,7 +23,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage @@ -34,7 +34,7 @@ import edu.ie3.simona.test.common.model.grid.DbfsTestGridWithParticipants import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, - TestSpawnerClassic + TestSpawnerClassic, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars @@ -51,7 +51,7 @@ class DBFSAlgorithmParticipantSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with DBFSMockGridAgents @@ -70,14 +70,14 @@ class DBFSAlgorithmParticipantSpec runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, - evDataService = None + evDataService = None, ) protected val resultListener: TestProbe = TestProbe("resultListener") private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), - Seq(supNodeA.getUuid) + Seq(supNodeA.getUuid), ) "Test participant" should { @@ -85,7 +85,7 @@ class DBFSAlgorithmParticipantSpec GridAgent.props( environmentRefs, simonaConfig, - Iterable(resultListener.ref) + Iterable(resultListener.ref), ) ) @@ -101,7 +101,7 @@ class DBFSAlgorithmParticipantSpec hvGridContainer, Seq.empty, subGridGateToActorRef, - RefSystem("2000 MVA", "110 kV") + RefSystem("2000 MVA", "110 kV"), ) val key = @@ -113,7 +113,7 @@ class DBFSAlgorithmParticipantSpec ScheduleActivation( gridAgentWithParticipants.toTyped, INIT_SIM_TICK, - Some(key) + Some(key), ) ) @@ -125,7 +125,7 @@ class DBFSAlgorithmParticipantSpec case ScheduleActivation( loadAgent, INIT_SIM_TICK, - _ + _, ) => loadAgent } @@ -133,7 +133,7 @@ class DBFSAlgorithmParticipantSpec scheduler.expectMsg( Completion( gridAgentWithParticipants.toTyped, - Some(3600) + Some(3600), ) ) @@ -145,7 +145,7 @@ class DBFSAlgorithmParticipantSpec primaryService.send( loadAgent.toClassic, - RegistrationFailedMessage(primaryService.ref) + RegistrationFailedMessage(primaryService.ref), ) scheduler.expectMsg(Completion(loadAgent, Some(0))) @@ -153,7 +153,7 @@ class DBFSAlgorithmParticipantSpec // triggering the loadAgent's calculation scheduler.send( loadAgent.toClassic, - Activation(0) + Activation(0), ) // the load agent should send a CompletionMessage scheduler.expectMsg(Completion(loadAgent, None)) @@ -165,14 +165,14 @@ class DBFSAlgorithmParticipantSpec // send init data to agent scheduler.send( gridAgentWithParticipants, - Activation(3600) + Activation(3600), ) // we expect a completion message scheduler.expectMsg( Completion( gridAgentWithParticipants.toTyped, - Some(3600) + Some(3600), ) ) @@ -201,10 +201,10 @@ class DBFSAlgorithmParticipantSpec ExchangeVoltage( supNodeA.getUuid, Kilovolts(380d), - Kilovolts(0d) + Kilovolts(0d), ) - ) - ) + ), + ), ) // power flow calculation should run now. After it's done, @@ -212,7 +212,7 @@ class DBFSAlgorithmParticipantSpec // hence we ask for them and expect a corresponding response superiorGridAgent.requestGridPower( gridAgentWithParticipants, - firstSweepNo + firstSweepNo, ) // the gridAgentWithParticipants has received an AssetPowerChangedMessage @@ -222,7 +222,7 @@ class DBFSAlgorithmParticipantSpec ExchangePower( supNodeA.getUuid, Megawatts(135.90837346741768), - Megavars(60.98643348675892) + Megavars(60.98643348675892), ) ) ) @@ -233,7 +233,7 @@ class DBFSAlgorithmParticipantSpec superiorGridAgent.requestGridPower( gridAgentWithParticipants, - secondSweepNo + secondSweepNo, ) // the agent now should ask for updated slack voltages from the superior grid @@ -249,10 +249,10 @@ class DBFSAlgorithmParticipantSpec ExchangeVoltage( supNodeA.getUuid, Kilovolts(374.2269461446d), - Kilovolts(65.9863075134d) + Kilovolts(65.9863075134d), ) - ) - ) + ), + ), ) // here the gridAgentWithParticipants has received a second AssetPowerUnchangedMessage @@ -262,7 +262,7 @@ class DBFSAlgorithmParticipantSpec ExchangePower( supNodeA.getUuid, Megawatts(135.90837346741768), - Megavars(60.98643348675892) + Megavars(60.98643348675892), ) ) ) @@ -271,13 +271,13 @@ class DBFSAlgorithmParticipantSpec // (here we do it by hand) superiorGridAgent.gaProbe.send( gridAgentWithParticipants, - FinishGridSimulationTrigger(3600L) + FinishGridSimulationTrigger(3600L), ) scheduler.expectMsg( Completion( gridAgentWithParticipants.toTyped, - Some(7200) + Some(7200), ) ) } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index 41fefc20d6..a9dd723f8d 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -22,11 +22,11 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, - RequestGridPowerMessage + RequestGridPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid @@ -34,7 +34,7 @@ import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, TestSpawnerClassic, - UnitSpec + UnitSpec, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.scala.quantities.Megavars @@ -57,7 +57,7 @@ class DBFSAlgorithmSupGridSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with UnitSpec @@ -77,7 +77,7 @@ class DBFSAlgorithmSupGridSpec runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, - evDataService = None + evDataService = None, ) val resultListener: TestProbe = TestProbe("resultListener") @@ -87,7 +87,7 @@ class DBFSAlgorithmSupGridSpec GridAgent.props( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref), ) ) @@ -100,7 +100,7 @@ class DBFSAlgorithmSupGridSpec ehvGridContainer, Seq.empty[ThermalGrid], subnetGatesToActorRef, - RefSystem("5000 MVA", "380 kV") + RefSystem("5000 MVA", "380 kV"), ) val key = @@ -112,7 +112,7 @@ class DBFSAlgorithmSupGridSpec ScheduleActivation( superiorGridAgentFSM.toTyped, INIT_SIM_TICK, - Some(key) + Some(key), ) ) @@ -163,10 +163,10 @@ class DBFSAlgorithmSupGridSpec ExchangePower( uuid, Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) } - ) + ), ) // we expect a completion message here and that the agent goes back to simulate grid @@ -221,24 +221,24 @@ class DBFSAlgorithmSupGridSpec Array( ( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), ( Megawatts(0.1), - Megavars(0.1) + Megavars(0.1), ), ( Megawatts(0.0), - Megavars(0.1) + Megavars(0.1), ), ( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), ( Megawatts(0.0), - Megavars(0.0) - ) + Megavars(0.0), + ), ) // bring agent in simulate grid state @@ -279,10 +279,10 @@ class DBFSAlgorithmSupGridSpec ExchangePower( uuid, deviations(sweepNo)._1, - deviations(sweepNo)._2 + deviations(sweepNo)._2, ) } - ) + ), ) // we expect a completion message here and that the agent goes back to simulate grid diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index 1e12ac315e..6a001d6e1b 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -11,12 +11,12 @@ import org.apache.pekko.testkit.TestProbe import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, - RequestGridPowerMessage + RequestGridPowerMessage, } import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.simona.ontology.messages.VoltageMessage.{ ProvideSlackVoltageMessage, - RequestSlackVoltageMessage + RequestSlackVoltageMessage, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} @@ -48,7 +48,7 @@ trait DBFSMockGridAgents extends UnitSpec { final case class InferiorGA( override val gaProbe: TestProbe, - override val nodeUuids: Seq[UUID] + override val nodeUuids: Seq[UUID], ) extends GAActorAndModel { def expectGridPowerRequest(): ActorRef = { @@ -61,7 +61,7 @@ trait DBFSMockGridAgents extends UnitSpec { def expectSlackVoltageProvision( expectedSweepNo: Int, - expectedExchangedVoltages: Seq[ExchangeVoltage] + expectedExchangedVoltages: Seq[ExchangeVoltage], ): Unit = { inside(gaProbe.expectMsgType[ProvideSlackVoltageMessage]) { case ProvideSlackVoltageMessage(sweepNo, exchangedVoltages) => @@ -88,13 +88,13 @@ trait DBFSMockGridAgents extends UnitSpec { def requestSlackVoltage(receiver: ActorRef, sweepNo: Int): Unit = gaProbe.send( receiver, - RequestSlackVoltageMessage(sweepNo, nodeUuids) + RequestSlackVoltageMessage(sweepNo, nodeUuids), ) } final case class SuperiorGA( override val gaProbe: TestProbe, - override val nodeUuids: Seq[UUID] + override val nodeUuids: Seq[UUID], ) extends GAActorAndModel { def expectSlackVoltageRequest(expectedSweepNo: Int): ActorRef = { @@ -113,7 +113,7 @@ trait DBFSMockGridAgents extends UnitSpec { def expectGridPowerProvision( expectedExchangedPowers: Seq[ExchangePower], - maxDuration: FiniteDuration = 30 seconds + maxDuration: FiniteDuration = 30 seconds, ): Unit = { inside(gaProbe.expectMsgType[ProvideGridPowerMessage](maxDuration)) { case ProvideGridPowerMessage(exchangedPower) => @@ -140,8 +140,8 @@ trait DBFSMockGridAgents extends UnitSpec { receiver, RequestGridPowerMessage( sweepNo, - nodeUuids - ) + nodeUuids, + ), ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentDataHelperSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentDataHelperSpec.scala index 76a438267d..3e2170cbdc 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentDataHelperSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentDataHelperSpec.scala @@ -16,7 +16,7 @@ object GridAgentDataHelperSpec { final case class TestGridData( subgridId: Int, - subgridGates: Vector[SubGridGate] + subgridGates: Vector[SubGridGate], ) extends GridAgentDataHelper { def getSuperiorGridGates: Vector[SubGridGate] = @@ -44,31 +44,31 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { UUID.fromString("107a3c34-d890-4f92-95e6-beb10975d9d3"), 1, UUID.fromString("0292fbe9-63b7-4580-9920-2c7c24032abc"), - 100 + 100, ) val superiorSubGridGate2: SubGridGate = build2wSubGridGate( UUID.fromString("97e957fb-b1c0-4ae0-bfe0-329ed85616b4"), 2, UUID.fromString("f05e40a4-8d48-44c3-bbe9-bebf10022fc0"), - 100 + 100, ) val centerSubGridGate1: SubGridGate = build2wSubGridGate( UUID.fromString("37ff2b4d-de5c-4036-b0b2-f343f839182c"), 100, UUID.fromString("960deb7c-cf50-45d8-8563-5fdd713d90f2"), - 1000 + 1000, ) val centerSubGridGate2: SubGridGate = build2wSubGridGate( UUID.fromString("73a2ec29-9054-4e8d-8f0d-a945434c89d8"), 100, UUID.fromString("b17a0ec9-9567-42c8-990f-186888c6eb37"), - 2000 + 2000, ) val centerSubGridGate3: SubGridGate = build2wSubGridGate( UUID.fromString("44065395-07bf-48ef-9df4-9e82c705946d"), 100, UUID.fromString("3bcda4b0-2d1a-44f5-95c1-a63ce1d40bed"), - 3000 + 3000, ) val superiorGridGates = Vector(superiorSubGridGate1) val centerGridGates = Vector( @@ -76,7 +76,7 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { superiorSubGridGate2, centerSubGridGate1, centerSubGridGate2, - centerSubGridGate3 + centerSubGridGate3, ) val inferiorGridGates = Vector(centerSubGridGate1) @@ -99,7 +99,7 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { superiorGridAgent.getSuperiorGridNodeUuids shouldBe Vector.empty[String] centerGridAgent.getSuperiorGridNodeUuids shouldBe Vector( UUID.fromString("107a3c34-d890-4f92-95e6-beb10975d9d3"), - UUID.fromString("97e957fb-b1c0-4ae0-bfe0-329ed85616b4") + UUID.fromString("97e957fb-b1c0-4ae0-bfe0-329ed85616b4"), ) inferiorGridAgent.getSuperiorGridNodeUuids shouldBe Vector( UUID.fromString("37ff2b4d-de5c-4036-b0b2-f343f839182c") @@ -114,7 +114,7 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { centerGridAgent.getInferiorGridGates shouldBe Vector( centerSubGridGate1, centerSubGridGate2, - centerSubGridGate3 + centerSubGridGate3, ) inferiorGridAgent.getInferiorGridGates shouldBe Vector.empty[SubGridGate] @@ -133,7 +133,7 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { superiorGridAgent.getSuperiorGridGates shouldBe Vector.empty[SubGridGate] centerGridAgent.getSuperiorGridGates shouldBe Vector( superiorSubGridGate1, - superiorSubGridGate2 + superiorSubGridGate2, ) inferiorGridAgent.getSuperiorGridGates shouldBe Vector(centerSubGridGate1) } @@ -151,7 +151,7 @@ class GridAgentDataHelperSpec extends UnitSpec with SubGridGateMokka { centerGridAgent.getInferiorGridNodeUuids shouldBe Vector( UUID.fromString("960deb7c-cf50-45d8-8563-5fdd713d90f2"), UUID.fromString("b17a0ec9-9567-42c8-990f-186888c6eb37"), - UUID.fromString("3bcda4b0-2d1a-44f5-95c1-a63ce1d40bed") + UUID.fromString("3bcda4b0-2d1a-44f5-95c1-a63ce1d40bed"), ) inferiorGridAgent.getInferiorGridNodeUuids shouldBe Vector.empty[String] } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala index e58ad3c2fb..3a5490b892 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala @@ -12,7 +12,7 @@ import org.apache.pekko.actor.{ ActorRef, ActorSystem, Identify, - Props + Props, } import org.apache.pekko.testkit.ImplicitSender import org.apache.pekko.util.Timeout @@ -40,7 +40,7 @@ class GridAgentSetup2WSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with ImplicitSender @@ -64,7 +64,7 @@ class GridAgentSetup2WSpec runtimeEventListener = self, primaryServiceProxy = self, weather = ActorRef.noSender, - evDataService = None + evDataService = None, ) SimonaStandaloneSetup( @@ -76,20 +76,20 @@ class GridAgentSetup2WSpec Set.empty[Class[_ <: ResultEntity]], ResultSinkType( simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName - ) - ) - ) + simonaConfig.simona.simulationName, + ), + ), + ), ).buildSubGridToActorRefMap( gridContainer.getSubGridTopologyGraph, context, environmentRefs, - Seq.empty[ActorRef] + Seq.empty[ActorRef], ) sender() ! "done" } })) ? "setup", - Duration(1, TimeUnit.SECONDS) + Duration(1, TimeUnit.SECONDS), ) val sel = system.actorSelection("user/**/GridAgent_*") @@ -99,7 +99,7 @@ class GridAgentSetup2WSpec val responses: Seq[ActorIdentity] = receiveWhile( max = Duration.create(500, "ms"), - idle = Duration.create(250, "ms") + idle = Duration.create(250, "ms"), ) { case msg: ActorIdentity => msg } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala index f2b2d44f41..e12209b4f2 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala @@ -12,7 +12,7 @@ import org.apache.pekko.actor.{ ActorRef, ActorSystem, Identify, - Props + Props, } import org.apache.pekko.testkit.ImplicitSender import org.apache.pekko.util.Timeout @@ -25,7 +25,7 @@ import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, - ThreeWindingTestData + ThreeWindingTestData, } import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig @@ -43,7 +43,7 @@ class GridAgentSetup3WSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with ImplicitSender @@ -66,7 +66,7 @@ class GridAgentSetup3WSpec runtimeEventListener = self, primaryServiceProxy = self, weather = ActorRef.noSender, - evDataService = None + evDataService = None, ) SimonaStandaloneSetup( @@ -78,20 +78,20 @@ class GridAgentSetup3WSpec Set.empty[Class[_ <: ResultEntity]], ResultSinkType( simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName - ) - ) - ) + simonaConfig.simona.simulationName, + ), + ), + ), ).buildSubGridToActorRefMap( threeWindingTestGrid.getSubGridTopologyGraph, context, environmentRefs, - Seq.empty[ActorRef] + Seq.empty[ActorRef], ) sender() ! "done" } })) ? "setup", - Duration(1, TimeUnit.SECONDS) + Duration(1, TimeUnit.SECONDS), ) val sel = system.actorSelection("user/**/GridAgent_*") @@ -101,7 +101,7 @@ class GridAgentSetup3WSpec val responses: Seq[ActorIdentity] = receiveWhile( max = Duration.create(500, "ms"), - idle = Duration.create(250, "ms") + idle = Duration.create(250, "ms"), ) { case msg: ActorIdentity => msg } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala index 2ae971cc5f..ce67a10c04 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridResultsSupportSpec.scala @@ -14,7 +14,7 @@ import edu.ie3.datamodel.models.result.NodeResult import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, - Transformer2WResult + Transformer2WResult, } import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.enums.NodeType @@ -22,20 +22,20 @@ import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, - PowerFlowCaseC + PowerFlowCaseC, } import edu.ie3.simona.model.grid.{ RefSystem, Transformer3wModel, TransformerModel, - TransformerTappingModel + TransformerTappingModel, } import edu.ie3.simona.test.common.exceptions.InvalidTestDataException import edu.ie3.simona.test.common.input.GridInputTestData import edu.ie3.simona.test.common.model.grid.{ BasicGrid, BasicGridWithSwitches, - TransformerTestData + TransformerTestData, } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import edu.ie3.util.TimeUtil @@ -75,8 +75,8 @@ class GridResultsSupportSpec 0, NodeType.PQ, Complex(0.9583756183209947, -0.04673985022513541), - Complex(0.006466666857417822, 2.7286658176028933e-15) - ) + Complex(0.006466666857417822, 2.7286658176028933e-15), + ), ) val nodeResult = @@ -86,7 +86,7 @@ class GridResultsSupportSpec nodeUuid, Quantities.getQuantity(0.9595146895129939, PU), Quantities - .getQuantity(-2.79209521012981881159, DEGREE_GEOM) + .getQuantity(-2.79209521012981881159, DEGREE_GEOM), ) nodeResult.getInputModel shouldBe expectedNodeResult.getInputModel @@ -95,12 +95,12 @@ class GridResultsSupportSpec QuantityUtil.isEquivalentAngle( nodeResult.getvAng, expectedNodeResult.getvAng, - 1e-12 + 1e-12, ) shouldBe true QuantityUtil.isEquivalentAbs( nodeResult.getvMag, expectedNodeResult.getvMag, - 1e-12 + 1e-12, ) shouldBe true } } @@ -112,7 +112,7 @@ class GridResultsSupportSpec val expectedSwitchResult = new SwitchResult( defaultSimulationStart, switch1.uuid, - switch1.isClosed + switch1.isClosed, ) switchResult.getTime shouldBe expectedSwitchResult.getTime @@ -132,7 +132,7 @@ class GridResultsSupportSpec Quantities .getQuantity(24.9409944828817942724, Units.AMPERE), Quantities - .getQuantity(153.57729374050189129708, DEGREE_GEOM) + .getQuantity(153.57729374050189129708, DEGREE_GEOM), ) val nodeAStateData = new StateData( @@ -140,18 +140,18 @@ class GridResultsSupportSpec NodeType.PQ, Complex( 0.8655176782269813, - -0.037052090894132306 + -0.037052090894132306, ), // Angle = -2,4512878986765928398° - Complex(0.319999917504236, 4.86242990316299e-15) + Complex(0.319999917504236, 4.86242990316299e-15), ) val nodeBStateData = new StateData( 2, NodeType.PQ, Complex( 0.8637364806386005, - -0.03745498173182088 + -0.03745498173182088, ), // Angle = -2,4830128149755043846° - Complex(0.31999991750423107, -2.3469073906490223e-14) + Complex(0.31999991750423107, -2.3469073906490223e-14), ) val lineResult: LineResult = calcLineResult( @@ -159,7 +159,7 @@ class GridResultsSupportSpec nodeAStateData, nodeBStateData, default400Kva10KvRefSystem.nominalCurrent, - defaultSimulationStart + defaultSimulationStart, ) lineResult.getInputModel shouldBe expectedLineResult.getInputModel @@ -167,23 +167,23 @@ class GridResultsSupportSpec QuantityUtil.isEquivalentAbs( lineResult.getiAMag, expectedLineResult.getiAMag, - 1e-4 + 1e-4, ) shouldBe true QuantityUtil.isEquivalentAngle( lineResult.getiAAng, expectedLineResult.getiAAng, - 1e-3 + 1e-3, ) shouldBe true QuantityUtil.isEquivalentAbs( lineResult.getiBMag, expectedLineResult.getiBMag, - 1e-4 + 1e-4, ) shouldBe true QuantityUtil.isEquivalentAngle( lineResult.getiBAng, expectedLineResult.getiBAng, - 1e-3 + 1e-3, ) shouldBe true // if line is disabled zero results are expected @@ -193,7 +193,7 @@ class GridResultsSupportSpec nodeAStateData, nodeBStateData, default400Kva10KvRefSystem.nominalCurrent, - defaultSimulationStart + defaultSimulationStart, ) disabledLineResult shouldBe new LineResult( @@ -202,7 +202,7 @@ class GridResultsSupportSpec ScalaQuantityUtil.zeroCompQuantity(Units.AMPERE), ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), ScalaQuantityUtil.zeroCompQuantity(Units.AMPERE), - ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM) + ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), ) } @@ -220,7 +220,7 @@ class GridResultsSupportSpec iAMag: Double, iAAng: Double, iBMag: Double, - iBAng: Double + iBAng: Double, ) => /* === Prepare test data and expected result === */ /* Get the correct transformer model */ @@ -241,7 +241,7 @@ class GridResultsSupportSpec 0, NodeType.SL, voltageHv, - Complex.zero + Complex.zero, ) /* Prepare node information for low voltage node */ @@ -249,13 +249,13 @@ class GridResultsSupportSpec 1, NodeType.PQ, voltageLv, - powerLv + powerLv, ) /* Set up grid's reference system */ val refSys = RefSystem( Kilowatts(400d), - Volts(400d) + Volts(400d), ) /* Artificial time stamp */ @@ -270,7 +270,7 @@ class GridResultsSupportSpec Quantities.getQuantity(iAAng, DEGREE_GEOM), Quantities.getQuantity(iBMag, AMPERE), Quantities.getQuantity(iBAng, DEGREE_GEOM), - tapPos + tapPos, ) /* === Perform the operation to test === */ @@ -279,7 +279,7 @@ class GridResultsSupportSpec hvNodeStateData, lvNodeStateData, refSys.nominalCurrent, - time + time, ) /* === Examine the result === */ @@ -288,23 +288,23 @@ class GridResultsSupportSpec QuantityUtil.isEquivalentAbs( actual.getiAMag(), expectedResult.getiAMag(), - 1e-3 + 1e-3, ) shouldBe true QuantityUtil.isEquivalentAngle( actual.getiAAng(), expectedResult.getiAAng(), - 1e-3 + 1e-3, ) shouldBe true QuantityUtil.isEquivalentAbs( actual.getiBMag(), expectedResult.getiBMag(), - 1e-3 + 1e-3, ) shouldBe true if ( QuantityUtil.isEquivalentAngle( actual.getiBAng(), expectedResult.getiBAng(), - 1e-3 + 1e-3, ) ) { /* Angles are considerably equal */ @@ -343,7 +343,7 @@ class GridResultsSupportSpec ) ) .to(AMPERE), - 1e-4 + 1e-4, ) shouldBe true /* Testing the imaginary part of the current */ QuantityUtil.isEquivalentAbs( @@ -373,7 +373,7 @@ class GridResultsSupportSpec ) ) .to(AMPERE), - 1e-4 + 1e-4, ) shouldBe true } actual.getTapPos shouldBe expectedResult.getTapPos @@ -391,13 +391,13 @@ class GridResultsSupportSpec 0, NodeType.SL, Complex.one, - Complex.zero + Complex.zero, ) val nodeStateDataLv: StateData = StateData( 1, NodeType.PQ, Complex.one, - Complex.zero + Complex.zero, ) val expectedResult: Transformer2WResult = new Transformer2WResult( @@ -407,7 +407,7 @@ class GridResultsSupportSpec ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), ScalaQuantityUtil.zeroCompQuantity(AMPERE), ScalaQuantityUtil.zeroCompQuantity(DEGREE_GEOM), - transformerModel.currentTapPos + transformerModel.currentTapPos, ) calcTransformer2wResult( @@ -416,9 +416,9 @@ class GridResultsSupportSpec nodeStateDataLv, RefSystem( Kilowatts(400d), - Volts(400d) + Volts(400d), ).nominalCurrent, - TimeUtil.withDefaults.toZonedDateTime("2020-06-08 09:03:00") + TimeUtil.withDefaults.toZonedDateTime("2020-06-08 09:03:00"), ) shouldBe expectedResult } } @@ -443,25 +443,25 @@ class GridResultsSupportSpec 10, -10, 0, - autoTap = true + autoTap = true, ), 1, PowerFlowCaseA, Each(0.1d), Each(0.2d), Each(0.3d), - Each(0.4d) + Each(0.4d), ) transformerA.initTapping() val transformerB = transformerA.copy( powerFlowCase = PowerFlowCaseB, g = Each(0d), - b = Each(0d) + b = Each(0d), ) val transformerC = transformerA.copy( powerFlowCase = PowerFlowCaseC, g = Each(0d), - b = Each(0d) + b = Each(0d), ) val iNominal = Amperes(100d) @@ -477,14 +477,14 @@ class GridResultsSupportSpec nodeStateData, internalNodeStateData, iNominal, - timeStamp + timeStamp, ) match { case PartialTransformer3wResult.PortA( time, input, currentMagnitude, currentAngle, - tapPos + tapPos, ) => time shouldBe timeStamp input shouldBe transformerA.uuid @@ -505,13 +505,13 @@ class GridResultsSupportSpec nodeStateData, internalNodeStateData, iNominal, - timeStamp + timeStamp, ) match { case PartialTransformer3wResult.PortB( time, input, currentMagnitude, - currentAngle + currentAngle, ) => time shouldBe timeStamp input shouldBe transformerB.uuid @@ -531,13 +531,13 @@ class GridResultsSupportSpec nodeStateData, internalNodeStateData, iNominal, - timeStamp + timeStamp, ) match { case PartialTransformer3wResult.PortC( time, input, currentMagnitude, - currentAngle + currentAngle, ) => time shouldBe timeStamp input shouldBe transformerC.uuid @@ -554,18 +554,18 @@ class GridResultsSupportSpec default400Kva10KvRefSystem, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ), new StateData(0, NodeType.PQ, Complex(1, 0), Complex(1, 0)), new StateData(1, NodeType.PQ, Complex(0.99, 0), Complex(0.98, 0)), default400Kva10KvRefSystem.nominalCurrent, - timeStamp + timeStamp, ) match { case PartialTransformer3wResult.PortB( time, input, currentMagnitude, - currentAngle + currentAngle, ) => time shouldBe timeStamp input shouldBe transformer3wInput.getUuid diff --git a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala index 66805b06d9..3be73dc240 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -49,7 +49,7 @@ class PowerFlowSupportSpec ExchangeVoltage( node6.uuid, Kilovolts(110d), - Kilovolts(0d) + Kilovolts(0d), ) ) ), @@ -59,11 +59,11 @@ class PowerFlowSupportSpec ExchangePower( node1.uuid, Megawatts(1d), - Megavars(0d) + Megavars(0d), ) ) ) - ) + ), ) val currentTolerance = 1e-3 // 1 mA @@ -97,7 +97,7 @@ class PowerFlowSupportSpec gridModel.gridComponents.transformers3w, gridModel.nodeUuidToIndexMap, receivedValuesStore, - gridModel.mainRefSystem + gridModel.mainRefSystem, ) operatingPoint.length shouldBe 10 withClue "safety check: 13 nodes minus 3 closed switches" @@ -106,7 +106,7 @@ class PowerFlowSupportSpec gridModel, 3, operatingPoint, - slackNodeVoltages + slackNodeVoltages, )(Vector(1e-12)) match { case successResult: ValidNewtonRaphsonPFResult => successResult case failure => fail(s"Newton-Raphson failed: $failure") @@ -115,7 +115,7 @@ class PowerFlowSupportSpec val sweepValueStore = SweepValueStore( result, gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap + gridModel.nodeUuidToIndexMap, ) val pfResult = @@ -127,26 +127,26 @@ class PowerFlowSupportSpec line18To1, line0To17, line0To15, - line16To3 + line16To3, ).map(_.uuid).toSet pfResult.lineResults .filter(lineRes => loadLinesLeft.contains(lineRes.getInputModel)) .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 30.4954d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 30.4954d.asAmpere, - currentTolerance + currentTolerance, ) normalizeAngle(lineRes.getiAAng()) should equalWithTolerance( 179.7095d.asDegreeGeom, - angleTolerance + angleTolerance, ) normalizeAngle(lineRes.getiBAng()) should equalWithTolerance( 179.7095d.asDegreeGeom, - angleTolerance + angleTolerance, ) } @@ -155,26 +155,26 @@ class PowerFlowSupportSpec Iterable( line1To13, line14To2, - line2To3 + line2To3, ).map(_.uuid).toSet pfResult.lineResults .filter(lineRes => loadLinesRight.contains(lineRes.getInputModel)) .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 27.723d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 27.723d.asAmpere, - currentTolerance + currentTolerance, ) normalizeAngle(lineRes.getiAAng()) should equalWithTolerance( 179.7095d.asDegreeGeom, - angleTolerance + angleTolerance, ) normalizeAngle(lineRes.getiBAng()) should equalWithTolerance( 179.7095d.asDegreeGeom, - angleTolerance + angleTolerance, ) } @@ -198,7 +198,7 @@ class PowerFlowSupportSpec gridModel.gridComponents.transformers3w, gridModel.nodeUuidToIndexMap, receivedValuesStore, - gridModel.mainRefSystem + gridModel.mainRefSystem, ) operatingPoint.length shouldBe 11 withClue "safety check: 13 nodes minus 2 closed switches" @@ -207,7 +207,7 @@ class PowerFlowSupportSpec gridModel, 50, operatingPoint, - slackNodeVoltages + slackNodeVoltages, )(Vector(1e-12)) match { case successResult: ValidNewtonRaphsonPFResult => successResult case failure => fail(s"Newton-Raphson failed: $failure") @@ -218,8 +218,8 @@ class PowerFlowSupportSpec SweepValueStore( result, gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap - ) + gridModel.nodeUuidToIndexMap, + ), )(ZonedDateTime.now()) // left/top side segments (lines that are adjacent to the open switch) should have no load @@ -230,11 +230,11 @@ class PowerFlowSupportSpec .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 0.0001d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 0.0001d.asAmpere, - currentTolerance + currentTolerance, ) // angles are not reliable enough with such small magnitudes } @@ -247,19 +247,19 @@ class PowerFlowSupportSpec .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 58.6017d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 58.6017d.asAmpere, - currentTolerance + currentTolerance, ) normalizeAngle(lineRes.getiAAng()) should equalWithTolerance( 179.4090d.asDegreeGeom, - angleTolerance + angleTolerance, ) normalizeAngle(lineRes.getiBAng()) should equalWithTolerance( 179.4090d.asDegreeGeom, - angleTolerance + angleTolerance, ) } @@ -283,7 +283,7 @@ class PowerFlowSupportSpec gridModel.gridComponents.transformers3w, gridModel.nodeUuidToIndexMap, receivedValuesStore, - gridModel.mainRefSystem + gridModel.mainRefSystem, ) operatingPoint.length shouldBe 11 withClue "safety check: 13 nodes minus 2 closed switches" @@ -292,7 +292,7 @@ class PowerFlowSupportSpec gridModel, 50, operatingPoint, - slackNodeVoltages + slackNodeVoltages, )(Vector(1e-12)) match { case successResult: ValidNewtonRaphsonPFResult => successResult case failure => fail(s"Newton-Raphson failed: $failure") @@ -303,8 +303,8 @@ class PowerFlowSupportSpec SweepValueStore( result, gridModel.gridComponents.nodes, - gridModel.nodeUuidToIndexMap - ) + gridModel.nodeUuidToIndexMap, + ), )(ZonedDateTime.now()) // left/top side segments (lines that are adjacent to the open switch) should have load @@ -315,19 +315,19 @@ class PowerFlowSupportSpec .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 58.5343d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 58.5343d.asAmpere, - currentTolerance + currentTolerance, ) normalizeAngle(lineRes.getiAAng()) should equalWithTolerance( 179.461d.asDegreeGeom, - angleTolerance + angleTolerance, ) normalizeAngle(lineRes.getiBAng()) should equalWithTolerance( 179.461d.asDegreeGeom, - angleTolerance + angleTolerance, ) } @@ -341,11 +341,11 @@ class PowerFlowSupportSpec .foreach { lineRes => lineRes.getiAMag() should equalWithTolerance( 0.0001d.asAmpere, - currentTolerance + currentTolerance, ) lineRes.getiBMag() should equalWithTolerance( 0.0001d.asAmpere, - currentTolerance + currentTolerance, ) // angles are not reliable enough with such small magnitudes } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala index e4d9fedf2c..0902a476ce 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala @@ -23,7 +23,7 @@ class ReceivedValuesStoreSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with UnitSpec @@ -42,7 +42,7 @@ class ReceivedValuesStoreSpec ), UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") -> Set( actorProbe2.ref - ) + ), ) // / subnet gate mapping for inferior grids @@ -51,7 +51,7 @@ class ReceivedValuesStoreSpec UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8"), 1, UUID.fromString("1676360a-c7c4-43a9-a667-90ddfe8a18e6"), - 2 + 2, ) -> actorProbe3.ref ) @@ -72,7 +72,7 @@ class ReceivedValuesStoreSpec ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 0 @@ -86,7 +86,7 @@ class ReceivedValuesStoreSpec ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedPower.size shouldBe 3 @@ -116,8 +116,8 @@ class ReceivedValuesStoreSpec ), UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") -> Set( actorProbe2.ref, - actorProbe3.ref - ) + actorProbe3.ref, + ), ) val inferiorSubGridGateToActorRefMap = Map.empty[SubGridGate, ActorRef] @@ -127,7 +127,7 @@ class ReceivedValuesStoreSpec ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 0 @@ -140,7 +140,7 @@ class ReceivedValuesStoreSpec UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") ) shouldBe Map( actorProbe2.ref -> None, - actorProbe3.ref -> None + actorProbe3.ref -> None, ) } @@ -153,7 +153,7 @@ class ReceivedValuesStoreSpec ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 0 @@ -178,14 +178,14 @@ class ReceivedValuesStoreSpec val superiorGridNodeUuids = Vector( UUID.fromString("baded8c4-b703-4316-b62f-75ffe09c9843"), - UUID.fromString("d5040bf7-56c1-4d6a-908a-47c05b0c5c54") + UUID.fromString("d5040bf7-56c1-4d6a-908a-47c05b0c5c54"), ) val receivedValuesStore = ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedPower.size shouldBe 0 @@ -209,7 +209,7 @@ class ReceivedValuesStoreSpec ReceivedValuesStore.empty( nodeToAssetAgentsMap, inferiorSubGridGateToActorRefMap, - superiorGridNodeUuids + superiorGridNodeUuids, ) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 0 diff --git a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala index ad8fbca59d..73239981d3 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/EvcsAgentModelCalculationSpec.scala @@ -22,23 +22,23 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation import edu.ie3.simona.config.SimonaConfig.EvcsRuntimeConfig import edu.ie3.simona.event.ResultEvent.{ FlexOptionsResultEvent, - ParticipantResultEvent + ParticipantResultEvent, } import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsState, - ScheduleEntry + ScheduleEntry, } import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._ import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -46,7 +46,7 @@ import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.test.ParticipantAgentSpec @@ -76,7 +76,7 @@ class EvcsAgentModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with EvcsInputTestData @@ -89,7 +89,7 @@ class EvcsAgentModelCalculationSpec NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) private val modelConfig = @@ -98,7 +98,7 @@ class EvcsAgentModelCalculationSpec scaling = 1.0, uuids = List("default"), chargingStrategy = "maxPower", - lowestEvSoc = 0.2 + lowestEvSoc = 0.2, ) protected implicit val simulationStartDate: ZonedDateTime = @@ -122,7 +122,7 @@ class EvcsAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ EvcsInput, EvcsRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = evcsInputModel, modelConfig = modelConfig, @@ -132,7 +132,7 @@ class EvcsAgentModelCalculationSpec resolution = resolution, requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -140,7 +140,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) evcsAgent.stateName shouldBe Uninitialized @@ -161,7 +161,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) @@ -173,7 +173,7 @@ class EvcsAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) deathProbe.expectTerminated(evcsAgent.ref) @@ -186,7 +186,7 @@ class EvcsAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ EvcsInput, EvcsRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = evcsInputModel, modelConfig = modelConfig, @@ -198,7 +198,7 @@ class EvcsAgentModelCalculationSpec resolution = resolution, requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -206,7 +206,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) @@ -226,7 +226,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) @@ -248,7 +248,7 @@ class EvcsAgentModelCalculationSpec timeBin, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(evcsInputModel) modelConfig shouldBe modelConfig @@ -268,7 +268,7 @@ class EvcsAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -292,10 +292,10 @@ class EvcsAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ), awaitRegistrationResponsesFrom, - foreseenNextDataTicks + foreseenNextDataTicks, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -306,13 +306,13 @@ class EvcsAgentModelCalculationSpec outputConfig shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower](resolution) @@ -329,7 +329,7 @@ class EvcsAgentModelCalculationSpec /* Reply, that registration was successful */ evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* Expect a completion message */ @@ -353,7 +353,7 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) @@ -363,14 +363,14 @@ class EvcsAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ evService.expectMsg(RegisterForEvDataMessage(evcsInputModel.getUuid)) evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, Some(900L)) + RegistrationSuccessfulMessage(evService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -382,12 +382,12 @@ class EvcsAgentModelCalculationSpec evcsAgent ! RequestAssetPowerMessage( 0L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsg( AssetPowerChangedMessage( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) @@ -400,9 +400,9 @@ class EvcsAgentModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) case _ => fail( @@ -418,27 +418,27 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) scheduler.send( evcsAgent, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* I'm not interested in the content of the CompletionMessage */ @@ -457,8 +457,8 @@ class EvcsAgentModelCalculationSpec 0L, evService.ref, arrivingEvsData, - unlockKey = key1 - ) + unlockKey = key1, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) @@ -468,7 +468,7 @@ class EvcsAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map(evService.ref -> None) @@ -489,7 +489,7 @@ class EvcsAgentModelCalculationSpec /* Trigger the agent */ scheduler.send( evcsAgent, - Activation(0) + Activation(0), ) /* The agent will notice, that all expected information are apparent, switch to Calculate and trigger itself @@ -508,7 +508,7 @@ class EvcsAgentModelCalculationSpec case Some(EvcsState(currentEvs, schedule, tick)) => currentEvs should contain theSameElementsAs Set( EvModelWrapper(evA), - EvModelWrapper(evB) + EvModelWrapper(evB), ) schedule shouldBe Map( @@ -516,16 +516,16 @@ class EvcsAgentModelCalculationSpec ScheduleEntry( 0, 200, - Kilowatts(11.0) + Kilowatts(11.0), ) ), evB.getUuid -> SortedSet( ScheduleEntry( 0, 200, - Kilowatts(11.0) + Kilowatts(11.0), ) - ) + ), ) tick shouldBe 0L @@ -554,27 +554,27 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) scheduler.send( evcsAgent, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* I'm not interested in the content of the CompletionMessage */ @@ -585,7 +585,7 @@ class EvcsAgentModelCalculationSpec /* Send out activation */ scheduler.send( evcsAgent, - Activation(0) + Activation(0), ) /* Find yourself in corresponding state and state data */ @@ -594,7 +594,7 @@ class EvcsAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map(evService.ref -> None) @@ -621,8 +621,8 @@ class EvcsAgentModelCalculationSpec 0L, evService.ref, arrivingEvsData, - unlockKey = key1 - ) + unlockKey = key1, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) @@ -642,7 +642,7 @@ class EvcsAgentModelCalculationSpec case Some(EvcsState(currentEvs, schedule, tick)) => currentEvs should contain theSameElementsAs Set( EvModelWrapper(evA), - EvModelWrapper(evB) + EvModelWrapper(evB), ) schedule shouldBe Map( evA.getUuid -> @@ -650,7 +650,7 @@ class EvcsAgentModelCalculationSpec ScheduleEntry( 0, 200, - Kilowatts(11.0) + Kilowatts(11.0), ) ), evB.getUuid -> @@ -658,9 +658,9 @@ class EvcsAgentModelCalculationSpec ScheduleEntry( 0, 200, - Kilowatts(11.0) + Kilowatts(11.0), ) - ) + ), ) tick shouldBe 0L @@ -687,27 +687,27 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) scheduler.send( evcsAgent, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* I'm not interested in the content of the CompletionMessage */ @@ -717,7 +717,7 @@ class EvcsAgentModelCalculationSpec evcsAgent ! RequestAssetPowerMessage( 7200L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsgType[AssetPowerChangedMessage] match { @@ -734,27 +734,27 @@ class EvcsAgentModelCalculationSpec new EvcsAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = Iterable.empty + listener = Iterable.empty, ) ) scheduler.send( evcsAgent, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) /* Refuse registration with primary service */ primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* I'm not interested in the content of the CompletionMessage */ @@ -764,13 +764,13 @@ class EvcsAgentModelCalculationSpec /* Send out public evcs request */ evService.send( evcsAgent, - EvFreeLotsRequest(0L) + EvFreeLotsRequest(0L), ) evService.expectMsg( FreeLotsResponse( evcsInputModel.getUuid, - 2 + 2, ) ) @@ -784,28 +784,28 @@ class EvcsAgentModelCalculationSpec 0L, evService.ref, ArrivingEvsData(Seq(EvModelWrapper(evA))), - unlockKey = key1 - ) + unlockKey = key1, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) scheduler.send( evcsAgent, - Activation(0) + Activation(0), ) scheduler.expectMsg(Completion(evcsAgent.toTyped)) /* Ask for public evcs lot count again with a later tick */ evService.send( evcsAgent, - EvFreeLotsRequest(3600L) + EvFreeLotsRequest(3600L), ) // this time, only one is still free evService.expectMsg( FreeLotsResponse( evcsInputModel.getUuid, - 1 + 1, ) ) @@ -826,9 +826,9 @@ class EvcsAgentModelCalculationSpec resolution = resolution, requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ), - listener = systemListener + listener = systemListener, ) ) @@ -841,14 +841,14 @@ class EvcsAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ evService.expectMsgType[RegisterForEvDataMessage] evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) /* I'm not interested in the content of the CompletionMessage */ @@ -864,8 +864,8 @@ class EvcsAgentModelCalculationSpec 0L, evService.ref, ArrivingEvsData(Seq(EvModelWrapper(evA.copyWithDeparture(3600L)))), - unlockKey = key1 - ) + unlockKey = key1, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 0, key1)) scheduler.send(evcsAgent, Activation(0)) @@ -876,7 +876,7 @@ class EvcsAgentModelCalculationSpec // departures first evService.send( evcsAgent, - DepartingEvsRequest(3600L, Seq(evA.getUuid)) + DepartingEvsRequest(3600L, Seq(evA.getUuid)), ) evService.expectMsgType[DepartingEvsResponse] match { case DepartingEvsResponse(evcs, evModels) => @@ -898,8 +898,8 @@ class EvcsAgentModelCalculationSpec 3600L, evService.ref, ArrivingEvsData(Seq(EvModelWrapper(evB.copyWithDeparture(7200L)))), - unlockKey = key2 - ) + unlockKey = key2, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 3600, key2)) @@ -911,7 +911,7 @@ class EvcsAgentModelCalculationSpec // departures first evService.send( evcsAgent, - DepartingEvsRequest(7200L, Seq(evB.getUuid)) + DepartingEvsRequest(7200L, Seq(evB.getUuid)), ) evService.expectMsgType[DepartingEvsResponse] match { case DepartingEvsResponse(evcs, evModels) => @@ -932,8 +932,8 @@ class EvcsAgentModelCalculationSpec 7200L, evService.ref, ArrivingEvsData(Seq(EvModelWrapper(evA.copyWithDeparture(10800L)))), - unlockKey = key3 - ) + unlockKey = key3, + ), ) scheduler.expectMsg(ScheduleActivation(evcsAgent.toTyped, 7200, key3)) @@ -945,7 +945,7 @@ class EvcsAgentModelCalculationSpec evcsAgent ! RequestAssetPowerMessage( 7500L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsgType[AssetPowerChangedMessage] match { @@ -962,7 +962,7 @@ class EvcsAgentModelCalculationSpec evcsAgent ! RequestAssetPowerMessage( 7500L, Each(1.000000000000001d), - Each(0.0) + Each(0.0), ) /* Expect, that nothing has changed */ @@ -978,7 +978,7 @@ class EvcsAgentModelCalculationSpec evcsAgent ! RequestAssetPowerMessage( 7500L, Each(0.98), - Each(0.0) + Each(0.0), ) /* Expect, the correct values (this model has fixed power factor) */ @@ -1011,9 +1011,9 @@ class EvcsAgentModelCalculationSpec requestVoltageDeviationThreshold = requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref, - maybeEmAgent = Some(emAgent.ref.toTyped) + maybeEmAgent = Some(emAgent.ref.toTyped), ), - listener = Iterable.empty + listener = Iterable.empty, ) ) @@ -1035,7 +1035,7 @@ class EvcsAgentModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig @@ -1055,14 +1055,14 @@ class EvcsAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) emAgent.expectMsg( RegisterParticipant( evcsInputModelQv.getUuid, evcsAgent.toTyped, - evcsInputModelQv + evcsInputModelQv, ) ) // only receive registration message. ScheduleFlexRequest after secondary service initialized @@ -1071,7 +1071,7 @@ class EvcsAgentModelCalculationSpec evService.expectMsg(RegisterForEvDataMessage(evcsInputModelQv.getUuid)) evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) emAgent.expectMsg( @@ -1097,7 +1097,7 @@ class EvcsAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -1110,7 +1110,7 @@ class EvcsAgentModelCalculationSpec foreseenDataTicks shouldBe Map(evService.ref -> None) voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore( resolution @@ -1146,12 +1146,12 @@ class EvcsAgentModelCalculationSpec outputConfig = NotifierConfig( simulationResultInfo = true, powerRequestReply = false, - flexResult = true + flexResult = true, ), primaryServiceProxy = primaryServiceProxy.ref, - maybeEmAgent = Some(emAgent.ref.toTyped) + maybeEmAgent = Some(emAgent.ref.toTyped), ), - listener = Iterable(resultListener.ref) + listener = Iterable(resultListener.ref), ) ) @@ -1173,7 +1173,7 @@ class EvcsAgentModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(evcsInputModelQv) modelConfig shouldBe modelConfig @@ -1187,7 +1187,7 @@ class EvcsAgentModelCalculationSpec outputConfig shouldBe NotifierConfig( simulationResultInfo = true, powerRequestReply = false, - flexResult = true + flexResult = true, ) maybeEmAgent shouldBe Some(emAgent.ref.toTyped) case unsuitableStateData => @@ -1197,14 +1197,14 @@ class EvcsAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( evcsAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) emAgent.expectMsg( RegisterParticipant( evcsInputModelQv.getUuid, evcsAgent.toTyped, - evcsInputModelQv + evcsInputModelQv, ) ) emAgent.expectNoMessage() @@ -1212,7 +1212,7 @@ class EvcsAgentModelCalculationSpec evService.expectMsg(RegisterForEvDataMessage(evcsInputModelQv.getUuid)) evService.send( evcsAgent, - RegistrationSuccessfulMessage(evService.ref, None) + RegistrationSuccessfulMessage(evService.ref, None), ) emAgent.expectMsg( @@ -1232,7 +1232,7 @@ class EvcsAgentModelCalculationSpec modelUuid, refPower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid refPower should approximate(Kilowatts(0.0)) @@ -1250,7 +1250,7 @@ class EvcsAgentModelCalculationSpec emAgent.send( evcsAgent, - IssueNoControl(0) + IssueNoControl(0), ) // next potential activation at fully charged battery: @@ -1261,7 +1261,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(0)) @@ -1285,8 +1285,8 @@ class EvcsAgentModelCalculationSpec ProvideEvDataMessage( 900, evService.ref, - ArrivingEvsData(Seq(ev900)) - ) + ArrivingEvsData(Seq(ev900)), + ), ) emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 900)) @@ -1297,7 +1297,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe ev900.sRatedAc @@ -1321,7 +1321,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate( @@ -1356,7 +1356,7 @@ class EvcsAgentModelCalculationSpec // departure first evService.send( evcsAgent, - DepartingEvsRequest(4500, Seq(ev900.uuid)) + DepartingEvsRequest(4500, Seq(ev900.uuid)), ) evService.expectMsgPF() { case DepartingEvsResponse(uuid, evs) => @@ -1403,8 +1403,8 @@ class EvcsAgentModelCalculationSpec ProvideEvDataMessage( 4500, evService.ref, - ArrivingEvsData(Seq(ev4500)) - ) + ArrivingEvsData(Seq(ev4500)), + ), ) emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 4500)) @@ -1415,7 +1415,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe ev4500.sRatedAc @@ -1441,7 +1441,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(11)) @@ -1466,7 +1466,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe ev4500.sRatedAc @@ -1494,7 +1494,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(10)) @@ -1536,8 +1536,8 @@ class EvcsAgentModelCalculationSpec ProvideEvDataMessage( 11700, evService.ref, - ArrivingEvsData(Seq(ev11700)) - ) + ArrivingEvsData(Seq(ev11700)), + ), ) emAgent.expectMsg(ScheduleFlexRequest(evcsInputModelQv.getUuid, 11700)) @@ -1554,7 +1554,7 @@ class EvcsAgentModelCalculationSpec modelUuid, refPower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid refPower shouldBe combinedChargingPowerSq @@ -1586,7 +1586,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(16)) @@ -1626,7 +1626,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe combinedChargingPowerSq @@ -1660,7 +1660,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(-20)) @@ -1708,7 +1708,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe combinedChargingPowerSq @@ -1744,7 +1744,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(-10)) @@ -1792,7 +1792,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe combinedChargingPowerSq @@ -1819,7 +1819,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(0)) @@ -1863,7 +1863,7 @@ class EvcsAgentModelCalculationSpec // departure first evService.send( evcsAgent, - DepartingEvsRequest(36000, Seq(ev900.uuid)) + DepartingEvsRequest(36000, Seq(ev900.uuid)), ) evService.expectMsgPF() { case DepartingEvsResponse(uuid, evs) => @@ -1910,7 +1910,7 @@ class EvcsAgentModelCalculationSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsInputModelQv.getUuid referencePower shouldBe ev4500.sRatedAc @@ -1937,7 +1937,7 @@ class EvcsAgentModelCalculationSpec modelUuid, result, requestAtNextActivation, - requestAtTick + requestAtTick, ) => modelUuid shouldBe evcsInputModelQv.getUuid result.p should approximate(Kilowatts(4)) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala index 8b64aa9c26..bdda047856 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ ParticipantInitializeStateData, ParticipantInitializingStateData, ParticipantUninitializedStateData, - SimpleInputContainer + SimpleInputContainer, } import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation @@ -33,7 +33,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage @@ -59,7 +59,7 @@ class FixedFeedInAgentModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with FixedFeedInputTestData { @@ -83,12 +83,12 @@ class FixedFeedInAgentModelCalculationSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult + simonaConfig.simona.output.participant.defaultConfig.flexResult, ) private val fixedFeedConfigUtil = ConfigUtil.ParticipantConfigUtil( @@ -105,7 +105,7 @@ class FixedFeedInAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ FixedFeedInInput, FixedFeedInRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -116,7 +116,7 @@ class FixedFeedInAgentModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -124,7 +124,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -144,7 +144,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -166,7 +166,7 @@ class FixedFeedInAgentModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -184,7 +184,7 @@ class FixedFeedInAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( fixedFeedAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a completion notification */ @@ -207,7 +207,7 @@ class FixedFeedInAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -218,7 +218,7 @@ class FixedFeedInAgentModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( @@ -236,7 +236,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -246,7 +246,7 @@ class FixedFeedInAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( fixedFeedAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the CompletionMessage */ @@ -258,12 +258,12 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedAgent ! RequestAssetPowerMessage( 0L, Each(1d), - Each(0d) + Each(0d), ) expectMsg( AssetPowerChangedMessage( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) ) @@ -276,9 +276,9 @@ class FixedFeedInAgentModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) - ) + ), ) case _ => fail( @@ -292,7 +292,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -302,7 +302,7 @@ class FixedFeedInAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( fixedFeedAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I am not interested in the CompletionMessage */ @@ -343,7 +343,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -354,7 +354,7 @@ class FixedFeedInAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( fixedFeedAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(fixedFeedAgent.toTyped, Some(0))) @@ -370,7 +370,7 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -384,7 +384,7 @@ class FixedFeedInAgentModelCalculationSpec new FixedFeedInAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -397,7 +397,7 @@ class FixedFeedInAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( fixedFeedAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(fixedFeedAgent.toTyped, Some(0))) @@ -411,7 +411,7 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -428,7 +428,7 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedAgent ! RequestAssetPowerMessage( 3000L, Each(1.000000000000001d), - Each(0d) + Each(0d), ) /* Expect, that nothing has changed */ @@ -444,7 +444,7 @@ class FixedFeedInAgentModelCalculationSpec fixedFeedAgent ! RequestAssetPowerMessage( 3000L, Each(0.98), - Each(0d) + Each(0d), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala index 88508845f5..e8fd0715aa 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -27,18 +27,18 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.{ ProvideWeatherMessage, RegisterForWeatherMessage, - WeatherData + WeatherData, } import edu.ie3.simona.test.ParticipantAgentSpec import edu.ie3.simona.test.common.model.participant.HpTestData @@ -48,7 +48,7 @@ import edu.ie3.util.scala.quantities.{ Megavars, ReactivePower, Vars, - WattsPerSquareMeter + WattsPerSquareMeter, } import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps @@ -73,7 +73,7 @@ class HpAgentModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with HpTestData @@ -101,7 +101,7 @@ class HpAgentModelCalculationSpec private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult + simonaConfig.simona.output.participant.defaultConfig.flexResult, ) private val participantConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -120,7 +120,7 @@ class HpAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ HpInput, HpRuntimeConfig, - ApparentPowerAndHeat + ApparentPowerAndHeat, ]( inputModel = hpInput, modelConfig = modelConfig, @@ -132,7 +132,7 @@ class HpAgentModelCalculationSpec simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref, - maybeEmAgent = None + maybeEmAgent = None, ) "be instantiated correctly" in { @@ -140,7 +140,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -162,7 +162,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -174,7 +174,7 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) deathProbe.expectTerminated(hpAgent) @@ -185,7 +185,7 @@ class HpAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ HpInput, HpRuntimeConfig, - ApparentPowerAndHeat + ApparentPowerAndHeat, ]( inputModel = hpInput, thermalGrid = thermalGrid, @@ -198,7 +198,7 @@ class HpAgentModelCalculationSpec simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, primaryServiceProxy = primaryServiceProxy.ref, - maybeEmAgent = None + maybeEmAgent = None, ) "be instantiated correctly" in { @@ -206,7 +206,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -226,7 +226,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -248,7 +248,7 @@ class HpAgentModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - _ + _, ) => inputModel shouldBe WithHeatInputContainer(hpInput, thermalGrid) modelConfig shouldBe modelConfig @@ -265,7 +265,7 @@ class HpAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -291,10 +291,10 @@ class HpAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ), awaitRegistrationResponsesFrom, - foreseenNextDataTicks + foreseenNextDataTicks, ) => /* Base state data */ startDate shouldBe defaultSimulationStart @@ -305,13 +305,13 @@ class HpAgentModelCalculationSpec outputConfig shouldBe NotifierConfig( simulationResultInfo = true, powerRequestReply = false, - flexResult = false + flexResult = false, ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPowerAndHeat]( @@ -330,7 +330,7 @@ class HpAgentModelCalculationSpec /* Reply, that registration was successful */ weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)), ) /* Expect a completion message */ @@ -356,7 +356,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -366,7 +366,7 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -375,7 +375,7 @@ class HpAgentModelCalculationSpec ) weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -387,12 +387,12 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 0L, Dimensionless.primaryUnit(1.0), - Dimensionless.primaryUnit(0.0) + Dimensionless.primaryUnit(0.0), ) expectMsg( AssetPowerChangedMessage( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) @@ -406,9 +406,9 @@ class HpAgentModelCalculationSpec 0L -> ApparentPowerAndHeat( Megawatts(0.0), Megavars(0.0), - Megawatts(0.0) + Megawatts(0.0), ) - ) + ), ) case _ => fail( @@ -422,7 +422,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -432,14 +432,14 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -452,12 +452,12 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ) weatherService.send( hpAgent, - ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)), ) /* Find yourself in corresponding state and state data */ @@ -466,7 +466,7 @@ class HpAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -507,8 +507,8 @@ class HpAgentModelCalculationSpec activePower, qDot, thermalGridState, - _ - ) + _, + ), ) ) => isRunning shouldBe false @@ -533,7 +533,7 @@ class HpAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 0L, - fail("Expected a simulation result for tick 900.") + fail("Expected a simulation result for tick 900."), ) match { case ApparentPowerAndHeat(p, q, qDot) => p should approximate(Megawatts(0d)) @@ -553,7 +553,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -563,14 +563,14 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -586,7 +586,7 @@ class HpAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -609,12 +609,12 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ) weatherService.send( hpAgent, - ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)), ) /* Expect confirmation */ @@ -635,8 +635,8 @@ class HpAgentModelCalculationSpec activePower, qDot, thermalGridState, - _ - ) + _, + ), ) ) => isRunning shouldBe false @@ -661,7 +661,7 @@ class HpAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 0L, - fail("Expected a simulation result for tick 0.") + fail("Expected a simulation result for tick 0."), ) match { case ApparentPowerAndHeat(p, q, qDot) => p should approximate(Megawatts(0d)) @@ -681,7 +681,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -692,14 +692,14 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -710,7 +710,7 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 7200L, Each(1.0), - Each(0.0) + Each(0.0), ) expectNoMessage(noReceiveTimeOut.duration) awaitAssert(hpAgent.stateName == Idle) @@ -720,7 +720,7 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ) weatherService.send( hpAgent, @@ -728,8 +728,8 @@ class HpAgentModelCalculationSpec 3600L, weatherService.ref, weatherData, - Some(7200L) - ) + Some(7200L), + ), ) /* Trigger the agent */ @@ -751,7 +751,7 @@ class HpAgentModelCalculationSpec new HpAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -763,14 +763,14 @@ class HpAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( hpAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( hpAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -788,10 +788,10 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ), - Some(3600L) - ) + Some(3600L), + ), ) scheduler.send(hpAgent, Activation(0)) scheduler.expectMsg(Completion(hpAgent.toTyped, Some(3600))) @@ -806,10 +806,10 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ), - Some(7200L) - ) + Some(7200L), + ), ) scheduler.send(hpAgent, Activation(3600)) scheduler.expectMsg(Completion(hpAgent.toTyped, Some(7200))) @@ -824,10 +824,10 @@ class HpAgentModelCalculationSpec WattsPerSquareMeter(0), WattsPerSquareMeter(0), Celsius(1.815), - MetersPerSecond(7.726576) + MetersPerSecond(7.726576), ), - None - ) + None, + ), ) scheduler.send(hpAgent, Activation(7200)) scheduler.expectMsg(Completion(hpAgent.toTyped)) @@ -836,7 +836,7 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 7500L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsgType[AssetPowerChangedMessage] match { @@ -853,7 +853,7 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 7500L, Each(1.000000000000001d), - Each(0.0) + Each(0.0), ) /* Expect, that nothing has changed */ @@ -869,7 +869,7 @@ class HpAgentModelCalculationSpec hpAgent ! RequestAssetPowerMessage( 7500L, Each(0.98), - Each(0.0) + Each(0.0), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala index 544f9c58b1..df28adfa5f 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ ParticipantInitializeStateData, ParticipantInitializingStateData, ParticipantUninitializedStateData, - SimpleInputContainer + SimpleInputContainer, } import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation @@ -33,7 +33,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage @@ -58,7 +58,7 @@ class LoadAgentFixedModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with LoadTestData @@ -75,12 +75,12 @@ class LoadAgentFixedModelCalculationSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult + simonaConfig.simona.output.participant.defaultConfig.flexResult, ) private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -99,7 +99,7 @@ class LoadAgentFixedModelCalculationSpec val initStateData = ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -110,7 +110,7 @@ class LoadAgentFixedModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -118,7 +118,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -138,7 +138,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -160,7 +160,7 @@ class LoadAgentFixedModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -178,7 +178,7 @@ class LoadAgentFixedModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a completion notification */ @@ -201,7 +201,7 @@ class LoadAgentFixedModelCalculationSpec requestValueStore, _, _, - _ + _, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -212,7 +212,7 @@ class LoadAgentFixedModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( @@ -230,7 +230,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -240,7 +240,7 @@ class LoadAgentFixedModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the CompletionMessage */ @@ -252,12 +252,12 @@ class LoadAgentFixedModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 0L, Each(1d), - Each(0d) + Each(0d), ) expectMsg( AssetPowerChangedMessage( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) ) @@ -270,9 +270,9 @@ class LoadAgentFixedModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) - ) + ), ) case _ => fail( @@ -286,7 +286,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -296,7 +296,7 @@ class LoadAgentFixedModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I am not interested in the CompletionMessage */ @@ -337,7 +337,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -348,7 +348,7 @@ class LoadAgentFixedModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -364,7 +364,7 @@ class LoadAgentFixedModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -378,7 +378,7 @@ class LoadAgentFixedModelCalculationSpec new FixedLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -391,7 +391,7 @@ class LoadAgentFixedModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -405,7 +405,7 @@ class LoadAgentFixedModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -422,7 +422,7 @@ class LoadAgentFixedModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 3000L, Each(1.000000000000001d), - Each(0d) + Each(0d), ) /* Expect, that nothing has changed */ @@ -438,7 +438,7 @@ class LoadAgentFixedModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 3000L, Each(0.98), - Each(0d) + Each(0d), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala index 6ce6f8761b..46df19190a 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ ParticipantInitializeStateData, ParticipantInitializingStateData, ParticipantUninitializedStateData, - SimpleInputContainer + SimpleInputContainer, } import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation @@ -33,7 +33,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage @@ -58,7 +58,7 @@ class LoadAgentProfileModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with LoadTestData @@ -75,12 +75,12 @@ class LoadAgentProfileModelCalculationSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.PROFILE, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult + simonaConfig.simona.output.participant.defaultConfig.flexResult, ) private val loadConfigUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -99,7 +99,7 @@ class LoadAgentProfileModelCalculationSpec val initStateData = ParticipantInitializeStateData[ LoadInput, LoadRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -110,7 +110,7 @@ class LoadAgentProfileModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -118,7 +118,7 @@ class LoadAgentProfileModelCalculationSpec new ProfileLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -138,7 +138,7 @@ class LoadAgentProfileModelCalculationSpec new ProfileLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -159,7 +159,7 @@ class LoadAgentProfileModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -177,7 +177,7 @@ class LoadAgentProfileModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a completion notification */ @@ -200,7 +200,7 @@ class LoadAgentProfileModelCalculationSpec requestValueStore, _, _, - _ + _, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -212,7 +212,7 @@ class LoadAgentProfileModelCalculationSpec foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower]( @@ -230,7 +230,7 @@ class LoadAgentProfileModelCalculationSpec new ProfileLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -240,7 +240,7 @@ class LoadAgentProfileModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the CompletionMessage */ @@ -252,12 +252,12 @@ class LoadAgentProfileModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 0L, Each(1d), - Each(0d) + Each(0d), ) expectMsg( AssetPowerChangedMessage( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) ) @@ -270,9 +270,9 @@ class LoadAgentProfileModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) - ) + ), ) case _ => fail( @@ -286,7 +286,7 @@ class LoadAgentProfileModelCalculationSpec new ProfileLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -296,7 +296,7 @@ class LoadAgentProfileModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I am not interested in the CompletionMessage */ @@ -336,7 +336,7 @@ class LoadAgentProfileModelCalculationSpec new ProfileLoadAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -348,7 +348,7 @@ class LoadAgentProfileModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( loadAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(loadAgent.toTyped, Some(0))) @@ -366,7 +366,7 @@ class LoadAgentProfileModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 1800L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -382,7 +382,7 @@ class LoadAgentProfileModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 1800L, Each(1.000000000000001d), - Each(0d) + Each(0d), ) /* Expect, that nothing has changed */ @@ -398,7 +398,7 @@ class LoadAgentProfileModelCalculationSpec loadAgent ! RequestAssetPowerMessage( 1800L, Each(0.98), - Each(0) + Each(0), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 0395abb332..fc5d0f66f5 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage @@ -52,7 +52,7 @@ class ParticipantAgent2ListenerSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with DefaultTestData @@ -72,7 +72,7 @@ class ParticipantAgent2ListenerSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val mockInputModel = mock[SystemParticipantInput] @@ -85,12 +85,12 @@ class ParticipantAgent2ListenerSpec val initStateData: NotifierConfig => ParticipantInitializeStateData[ SystemParticipantInput, BaseRuntimeConfig, - ApparentPower + ApparentPower, ] = outputConfig => ParticipantInitializeStateData[ SystemParticipantInput, BaseRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = mockInputModel, modelConfig = mock[BaseRuntimeConfig], @@ -101,7 +101,7 @@ class ParticipantAgent2ListenerSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = outputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "inform listeners about new simulation results, when asked to do" in { @@ -109,14 +109,14 @@ class ParticipantAgent2ListenerSpec val outputConfig = NotifierConfig( simulationResultInfo = true, powerRequestReply = false, - flexResult = false + flexResult = false, ) val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, initStateData = initStateData(outputConfig), - listener = systemListener + listener = systemListener, ) ) @@ -127,7 +127,7 @@ class ParticipantAgent2ListenerSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -146,11 +146,11 @@ class ParticipantAgent2ListenerSpec ) => systemParticipantResult.getP should equalWithTolerance( Quantities.getQuantity(2, MEGAWATT), - quantityTolerance + quantityTolerance, ) systemParticipantResult.getQ should equalWithTolerance( Quantities.getQuantity(1, MEGAVAR), - quantityTolerance + quantityTolerance, ) case _ => fail("Expected a SystemParticipantResult") } @@ -161,14 +161,14 @@ class ParticipantAgent2ListenerSpec val outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, initStateData = initStateData(outputConfig), - listener = systemListener + listener = systemListener, ) ) @@ -179,7 +179,7 @@ class ParticipantAgent2ListenerSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -197,14 +197,14 @@ class ParticipantAgent2ListenerSpec val outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = true, - flexResult = false + flexResult = false, ) val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, initStateData = initStateData(outputConfig), - listener = systemListener + listener = systemListener, ) ) @@ -215,7 +215,7 @@ class ParticipantAgent2ListenerSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -229,7 +229,7 @@ class ParticipantAgent2ListenerSpec mockAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) /* Wait for original reply (this is the querying agent) */ @@ -258,14 +258,14 @@ class ParticipantAgent2ListenerSpec val outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, initStateData = initStateData(outputConfig), - listener = systemListener + listener = systemListener, ) ) @@ -276,7 +276,7 @@ class ParticipantAgent2ListenerSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -291,7 +291,7 @@ class ParticipantAgent2ListenerSpec mockAgent ! RequestAssetPowerMessage( 3000L, Each(1d), - Each(0d) + Each(0d), ) /* Wait for original reply (this is the querying agent) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala index 976a2c25b6..784fde78dd 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -19,7 +19,7 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ActivePower, ActivePowerAndHeat, ApparentPower, - ApparentPowerAndHeat + ApparentPowerAndHeat, } import edu.ie3.simona.agent.participant.statedata.BaseStateData.FromOutsideBaseStateData import edu.ie3.simona.agent.participant.statedata.DataCollectionStateData @@ -27,7 +27,7 @@ import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ ParticipantInitializeStateData, ParticipantInitializingStateData, ParticipantUninitializedStateData, - SimpleInputContainer + SimpleInputContainer, } import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.ParticipantAgentState.HandleInformation @@ -42,7 +42,7 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage @@ -77,7 +77,7 @@ class ParticipantAgentExternalSourceSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with DefaultTestData @@ -98,7 +98,7 @@ class ParticipantAgentExternalSourceSpec mock[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ]] when(mockModel.getUuid).thenReturn(testUUID) private val activeToReactivePowerFunction: Power => ReactivePower = @@ -111,12 +111,12 @@ class ParticipantAgentExternalSourceSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0.0)) + LoadReference.ActivePower(Kilowatts(0.0)), ) private val defaultOutputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds @@ -128,7 +128,7 @@ class ParticipantAgentExternalSourceSpec val initStateData = ParticipantInitializeStateData[ SystemParticipantInput, BaseRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = mockInputModel, modelConfig = mock[BaseRuntimeConfig], @@ -139,14 +139,14 @@ class ParticipantAgentExternalSourceSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -165,7 +165,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -188,7 +188,7 @@ class ParticipantAgentExternalSourceSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(mockInputModel) modelConfig shouldBe modelConfig @@ -206,7 +206,7 @@ class ParticipantAgentExternalSourceSpec /* Reply, that registration was successful */ primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(4711L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(4711L)), ) scheduler.expectMsg(Completion(mockAgent.toTyped, Some(4711L))) @@ -217,7 +217,7 @@ class ParticipantAgentExternalSourceSpec case baseStateData: FromOutsideBaseStateData[SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map( @@ -234,7 +234,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -244,7 +244,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -256,12 +256,12 @@ class ParticipantAgentExternalSourceSpec mockAgent ! RequestAssetPowerMessage( 0L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsg( AssetPowerChangedMessage( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) @@ -277,16 +277,16 @@ class ParticipantAgentExternalSourceSpec _, _, _, - requestValueStore + requestValueStore, ) => requestValueStore shouldBe ValueStore[ApparentPower]( resolution, SortedMap( 0L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) case _ => fail( @@ -299,7 +299,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -309,7 +309,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -324,10 +324,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ), - Some(1800L) - ) + Some(1800L), + ), ) /* Find yourself in corresponding state and state data */ @@ -337,10 +337,10 @@ class ParticipantAgentExternalSourceSpec baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -352,7 +352,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref -> Some( ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ) ) ) @@ -377,7 +377,7 @@ class ParticipantAgentExternalSourceSpec case baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower] => /* The new data is apparent in the result value store */ baseStateData.resultValueStore match { @@ -385,7 +385,7 @@ class ParticipantAgentExternalSourceSpec store shouldBe Map( 900L -> ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ) ) } @@ -400,7 +400,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -410,7 +410,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -427,10 +427,10 @@ class ParticipantAgentExternalSourceSpec baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -456,10 +456,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ), - Some(1800L) - ) + Some(1800L), + ), ) /* Expect confirmation */ @@ -471,7 +471,7 @@ class ParticipantAgentExternalSourceSpec case baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower] => /* The new data is apparent in the result value store */ baseStateData.resultValueStore match { @@ -479,7 +479,7 @@ class ParticipantAgentExternalSourceSpec store shouldBe Map( 900L -> ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ) ) } @@ -494,7 +494,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -505,7 +505,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -516,7 +516,7 @@ class ParticipantAgentExternalSourceSpec mockAgent ! RequestAssetPowerMessage( 1800L, Each(1.0), - Each(0.0) + Each(0.0), ) expectNoMessage(noReceiveTimeOut.duration) awaitAssert(mockAgent.stateName == Idle) @@ -529,10 +529,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(0.0), - Kilovars(900.0) + Kilovars(900.0), ), - Some(1800L) - ) + Some(1800L), + ), ) /* Trigger the agent */ @@ -547,7 +547,7 @@ class ParticipantAgentExternalSourceSpec val mockAgent = TestFSMRef( new ParticipantAgentMock( scheduler = scheduler.ref, - initStateData = initStateData + initStateData = initStateData, ) ) @@ -555,11 +555,11 @@ class ParticipantAgentExternalSourceSpec val baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower] = FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower]( mockModel, defaultSimulationStart, @@ -571,10 +571,10 @@ class ParticipantAgentExternalSourceSpec 1e-4, ValueStore.forVoltage( 900L, - Each(1.0) + Each(1.0), ), ValueStore.forResult(900L, 1L), - ValueStore(900L) + ValueStore(900L), ) val actualFunction = @@ -586,11 +586,11 @@ class ParticipantAgentExternalSourceSpec val baseStateData: FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower] = FromOutsideBaseStateData[SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ], ApparentPower]( mockModel, defaultSimulationStart, @@ -602,10 +602,10 @@ class ParticipantAgentExternalSourceSpec 1e-4, ValueStore.forVoltage( 900L, - Each(1.0) + Each(1.0), ), ValueStore.forResult(900L, 1L), - ValueStore(900L) + ValueStore(900L), ) val actualFunction = @@ -621,7 +621,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( mockAgent, - RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)) + RegistrationSuccessfulMessage(primaryServiceProxy.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -637,10 +637,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(100.0), - Kilovars(33.0) + Kilovars(33.0), ), - Some(1800L) - ) + Some(1800L), + ), ) scheduler.send(mockAgent, Activation(900)) scheduler.expectMsg(Completion(mockAgent.toTyped, Some(1800))) @@ -653,10 +653,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(150.0), - Kilovars(49.0) + Kilovars(49.0), ), - Some(2700L) - ) + Some(2700L), + ), ) scheduler.send(mockAgent, Activation(1800)) scheduler.expectMsg(Completion(mockAgent.toTyped, Some(2700))) @@ -669,10 +669,10 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref, ApparentPower( Kilowatts(200.0), - Kilovars(66.0) + Kilovars(66.0), ), - None - ) + None, + ), ) scheduler.send(mockAgent, Activation(2700)) scheduler.expectMsg(Completion(mockAgent.toTyped)) @@ -683,7 +683,7 @@ class ParticipantAgentExternalSourceSpec mockAgent ! RequestAssetPowerMessage( 3000L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsgType[AssetPowerChangedMessage] match { @@ -699,7 +699,7 @@ class ParticipantAgentExternalSourceSpec mockAgent ! RequestAssetPowerMessage( 3000L, Each(1.000000000000001d), - Each(0.0) + Each(0.0), ) /* Expect, that nothing has changed */ @@ -716,7 +716,7 @@ class ParticipantAgentExternalSourceSpec mockAgent ! RequestAssetPowerMessage( 3000L, Each(0.98d), - Each(0.0) + Each(0.0), ) /* Expect, that nothing has changed, as this model is meant to forward information from outside */ @@ -741,7 +741,7 @@ class ParticipantAgentExternalSourceSpec ApparentPowerAndHeat( Kilowatts(0.0), Kilovars(0.0), - Kilowatts(0.0) + Kilowatts(0.0), ) ) ) @@ -762,7 +762,7 @@ class ParticipantAgentExternalSourceSpec primaryServiceProxy.ref -> Some( ActivePowerAndHeat( Kilowatts(0.0), - Kilowatts(0.0) + Kilowatts(0.0), ) ) ) @@ -792,7 +792,7 @@ class ParticipantAgentExternalSourceSpec case Failure(exception) => fail( "Was meant to succeed, but failed with exception.", - exception + exception, ) } } @@ -806,7 +806,7 @@ class ParticipantAgentExternalSourceSpec participantAgent.prepareData( data, - (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))) + (p: squants.Power) => Kilovars(p.toKilowatts * tan(acos(0.9))), ) match { case Success(ApparentPower(p, q)) => p should approximate(Kilowatts(100.0)) @@ -816,7 +816,7 @@ class ParticipantAgentExternalSourceSpec case Failure(exception) => fail( "Was meant to succeed, but failed with exception.", - exception + exception, ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala index 752dcc424f..02ba2dd0ad 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentFundamentalsSpec.scala @@ -24,7 +24,7 @@ import edu.ie3.simona.config.SimonaConfig.BaseRuntimeConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.{ AgentInitializationException, - InconsistentStateException + InconsistentStateException, } import edu.ie3.simona.model.participant.CalcRelevantData.FixedRelevantData import edu.ie3.simona.model.participant.SystemParticipant @@ -56,7 +56,7 @@ class ParticipantAgentFundamentalsSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with LoadTestData @@ -72,7 +72,7 @@ class ParticipantAgentFundamentalsSpec NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) /* Get one instance of the mock for participant agent */ @@ -85,8 +85,8 @@ class ParticipantAgentFundamentalsSpec initStateData = mock[ParticipantInitializeStateData[ SystemParticipantInput, BaseRuntimeConfig, - ApparentPower - ]] + ApparentPower, + ]], ) ) val mockAgent: ParticipantAgentMock = mockAgentTestRef.underlyingActor @@ -95,36 +95,36 @@ class ParticipantAgentFundamentalsSpec Map( 0L -> ApparentPower( Megawatts(1.0), - Megavars(0.0) + Megavars(0.0), ), 1L -> ApparentPower( Megawatts(2.0), - Megavars(1.0) + Megavars(1.0), ), 3L -> ApparentPower( Megawatts(3.0), - Megavars(2.0) + Megavars(2.0), ), 4L -> ApparentPower( Megawatts(5.0), - Megavars(4.0) + Megavars(4.0), ), 7L -> ApparentPower( Megawatts(3.0), - Megavars(2.0) + Megavars(2.0), ), 8L -> ApparentPower( Megawatts(6.0), - Megavars(5.0) + Megavars(5.0), ), 9L -> ApparentPower( Megawatts(6.0), - Megavars(5.0) + Megavars(5.0), ), 10L -> ApparentPower( Megawatts(4.0), - Megavars(3.0) - ) + Megavars(3.0), + ), ) /* Calculates the reactive power as the square of the active power */ @@ -161,21 +161,21 @@ class ParticipantAgentFundamentalsSpec ("2020-01-01 00:15:00", 900L, 0L), ("2020-01-01 00:15:10", 900L, 890L), ("2020-01-01 00:15:00", 1800L, 900L), - ("2020-01-01 00:14:10", 1800L, 950L) + ("2020-01-01 00:14:10", 1800L, 950L), ) forAll(testData) { ( simulationStartString: String, resolution: Long, - expectedFirstTick: Long + expectedFirstTick: Long, ) => { val simulationStart = TimeUtil.withDefaults.toZonedDateTime(simulationStartString) val firstTick = mockAgent.firstFullResolutionInSimulation( simulationStart, - resolution + resolution, ) firstTick shouldBe expectedFirstTick @@ -190,7 +190,7 @@ class ParticipantAgentFundamentalsSpec "resolution", "operationStart", "operationEnd", - "expectedTicks" + "expectedTicks", ), ("2020-01-01 00:00:00", 900L, 0L, 2700L, List(0L, 900L, 1800L, 2700L)), ("2020-01-01 00:15:00", 900L, 0L, 2700L, List(0L, 900L, 1800L, 2700L)), @@ -201,8 +201,8 @@ class ParticipantAgentFundamentalsSpec 900L, 0L, 2880L, - List(180L, 1080L, 1980L, 2880L) - ) + List(180L, 1080L, 1980L, 2880L), + ), ) forAll(testData) { @@ -211,7 +211,7 @@ class ParticipantAgentFundamentalsSpec resolution: Long, operationStart: Long, operationEnd: Long, - expectedTicks: List[Long] + expectedTicks: List[Long], ) => { val simulationStart = @@ -221,7 +221,7 @@ class ParticipantAgentFundamentalsSpec simulationStart, resolution, operationStart, - operationEnd + operationEnd, ) additionalActivationTicks.corresponds(expectedTicks)( @@ -236,7 +236,7 @@ class ParticipantAgentFundamentalsSpec "bring up no activation trigger" in { val baseStateData = ParticipantAgentFundamentalsSpec.mockBaseStateData( SortedSet.empty, - Map.empty + Map.empty, ) mockAgent.popNextActivationTrigger(baseStateData) match { @@ -253,8 +253,8 @@ class ParticipantAgentFundamentalsSpec SortedSet(100L, 200L, 300L), Map( self -> Some(10L), - noSender -> Some(0L) - ) + noSender -> Some(0L), + ), ) mockAgent.popNextActivationTrigger(baseStateData) match { @@ -272,8 +272,8 @@ class ParticipantAgentFundamentalsSpec SortedSet(0L, 10L, 20L), Map( self -> Some(200L), - noSender -> Some(100L) - ) + noSender -> Some(100L), + ), ) mockAgent.popNextActivationTrigger(baseStateData) match { @@ -294,8 +294,8 @@ class ParticipantAgentFundamentalsSpec SortedSet(0L, 10L, 20L), Map( self -> Some(20L), - noSender -> Some(0L) - ) + noSender -> Some(0L), + ), ) mockAgent.popNextActivationTrigger(baseStateData) match { @@ -318,7 +318,7 @@ class ParticipantAgentFundamentalsSpec powerValues, -10L, 5L, - None + None, ) apparentPower match { case ApparentPower(p, q) => @@ -333,7 +333,7 @@ class ParticipantAgentFundamentalsSpec powerValues, 8L, 15L, - None + None, ) apparentPower match { case ApparentPower(p, q) => @@ -348,7 +348,7 @@ class ParticipantAgentFundamentalsSpec powerValues, 8L, 15L, - None + None, ) apparentPower match { case ApparentPower(p, q) => @@ -363,7 +363,7 @@ class ParticipantAgentFundamentalsSpec powerValues, -10L, 5L, - activeToReactivePowerFuncOpt + activeToReactivePowerFuncOpt, ) apparentPower match { case ApparentPower(p, q) => @@ -378,7 +378,7 @@ class ParticipantAgentFundamentalsSpec powerValues, 8L, 15L, - activeToReactivePowerFuncOpt + activeToReactivePowerFuncOpt, ) apparentPower match { case ApparentPower(p, q) => @@ -393,7 +393,7 @@ class ParticipantAgentFundamentalsSpec powerValues, 8L, 15L, - activeToReactivePowerFuncOpt + activeToReactivePowerFuncOpt, ) apparentPower match { case ApparentPower(p, q) => @@ -411,44 +411,44 @@ class ParticipantAgentFundamentalsSpec SortedMap( 800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1000L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1200L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1400L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1600L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) - ) - ) + Megavars(0.0), + ), + ), ) val requestValueStore = ValueStore( 900, SortedMap( 900L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) mockAgent.getRelevantResultData( requestTick, resultValueStore, - requestValueStore + requestValueStore, ) shouldBe Some( RelevantResultValues( 900L, @@ -456,29 +456,29 @@ class ParticipantAgentFundamentalsSpec Map( 800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1000L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1200L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1400L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1600L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ), 1800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) - ) - ) + Megavars(0.0), + ), + ), ) ) } @@ -490,24 +490,24 @@ class ParticipantAgentFundamentalsSpec SortedMap( 800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) val requestValueStore = ValueStore( 900, SortedMap( 900L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) mockAgent.getRelevantResultData( requestTick, resultValueStore, - requestValueStore + requestValueStore, ) shouldBe Some( RelevantResultValues( 900L, @@ -515,9 +515,9 @@ class ParticipantAgentFundamentalsSpec Map( 800L -> ApparentPower( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) - ) + ), ) ) } @@ -529,7 +529,7 @@ class ParticipantAgentFundamentalsSpec ApparentPower, FixedLoadRelevantData.type, ConstantState.type, - FixedLoadModel + FixedLoadModel, ]( simulationStartDate, simulationEndDate, @@ -541,7 +541,7 @@ class ParticipantAgentFundamentalsSpec CosPhiFixed(0.95), Kilowatts(100.0), 0.95, - LoadReference.ActivePower(Kilowatts(95.0)) + LoadReference.ActivePower(Kilowatts(95.0)), ), None, outputConfig, @@ -553,12 +553,12 @@ class ParticipantAgentFundamentalsSpec ValueStore(901L), ValueStore(901L), ValueStore(901L), - None + None, ) ParticipantAgent.getAndCheckNodalVoltage( baseStateData, - 1000L + 1000L, ) shouldBe Each(1.0) } @@ -567,7 +567,7 @@ class ParticipantAgentFundamentalsSpec ApparentPower, FixedLoadRelevantData.type, ConstantState.type, - FixedLoadModel + FixedLoadModel, ]( simulationStartDate, simulationEndDate, @@ -579,7 +579,7 @@ class ParticipantAgentFundamentalsSpec CosPhiFixed(0.95), Kilowatts(100.0), 0.95, - LoadReference.ActivePower(Kilowatts(95.0)) + LoadReference.ActivePower(Kilowatts(95.0)), ), None, outputConfig, @@ -591,7 +591,7 @@ class ParticipantAgentFundamentalsSpec ValueStore(901L), ValueStore(901L), ValueStore(901L), - None + None, ) intercept[InconsistentStateException] { @@ -615,17 +615,17 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { */ def mockBaseStateData( additionalActivationTicks: SortedSet[Long], - foreseenDataTicks: Map[ActorRef, Option[Long]] + foreseenDataTicks: Map[ActorRef, Option[Long]], ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, ConstantState.type, - SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type] + SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type], ] = { val modelMock = mock[SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ]] when(modelMock.getUuid).thenReturn(UUID.randomUUID()) @@ -636,8 +636,8 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ]( TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00"), TimeUtil.withDefaults.toZonedDateTime("2020-01-01 23:59:00"), @@ -646,7 +646,7 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ), additionalActivationTicks, foreseenDataTicks, @@ -656,7 +656,7 @@ case object ParticipantAgentFundamentalsSpec extends MockitoSugar { ValueStore(0L), ValueStore(0L), ValueStore(0L), - None + None, ) } } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala index 82e6d896f8..2b7b5f399e 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentMock.scala @@ -13,18 +13,18 @@ import edu.ie3.datamodel.models.result.system.SystemParticipantResult import edu.ie3.simona.agent.ValueStore import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ApparentPower, - ZERO_POWER + ZERO_POWER, } import edu.ie3.simona.agent.participant.data.Data.SecondaryData import edu.ie3.simona.agent.participant.data.secondary.SecondaryDataService import edu.ie3.simona.agent.participant.statedata.BaseStateData.ParticipantModelBaseStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ InputModelContainer, - ParticipantInitializeStateData + ParticipantInitializeStateData, } import edu.ie3.simona.agent.participant.statedata.{ BaseStateData, - ParticipantStateData + ParticipantStateData, } import edu.ie3.simona.agent.state.AgentState import edu.ie3.simona.agent.state.AgentState.Idle @@ -39,7 +39,7 @@ import edu.ie3.simona.model.participant.{ CalcRelevantData, FlexChangeIndicator, ModelState, - SystemParticipant + SystemParticipant, } import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.FlexResponse import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble @@ -66,9 +66,9 @@ class ParticipantAgentMock( initStateData: ParticipantInitializeStateData[ SystemParticipantInput, SimonaConfig.BaseRuntimeConfig, - ApparentPower + ApparentPower, ], - override val listener: Iterable[ActorRef] = Iterable.empty[ActorRef] + override val listener: Iterable[ActorRef] = Iterable.empty[ActorRef], ) extends ParticipantAgent[ ApparentPower, FixedRelevantData.type, @@ -79,8 +79,8 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ](scheduler, initStateData) with ParticipantAgentFundamentals[ ApparentPower, @@ -92,8 +92,8 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ] { override protected val pdClassTag: ClassTag[ApparentPower] = classTag[ApparentPower] @@ -112,16 +112,16 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ], ConstantState.type, - squants.Dimensionless + squants.Dimensionless, ) => ApparentPower = (_, _, _, _) => // output different from default (0, 0) ApparentPower( Megawatts(2.0), - Megavars(1.0) + Megavars(1.0), ) /** Abstractly calculate the power output of the participant with all needed @@ -148,12 +148,12 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ], modelState: ConstantState.type, currentTick: Long, - scheduler: ActorRef + scheduler: ActorRef, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = throw new InvalidRequestException( "Request to calculate power with secondary data cannot be processed for this mock agent." @@ -192,27 +192,27 @@ class ParticipantAgentMock( resolution: Long, requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, - maybeEmAgent: Option[TypedActorRef[FlexResponse]] + maybeEmAgent: Option[TypedActorRef[FlexResponse]], ): ParticipantModelBaseStateData[ ApparentPower, FixedRelevantData.type, ConstantState.type, - SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type] + SystemParticipant[FixedRelevantData.type, ApparentPower, ConstantState.type], ] = { val func = CosPhiFixed(0.95).activeToReactivePowerFunc( Kilowatts(0.0), 0.95d, - Each(1.0) + Each(1.0), ) val participant: SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ] = mock[SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ]] doReturn(func).when(participant).activeToReactivePowerFunc(any()) @@ -223,8 +223,8 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ]( simulationStartDate, simulationEndDate, @@ -236,13 +236,13 @@ class ParticipantAgentMock( requestVoltageDeviationThreshold, ValueStore.forVoltage( resolution, - Each(1.0) + Each(1.0), ), ValueStore.forResult(resolution, 2), ValueStore(resolution), ValueStore(resolution), ValueStore(resolution), - None + None, ) } @@ -262,17 +262,17 @@ class ParticipantAgentMock( inputModel: InputModelContainer[SystemParticipantInput], modelConfig: BaseRuntimeConfig, simulationStartDate: ZonedDateTime, - simulationEndDate: ZonedDateTime + simulationEndDate: ZonedDateTime, ): SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ] = { val mockModel = mock[SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type + ConstantState.type, ]] val uuid = inputModel.electricalInputModel.getUuid Mockito.when(mockModel.getUuid).thenReturn(uuid) @@ -287,8 +287,8 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ] ): ModelState.ConstantState.type = ConstantState @@ -301,10 +301,10 @@ class ParticipantAgentMock( SystemParticipant[ FixedRelevantData.type, ApparentPower, - ConstantState.type - ] + ConstantState.type, + ], ], - tick: Long + tick: Long, ): FixedRelevantData.type = FixedRelevantData @@ -319,7 +319,7 @@ class ParticipantAgentMock( */ override def finalizeTickAfterPF( baseStateData: BaseStateData[ApparentPower], - currentTick: Long + currentTick: Long, ): FSM.State[AgentState, ParticipantStateData[ApparentPower]] = goto(Idle) using baseStateData @@ -342,14 +342,14 @@ class ParticipantAgentMock( windowEnd: Long, activeToReactivePowerFuncOpt: Option[ squants.Power => ReactivePower - ] = None + ] = None, ): ApparentPower = ParticipantAgentFundamentals.averageApparentPower( tickToResults, windowStart, windowEnd, activeToReactivePowerFuncOpt, - log + log, ) /** Determines the correct result. @@ -366,13 +366,13 @@ class ParticipantAgentMock( override protected def buildResult( uuid: UUID, dateTime: ZonedDateTime, - result: ApparentPower + result: ApparentPower, ): SystemParticipantResult = new SystemParticipantResult( dateTime, uuid, result.p.toMegawatts.asMegaWatt, - result.q.toMegavars.asMegaVar + result.q.toMegavars.asMegaVar, ) {} /** Handle an active power change by flex control. @@ -399,19 +399,19 @@ class ParticipantAgentMock( SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ModelState.ConstantState.type - ] + ModelState.ConstantState.type, + ], ], data: CalcRelevantData.FixedRelevantData.type, lastState: ModelState.ConstantState.type, - setPower: squants.Power + setPower: squants.Power, ): (ModelState.ConstantState.type, ApparentPower, FlexChangeIndicator) = ( ConstantState, ApparentPower( Kilowatts(0.0), - Kilovars(0.0) + Kilovars(0.0), ), - FlexChangeIndicator() + FlexChangeIndicator(), ) /** Update the last known model state with the given external, relevant data @@ -438,8 +438,8 @@ class ParticipantAgentMock( model: SystemParticipant[ CalcRelevantData.FixedRelevantData.type, ApparentPower, - ModelState.ConstantState.type - ] + ModelState.ConstantState.type, + ], ): ModelState.ConstantState.type = modelState } @@ -449,13 +449,13 @@ object ParticipantAgentMock { initStateData: ParticipantInitializeStateData[ SystemParticipantInput, SimonaConfig.BaseRuntimeConfig, - ApparentPower - ] + ApparentPower, + ], ): Props = Props( new ParticipantAgentMock( scheduler, - initStateData + initStateData, ) ) } diff --git a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala index 471ce0dff6..7e7e7d28f2 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -30,18 +30,18 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.{ ProvideWeatherMessage, RegisterForWeatherMessage, - WeatherData + WeatherData, } import edu.ie3.simona.test.ParticipantAgentSpec import edu.ie3.simona.test.common.input.PvInputTestData @@ -52,7 +52,7 @@ import edu.ie3.util.scala.quantities.{ Megavars, ReactivePower, Vars, - WattsPerSquareMeter + WattsPerSquareMeter, } import squants.energy.{Kilowatts, Megawatts, Watts} import squants.motion.MetersPerSecond @@ -71,7 +71,7 @@ class PvAgentModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with PvInputTestData { @@ -96,12 +96,12 @@ class PvAgentModelCalculationSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val defaultOutputConfig = NotifierConfig( simonaConfig.simona.output.participant.defaultConfig.simulationResult, simonaConfig.simona.output.participant.defaultConfig.powerRequestReply, - simonaConfig.simona.output.participant.defaultConfig.flexResult + simonaConfig.simona.output.participant.defaultConfig.flexResult, ) private val configUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -122,7 +122,7 @@ class PvAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ PvInput, PvRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -133,7 +133,7 @@ class PvAgentModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -141,7 +141,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -163,7 +163,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -175,7 +175,7 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) deathProbe.expectTerminated(pvAgent.ref) @@ -186,7 +186,7 @@ class PvAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ PvInput, PvRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -197,7 +197,7 @@ class PvAgentModelCalculationSpec requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, - primaryServiceProxy = primaryServiceProxy.ref + primaryServiceProxy = primaryServiceProxy.ref, ) "be instantiated correctly" in { @@ -205,7 +205,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -225,7 +225,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -247,7 +247,7 @@ class PvAgentModelCalculationSpec resolution, requestVoltageDeviationThreshold, outputConfig, - maybeEmAgent + maybeEmAgent, ) => inputModel shouldBe SimpleInputContainer(voltageSensitiveInput) modelConfig shouldBe modelConfig @@ -265,7 +265,7 @@ class PvAgentModelCalculationSpec /* Refuse registration */ primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -291,10 +291,10 @@ class PvAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ), awaitRegistrationResponsesFrom, - foreseenNextDataTicks + foreseenNextDataTicks, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -305,13 +305,13 @@ class PvAgentModelCalculationSpec outputConfig shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower](resolution) @@ -328,7 +328,7 @@ class PvAgentModelCalculationSpec /* Reply, that registration was successful */ weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)), ) /* Expect a completion message */ @@ -354,7 +354,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -364,7 +364,7 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -373,7 +373,7 @@ class PvAgentModelCalculationSpec ) weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -385,12 +385,12 @@ class PvAgentModelCalculationSpec pvAgent ! RequestAssetPowerMessage( 0L, Each(1d), - Each(0d) + Each(0d), ) expectMsg( AssetPowerChangedMessage( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) ) @@ -403,9 +403,9 @@ class PvAgentModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) - ) + ), ) case _ => fail( @@ -419,7 +419,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -429,14 +429,14 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -449,12 +449,12 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ) weatherService.send( pvAgent, - ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)), ) /* Find yourself in corresponding state and state data */ @@ -463,7 +463,7 @@ class PvAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -507,7 +507,7 @@ class PvAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 0L, - fail("Expected a simulation result for tick 900.") + fail("Expected a simulation result for tick 900."), ) match { case ApparentPower(p, q) => p should approximate(Megawatts(0.0)) @@ -526,7 +526,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -536,14 +536,14 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -559,7 +559,7 @@ class PvAgentModelCalculationSpec case DataCollectionStateData( baseStateData: ParticipantModelBaseStateData[_, _, _, _], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -582,12 +582,12 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ) weatherService.send( pvAgent, - ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)) + ProvideWeatherMessage(0L, weatherService.ref, weatherData, Some(3600L)), ) /* Expect confirmation */ @@ -611,7 +611,7 @@ class PvAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 0L, - fail("Expected a simulation result for tick 0.") + fail("Expected a simulation result for tick 0."), ) match { case ApparentPower(p, q) => p should approximate(Megawatts(0.0)) @@ -630,7 +630,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -641,14 +641,14 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(3600L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -659,7 +659,7 @@ class PvAgentModelCalculationSpec pvAgent ! RequestAssetPowerMessage( 7200L, Each(1d), - Each(0d) + Each(0d), ) expectNoMessage(noReceiveTimeOut.duration) awaitAssert(pvAgent.stateName == Idle) @@ -669,7 +669,7 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ) weatherService.send( pvAgent, @@ -677,8 +677,8 @@ class PvAgentModelCalculationSpec 3600L, weatherService.ref, weatherData, - Some(7200L) - ) + Some(7200L), + ), ) /* Trigger the agent */ @@ -700,7 +700,7 @@ class PvAgentModelCalculationSpec new PvAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -712,14 +712,14 @@ class PvAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( pvAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( pvAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(0L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(0L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -737,10 +737,10 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ), - Some(3600L) - ) + Some(3600L), + ), ) scheduler.send(pvAgent, Activation(0)) scheduler.expectMsg(Completion(pvAgent.toTyped, Some(3600))) @@ -755,10 +755,10 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ), - Some(7200L) - ) + Some(7200L), + ), ) scheduler.send(pvAgent, Activation(3600)) scheduler.expectMsg(Completion(pvAgent.toTyped, Some(7200))) @@ -773,10 +773,10 @@ class PvAgentModelCalculationSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(1.815d), - MetersPerSecond(7.726576d) + MetersPerSecond(7.726576d), ), - None - ) + None, + ), ) scheduler.send(pvAgent, Activation(7200)) scheduler.expectMsg(Completion(pvAgent.toTyped)) @@ -785,7 +785,7 @@ class PvAgentModelCalculationSpec pvAgent ! RequestAssetPowerMessage( 7500L, Each(1d), - Each(0d) + Each(0d), ) expectMsgType[AssetPowerChangedMessage] match { @@ -802,7 +802,7 @@ class PvAgentModelCalculationSpec pvAgent ! RequestAssetPowerMessage( 7500L, Each(1.000000000000001d), - Each(0d) + Each(0d), ) /* Expect, that nothing has changed */ @@ -818,7 +818,7 @@ class PvAgentModelCalculationSpec pvAgent ! RequestAssetPowerMessage( 7500L, Each(0.98), - Each(0d) + Each(0d), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/agent/participant/RichValueSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/RichValueSpec.scala index 5cf286ba8c..5710c15417 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/RichValueSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/RichValueSpec.scala @@ -12,7 +12,7 @@ import edu.ie3.datamodel.models.value.{ HeatDemandValue, PValue, SValue, - Value + Value, } import edu.ie3.simona.agent.participant.data.Data.PrimaryData import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ @@ -20,7 +20,7 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ActivePowerAndHeat, ApparentPower, ApparentPowerAndHeat, - RichValue + RichValue, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.quantities.PowerSystemUnits @@ -54,32 +54,32 @@ class RichValueSpec extends UnitSpec with TableDrivenPropertyChecks { new PValue(null), new HeatAndPValue( null, - Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT), ), new HeatAndPValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), - null + null, ), new SValue(null, Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR)), new SValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), - null + null, ), new HeatAndSValue( null, Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR), - Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT), ), new HeatAndSValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), null, - Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT), ), new HeatAndSValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR), - null - ) + null, + ), ) forAll(table)({ maliciousValue: Value => @@ -99,40 +99,40 @@ class RichValueSpec extends UnitSpec with TableDrivenPropertyChecks { ("value", "primaryData"), ( new PValue(Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT)), - ActivePower(Kilowatts(50d)) + ActivePower(Kilowatts(50d)), ), ( new HeatAndPValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), - Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT), ), ActivePowerAndHeat( Kilowatts(50d), - Kilowatts(12.5d) - ) + Kilowatts(12.5d), + ), ), ( new SValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), - Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR) + Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR), ), ApparentPower( Kilowatts(50d), - Kilovars(25d) - ) + Kilovars(25d), + ), ), ( new HeatAndSValue( Quantities.getQuantity(50d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(25d, PowerSystemUnits.KILOVAR), - Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(12.5, PowerSystemUnits.KILOWATT), ), ApparentPowerAndHeat( Kilowatts(50d), Kilovars(25d), - Kilowatts(12.5) - ) - ) + Kilowatts(12.5), + ), + ), ) forAll(table)({ case (value: Value, primaryData: PrimaryData) => @@ -142,7 +142,7 @@ class RichValueSpec extends UnitSpec with TableDrivenPropertyChecks { case Failure(exception) => fail( s"Conversion of '$value' to primary data should succeed, but failed.", - exception + exception, ) } }) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala index a0b6df4aaf..4e2151087f 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -21,7 +21,7 @@ import edu.ie3.simona.agent.participant.statedata.DataCollectionStateData import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.{ CollectRegistrationConfirmMessages, ParticipantInitializeStateData, - ParticipantUninitializedStateData + ParticipantUninitializedStateData, } import edu.ie3.simona.agent.participant.wec.WecAgent import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} @@ -37,18 +37,18 @@ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ AssetPowerChangedMessage, AssetPowerUnchangedMessage, - RequestAssetPowerMessage + RequestAssetPowerMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.ontology.messages.services.WeatherMessage.{ ProvideWeatherMessage, RegisterForWeatherMessage, - WeatherData + WeatherData, } import edu.ie3.simona.test.ParticipantAgentSpec import edu.ie3.simona.test.common.input.WecInputTestData @@ -59,7 +59,7 @@ import edu.ie3.util.scala.quantities.{ Megavars, ReactivePower, Vars, - WattsPerSquareMeter + WattsPerSquareMeter, } import org.scalatest.PrivateMethodTester import squants.Each @@ -79,7 +79,7 @@ class WecAgentModelCalculationSpec .parseString(""" |pekko.loggers =["org.apache.pekko.event.slf4j.Slf4jLogger"] |pekko.loglevel="DEBUG" - """.stripMargin) + """.stripMargin), ) ) with PrivateMethodTester @@ -104,7 +104,7 @@ class WecAgentModelCalculationSpec private val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0d)) + LoadReference.ActivePower(Kilowatts(0d)), ) private val configUtil = ConfigUtil.ParticipantConfigUtil( simonaConfig.simona.runtime.participant @@ -125,7 +125,7 @@ class WecAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ WecInput, WecRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, simulationStartDate = simulationStartDate, @@ -139,8 +139,8 @@ class WecAgentModelCalculationSpec outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false - ) + flexResult = false, + ), ) "be instantiated correctly" in { @@ -148,7 +148,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -170,7 +170,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -182,7 +182,7 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) deathProbe.expectTerminated(wecAgent.ref) @@ -193,7 +193,7 @@ class WecAgentModelCalculationSpec val initStateData = ParticipantInitializeStateData[ WecInput, WecRuntimeConfig, - ApparentPower + ApparentPower, ]( inputModel = voltageSensitiveInput, modelConfig = modelConfig, @@ -207,8 +207,8 @@ class WecAgentModelCalculationSpec outputConfig = NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false - ) + flexResult = false, + ), ) "be instantiated correctly" in { @@ -216,7 +216,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -236,7 +236,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -246,7 +246,7 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ @@ -270,10 +270,10 @@ class WecAgentModelCalculationSpec requestValueStore, _, _, - _ + _, ), awaitRegistrationResponsesFrom, - foreseenNextDataTicks + foreseenNextDataTicks, ) => /* Base state data */ startDate shouldBe simulationStartDate @@ -282,13 +282,13 @@ class WecAgentModelCalculationSpec outputConfig shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) additionalActivationTicks shouldBe empty foreseenDataTicks shouldBe Map.empty voltageValueStore shouldBe ValueStore( resolution, - SortedMap(0L -> Each(1.0)) + SortedMap(0L -> Each(1.0)), ) resultValueStore shouldBe ValueStore(resolution) requestValueStore shouldBe ValueStore[ApparentPower](resolution) @@ -305,7 +305,7 @@ class WecAgentModelCalculationSpec /* Reply, that registration was successful */ weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(4711L)), ) /* Expect a completion message */ @@ -318,7 +318,7 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] => /* Only check the awaited next data ticks, as the rest has yet been checked */ baseStateData.foreseenDataTicks shouldBe Map( @@ -336,7 +336,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -346,14 +346,14 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* Expect a registration message */ weatherService.expectMsg(RegisterForWeatherMessage(51.4843281, 7.4116482)) weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -365,12 +365,12 @@ class WecAgentModelCalculationSpec wecAgent ! RequestAssetPowerMessage( 0L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsg( AssetPowerChangedMessage( Megawatts(0.0), - Megavars(0.0) + Megavars(0.0), ) ) @@ -379,7 +379,7 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] => modelBaseStateData.requestValueStore shouldBe ValueStore[ ApparentPower @@ -388,9 +388,9 @@ class WecAgentModelCalculationSpec SortedMap( 0L -> ApparentPower( Megawatts(0d), - Megavars(0d) + Megavars(0d), ) - ) + ), ) case _ => fail( @@ -404,7 +404,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -414,14 +414,14 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -434,7 +434,7 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ) weatherService.send( @@ -443,8 +443,8 @@ class WecAgentModelCalculationSpec 900L, weatherService.ref, weatherData, - Some(1800L) - ) + Some(1800L), + ), ) /* Find yourself in corresponding state and state data */ @@ -455,10 +455,10 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -491,7 +491,7 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] => /* The store for calculation relevant data has been extended */ baseStateData.receivedSecondaryDataStore match { @@ -507,7 +507,7 @@ class WecAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 900L, - fail("Expected a simulation result for tick 900.") + fail("Expected a simulation result for tick 900."), ) match { case ApparentPower(p, q) => p should approximate(Megawatts(0.0)) @@ -526,7 +526,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -536,14 +536,14 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -561,10 +561,10 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ], expectedSenders, - isYetTriggered + isYetTriggered, ) => /* The next data tick is already registered */ baseStateData.foreseenDataTicks shouldBe Map( @@ -587,7 +587,7 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ) weatherService.send( @@ -596,8 +596,8 @@ class WecAgentModelCalculationSpec 900L, weatherService.ref, weatherData, - Some(1800L) - ) + Some(1800L), + ), ) /* Expect confirmation */ @@ -610,7 +610,7 @@ class WecAgentModelCalculationSpec ApparentPower, WecRelevantData, ConstantState.type, - WecModel + WecModel, ] => /* The store for calculation relevant data has been extended */ baseStateData.receivedSecondaryDataStore match { @@ -626,7 +626,7 @@ class WecAgentModelCalculationSpec store.size shouldBe 1 store.getOrElse( 900L, - fail("Expected a simulation result for tick 900.") + fail("Expected a simulation result for tick 900."), ) match { case ApparentPower(p, q) => p should approximate(Megawatts(0.0)) @@ -645,7 +645,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -656,14 +656,14 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -674,7 +674,7 @@ class WecAgentModelCalculationSpec wecAgent ! RequestAssetPowerMessage( 1800L, Each(1.0), - Each(0.0) + Each(0.0), ) expectNoMessage(noReceiveTimeOut.duration) awaitAssert(wecAgent.stateName == Idle) @@ -684,7 +684,7 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ) weatherService.send( wecAgent, @@ -692,8 +692,8 @@ class WecAgentModelCalculationSpec 900L, weatherService.ref, weatherData, - Some(1800L) - ) + Some(1800L), + ), ) /* Trigger the agent */ @@ -715,7 +715,7 @@ class WecAgentModelCalculationSpec new WecAgent( scheduler = scheduler.ref, initStateData = initStateData, - listener = systemListener + listener = systemListener, ) ) @@ -727,14 +727,14 @@ class WecAgentModelCalculationSpec primaryServiceProxy.expectMsgType[PrimaryServiceRegistrationMessage] primaryServiceProxy.send( wecAgent, - RegistrationFailedMessage(primaryServiceProxy.ref) + RegistrationFailedMessage(primaryServiceProxy.ref), ) /* I'm not interested in the content of the RegistrationMessage */ weatherService.expectMsgType[RegisterForWeatherMessage] weatherService.send( wecAgent, - RegistrationSuccessfulMessage(weatherService.ref, Some(900L)) + RegistrationSuccessfulMessage(weatherService.ref, Some(900L)), ) /* I'm not interested in the content of the CompletionMessage */ @@ -752,10 +752,10 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ), - Some(1800L) - ) + Some(1800L), + ), ) scheduler.send(wecAgent, Activation(900)) scheduler.expectMsg(Completion(wecAgent.toTyped, Some(1800))) @@ -770,10 +770,10 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ), - Some(2700L) - ) + Some(2700L), + ), ) scheduler.send(wecAgent, Activation(1800)) scheduler.expectMsg(Completion(wecAgent.toTyped, Some(2700))) @@ -788,10 +788,10 @@ class WecAgentModelCalculationSpec WattsPerSquareMeter(50d), WattsPerSquareMeter(100d), Celsius(0d), - MetersPerSecond(0d) + MetersPerSecond(0d), ), - None - ) + None, + ), ) scheduler.send(wecAgent, Activation(2700)) scheduler.expectMsg(Completion(wecAgent.toTyped)) @@ -800,7 +800,7 @@ class WecAgentModelCalculationSpec wecAgent ! RequestAssetPowerMessage( 3000L, Each(1.0), - Each(0.0) + Each(0.0), ) expectMsgType[AssetPowerChangedMessage] match { @@ -817,7 +817,7 @@ class WecAgentModelCalculationSpec wecAgent ! RequestAssetPowerMessage( 3000L, Each(1.000000000000001d), - Each(0.0) + Each(0.0), ) /* Expect, that nothing has changed */ @@ -833,7 +833,7 @@ class WecAgentModelCalculationSpec wecAgent ! RequestAssetPowerMessage( 3000L, Each(0.98d), - Each(0.0) + Each(0.0), ) /* Expect, the correct values (this model has fixed power factor) */ diff --git a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala index 54dcd9f061..da6431493b 100644 --- a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala +++ b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala @@ -16,11 +16,11 @@ import edu.ie3.simona.api.simulation.ontology.{ ActivationMessage, TerminationCompleted, TerminationMessage, - CompletionMessage => ExtCompletionMessage + CompletionMessage => ExtCompletionMessage, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.ScheduleServiceActivation import edu.ie3.simona.ontology.messages.{Activation, StopMessage} @@ -41,7 +41,7 @@ class ExtSimAdapterSpec .parseString(""" |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel = "INFO" - |""".stripMargin) + |""".stripMargin), ) ) with AnyWordSpecLike @@ -89,7 +89,7 @@ class ExtSimAdapterSpec awaitCond( !extData.receiveMessageQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveMessageQueue.size() shouldBe 1 extData.receiveMessageQueue.take() shouldBe new ActivationMessage( @@ -129,7 +129,7 @@ class ExtSimAdapterSpec awaitCond( !extData.receiveMessageQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveMessageQueue.size() shouldBe 1 extData.receiveMessageQueue.take() @@ -169,7 +169,7 @@ class ExtSimAdapterSpec awaitCond( !extData.receiveMessageQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveMessageQueue.size() shouldBe 1 extData.receiveMessageQueue.take() shouldBe new TerminationMessage( diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index df2333ca9f..a9eacda69a 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -33,7 +33,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { new Time( "2020-06-18 13:41:00", None, - "2020-05-18 13:41:00" + "2020-05-18 13:41:00", ) ) } @@ -45,7 +45,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { new Time( "2020-06-18 13:41:00", None, - "2020-07-18 13:41:00" + "2020-07-18 13:41:00", ) ) }.getMessage shouldBe "Invalid time configuration." + @@ -88,11 +88,11 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { 10, new Newtonraphson( List(10, 30), - 100 + 100, ), Duration.of(3600, ChronoUnit.SECONDS), stopOnFailure = false, - Duration.of(3600, ChronoUnit.SECONDS) + Duration.of(3600, ChronoUnit.SECONDS), ) ) } @@ -105,11 +105,11 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { 10, new Newtonraphson( List(10, 30), - 100 + 100, ), resolution = Duration.of(3600, ChronoUnit.NANOS), stopOnFailure = false, - sweepTimeout = Duration.of(3600, ChronoUnit.SECONDS) + sweepTimeout = Duration.of(3600, ChronoUnit.SECONDS), ) ) }.getMessage shouldBe "Invalid time resolution. Please ensure, that the time resolution for power flow calculation is at least rounded to a full second!" @@ -450,7 +450,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ConfigFailFast invokePrivate checkBaseRuntimeConfigs( simonaConfig.simona.runtime.participant.load.defaultConfig, simonaConfig.simona.runtime.participant.load.individualConfigs, - defaultString + defaultString, ) }.getMessage shouldBe "There has to be at least one identifier for each participant." } @@ -476,7 +476,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ConfigFailFast invokePrivate checkBaseRuntimeConfigs( simonaConfig.simona.runtime.participant.load.defaultConfig, simonaConfig.simona.runtime.participant.load.individualConfigs, - defaultString + defaultString, ) }.getMessage shouldBe "Found invalid UUID 'blabla' it was meant to be the string 'default' or a valid UUID." } @@ -502,7 +502,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ConfigFailFast invokePrivate checkBaseRuntimeConfigs( simonaConfig.simona.runtime.participant.load.defaultConfig, simonaConfig.simona.runtime.participant.load.individualConfigs, - defaultString + defaultString, ) }.getMessage shouldBe s"Found invalid UUID 'blabla' it was meant to be the string 'default' or a valid UUID." } @@ -528,7 +528,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ConfigFailFast invokePrivate checkBaseRuntimeConfigs( simonaConfig.simona.runtime.participant.load.defaultConfig, simonaConfig.simona.runtime.participant.load.individualConfigs, - defaultString + defaultString, ) }.getMessage shouldBe "The scaling factor for system participants with UUID '49f250fa-41ff-4434-a083-79c98d260a76' may not be negative." } @@ -569,7 +569,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ConfigFailFast invokePrivate checkBaseRuntimeConfigs( simonaConfig.simona.runtime.participant.load.defaultConfig, simonaConfig.simona.runtime.participant.load.individualConfigs, - defaultString + defaultString, ) }.getMessage shouldBe "The basic model configurations contain ambiguous definitions." } @@ -688,20 +688,20 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { notifier = "load", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, simulationResult = false, - flexResult = false - ) + flexResult = false, + ), ) noException shouldBe thrownBy { @@ -717,20 +717,20 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { notifier = "load", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = false, simulationResult = true, - flexResult = false - ) + flexResult = false, + ), ) intercept[InvalidConfigParameterException]( @@ -757,7 +757,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { Sink( Some(Csv("", "", "", isHierarchic = false)), Some(InfluxDb1x("", 0, "")), - None + None, ) ) }.getLocalizedMessage shouldBe "Multiple sink configurations are not supported! Please ensure that only " + @@ -785,9 +785,9 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { 0, "00000000-0000-0000-0000-000000000000", "https://reg:123", - "topic" + "topic", ) - ) + ), ) ) }.getMessage shouldBe "Connection with kafka broker localhost:12345 failed." @@ -802,7 +802,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { CsvConfigUtil.checkBaseCsvParams( csvParams, - "CsvGridData" + "CsvGridData", ) }.getMessage shouldBe "The csvSep parameter '\t' for 'CsvGridData' configuration is invalid! Please choose between ';' or ','!" } @@ -812,7 +812,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { CsvConfigUtil.checkBaseCsvParams( csvParams, - "CsvGridData" + "CsvGridData", ) }.getMessage shouldBe "The provided directoryPath for .csv-files '' for 'CsvGridData' configuration is invalid! Please correct the path!" } @@ -824,7 +824,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { intercept[InvalidConfigParameterException] { CsvConfigUtil.checkBaseCsvParams( csvParams, - "CsvGridData" + "CsvGridData", ) }.getMessage shouldBe "The provided directoryPath for .csv-files 'somewhere/else' for 'CsvGridData' configuration is invalid! Please correct the path!" } @@ -833,13 +833,13 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { val csvParams = BaseCsvParams( ",", "inputData/common/pekko.conf", - isHierarchic = false + isHierarchic = false, ) intercept[InvalidConfigParameterException] { CsvConfigUtil.checkBaseCsvParams( csvParams, - "CsvGridData" + "CsvGridData", ) }.getMessage shouldBe "The provided directoryPath for .csv-files 'inputData/common/pekko.conf' for 'CsvGridData' configuration is invalid! Please correct the path!" } @@ -850,7 +850,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { noException shouldBe thrownBy { CsvConfigUtil.checkBaseCsvParams( csvParams, - "CsvGridData" + "CsvGridData", ) } } @@ -863,7 +863,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { Some( BaseCsvParams(",", "inputData/vn_simona", isHierarchic = false) ), - id = "" + id = "", ) intercept[InvalidConfigParameterException] { @@ -874,7 +874,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "identify unsupported id" in { val gridDataSource = SimonaConfig.Simona.Input.Grid.Datasource( None, - id = "someWhereUndefined" + id = "someWhereUndefined", ) intercept[InvalidConfigParameterException] { @@ -885,7 +885,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "identify missing csv parameters" in { val gridDataSource = SimonaConfig.Simona.Input.Grid.Datasource( None, - id = "csv" + id = "csv", ) intercept[InvalidConfigParameterException] { @@ -900,10 +900,10 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { BaseCsvParams( ",", "input/samples/vn_simona", - isHierarchic = false + isHierarchic = false, ) ), - id = "csv" + id = "csv", ) noException shouldBe thrownBy { @@ -929,7 +929,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { SimonaConfig.Simona.Input.Weather.Datasource.CoordinateSource .SampleParams(true) ), - None + None, ), None, None, @@ -941,7 +941,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { ), "this won't work", None, - Some("yyyy-MM-dd HH:mm") + Some("yyyy-MM-dd HH:mm"), ) intercept[InvalidConfigParameterException] { ConfigFailFast invokePrivate checkWeatherDataSource( diff --git a/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala b/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala index be5d9b95c4..13dfc0c5d1 100644 --- a/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/RefSystemParserSpec.scala @@ -24,7 +24,7 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) + ), ), new RefSystemConfig( gridIds = Some(List("100")), @@ -33,16 +33,16 @@ class RefSystemParserSpec extends UnitSpec { voltLvls = Some( List( VoltLvlConfig("HS", "110 kV"), - VoltLvlConfig("HoeS", "380 kV") + VoltLvlConfig("HoeS", "380 kV"), ) - ) + ), ), new RefSystemConfig( gridIds = None, sNom = "5000 MVA", vNom = "110 kV", - voltLvls = None - ) + voltLvls = None, + ), ) val configRefSystems = RefSystemParser.parse(validRefSystems) @@ -71,7 +71,7 @@ class RefSystemParserSpec extends UnitSpec { 18 -> configRefSystemOne, 19 -> configRefSystemOne, 20 -> configRefSystemOne, - 100 -> configRefSystemTwo + 100 -> configRefSystemTwo, ) // check internal voltLvLRefSystems @@ -81,7 +81,7 @@ class RefSystemParserSpec extends UnitSpec { GermanVoltageLevelUtils.MV_10KV -> configRefSystemOne, GermanVoltageLevelUtils.MV_20KV -> configRefSystemOne, GermanVoltageLevelUtils.HV -> configRefSystemTwo, - GermanVoltageLevelUtils.EHV_380KV -> configRefSystemTwo + GermanVoltageLevelUtils.EHV_380KV -> configRefSystemTwo, ) } @@ -96,7 +96,7 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) + ), ) ) intercept[InvalidConfigParameterException] { @@ -115,7 +115,7 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) + ), ), new RefSystemConfig( gridIds = None, @@ -123,8 +123,8 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) - ) + ), + ), ) intercept[InvalidConfigParameterException] { RefSystemParser.parse(validRefSystems) @@ -142,7 +142,7 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) + ), ), new RefSystemConfig( gridIds = None, @@ -150,8 +150,8 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) - ) + ), + ), ) intercept[InvalidConfigParameterException] { RefSystemParser.parse(validRefSystems) @@ -171,7 +171,7 @@ class RefSystemParserSpec extends UnitSpec { vNom = "10 kV", voltLvls = Some( List(VoltLvlConfig("MS", "10 kV"), VoltLvlConfig("MS", "20 kV")) - ) + ), ), new RefSystemConfig( gridIds = Some(List("100")), @@ -179,8 +179,8 @@ class RefSystemParserSpec extends UnitSpec { vNom = "110 kV", voltLvls = Some( List(VoltLvlConfig("HS", "110 kV"), VoltLvlConfig("HoeS", "380 kV")) - ) - ) + ), + ), ) val configRefSystems = RefSystemParser.parse(validRefSystems) @@ -199,7 +199,7 @@ class RefSystemParserSpec extends UnitSpec { configRefSystems.find( 1, - Some(GermanVoltageLevelUtils.MV_10KV) + Some(GermanVoltageLevelUtils.MV_10KV), ) shouldBe Some( configRefSystemOne ) @@ -210,7 +210,7 @@ class RefSystemParserSpec extends UnitSpec { configRefSystems.find( 1000, - Some(GermanVoltageLevelUtils.HV) + Some(GermanVoltageLevelUtils.HV), ) shouldBe Some( configRefSystemTwo ) @@ -227,7 +227,7 @@ class RefSystemParserSpec extends UnitSpec { configRefSystems.find( 1000, - Some(GermanVoltageLevelUtils.EHV_220KV) + Some(GermanVoltageLevelUtils.EHV_220KV), ) shouldBe None } diff --git a/src/test/scala/edu/ie3/simona/deploy/DeploySpec.scala b/src/test/scala/edu/ie3/simona/deploy/DeploySpec.scala index f329122b50..82f2c349db 100644 --- a/src/test/scala/edu/ie3/simona/deploy/DeploySpec.scala +++ b/src/test/scala/edu/ie3/simona/deploy/DeploySpec.scala @@ -77,7 +77,7 @@ class DeploySpec extends UnitSpec { case Failure(exception) => fail( s"Cannot build class from execution class '$classString' in run-simona-cmd.sh!", - exception + exception, ) case Success(clazz) => clazz } diff --git a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala index a2a72a34ce..654e6ff8d4 100644 --- a/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/NotifierSpec.scala @@ -30,7 +30,7 @@ class NotifierSpec .parseString(""" |pekko.loggers =["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel="OFF" - |""".stripMargin) + |""".stripMargin), ) ) with Matchers @@ -88,7 +88,7 @@ class NotifierSpec Storage -> classOf[StorageResult], Ev -> - classOf[EvResult] + classOf[EvResult], ) // TODO: Grid results are not covered, yet. @@ -106,7 +106,7 @@ object NotifierSpec { final case class TestEventEnvelope( testEvent: TestEvent, - msg: String = "Please notify others of this!" + msg: String = "Please notify others of this!", ) } diff --git a/src/test/scala/edu/ie3/simona/event/SimonaListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/SimonaListenerSpec.scala index 538a4732f4..c9c6b0238c 100644 --- a/src/test/scala/edu/ie3/simona/event/SimonaListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/SimonaListenerSpec.scala @@ -36,7 +36,7 @@ class SimonaListenerSpec |pekko.loggers =["edu.ie3.simona.test.common.SilentTestEventListener"] |pekko.loglevel="debug" |""".stripMargin - ) + ), ) ) with Matchers { @@ -78,7 +78,7 @@ class SimonaListenerSpec EventFilter .debug( message = s"$logPrefix Received '$msg' from date $msgDate", - occurrences = 1 + occurrences = 1, ) .intercept { listener ! TestEvent(msg, msgDate) @@ -91,7 +91,7 @@ class SimonaListenerSpec EventFilter .warning( message = s"$logPrefix Received unknown event", - occurrences = 1 + occurrences = 1, ) .intercept { listener ! UnknownEvent @@ -100,7 +100,7 @@ class SimonaListenerSpec EventFilter .warning( message = s"$logPrefix Received unknown message: $unknownMessage", - occurrences = 1 + occurrences = 1, ) .intercept { listener ! unknownMessage diff --git a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala index 6f7aba992e..067162f30b 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala @@ -11,14 +11,14 @@ import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, Transformer2WResult, - Transformer3WResult + Transformer3WResult, } import edu.ie3.datamodel.models.result.system.PvResult import edu.ie3.datamodel.models.result.{NodeResult, ResultEntity} import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult import edu.ie3.simona.event.ResultEvent.{ ParticipantResultEvent, - PowerFlowResultEvent + PowerFlowResultEvent, } import edu.ie3.simona.io.result.{ResultEntitySink, ResultSinkType} import edu.ie3.simona.ontology.messages.StopMessage @@ -29,7 +29,7 @@ import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig import edu.ie3.util.io.FileIOUtils import org.apache.pekko.actor.testkit.typed.scaladsl.{ ActorTestKit, - ScalaTestWithActorTestKit + ScalaTestWithActorTestKit, } import org.apache.pekko.testkit.TestKit.awaitCond import org.apache.pekko.testkit.TestProbe @@ -47,7 +47,7 @@ class ResultEventListenerSpec extends ScalaTestWithActorTestKit( ActorTestKit.ApplicationTestConfig.withValue( "org.apache.pekko.actor.testkit.typed.filter-leeway", - ConfigValueFactory.fromAnyRef("10s") + ConfigValueFactory.fromAnyRef("10s"), ) ) with UnitSpec @@ -62,7 +62,7 @@ class ResultEventListenerSpec classOf[Transformer2WResult], classOf[Transformer3WResult], classOf[SwitchResult], - classOf[LineResult] + classOf[LineResult], ) private val timeoutDuration: Duration = 30.seconds @@ -71,16 +71,16 @@ class ResultEventListenerSpec private def resultFileHierarchy( runId: Int, fileFormat: String, - classes: Set[Class[_ <: ResultEntity]] = resultEntitiesToBeWritten + classes: Set[Class[_ <: ResultEntity]] = resultEntitiesToBeWritten, ): ResultFileHierarchy = ResultFileHierarchy( outputDir = testTmpDir + File.separator + runId, simulationName, ResultEntityPathConfig( classes, - ResultSinkType.Csv(fileFormat = fileFormat) + ResultSinkType.Csv(fileFormat = fileFormat), ), - createDirs = true + createDirs = true, ) def createDir( @@ -113,7 +113,7 @@ class ResultEventListenerSpec val fileHierarchy = resultFileHierarchy(1, ".csv") Await.ready( Future.sequence(createDir(fileHierarchy)), - 60 seconds + 60 seconds, ) // after the creation of the listener, it is expected that a corresponding raw result data file is present @@ -122,7 +122,7 @@ class ResultEventListenerSpec classOf[PvResult], fail( s"Cannot get filepath for raw result file of class '${classOf[PvResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ) @@ -162,7 +162,7 @@ class ResultEventListenerSpec classOf[PvResult], fail( s"Cannot get filepath for raw result file of class '${classOf[PvResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ) @@ -170,7 +170,7 @@ class ResultEventListenerSpec awaitCond( outputFile.exists(), interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) // stop listener so that result is flushed out @@ -180,7 +180,7 @@ class ResultEventListenerSpec awaitCond( getFileLinesLength(outputFile) == 2, interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) val resultFileSource = Source.fromFile(outputFile) @@ -210,7 +210,7 @@ class ResultEventListenerSpec Iterable(dummySwitchResult), Iterable(dummyLineResult), Iterable(dummyTrafo2wResult), - Iterable.empty[PartialTransformer3wResult] + Iterable.empty[PartialTransformer3wResult], ) val outputFiles = Map( @@ -219,7 +219,7 @@ class ResultEventListenerSpec classOf[NodeResult], fail( s"Cannot get filepath for raw result file of class '${classOf[NodeResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ), dummySwitchResultString -> new File( @@ -227,7 +227,7 @@ class ResultEventListenerSpec classOf[SwitchResult], fail( s"Cannot get filepath for raw result file of class '${classOf[SwitchResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ), dummyLineResultDataString -> new File( @@ -235,7 +235,7 @@ class ResultEventListenerSpec classOf[LineResult], fail( s"Cannot get filepath for raw result file of class '${classOf[LineResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ), dummyTrafo2wResultDataString -> new File( @@ -243,16 +243,16 @@ class ResultEventListenerSpec classOf[Transformer2WResult], fail( s"Cannot get filepath for raw result file of class '${classOf[Transformer2WResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) - ) + ), ) // wait until all output files exist (headers are flushed out immediately): awaitCond( outputFiles.values.map(_.exists()).forall(identity), interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) // stop listener so that result is flushed out @@ -262,7 +262,7 @@ class ResultEventListenerSpec awaitCond( !outputFiles.values.exists(file => getFileLinesLength(file) < 2), interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) outputFiles.foreach { case (resultRowString, outputFile) => @@ -291,7 +291,7 @@ class ResultEventListenerSpec Iterable.empty[SwitchResult], Iterable.empty[LineResult], Iterable.empty[Transformer2WResult], - Iterable(partialResult) + Iterable(partialResult), ) "correctly reacts on received results" in { @@ -308,14 +308,14 @@ class ResultEventListenerSpec classOf[Transformer3WResult], fail( s"Cannot get filepath for raw result file of class '${classOf[Transformer3WResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ) /* The result file is created at start up and only contains a head line. */ awaitCond( outputFile.exists(), interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) getFileLinesLength(outputFile) shouldBe 1 @@ -346,7 +346,7 @@ class ResultEventListenerSpec awaitCond( getFileLinesLength(outputFile) == 2, interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) /* Check the result */ val resultFileSource = Source.fromFile(outputFile) @@ -387,16 +387,16 @@ class ResultEventListenerSpec classOf[PvResult], fail( s"Cannot get filepath for raw result file of class '${classOf[PvResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ), - "" + "", ) ) awaitCond( outputFile.exists(), interval = 500.millis, - max = timeoutDuration + max = timeoutDuration, ) // stopping the actor should wait until existing messages within an actor are fully processed @@ -415,10 +415,10 @@ class ResultEventListenerSpec classOf[PvResult], fail( s"Cannot get filepath for raw result file of class '${classOf[PvResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ).exists, - timeoutDuration + timeoutDuration, ) val resultFileSource = Source.fromInputStream( @@ -428,7 +428,7 @@ class ResultEventListenerSpec classOf[PvResult], fail( s"Cannot get filepath for raw result file of class '${classOf[PvResult].getSimpleName}' from outputFileHierarchy!'" - ) + ), ) ) ) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala index 1cfda26aa6..47b14f6aee 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala @@ -57,19 +57,19 @@ class RuntimeEventListenerKafkaSpec deserializer.configure( Map(SCHEMA_REGISTRY_URL_CONFIG -> mockSchemaRegistryUrl).asJava, - false + false, ) override def beforeAll(): Unit = { super.beforeAll() val config = Map[String, AnyRef]( "group.id" -> "test", - "bootstrap.servers" -> kafka.bootstrapServers + "bootstrap.servers" -> kafka.bootstrapServers, ) testConsumer = new KafkaConsumer[Bytes, SimonaEndMessage]( config.asJava, Serdes.Bytes().deserializer(), - deserializer + deserializer, ) testConsumer.assign(topicPartitions.asJava) @@ -93,12 +93,12 @@ class RuntimeEventListenerKafkaSpec linger = 0, runId = runId.toString, schemaRegistryUrl = mockSchemaRegistryUrl, - topic = testTopic.name + topic = testTopic.name, ) - ) + ), ), None, - startDateTimeString + startDateTimeString, ) ) @@ -109,13 +109,13 @@ class RuntimeEventListenerKafkaSpec ("event", "expectedMsg"), ( Done(1800L, 3L, errorInSim = false), - SimonaEndMessage(runId, 1, error = false) + SimonaEndMessage(runId, 1, error = false), ), ( Done(3600L, 3L, errorInSim = true), - SimonaEndMessage(runId, 1, error = true) + SimonaEndMessage(runId, 1, error = true), ), - (Error(errMsg), SimonaEndMessage(runId, -1, error = true)) + (Error(errMsg), SimonaEndMessage(runId, -1, error = true)), ) Then("records can be fetched from Kafka") diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala index 22ef952a8a..a1bad16bde 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.event.listener import org.apache.pekko.actor.testkit.typed.scaladsl.{ ActorTestKit, LoggingTestKit, - ScalaTestWithActorTestKit + ScalaTestWithActorTestKit, } import com.typesafe.config.ConfigValueFactory import edu.ie3.simona.config.SimonaConfig @@ -22,7 +22,7 @@ import edu.ie3.simona.event.RuntimeEvent.{ Initializing, PowerFlowFailed, Ready, - Simulating + Simulating, } import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.TimeUtil @@ -39,7 +39,7 @@ class RuntimeEventListenerSpec // Timeout for LoggingTestKit via TestKitSettings // Log message sometimes seem to take a while until caught by the test kit "org.apache.pekko.actor.testkit.typed.filter-leeway", - ConfigValueFactory.fromAnyRef("30s") + ConfigValueFactory.fromAnyRef("30s"), ) ) with AnyWordSpecLike @@ -62,10 +62,10 @@ class RuntimeEventListenerSpec RuntimeEventListener( SimonaConfig.Simona.Runtime.Listener( None, - None + None, ), Some(eventQueue), - startDateTimeString + startDateTimeString, ) ) @@ -78,7 +78,7 @@ class RuntimeEventListenerSpec Ready(currentTick, duration), Simulating(currentTick, 0), Done(endTick, duration, errorInSim = false), - Error(errMsg) + Error(errMsg), ) for (event <- eventsToQueue) { @@ -113,38 +113,38 @@ class RuntimeEventListenerSpec ( Initializing, Level.INFO, - "Initializing Agents and Services for Simulation ... " + "Initializing Agents and Services for Simulation ... ", ), ( InitComplete(0L), Level.INFO, - s"Initialization complete. (duration: 0h : 0m : 0s )" + s"Initialization complete. (duration: 0h : 0m : 0s )", ), ( Ready(currentTick, 0L), Level.INFO, - s"Switched from 'Simulating' to 'Ready'. Last simulated time: ${calcTime(currentTick)}." + s"Switched from 'Simulating' to 'Ready'. Last simulated time: ${calcTime(currentTick)}.", ), ( Simulating(currentTick, endTick), Level.INFO, - s"Simulating from ${calcTime(currentTick)} until ${calcTime(endTick)}." + s"Simulating from ${calcTime(currentTick)} until ${calcTime(endTick)}.", ), ( CheckWindowPassed(currentTick, 0L), Level.INFO, - s"Simulation until ${calcTime(currentTick)} completed." + s"Simulation until ${calcTime(currentTick)} completed.", ), ( Done(endTick, duration, errorInSim = false), Level.INFO, - s"Simulation completed with \u001b[0;32mSUCCESS (Failed PF: 2)\u001b[0;30m in time step ${calcTime(endTick)}. Total runtime: 3h : 0m : 5s " + s"Simulation completed with \u001b[0;32mSUCCESS (Failed PF: 2)\u001b[0;30m in time step ${calcTime(endTick)}. Total runtime: 3h : 0m : 5s ", ), ( Error(errMsg), Level.ERROR, - errMsg - ) + errMsg, + ), ) events.foreach { case (event, level, msg) => diff --git a/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultHandlingSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultHandlingSpec.scala index 87a13e05e7..997cef986b 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultHandlingSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultHandlingSpec.scala @@ -28,19 +28,19 @@ class ThreeWindingResultHandlingSpec UUID.randomUUID(), Amperes(1d), Degrees(2d), - -5 + -5, ) val mockBResult = PartialTransformer3wResult.PortB( TimeUtil.withDefaults.toZonedDateTime("2021-06-23 20:51:00"), UUID.randomUUID(), Amperes(3d), - Degrees(4d) + Degrees(4d), ) val mockCResult = PartialTransformer3wResult.PortC( TimeUtil.withDefaults.toZonedDateTime("2021-06-23 20:51:00"), UUID.randomUUID(), Amperes(5d), - Degrees(6d) + Degrees(6d), ) "correctly indicate readiness" in { @@ -53,7 +53,7 @@ class ThreeWindingResultHandlingSpec (Some(mockAResult), Some(mockBResult), None, false), (None, Some(mockBResult), Some(mockCResult), false), (Some(mockAResult), None, Some(mockCResult), false), - (Some(mockAResult), Some(mockBResult), Some(mockCResult), true) + (Some(mockAResult), Some(mockBResult), Some(mockCResult), true), ) forAll(cases) { @@ -61,7 +61,7 @@ class ThreeWindingResultHandlingSpec a: Option[PartialTransformer3wResult.PortA], b: Option[PartialTransformer3wResult.PortB], c: Option[PartialTransformer3wResult.PortC], - expected: Boolean + expected: Boolean, ) => val dut = AggregatedTransformer3wResult(a, b, c) @@ -78,14 +78,14 @@ class ThreeWindingResultHandlingSpec (None, None, Some(mockCResult)), (Some(mockAResult), Some(mockBResult), None), (None, Some(mockBResult), Some(mockCResult)), - (Some(mockAResult), None, Some(mockCResult)) + (Some(mockAResult), None, Some(mockCResult)), ) forAll(cases) { ( a: Option[PartialTransformer3wResult.PortA], b: Option[PartialTransformer3wResult.PortB], - c: Option[PartialTransformer3wResult.PortC] + c: Option[PartialTransformer3wResult.PortC], ) => val dut = AggregatedTransformer3wResult(a, b, c) @@ -106,7 +106,7 @@ class ThreeWindingResultHandlingSpec AggregatedTransformer3wResult( Some(resultA), Some(resultB), - Some(resultC) + Some(resultC), ).consolidate match { case Success(consolidated) => consolidated.getTime shouldBe expected.getTime diff --git a/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultTestData.scala b/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultTestData.scala index 579efe228f..d02ab4e5ac 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultTestData.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/ThreeWindingResultTestData.scala @@ -27,21 +27,21 @@ trait ThreeWindingResultTestData { inputModel, Amperes(1d), Degrees(2d), - -5 + -5, ) val resultB: PartialTransformer3wResult.PortB = PartialTransformer3wResult.PortB( time, inputModel, Amperes(3d), - Degrees(4d) + Degrees(4d), ) val resultC: PartialTransformer3wResult.PortC = PartialTransformer3wResult.PortC( time, inputModel, Amperes(5d), - Degrees(6d) + Degrees(6d), ) val expected = new Transformer3WResult( time, @@ -52,6 +52,6 @@ trait ThreeWindingResultTestData { Quantities.getQuantity(4d, StandardUnits.ELECTRIC_CURRENT_ANGLE), Quantities.getQuantity(5d, StandardUnits.ELECTRIC_CURRENT_MAGNITUDE), Quantities.getQuantity(6d, StandardUnits.ELECTRIC_CURRENT_ANGLE), - -5 + -5, ) } diff --git a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala index 39e6aaa368..bbb75ab499 100644 --- a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala +++ b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala @@ -45,15 +45,15 @@ class RunSimonaStandaloneIT .empty() .withValue( "simona.output.base.dir", - ConfigValueFactory.fromAnyRef(testTmpDir) + ConfigValueFactory.fromAnyRef(testTmpDir), ) .withValue( "simona.time.startDateTime", - ConfigValueFactory.fromAnyRef("2011-01-01 00:00:00") + ConfigValueFactory.fromAnyRef("2011-01-01 00:00:00"), ) .withValue( "simona.time.endDateTime", - ConfigValueFactory.fromAnyRef("2011-01-01 02:00:00") + ConfigValueFactory.fromAnyRef("2011-01-01 02:00:00"), ) .withFallback( ConfigFactory @@ -78,7 +78,7 @@ class RunSimonaStandaloneIT val simonaStandaloneSetup = SimonaStandaloneSetup( parsedConfig, resultFileHierarchy, - Some(runtimeEventQueue) + Some(runtimeEventQueue), ) /* run simulation */ @@ -100,7 +100,7 @@ class RunSimonaStandaloneIT // todo implement if valid result handling is implemented val pvResultFileContent = getFileSource( resultFileHierarchy, - classOf[PvResult] + classOf[PvResult], ).getLines().toVector pvResultFileContent.size shouldBe 190 pvResultFileContent.headOption.map( @@ -113,12 +113,12 @@ class RunSimonaStandaloneIT private def getFileSource( resultFileHierarchy: ResultFileHierarchy, - entityClass: Class[_ <: ResultEntity] + entityClass: Class[_ <: ResultEntity], ): BufferedSource = { Source.fromFile( resultFileHierarchy.rawOutputDataFilePaths.getOrElse( entityClass, - fail(s"Unable to get output path for result entity: $entityClass") + fail(s"Unable to get output path for result entity: $entityClass"), ) ) } diff --git a/src/test/scala/edu/ie3/simona/io/file/ResultFileHierarchySpec.scala b/src/test/scala/edu/ie3/simona/io/file/ResultFileHierarchySpec.scala index e871b4ffb7..3b89d418f2 100644 --- a/src/test/scala/edu/ie3/simona/io/file/ResultFileHierarchySpec.scala +++ b/src/test/scala/edu/ie3/simona/io/file/ResultFileHierarchySpec.scala @@ -47,8 +47,8 @@ class ResultFileHierarchySpec runOutputDir, ResultEntityPathConfig( Set(classOf[PvResult]), - ResultSinkType.Csv("csv", "pref", "suff") - ) + ResultSinkType.Csv("csv", "pref", "suff"), + ), ) val runOutputDirWithDate = @@ -95,9 +95,9 @@ class ResultFileHierarchySpec runOutputDir, ResultEntityPathConfig( Set(classOf[PvResult]), - ResultSinkType.Csv("csv", "pref", "suff") + ResultSinkType.Csv("csv", "pref", "suff"), ), - createDirs = true + createDirs = true, ) // check for existence of run output dir diff --git a/src/test/scala/edu/ie3/simona/io/result/ResultEntityCsvSinkSpec.scala b/src/test/scala/edu/ie3/simona/io/result/ResultEntityCsvSinkSpec.scala index 61e5175ebb..aaed7c1d76 100644 --- a/src/test/scala/edu/ie3/simona/io/result/ResultEntityCsvSinkSpec.scala +++ b/src/test/scala/edu/ie3/simona/io/result/ResultEntityCsvSinkSpec.scala @@ -40,7 +40,7 @@ class ResultEntityCsvSinkSpec |pekko.loglevel="DEBUG" |pekko.coordinated-shutdown.phases.actor-system-terminate.timeout = 500s """.stripMargin - ) + ), ) ) with UnitSpec @@ -58,7 +58,7 @@ class ResultEntityCsvSinkSpec ResultEntityCsvSink( outFileName, resultEntityProcessor, - outFileName.endsWith(".gz") + outFileName.endsWith(".gz"), ) resultEntitySink.outfileName shouldBe outFileName @@ -103,7 +103,7 @@ class ResultEntityCsvSinkSpec .single(testText) .map(t => ByteString(t)) .runWith(FileIO.toPath(path, Set(WRITE, TRUNCATE_EXISTING, CREATE))), - 5.seconds + 5.seconds, ) val resultEntityProcessor = new ResultEntityProcessor(classOf[PvResult]) @@ -111,7 +111,7 @@ class ResultEntityCsvSinkSpec val resultEntitySink = ResultEntityCsvSink( outFileName, resultEntityProcessor, - outFileName.endsWith(".gz") + outFileName.endsWith(".gz"), ) // close sink to ensure that everything is written out @@ -152,14 +152,14 @@ class ResultEntityCsvSinkSpec TimeUtil.withDefaults.toZonedDateTime("2020-01-30 17:26:44"), UUID.fromString("e5ac84d3-c7a5-4870-a42d-837920aec9bb"), Quantities.getQuantity(10, StandardUnits.ACTIVE_POWER_IN), - Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN) + Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN), ) val resultEntitySink = ResultEntityCsvSink( outFileName, resultEntityProcessor, - outFileName.endsWith(".gz") + outFileName.endsWith(".gz"), ) resultEntitySink.handleResultEntity(dummyPvResult) @@ -197,14 +197,14 @@ class ResultEntityCsvSinkSpec TimeUtil.withDefaults.toZonedDateTime("2020-01-30 17:26:44"), UUID.fromString("e5ac84d3-c7a5-4870-a42d-837920aec9bb"), Quantities.getQuantity(10, StandardUnits.ACTIVE_POWER_IN), - Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN) + Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN), ) val resultEntitySink = ResultEntityCsvSink( outFileName, resultEntityProcessor, - outFileName.endsWith(".gz") + outFileName.endsWith(".gz"), ) val exception = intercept[ProcessResultEventException] { diff --git a/src/test/scala/edu/ie3/simona/io/result/ResultEntityKafkaSpec.scala b/src/test/scala/edu/ie3/simona/io/result/ResultEntityKafkaSpec.scala index 9edf05b5ee..ed88041bc0 100644 --- a/src/test/scala/edu/ie3/simona/io/result/ResultEntityKafkaSpec.scala +++ b/src/test/scala/edu/ie3/simona/io/result/ResultEntityKafkaSpec.scala @@ -65,19 +65,19 @@ class ResultEntityKafkaSpec deserializer.configure( Map(SCHEMA_REGISTRY_URL_CONFIG -> mockSchemaRegistryUrl).asJava, - false + false, ) override def beforeAll(): Unit = { super.beforeAll() val config = Map[String, AnyRef]( "group.id" -> "test", - "bootstrap.servers" -> kafka.bootstrapServers + "bootstrap.servers" -> kafka.bootstrapServers, ) testConsumer = new KafkaConsumer[Bytes, PlainNodeResult]( config.asJava, Serdes.Bytes().deserializer(), - deserializer + deserializer, ) testConsumer.assign(topicPartitions.asJava) @@ -103,9 +103,9 @@ class ResultEntityKafkaSpec runId, kafka.bootstrapServers, mockSchemaRegistryUrl, - 20 - ) - ) + 20, + ), + ), ) ) ) @@ -115,19 +115,19 @@ class ResultEntityKafkaSpec ZonedDateTime.parse("2021-01-01T00:00:00+01:00[Europe/Berlin]"), UUID.randomUUID(), Quantities.getQuantity(1d, PowerSystemUnits.PU), - Quantities.getQuantity(0d, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(0d, PowerSystemUnits.DEGREE_GEOM), ) val nodeRes2 = new NodeResult( ZonedDateTime.parse("2021-01-01T00:00:00+01:00[Europe/Berlin]"), UUID.randomUUID(), Quantities.getQuantity(0.8d, PowerSystemUnits.PU), - Quantities.getQuantity(15d, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(15d, PowerSystemUnits.DEGREE_GEOM), ) val nodeRes3 = new NodeResult( ZonedDateTime.parse("2021-01-10T00:00:00+01:00[Europe/Berlin]"), UUID.randomUUID(), Quantities.getQuantity(0.75d, PowerSystemUnits.PU), - Quantities.getQuantity(90d, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(90d, PowerSystemUnits.DEGREE_GEOM), ) When("receiving the NodeResults") @@ -136,7 +136,7 @@ class ResultEntityKafkaSpec Iterable.empty, Iterable.empty, Iterable.empty, - Iterable.empty + Iterable.empty, ) Then("records can be fetched from Kafka") @@ -155,7 +155,7 @@ class ResultEntityKafkaSpec nodeRes1.getUuid, nodeRes1.getInputModel, nodeRes1.getvMag().getValue.doubleValue(), - nodeRes1.getvAng().getValue.doubleValue() + nodeRes1.getvAng().getValue.doubleValue(), ) ) records should contain( @@ -165,7 +165,7 @@ class ResultEntityKafkaSpec nodeRes2.getUuid, nodeRes2.getInputModel, nodeRes2.getvMag().getValue.doubleValue(), - nodeRes2.getvAng().getValue.doubleValue() + nodeRes2.getvAng().getValue.doubleValue(), ) ) records should contain( @@ -175,7 +175,7 @@ class ResultEntityKafkaSpec nodeRes3.getUuid, nodeRes3.getInputModel, nodeRes3.getvMag().getValue.doubleValue(), - nodeRes3.getvAng().getValue.doubleValue() + nodeRes3.getvAng().getValue.doubleValue(), ) ) } diff --git a/src/test/scala/edu/ie3/simona/io/result/ResultSinkTypeSpec.scala b/src/test/scala/edu/ie3/simona/io/result/ResultSinkTypeSpec.scala index 66b6986c47..2c93aced13 100644 --- a/src/test/scala/edu/ie3/simona/io/result/ResultSinkTypeSpec.scala +++ b/src/test/scala/edu/ie3/simona/io/result/ResultSinkTypeSpec.scala @@ -22,11 +22,11 @@ class ResultSinkTypeSpec extends UnitSpec { fileFormat = ".csv", filePrefix = "", fileSuffix = "", - isHierarchic = false + isHierarchic = false, ) ), influxDb1x = None, - kafka = None + kafka = None, ) inside(ResultSinkType(conf, "testRun")) { @@ -46,10 +46,10 @@ class ResultSinkTypeSpec extends UnitSpec { SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = "test", port = 1, - url = "localhost/" + url = "localhost/", ) ), - kafka = None + kafka = None, ) val runName = "testRun" @@ -73,9 +73,9 @@ class ResultSinkTypeSpec extends UnitSpec { 12, "00000000-0000-0000-0000-000000000000", "https://reg:123", - "topic" + "topic", ) - ) + ), ) val runName = "testRun" @@ -85,7 +85,7 @@ class ResultSinkTypeSpec extends UnitSpec { runId, bootstrapServers, schemaRegistryUrl, - linger + linger, ) => topicNodeRes shouldBe "topic" runId shouldBe UUID.fromString("00000000-0000-0000-0000-000000000000") @@ -104,17 +104,17 @@ class ResultSinkTypeSpec extends UnitSpec { fileFormat = ".csv", filePrefix = "", fileSuffix = "", - isHierarchic = false + isHierarchic = false, ) ), influxDb1x = Some( SimonaConfig.Simona.Output.Sink.InfluxDb1x( database = "test", port = 1, - url = "localhost" + url = "localhost", ) ), - kafka = None + kafka = None, ) assertThrows[IllegalArgumentException](ResultSinkType(conf, "testRun")) @@ -124,7 +124,7 @@ class ResultSinkTypeSpec extends UnitSpec { val conf = SimonaConfig.Simona.Output.Sink( csv = None, influxDb1x = None, - kafka = None + kafka = None, ) assertThrows[IllegalArgumentException](ResultSinkType(conf, "testRun")) diff --git a/src/test/scala/edu/ie3/simona/io/result/plain/PlainWriterSpec.scala b/src/test/scala/edu/ie3/simona/io/result/plain/PlainWriterSpec.scala index ab3c7a8390..14554d60a5 100644 --- a/src/test/scala/edu/ie3/simona/io/result/plain/PlainWriterSpec.scala +++ b/src/test/scala/edu/ie3/simona/io/result/plain/PlainWriterSpec.scala @@ -43,7 +43,7 @@ class PlainWriterSpec extends UnitSpec with GivenWhenThen { time, inputModelId, vMag, - vAng + vAng, ) When("converting to a plain result") @@ -77,7 +77,7 @@ class PlainWriterSpec extends UnitSpec with GivenWhenThen { eventId, inputModelId, vMag, - vAng + vAng, ) When("converting to a full NodeResult") @@ -91,7 +91,7 @@ class PlainWriterSpec extends UnitSpec with GivenWhenThen { .getvMag() shouldBe Quantities.getQuantity(vMag, PowerSystemUnits.PU) plainResult.getvAng() shouldBe Quantities.getQuantity( vAng, - PowerSystemUnits.DEGREE_GEOM + PowerSystemUnits.DEGREE_GEOM, ) } } diff --git a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala index 0540ed770a..d3a77f3c4a 100644 --- a/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/assets/control/QControlSpec.scala @@ -10,14 +10,14 @@ import edu.ie3.datamodel.models.input.system.characteristic import edu.ie3.datamodel.models.input.system.characteristic.{ CharacteristicPoint, CosPhiP => CosPhiPInput, - QV => QVInput + QV => QVInput, } import edu.ie3.simona.exceptions.QControlException import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.control.QControl.{ CosPhiFixed, CosPhiP, - QV + QV, } import edu.ie3.simona.model.system.Characteristic.XYPair import edu.ie3.simona.test.common.UnitSpec @@ -47,7 +47,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { def createXYPair( d1: Double, - d2: Double + d2: Double, ): XYPair[squants.Dimensionless, squants.Dimensionless] = { XYPair(Each(d1), Each(d2)) } @@ -59,12 +59,12 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { util.Arrays.asList( new CharacteristicPoint[Dimensionless, Dimensionless]( getQuantity(1d, PU), - getQuantity(2d, PU) + getQuantity(2d, PU), ), new CharacteristicPoint[Dimensionless, Dimensionless]( getQuantity(3d, PU), - getQuantity(4d, PU) - ) + getQuantity(4d, PU), + ), ) ) val invalidInput = @@ -90,7 +90,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { Vector( createXYPair(0.0, -1.0), createXYPair(0.5, -0.8), - createXYPair(1.0, -0.2) + createXYPair(1.0, -0.2), ) ) ) @@ -103,7 +103,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { createXYPair(0.9, -1.0), createXYPair(0.95, 0.0), createXYPair(1.05, 0.0), - createXYPair(1.1, 1.0) + createXYPair(1.1, 1.0), ) ) ) @@ -158,7 +158,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { (1.03, 0.375), (1.04, 0.5), (1.05, 0.625), - (1.10, 0.625) + (1.10, 0.625), ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => @@ -196,7 +196,7 @@ class QControlSpec extends UnitSpec with TableDrivenPropertyChecks { (1.08, 0.6), (1.09, 0.8), (1.1, 1.0), - (1.12, 1.0) + (1.12, 1.0), ) forAll(testingPoints) { (v: Double, scaleExpected: Double) => diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 3b73c59dfd..7a86895f74 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, BasicGridWithSwitches, - FiveLinesWithNodes + FiveLinesWithNodes, } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} @@ -66,12 +66,12 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { ) val getLinesAdmittance: ( Map[UUID, Int], - LineModel + LineModel, ) => (Int, Int, Complex, Complex, Complex) = (nodeUuidToIndexMap, line) => GridModel invokePrivate getLinesAdmittanceMethod( nodeUuidToIndexMap, - line + line, ) // result of method call @@ -79,7 +79,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { GridModel invokePrivate buildAssetAdmittanceMatrix( nodeUuidToIndexMap, lines, - getLinesAdmittance + getLinesAdmittance, ) _printAdmittanceMatrixOnMismatch(actualResult, lineAdmittanceMatrix) @@ -94,7 +94,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { GridModel.updateUuidToIndexMap(withClosedSwitches) private val admittanceMatixClosed = GridModel.composeAdmittanceMatrix( withClosedSwitches.nodeUuidToIndexMap, - withClosedSwitches.gridComponents + withClosedSwitches.gridComponents, ) private val withOpenSwitches = createGridCopy() @@ -102,7 +102,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { GridModel.updateUuidToIndexMap(withOpenSwitches) private val admittanceMatrixOpen = GridModel.composeAdmittanceMatrix( withOpenSwitches.nodeUuidToIndexMap, - withOpenSwitches.gridComponents + withOpenSwitches.gridComponents, ) // dimension of admittance matrix with closed switches should be the dimension @@ -120,7 +120,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { .flatMap { switch => Iterable( switch.nodeAUuid -> switch.nodeBUuid, - switch.nodeBUuid -> switch.nodeAUuid + switch.nodeBUuid -> switch.nodeAUuid, ) } .groupMap { case (key, _) => key } { case (_, value) => value } @@ -168,7 +168,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { admittanceMatixClosed.valueAt( iClosed, - jClosed + jClosed, ) shouldBe sumOfAdmittancesOpenSwitches withClue s" at \n\tposition ($iClosed, $jClosed) of the grid with closed switches/" + s"\n\tpositions (${iOpenAll.mkString(",")}) x (${jOpenAll.mkString(",")}) of the grid with open switches" @@ -203,8 +203,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches - ) + switches, + ), ) // get the private method for validation val validateConnectivity: PrivateMethod[Unit] = @@ -231,8 +231,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { adaptedLines, Set(transformer2wModel), Set.empty[Transformer3wModel], - Set.empty[SwitchModel] - ) + Set.empty[SwitchModel], + ), ) // get the private method for validation @@ -259,7 +259,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { "SecondSwitch1", defaultOperationInterval, node1.uuid, - node13.uuid + node13.uuid, ) // add the second switch + enable switches override val switches: Set[SwitchModel] = super.switches + secondSwitch @@ -276,8 +276,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches - ) + switches, + ), ) // get the private method for validation @@ -380,8 +380,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches - ) + switches, + ), ) // update the uuidToIndexMap @@ -431,8 +431,8 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - Set.empty[SwitchModel] - ) + Set.empty[SwitchModel], + ), ) // update the uuidToIndexMap @@ -463,7 +463,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { validTestGridInputModel, gridInputModelTestDataRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) } diff --git a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala index 33d068ed65..c1a3fe9ebf 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/LineSpec.scala @@ -41,7 +41,7 @@ class LineSpec extends UnitSpec with LineInputTestData { Each(0.0013109999999999999d), Each(0.0010680000000000002d), Each(0d), - Each(0.60375d) + Each(0.60375d), ) } @@ -63,7 +63,7 @@ class LineSpec extends UnitSpec with LineInputTestData { lineInputMs10Kv, refSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(validLineModel) { @@ -78,7 +78,7 @@ class LineSpec extends UnitSpec with LineInputTestData { r, x, g, - b + b, ) => uuid shouldBe lineInputMs10Kv.getUuid id shouldBe lineInputMs10Kv.getId @@ -136,7 +136,7 @@ class LineSpec extends UnitSpec with LineInputTestData { "calculate the branch admittance Y_ij of a given line model correctly" in new ValidLineModel { LineModel.yij(validLineModel) shouldBe Complex( 1375.489841204891, - -1120.5363466108497 + -1120.5363466108497, ) } diff --git a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala index 87532ffa3d..140ecec17f 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/NodeInputModelSpec.scala @@ -27,7 +27,7 @@ class NodeInputModelSpec extends UnitSpec with NodeInputTestData { NodeModel( nodeInputNoSlackNs04KvA, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(validNodeModel) { @@ -37,7 +37,7 @@ class NodeInputModelSpec extends UnitSpec with NodeInputTestData { operationInterval, isSlack, vTarget, - voltLvl + voltLvl, ) => uuid shouldBe nodeInputNoSlackNs04KvA.getUuid id shouldBe nodeInputNoSlackNs04KvA.getId diff --git a/src/test/scala/edu/ie3/simona/model/grid/SwitchModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/SwitchModelSpec.scala index 8ed9db9023..be7814fc23 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/SwitchModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/SwitchModelSpec.scala @@ -21,7 +21,7 @@ class SwitchModelSpec extends UnitSpec with DefaultTestData { val switchModel: SwitchModel = SwitchModel( switchInput, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(switchModel) { @@ -30,7 +30,7 @@ class SwitchModelSpec extends UnitSpec with DefaultTestData { id, operationInterval, nodeAUuid, - nodeBUuid + nodeBUuid, ) => uuid should be(switchInput.getUuid) id should be(switchInput.getId) diff --git a/src/test/scala/edu/ie3/simona/model/grid/SystemComponentSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/SystemComponentSpec.scala index 4ff98b2b02..c9668e16d2 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/SystemComponentSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/SystemComponentSpec.scala @@ -70,10 +70,10 @@ object SystemComponentSpec { final case class SystemComponentMock( uuid: UUID = UUID.fromString("94b633a2-dfc0-4c28-acf5-d756150e5cde"), id: String = "SystemComponentMock", - operationInterval: OperationInterval + operationInterval: OperationInterval, ) extends SystemComponent( uuid, id, - operationInterval + operationInterval, ) // concrete implementation for testing } diff --git a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala index 3fe005b09c..4f865f58af 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/Transformer3wModelSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.exceptions.InvalidActionRequestException import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, - PowerFlowCaseC + PowerFlowCaseC, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.input.Transformer3wTestData @@ -42,7 +42,7 @@ class Transformer3wModelSpec transformer3wInput.getType.getTapMax, transformer3wInput.getType.getTapMin, transformer3wInput.getType.getTapNeutr, - transformer3wInput.isAutoTap + transformer3wInput.isAutoTap, ) val transformerModel: Transformer3wModel = @@ -51,7 +51,7 @@ class Transformer3wModelSpec mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(transformerModel) { @@ -70,7 +70,7 @@ class Transformer3wModelSpec r, x, g, - b + b, ) => uuid shouldBe transformer3wInput.getUuid id shouldBe transformer3wInput.getId @@ -93,13 +93,13 @@ class Transformer3wModelSpec val yii: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.A + Transformer3wModel.Transformer3wPort.A, ) yii shouldBe Complex.zero val yjj: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.INTERNAL + Transformer3wModel.Transformer3wPort.INTERNAL, ) implicit val doubleTolerance: Double = 1e-11 yjj.real shouldBe 1.874312e-6 +- doubleTolerance @@ -117,7 +117,7 @@ class Transformer3wModelSpec transformer3wInput.getType.getTapMax, transformer3wInput.getType.getTapMin, transformer3wInput.getType.getTapNeutr, - transformer3wInput.isAutoTap + transformer3wInput.isAutoTap, ) val transformerModel: Transformer3wModel = @@ -126,7 +126,7 @@ class Transformer3wModelSpec mainRefSystemHv, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(transformerModel) { @@ -145,7 +145,7 @@ class Transformer3wModelSpec r, x, g, - b + b, ) => uuid shouldBe transformer3wInput.getUuid id shouldBe transformer3wInput.getId @@ -168,13 +168,13 @@ class Transformer3wModelSpec val yii: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.A + Transformer3wModel.Transformer3wPort.A, ) yii shouldBe Complex.zero val yjj: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.INTERNAL + Transformer3wModel.Transformer3wPort.INTERNAL, ) yjj shouldBe Complex.zero @@ -192,7 +192,7 @@ class Transformer3wModelSpec transformer3wInput.getType.getTapMax, transformer3wInput.getType.getTapMin, transformer3wInput.getType.getTapNeutr, - transformer3wInput.isAutoTap + transformer3wInput.isAutoTap, ) val transformerModel: Transformer3wModel = @@ -201,7 +201,7 @@ class Transformer3wModelSpec mainRefSystemLv, 3, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(transformerModel) { @@ -220,7 +220,7 @@ class Transformer3wModelSpec r, x, g, - b + b, ) => uuid shouldBe transformer3wInput.getUuid id shouldBe transformer3wInput.getId @@ -243,13 +243,13 @@ class Transformer3wModelSpec val yii: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.A + Transformer3wModel.Transformer3wPort.A, ) yii shouldBe Complex.zero val yjj: Complex = Transformer3wModel.y0( transformerModel, - Transformer3wModel.Transformer3wPort.INTERNAL + Transformer3wModel.Transformer3wPort.INTERNAL, ) yjj shouldBe Complex.zero val yij: Complex = Transformer3wModel.yij(transformerModel) @@ -265,7 +265,7 @@ class Transformer3wModelSpec mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelHvTemp: Transformer3wModel = Transformer3wModel( @@ -273,7 +273,7 @@ class Transformer3wModelSpec mainRefSystemHv, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelLvTemp: Transformer3wModel = Transformer3wModel( @@ -281,7 +281,7 @@ class Transformer3wModelSpec mainRefSystemLv, 3, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformerModelEhvTemp.isInOperation shouldBe true @@ -296,7 +296,7 @@ class Transformer3wModelSpec mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelHvTemp: Transformer3wModel = Transformer3wModel( @@ -304,7 +304,7 @@ class Transformer3wModelSpec mainRefSystemHv, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelLvTemp: Transformer3wModel = Transformer3wModel( @@ -312,7 +312,7 @@ class Transformer3wModelSpec mainRefSystemLv, 3, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformerModelEhvTemp.isInOperation shouldBe false @@ -330,7 +330,7 @@ class Transformer3wModelSpec mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelHvTemp: Transformer3wModel = Transformer3wModel( @@ -338,7 +338,7 @@ class Transformer3wModelSpec mainRefSystemHv, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerModelLvTemp: Transformer3wModel = Transformer3wModel( @@ -346,7 +346,7 @@ class Transformer3wModelSpec mainRefSystemLv, 3, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformerModelEhvTemp invokePrivate tapRatio() shouldBe 1.15 @@ -363,7 +363,7 @@ class Transformer3wModelSpec mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformerModel.disable().isSuccess shouldBe true @@ -462,8 +462,8 @@ class Transformer3wModelSpec -8, -0.05d, 0.75d, - -2 - ) /* Limit to min tap (should be -3 limited to -2) */ + -2, + ), /* Limit to min tap (should be -3 limited to -2) */ ) val transformerModel: Transformer3wModel = transformerModelEhv @@ -473,7 +473,7 @@ class Transformer3wModelSpec currentTapPos: Int, vChangeVal: Double, deadBandVal: Double, - expected: Int + expected: Int, ) => { val vChange = Quantities.getQuantity(vChangeVal, PU) @@ -493,19 +493,19 @@ class Transformer3wModelSpec tapPos: Int, yijExpected: Complex, yiiExpected: Complex, - yjjExpected: Complex + yjjExpected: Complex, ) => { transformer.updateTapPos(tapPos) val yijActual = Transformer3wModel.yij(transformer) val yiiActual = Transformer3wModel.y0( transformer, - Transformer3wModel.Transformer3wPort.A + Transformer3wModel.Transformer3wPort.A, ) val yjjActual = Transformer3wModel.y0( transformer, - Transformer3wModel.Transformer3wPort.INTERNAL + Transformer3wModel.Transformer3wPort.INTERNAL, ) /* Remark: This is not really precise. At the moment, double-based calculations do diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index ecaa55b2e5..d7fd3025ff 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -11,7 +11,7 @@ import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, - Transformer2WInput + Transformer2WInput, } import edu.ie3.powerflow.NewtonRaphsonPF import edu.ie3.powerflow.model.NodeData.{PresetData, StateData} @@ -22,7 +22,7 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.{ TapTestData, TransformerTestData, - TransformerTestGrid + TransformerTestGrid, } import edu.ie3.util.quantities.PowerSystemUnits._ import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor4} @@ -51,7 +51,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { noException shouldBe thrownBy { TransformerModel.validateInputModel( unmodifiedTransformerInputModel, - mainRefSystem + mainRefSystem, ) } } @@ -70,7 +70,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { ConnectorPort.B else ConnectorPort.A - } + }, ) val dut: TransformerModel = @@ -78,7 +78,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { inputModel, mainRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(dut) { @@ -96,7 +96,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { r, x, g, - b + b, ) => uuid should be(inputModel.getUuid) id should be(inputModel.getId) @@ -114,7 +114,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { _, _, _, - tapSide + tapSide, ) => _currentTapPos shouldBe 0 tapSide shouldBe ConnectorPort.A @@ -159,7 +159,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { transformerInputTapHv, mainRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformer2w.isInOperation shouldBe true @@ -173,7 +173,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { transformerInputTapHv, mainRefSystem, earlySimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) transformer2w.isInOperation shouldBe false @@ -188,7 +188,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { transformerInputTapHv, mainRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) dut invokePrivate tapRatio() shouldBe 1.0 @@ -260,8 +260,8 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { -8, -0.08d, 0.75d, - -2 - ) /* Limit to min tap (should be -3 limited to -2) */ + -2, + ), /* Limit to min tap (should be -3 limited to -2) */ ) forAll(cases) { @@ -269,7 +269,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { currentTapPos: Int, vChangeVal: Double, deadBandVal: Double, - expected: Int + expected: Int, ) => { val vChange = Quantities.getQuantity(vChangeVal, PU) @@ -278,7 +278,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { transformerModelTapHv.updateTapPos(currentTapPos) transformerModelTapHv.computeDeltaTap( vChange, - deadBand + deadBand, ) shouldBe expected } } @@ -291,7 +291,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { tapPos: Int, yijExpected: Complex, yiiExpected: Complex, - yjjExpected: Complex + yjjExpected: Complex, ) => { val transformer = tapSide match { @@ -355,7 +355,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { tapPos: Int, p: BigDecimal, e: Double, - f: Double + f: Double, ) => { logger.debug( @@ -377,7 +377,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { grid, refSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) gridModel.gridComponents.transformers @@ -386,20 +386,20 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { val admittanceMatrix = GridModel.composeAdmittanceMatrix( nodeUuidToIndexMap, - gridModel.gridComponents + gridModel.gridComponents, ) val operationPoint = Array( PresetData(0, NodeType.SL, Complex.zero), - PresetData(1, NodeType.PQ, Complex(p.doubleValue, 0d)) + PresetData(1, NodeType.PQ, Complex(p.doubleValue, 0d)), ) val powerFlow = new NewtonRaphsonPF( epsilon, maxIterations, admittanceMatrix, - Option.apply(Vector(0, 1)) + Option.apply(Vector(0, 1)), ) val result = powerFlow.calculate(operationPoint, startData) diff --git a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala index ae62893e12..43f4ef8baa 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/ApparentPowerAndHeatSpec.scala @@ -31,7 +31,7 @@ class ApparentPowerAndHeatSpec extends UnitSpec { 50L, Each(1.0d), ConstantState, - FixedRelevantData + FixedRelevantData, ) match { case ApparentPowerAndHeat(p, q, qDot) => p should approximate(Megawatts(0d)) @@ -46,7 +46,7 @@ class ApparentPowerAndHeatSpec extends UnitSpec { 10L, Each(1.0d), ConstantState, - FixedRelevantData + FixedRelevantData, ) match { case ApparentPowerAndHeat(p, q, qDot) => p should approximate(Megawatts(43d)) @@ -63,7 +63,7 @@ object ApparentPowerAndHeatSpec { extends SystemParticipant[ FixedRelevantData.type, ApparentPowerAndHeat, - ConstantState.type + ConstantState.type, ]( UUID.randomUUID(), "ParticipantMock", @@ -71,11 +71,11 @@ object ApparentPowerAndHeatSpec { 1.0, CosPhiFixed(0.97), Kilowatts(42d), - 0.97 + 0.97, ) with ApparentPowerAndHeatParticipant[ FixedRelevantData.type, - ConstantState.type + ConstantState.type, ] { this.enable() @@ -92,7 +92,7 @@ object ApparentPowerAndHeatSpec { override def calculateHeat( tick: Long, modelState: ConstantState.type, - data: CalcRelevantData.FixedRelevantData.type + data: CalcRelevantData.FixedRelevantData.type, ): Power = Megawatts(42d) /** Calculate the active power behaviour of the model @@ -104,7 +104,7 @@ object ApparentPowerAndHeatSpec { */ override protected def calculateActivePower( modelState: ConstantState.type, - data: CalcRelevantData.FixedRelevantData.type + data: CalcRelevantData.FixedRelevantData.type, ): Power = Megawatts(43d) /** @param data @@ -114,11 +114,11 @@ object ApparentPowerAndHeatSpec { */ override def determineFlexOptions( data: CalcRelevantData.FixedRelevantData.type, - lastState: ModelState.ConstantState.type + lastState: ModelState.ConstantState.type, ): FlexibilityMessage.ProvideFlexOptions = ProvideMinMaxFlexOptions.noFlexOption( this.getUuid, - calculateActivePower(ConstantState, data) + calculateActivePower(ConstantState, data), ) /** @param data @@ -132,7 +132,7 @@ object ApparentPowerAndHeatSpec { override def handleControlledPowerChange( data: CalcRelevantData.FixedRelevantData.type, lastState: ModelState.ConstantState.type, - setPower: Power + setPower: Power, ): (ModelState.ConstantState.type, FlexChangeIndicator) = (lastState, FlexChangeIndicator()) } diff --git a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala index b2f153e850..16665692f6 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/FixedFeedInModelSpec.scala @@ -35,7 +35,7 @@ class FixedFeedInModelSpec val simonaConfig: SimonaConfig = createSimonaConfig( LoadModelBehaviour.FIX, - LoadReference.ActivePower(Kilowatts(0.0)) + LoadReference.ActivePower(Kilowatts(0.0)), ) val modelConfig = ConfigUtil .ParticipantConfigUtil( @@ -47,7 +47,7 @@ class FixedFeedInModelSpec fixedFeedInput, modelConfig, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) inside(actualModel) { @@ -58,7 +58,7 @@ class FixedFeedInModelSpec scalingFactor, qControl, sRated, - cosPhiRated + cosPhiRated, ) => uuid shouldBe fixedFeedInput.getUuid id shouldBe fixedFeedInput.getId diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala index 3ac1dd56bb..ef2e082265 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureLowerBoundaryReached, - HouseTemperatureUpperBoundaryReached + HouseTemperatureUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -39,7 +39,7 @@ class HpModelSpec "expectedRunningState", "expectedActivePower", "expectedInnerTemperature", - "expectedNextThreshold" + "expectedNextThreshold", ), ( HpState( @@ -49,12 +49,12 @@ class HpModelSpec Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(17d)), - None + None, ), true, 95, 15.6, - Some(HouseTemperatureUpperBoundaryReached(31711L)) + Some(HouseTemperatureUpperBoundaryReached(31711L)), ), ( HpState( @@ -64,12 +64,12 @@ class HpModelSpec Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(18)), - None + None, ), true, 95, 16.4, - Some(HouseTemperatureUpperBoundaryReached(30642L)) + Some(HouseTemperatureUpperBoundaryReached(30642L)), ), ( HpState( @@ -79,12 +79,12 @@ class HpModelSpec Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(20)), - None + None, ), true, 95, 18.0, - Some(HouseTemperatureUpperBoundaryReached(27771L)) + Some(HouseTemperatureUpperBoundaryReached(27771L)), ), ( HpState( @@ -94,12 +94,12 @@ class HpModelSpec Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(22)), - None + None, ), false, 0, 19.6, - Some(HouseTemperatureLowerBoundaryReached(13200L)) + Some(HouseTemperatureLowerBoundaryReached(13200L)), ), ( HpState( @@ -109,12 +109,12 @@ class HpModelSpec Kilowatts(0d), Kilowatts(0d), thermalState(Celsius(23)), - None + None, ), false, 0, 20.4, - Some(HouseTemperatureLowerBoundaryReached(15508L)) + Some(HouseTemperatureLowerBoundaryReached(15508L)), ), ( HpState( @@ -124,12 +124,12 @@ class HpModelSpec Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(17)), - None + None, ), true, 95, 15.6, - Some(HouseTemperatureUpperBoundaryReached(31711L)) + Some(HouseTemperatureUpperBoundaryReached(31711L)), ), ( HpState( @@ -139,12 +139,12 @@ class HpModelSpec Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(18)), - None + None, ), true, 95, 16.4, - Some(HouseTemperatureUpperBoundaryReached(30642L)) + Some(HouseTemperatureUpperBoundaryReached(30642L)), ), ( HpState( @@ -154,12 +154,12 @@ class HpModelSpec Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(20)), - None + None, ), true, 95, 18.0, - Some(HouseTemperatureUpperBoundaryReached(27771L)) + Some(HouseTemperatureUpperBoundaryReached(27771L)), ), ( HpState( @@ -169,12 +169,12 @@ class HpModelSpec Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(22)), - None + None, ), true, 95, 19.6, - Some(HouseTemperatureUpperBoundaryReached(23200L)) + Some(HouseTemperatureUpperBoundaryReached(23200L)), ), ( HpState( @@ -184,13 +184,13 @@ class HpModelSpec Kilowatts(95d), Kilowatts(80d), thermalState(Celsius(25)), - None + None, ), false, 0, 22.0, - Some(HouseTemperatureLowerBoundaryReached(19200L)) - ) + Some(HouseTemperatureLowerBoundaryReached(19200L)), + ), ) forAll(cases) { @@ -199,7 +199,7 @@ class HpModelSpec expectedRunningState, expectedActivePower, expectedInnerTemperature, - expectedNextThreshold + expectedNextThreshold, ) => val data = hpData val house = thermalHouse(18, 22) @@ -214,7 +214,7 @@ class HpModelSpec activePower, _, ThermalGridState(Some(thermalHouseState), _), - maybeThreshold + maybeThreshold, ) => isRunning shouldBe expectedRunningState activePower should approximate(Kilowatts(expectedActivePower)) @@ -245,16 +245,16 @@ class HpModelSpec ThermalHouseState( 0L, Celsius(21), - Kilowatts(80) + Kilowatts(80), ) ), Some( ThermalStorageState( 0L, KilowattHours(20), - Kilowatts(0) + Kilowatts(0), ) - ) + ), ) val lastState = HpState( isRunning = true, @@ -263,7 +263,7 @@ class HpModelSpec Kilowatts(95.0), Kilowatts(80.0), thermalState, - Some(HouseTemperatureUpperBoundaryReached(7995L)) + Some(HouseTemperatureUpperBoundaryReached(7995L)), ) hp.determineFlexOptions(relevantData, lastState) match { @@ -271,7 +271,7 @@ class HpModelSpec modelUuid, referencePower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe hp.uuid referencePower should approximate(Kilowatts(95.0)) diff --git a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala index 0f4569ada4..561b6a6074 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelTestData.scala @@ -11,7 +11,7 @@ import edu.ie3.datamodel.models.input.system.`type`.HpTypeInput import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.input.thermal.{ ThermalBusInput, - ThermalHouseInput + ThermalHouseInput, } import edu.ie3.datamodel.models.input.{NodeInput, OperatorInput} import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils @@ -24,7 +24,7 @@ import edu.ie3.simona.model.thermal.{ CylindricalThermalStorage, ThermalGrid, ThermalHouse, - ThermalStorage + ThermalStorage, } import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval @@ -48,7 +48,7 @@ trait HpModelTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - 2 + 2, ) protected val hpTypeInput = new HpTypeInput( @@ -58,7 +58,7 @@ trait HpModelTestData { Quantities.getQuantity(200d, PowerSystemUnits.EURO_PER_MEGAWATTHOUR), Quantities.getQuantity(100, PowerSystemUnits.KILOVOLTAMPERE), 0.95, - Quantities.getQuantity(15, PowerSystemUnits.KILOWATT) + Quantities.getQuantity(15, PowerSystemUnits.KILOWATT), ) protected val hpInputModel = new HpInput( @@ -69,7 +69,7 @@ trait HpModelTestData { nodeInput, thermalBus, new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), - hpTypeInput + hpTypeInput, ) protected def hpModel(thermalGrid: ThermalGrid) = new HpModel( @@ -81,16 +81,16 @@ trait HpModelTestData { Kilowatts(100d), 0.95, Kilowatts(15d), - thermalGrid + thermalGrid, ) protected def thermalGrid( thermalHouse: ThermalHouse, - thermalStorage: Option[ThermalStorage] = None + thermalStorage: Option[ThermalStorage] = None, ): ThermalGrid = ThermalGrid( Some(thermalHouse), - thermalStorage + thermalStorage, ) private val thermHouseUuid: UUID = @@ -101,7 +101,7 @@ trait HpModelTestData { protected def thermalHouse( lowerTemperatureBoundary: Double, - upperTemperatureBoundary: Double + upperTemperatureBoundary: Double, ): ThermalHouse = ThermalHouse( new ThermalHouseInput( thermHouseUuid, @@ -111,10 +111,10 @@ trait HpModelTestData { Quantities.getQuantity(10.0, StandardUnits.HEAT_CAPACITY), Quantities.getQuantity( (lowerTemperatureBoundary + upperTemperatureBoundary) / 2.0, - Units.CELSIUS + Units.CELSIUS, ), Quantities.getQuantity(upperTemperatureBoundary, Units.CELSIUS), - Quantities.getQuantity(lowerTemperatureBoundary, Units.CELSIUS) + Quantities.getQuantity(lowerTemperatureBoundary, Units.CELSIUS), ) ) @@ -127,21 +127,21 @@ trait HpModelTestData { KilowattHours(20d), KilowattHours(500d), Kilowatts(10d), - KilowattHours(0d) + KilowattHours(0d), ) protected def thermalState( temperature: Temperature, - qDot: Power = Kilowatts(0d) + qDot: Power = Kilowatts(0d), ): ThermalGridState = ThermalGridState( Some( ThermalHouseState( 0L, temperature, - qDot + qDot, ) ), - None + None, ) protected def hpData: HpRelevantData = diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala index 3d83e05bec..358090b0a3 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/EvcsModelSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.model.participant.FlexChangeIndicator import edu.ie3.simona.model.participant.evcs.EvcsModel.{ EvcsRelevantData, EvcsState, - ScheduleEntry + ScheduleEntry, } import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.test.common.UnitSpec @@ -45,7 +45,7 @@ class EvcsModelSpec "configured as a charging hub" in { val evcsModel = evcsStandardModel.copy( strategy = ChargingStrategy.CONSTANT_POWER, - locationType = EvcsLocationType.CHARGING_HUB_TOWN + locationType = EvcsLocationType.CHARGING_HUB_TOWN, ) val evModel = EvModelWrapper( @@ -56,16 +56,16 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 20.0.asKiloWattHour, 5.0.asKiloWattHour, - 10800L + 10800L, ) ) val actualSchedule = evcsModel.calculateNewScheduling( EvcsRelevantData( 3600L, - Seq.empty + Seq.empty, ), - Seq(evModel) + Seq(evModel), ) actualSchedule shouldBe Map( @@ -78,7 +78,7 @@ class EvcsModelSpec "configured as a home cs with constant power strategy" in { val evcsModel = evcsStandardModel.copy( strategy = ChargingStrategy.CONSTANT_POWER, - locationType = EvcsLocationType.HOME + locationType = EvcsLocationType.HOME, ) val evModel = EvModelWrapper( @@ -89,16 +89,16 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 20.0.asKiloWattHour, 15.0.asKiloWattHour, - 10800L + 10800L, ) ) val actualSchedule = evcsModel.calculateNewScheduling( EvcsRelevantData( 3600L, - Seq.empty + Seq.empty, ), - Seq(evModel) + Seq(evModel), ) actualSchedule shouldBe Map( @@ -123,7 +123,7 @@ class EvcsModelSpec "chargeEnd", "lastCalcTick", "power", - "expectedStored" + "expectedStored", ), // charging ends before currentTick (0.0, 0L, 2700L, 0L, 5.0, 3.75), @@ -142,7 +142,7 @@ class EvcsModelSpec (0.0, 0L, 7200L, 0L, 2.5, 2.5), (0.0, 900L, 7200L, 0L, 5.0, 3.75), (2.5, 0L, 7200L, 1800L, 5.0, 5.0), - (2.5, 0L, 7200L, 2700L, 5.0, 3.75) + (2.5, 0L, 7200L, 2700L, 5.0, 3.75), ) forAll(cases) { @@ -152,7 +152,7 @@ class EvcsModelSpec chargeEnd, lastCalcTick, power, - expectedStored + expectedStored, ) => val ev = EvModelWrapper( new MockEvModel( @@ -162,7 +162,7 @@ class EvcsModelSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, storedEnergy.asKiloWattHour, - 7200L // is ignored here + 7200L, // is ignored here ) ) @@ -172,12 +172,12 @@ class EvcsModelSpec val state = EvcsState( Seq(ev), Map(ev.uuid -> entry), - lastCalcTick + lastCalcTick, ) val actualOutput = evcsModel.applySchedule( state, - currentTick + currentTick, ) actualOutput should have size 1 @@ -213,13 +213,13 @@ class EvcsModelSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 0d.asKiloWattHour, - 10800L + 10800L, ) ) val schedule = SortedSet( ScheduleEntry(3600L, 5400L, Kilowatts(2d)), - ScheduleEntry(7200L, 9000L, Kilowatts(4d)) + ScheduleEntry(7200L, 9000L, Kilowatts(4d)), ) // tick, p in kW @@ -229,7 +229,7 @@ class EvcsModelSpec (3600L, 2d), (5400L, 0d), (7200L, 4d), - (9000L, 0d) + (9000L, 0d), ) val cases = Table( @@ -237,7 +237,7 @@ class EvcsModelSpec "lastTick", "currentTick", "firstResultIndex", - "lastResultIndex" + "lastResultIndex", ), (1800L, 10800L, 0, 5), (3600L, 10000L, 1, 5), @@ -247,7 +247,7 @@ class EvcsModelSpec (5400L, 9001L, 2, 5), (5400L, 8999L, 2, 4), (8999L, 9000L, 3, 4), - (8999L, 9060L, 3, 5) + (8999L, 9060L, 3, 5), ) forAll(cases) { @@ -255,19 +255,19 @@ class EvcsModelSpec lastTick, currentTick, firstResultIndex, - lastResultIndex + lastResultIndex, ) => val lastState = EvcsState( Seq(ev), Map(ev.uuid -> schedule), - lastTick + lastTick, ) val (actualEvResults, actualEvcsResults) = evcsStandardModel.createResults( lastState, currentTick, - Each(1d) + Each(1d), ) val (_, firstPower) = generalEvResults(firstResultIndex) @@ -307,7 +307,7 @@ class EvcsModelSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 0d.asKiloWattHour, - 18000L + 18000L, ) ) @@ -319,14 +319,14 @@ class EvcsModelSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 0d.asKiloWattHour, - 18000L + 18000L, ) ) val schedule1 = SortedSet( ScheduleEntry(3600L, 7200L, Kilowatts(2d)), - ScheduleEntry(9000L, 14400L, Kilowatts(3d)) + ScheduleEntry(9000L, 14400L, Kilowatts(3d)), ) val schedule2 = SortedSet( @@ -339,14 +339,14 @@ class EvcsModelSpec val lastState = EvcsState( Seq(ev1, ev2), Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), - lastTick + lastTick, ) val (actualEvResults, actualEvcsResults) = evcsStandardModel.createResults( lastState, currentTick, - Each(1d) + Each(1d), ) // tick, p in kW, soc in % @@ -355,7 +355,7 @@ class EvcsModelSpec (1800L, 0d, 0d), (3600L, 2d, 0d), (7200L, 0d, 20d), - (9000L, 3d, 20d) + (9000L, 3d, 20d), ) // tick, p in kW, soc in % @@ -363,7 +363,7 @@ class EvcsModelSpec Seq( (1800L, 0d, 0d), (5400L, 2d, 0d), - (9000L, 0d, 20d) + (9000L, 0d, 20d), ) // tick, p in kW @@ -373,7 +373,7 @@ class EvcsModelSpec (3600L, 2d), (5400L, 4d), (7200L, 2d), - (9000L, 3d) + (9000L, 3d), ) actualEvResults should have size expectedEv1Results.size + expectedEv2Results.size @@ -420,7 +420,7 @@ class EvcsModelSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 0d.asKiloWattHour, - 7200L // equals the current tick + 7200L, // equals the current tick ) ) @@ -434,14 +434,14 @@ class EvcsModelSpec val lastState = EvcsState( Seq(ev), Map(ev.uuid -> schedule), - lastTick + lastTick, ) val (actualEvResults, actualEvcsResults) = evcsStandardModel.createResults( lastState, currentTick, - Each(1d) + Each(1d), ) // tick, p in kW, soc in % @@ -451,14 +451,14 @@ class EvcsModelSpec (3600L, 2d, 0d), // this result normally does not appear // if EV does not depart at current tick - (7200L, 0d, 20d) + (7200L, 0d, 20d), ) // tick, p in kW val expectedEvcsResults = Seq( (1800L, 0d), - (3600L, 2d) + (3600L, 2d), ) actualEvResults should have size expectedEvResults.size @@ -494,7 +494,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty + Seq.empty, ) val cases = Table( @@ -504,7 +504,7 @@ class EvcsModelSpec "lastPower2", "expectedPRef", "expectedPMin", - "expectedPMax" + "expectedPMax", ), /* 1: empty */ @@ -557,7 +557,7 @@ class EvcsModelSpec // 2: almost full (12.5 kWh) (10.0, 5.0, 5.0, 1.25, -15.0, 5.0), // 2: full (set) - (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) + (10.0, 15.0, 0.0, 0.0, -15.0, 0.0), ) forAll(cases) { @@ -567,7 +567,7 @@ class EvcsModelSpec lastPower2, expectedPRef, expectedPMin, - expectedPMax + expectedPMax, ) => // stays one more hour val ev1 = EvModelWrapper( @@ -578,7 +578,7 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 10.0.asKiloWattHour, lastStored1.asKiloWattHour, - 10800L + 10800L, ) ) @@ -596,7 +596,7 @@ class EvcsModelSpec 10.0.asKiloWatt, // DC is not 15.0.asKiloWattHour, lastStored2.asKiloWattHour, - 14400L + 14400L, ) ) @@ -610,14 +610,14 @@ class EvcsModelSpec EvcsState( Seq(ev1, ev2), Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), - 0L - ) + 0L, + ), ) match { case ProvideMinMaxFlexOptions( modelUuid, refPower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsModel.getUuid refPower should approximate(Kilowatts(expectedPRef)) @@ -636,7 +636,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty + Seq.empty, ) val cases = Table( @@ -646,7 +646,7 @@ class EvcsModelSpec "lastPower2", "expectedPRef", "expectedPMin", - "expectedPMax" + "expectedPMax", ), /* 1: empty */ @@ -699,7 +699,7 @@ class EvcsModelSpec // 2: almost full (charged to 12.5 kWh) (10.0, 5.0, 5.0, 5.0, -15.0, 5.0), // 2: full (set to 15 kWh) - (10.0, 15.0, 0.0, 0.0, -15.0, 0.0) + (10.0, 15.0, 0.0, 0.0, -15.0, 0.0), ) forAll(cases) { @@ -709,7 +709,7 @@ class EvcsModelSpec lastPower2, expectedPRef, expectedPMin, - expectedPMax + expectedPMax, ) => val ev1 = EvModelWrapper( new MockEvModel( @@ -719,7 +719,7 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 10.0.asKiloWattHour, lastStored1.asKiloWattHour, - 10800L + 10800L, ) ) @@ -735,7 +735,7 @@ class EvcsModelSpec 10.0.asKiloWatt, // DC is not 15.0.asKiloWattHour, lastStored2.asKiloWattHour, - 10800L + 10800L, ) ) @@ -748,14 +748,14 @@ class EvcsModelSpec EvcsState( Seq(ev1, ev2), Map(ev1.uuid -> schedule1, ev2.uuid -> schedule2), - 0L - ) + 0L, + ), ) match { case ProvideMinMaxFlexOptions( modelUuid, refPower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsModel.getUuid refPower should approximate(Kilowatts(expectedPRef)) @@ -769,14 +769,14 @@ class EvcsModelSpec "disallowing v2g" in { val evcsModel = evcsStandardModel.copy( vehicle2grid = false, - strategy = ChargingStrategy.CONSTANT_POWER + strategy = ChargingStrategy.CONSTANT_POWER, ) val currentTick = 7200L val data = EvcsRelevantData( currentTick, - Seq.empty + Seq.empty, ) val ev1 = EvModelWrapper( @@ -787,7 +787,7 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 10.0.asKiloWattHour, 0.0.asKiloWattHour, - 10800L + 10800L, ) ) @@ -800,14 +800,14 @@ class EvcsModelSpec EvcsState( Seq(ev1), Map(ev1.uuid -> schedule1), - 0L - ) + 0L, + ), ) match { case ProvideMinMaxFlexOptions( modelUuid, refPower, minPower, - maxPower + maxPower, ) => modelUuid shouldBe evcsModel.getUuid refPower should approximate(Kilowatts(5.0)) // one hour left @@ -828,7 +828,7 @@ class EvcsModelSpec val data = EvcsRelevantData( currentTick, - Seq.empty + Seq.empty, ) val cases = Table( @@ -839,7 +839,7 @@ class EvcsModelSpec "expPowerAndTick1", "expPowerAndTick2", "expNextActivation", - "expNextTick" + "expNextTick", ), /* setPower is 0 kWh */ @@ -882,7 +882,7 @@ class EvcsModelSpec (10.0, 8.0, -15.0, S(-10.0, 6480L), S(-5.0, 7200L), true, S(6480L)), (10.0, 5.5, -15.0, S(-10.0, 6480L), S(-5.0, 5400L), true, S(5400L)), (10.0, 15.0, -15.0, S(-10.0, 6480L), S(-5.0, 10800L), true, S(6480L)), - (7.0, 10.5, -15.0, S(-10.0, 5400L), S(-5.0, 9000L), false, S(5400L)) + (7.0, 10.5, -15.0, S(-10.0, 5400L), S(-5.0, 9000L), false, S(5400L)), ) forAll(cases) { @@ -893,7 +893,7 @@ class EvcsModelSpec expPowerAndTick1: Option[(Double, Long)], expPowerAndTick2: Option[(Double, Long)], expNextActivation: Boolean, - expNextTick: Option[Long] + expNextTick: Option[Long], ) => val ev1 = EvModelWrapper( new MockEvModel( @@ -903,7 +903,7 @@ class EvcsModelSpec 20.0.asKiloWatt, // DC is not 10.0.asKiloWattHour, stored1.asKiloWattHour, - 7200L + 7200L, ) ) @@ -915,7 +915,7 @@ class EvcsModelSpec 10.0.asKiloWatt, // DC is not 15.0.asKiloWattHour, stored2.asKiloWattHour, - 10800L + 10800L, ) ) @@ -924,13 +924,13 @@ class EvcsModelSpec EvcsState( Seq(ev1, ev2), Map.empty, - 0L + 0L, ), - Kilowatts(setPower) + Kilowatts(setPower), ) match { case ( EvcsState(actualEvs, actualSchedules, actualTick), - FlexChangeIndicator(actualNextActivation, actualNextTick) + FlexChangeIndicator(actualNextActivation, actualNextTick), ) => // evs have not changed here since no schedules were given as input actualEvs should have size 2 @@ -944,7 +944,7 @@ class EvcsModelSpec ( entry.chargingPower.toKilowatts, - entry.tickStop + entry.tickStop, ) } shouldBe expPowerAndTick1 actualSchedules.get(ev2.uuid).map { entries => @@ -955,7 +955,7 @@ class EvcsModelSpec ( entry.chargingPower.toKilowatts, - entry.tickStop + entry.tickStop, ) } shouldBe expPowerAndTick2 diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala index 6b8612ae00..59209ce259 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/ConstantPowerChargingSpec.scala @@ -35,13 +35,13 @@ class ConstantPowerChargingSpec 10.0.asKiloWatt, 20.0.asKiloWattHour, 20.0.asKiloWattHour, - 3600L + 3600L, ) ) val actualSchedule = evcsModel.chargeWithConstantPower( 1800L, - Seq(ev) + Seq(ev), ) actualSchedule shouldBe Map.empty @@ -61,7 +61,7 @@ class ConstantPowerChargingSpec (1800L, 5.0, 5.0), // more than max power, limited (3600L, 5.0, 5.0), // exactly max power (7200L, 5.0, 2.5), // less than max power - (180000L, 5.0, 0.1) // long stay: 100 hours + (180000L, 5.0, 0.1), // long stay: 100 hours ) forAll(cases) { (stayingTicks, storedEnergy, expectedPower) => @@ -73,13 +73,13 @@ class ConstantPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, storedEnergy.asKiloWattHour, - offset + stayingTicks + offset + stayingTicks, ) ) val chargingMap = evcsModel.chargeWithConstantPower( offset, - Seq(ev) + Seq(ev), ) chargingMap shouldBe Map( @@ -87,7 +87,7 @@ class ConstantPowerChargingSpec ScheduleEntry( offset, offset + stayingTicks, - Kilowatts(expectedPower) + Kilowatts(expectedPower), ) ) ) @@ -109,7 +109,7 @@ class ConstantPowerChargingSpec (1800L, 5.0, 5.0), // more than max power, limited (3600L, 5.0, 5.0), // exactly max power (7200L, 5.0, 2.5), // less than max power - (180000L, 5.0, 0.1) // long stay: 100 hours + (180000L, 5.0, 0.1), // long stay: 100 hours ) forAll(cases) { (stayingTicks, storedEnergy, expectedPower) => @@ -121,7 +121,7 @@ class ConstantPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 5.0.asKiloWattHour, - offset + 3600L + offset + 3600L, ) ) @@ -133,13 +133,13 @@ class ConstantPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, storedEnergy.asKiloWattHour, - offset + stayingTicks + offset + stayingTicks, ) ) val chargingMap = evcsModel.chargeWithConstantPower( offset, - Seq(givenEv, ev) + Seq(givenEv, ev), ) chargingMap shouldBe Map( @@ -147,16 +147,16 @@ class ConstantPowerChargingSpec ScheduleEntry( offset, offset + 3600L, - Kilowatts(5.0) + Kilowatts(5.0), ) ), ev.uuid -> SortedSet( ScheduleEntry( offset, offset + stayingTicks, - Kilowatts(expectedPower) + Kilowatts(expectedPower), ) - ) + ), ) } diff --git a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala index af1dbf6000..a53b82981e 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/evcs/uncontrolled/MaximumPowerChargingSpec.scala @@ -35,13 +35,13 @@ class MaximumPowerChargingSpec 10.0.asKiloWatt, 20.0.asKiloWattHour, 20.0.asKiloWattHour, - 3600 + 3600, ) ) val actualSchedule = evcsModel.chargeWithMaximumPower( 1800L, - Seq(ev) + Seq(ev), ) actualSchedule shouldBe Map.empty @@ -59,7 +59,7 @@ class MaximumPowerChargingSpec // half full battery (1800L, 5.0, 1800L), // stay shorter than full (3600L, 5.0, 3600L), // exactly full - (14400L, 5.0, 3600L) // full before end of stay + (14400L, 5.0, 3600L), // full before end of stay ) forAll(cases) { (stayingTicks, storedEnergy, expectedDuration) => @@ -71,13 +71,13 @@ class MaximumPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, storedEnergy.asKiloWattHour, - offset + stayingTicks + offset + stayingTicks, ) ) val chargingMap = evcsModel.chargeWithMaximumPower( offset, - Seq(ev) + Seq(ev), ) chargingMap shouldBe Map( @@ -85,7 +85,7 @@ class MaximumPowerChargingSpec ScheduleEntry( offset, offset + expectedDuration, - ev.sRatedAc + ev.sRatedAc, ) ) ) @@ -105,7 +105,7 @@ class MaximumPowerChargingSpec // half full battery (1800L, 5.0, 1800L), // stay shorter than full (3600L, 5.0, 3600L), // exactly full - (14400L, 5.0, 3600L) // full before end of stay + (14400L, 5.0, 3600L), // full before end of stay ) forAll(cases) { (stayingTicks, storedEnergy, expectedDuration) => @@ -117,7 +117,7 @@ class MaximumPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, 5.0.asKiloWattHour, - offset + 3600L + offset + 3600L, ) ) @@ -129,13 +129,13 @@ class MaximumPowerChargingSpec 10.0.asKiloWatt, 10.0.asKiloWattHour, storedEnergy.asKiloWattHour, - offset + stayingTicks + offset + stayingTicks, ) ) val chargingMap = evcsModel.chargeWithMaximumPower( offset, - Seq(givenEv, ev) + Seq(givenEv, ev), ) chargingMap shouldBe Map( @@ -143,16 +143,16 @@ class MaximumPowerChargingSpec ScheduleEntry( offset, offset + 3600L, - Kilowatts(5.0) + Kilowatts(5.0), ) ), ev.uuid -> SortedSet( ScheduleEntry( offset, offset + expectedDuration, - Kilowatts(5.0) + Kilowatts(5.0), ) - ) + ), ) } diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index c419b884cf..351cb6630d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -18,7 +18,7 @@ import edu.ie3.simona.model.participant.ModelState.ConstantState import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, - EnergyConsumption + EnergyConsumption, } import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.model.participant.load.random.RandomLoadModel @@ -59,20 +59,20 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), - 0.95 + 0.95, ) val foreSeenOperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - profileLoadInput.getOperationTime + profileLoadInput.getOperationTime, ) val targetEnergyConsumption = KilowattHours(3000d) @@ -83,7 +83,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "profile", BdewStandardLoadProfile.H0, BdewStandardLoadProfile.L0, - BdewStandardLoadProfile.G0 + BdewStandardLoadProfile.G0, ) ) { profile => val model = ProfileLoadModel( @@ -101,7 +101,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ), profileLoadInput.getCosPhiRated, profile, - EnergyConsumption(targetEnergyConsumption) + EnergyConsumption(targetEnergyConsumption), ) model.enable() @@ -113,7 +113,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { calculateEnergyDiffForYear( model, simulationStartDate, - targetEnergyConsumption + targetEnergyConsumption, ) should be < Percent(2d) } } @@ -137,14 +137,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, - EnergyConsumption(targetEnergyConsumption) + EnergyConsumption(targetEnergyConsumption), ) model.enable() calculateEnergyDiffForYear( model, simulationStartDate, - expectedEnergy + expectedEnergy, ) should be < Percent(2d) } @@ -156,7 +156,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { "profile", BdewStandardLoadProfile.H0, BdewStandardLoadProfile.L0, - BdewStandardLoadProfile.G0 + BdewStandardLoadProfile.G0, ) ) { profile => val model = ProfileLoadModel( @@ -174,13 +174,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ), profileLoadInput.getCosPhiRated, profile, - ActivePower(targetMaximumPower) + ActivePower(targetMaximumPower), ) model.enable() val maximumPower = calculatePowerForYear( model, - simulationStartDate + simulationStartDate, ).maxOption.value implicit val tolerance: Power = Watts(1d) @@ -207,13 +207,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { ), profileLoadInput.getCosPhiRated, BdewStandardLoadProfile.H0, - ActivePower(targetMaximumPower) + ActivePower(targetMaximumPower), ) model.enable() val maximumPower = calculatePowerForYear( model, - simulationStartDate + simulationStartDate, ).maxOption.value implicit val tolerance: Power = Watts(1.5d) @@ -237,20 +237,20 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), - 0.95 + 0.95, ) val foreSeenOperationInterval = SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - randomLoadInput.getOperationTime + randomLoadInput.getOperationTime, ) val targetEnergyConsumption = KilowattHours(3000d) @@ -270,14 +270,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue ), randomLoadInput.getCosPhiRated, - EnergyConsumption(targetEnergyConsumption) + EnergyConsumption(targetEnergyConsumption), ) model.enable() calculateEnergyDiffForYear( model, simulationStartDate, - targetEnergyConsumption + targetEnergyConsumption, ) should be < Percent(1d) } @@ -299,14 +299,14 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue ), randomLoadInput.getCosPhiRated, - EnergyConsumption(targetEnergyConsumption) + EnergyConsumption(targetEnergyConsumption), ) model.enable() calculateEnergyDiffForYear( model, simulationStartDate, - expectedEnergy + expectedEnergy, ) should be < Percent(2d) } @@ -326,20 +326,20 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue ), randomLoadInput.getCosPhiRated, - ActivePower(targetMaximumPower) + ActivePower(targetMaximumPower), ) model.enable() val powers = calculatePowerForYear( model, - simulationStartDate + simulationStartDate, ).toIndexedSeq.sorted.toArray val quantile95 = RandomLoadModelSpec.get95Quantile(powers) getRelativeDifference( quantile95, - targetMaximumPower + targetMaximumPower, ) should be < Percent(1d) } @@ -361,13 +361,13 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue ), randomLoadInput.getCosPhiRated, - ActivePower(targetMaximumPower) + ActivePower(targetMaximumPower), ) model.enable() val powers = calculatePowerForYear( model, - simulationStartDate + simulationStartDate, ).toIndexedSeq.sorted.toArray /* Tolerance is equivalent to 10 W difference between the 95%-percentile of the obtained random results and the @@ -382,26 +382,26 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { def calculateEnergyDiffForYear[C <: LoadRelevantData]( model: LoadModel[C], simulationStartDate: ZonedDateTime, - expectedEnergy: Energy + expectedEnergy: Energy, ): Dimensionless = { val duration = Minutes(15d) val avgEnergy = calculatePowerForYear( model: LoadModel[C], - simulationStartDate: ZonedDateTime + simulationStartDate: ZonedDateTime, ).foldLeft(KilowattHours(0)) { case (energySum, power) => energySum + (power * duration) } getRelativeDifference( avgEnergy, - expectedEnergy + expectedEnergy, ) } def calculatePowerForYear[C <: LoadRelevantData]( model: LoadModel[C], - simulationStartDate: ZonedDateTime + simulationStartDate: ZonedDateTime, ): Iterable[Power] = { val quarterHoursInYear = 365L * 96L @@ -417,7 +417,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { tick, Each(0d), ConstantState, - relevantData + relevantData, ) .p } @@ -433,7 +433,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { def getRelativeDifference[Q <: Quantity[Q]]( actualResult: Q, - expectedResult: Q + expectedResult: Q, ): Dimensionless = Each((expectedResult - actualResult).abs / expectedResult) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala index d22eb65b07..8129394a54 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelSpec.scala @@ -33,12 +33,12 @@ class LoadModelSpec ("reference", "sRated"), ( LoadReference.ActivePower(Watts(268.6)), - Watts(282.7368421052632) + Watts(282.7368421052632), ), ( LoadReference.EnergyConsumption(KilowattHours(3000.0)), - Watts(848.2105263157896) - ) + Watts(848.2105263157896), + ), ) forAll(params) { @@ -48,7 +48,7 @@ class LoadModelSpec loadInput, defaultOperationInterval, foreSeenScalingFactor, - foreSeenReference + foreSeenReference, ) inside(actual) { case ProfileLoadModel( @@ -60,7 +60,7 @@ class LoadModelSpec sRated, cosPhiRated, loadProfile, - reference + reference, ) => uuid shouldBe loadInput.getUuid id shouldBe loadInput.getId @@ -82,12 +82,12 @@ class LoadModelSpec ("reference", "sRated"), ( LoadReference.ActivePower(Watts(268.6)), - Watts(311.0105263157895) + Watts(311.0105263157895), ), ( LoadReference.EnergyConsumption(KilowattHours(3000.0)), - Watts(770.8076055515501) - ) + Watts(770.8076055515501), + ), ) forAll(params) { @@ -97,7 +97,7 @@ class LoadModelSpec loadInput, defaultOperationInterval, foreSeenScalingFactor, - foreSeenReference + foreSeenReference, ) inside(actual) { case RandomLoadModel( @@ -108,7 +108,7 @@ class LoadModelSpec qControl, sRated, cosPhiRated, - reference + reference, ) => uuid shouldBe loadInput.getUuid id shouldBe loadInput.getId diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala index 5b20449de8..d8ca0da750 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadProfileStoreSpec.scala @@ -12,7 +12,7 @@ import edu.ie3.datamodel.models.profile.StandardLoadProfile import edu.ie3.simona.model.participant.load.profile.{ LoadProfileKey, LoadProfileStore, - TypeDayProfile + TypeDayProfile, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -48,30 +48,30 @@ class LoadProfileStoreSpec ( "2019-04-01T05:00:00+02:00[Europe/Berlin]", L0, - 55.6d + 55.6d, ), // Weekday, transitional, 20th quarter hour ( "2019-06-02T00:00:00+02:00[Europe/Berlin]", G0, - 68.8d + 68.8d, ), // Sunday, summer, 0th quarter hour ( "2019-01-05T02:15:00+01:00[Europe/Berlin]", H0, - 52.8d + 52.8d, ), // Saturday, winter, 9th quarter hour, 5th day -> dynamization factor 1.2473 ( "2019-07-21T01:00:00+02:00[Europe/Berlin]", H0, - 58.1d - ) // Sunday, summer, 4th quarter hour, 202nd day -> dynamization factor 0.7847 + 58.1d, + ), // Sunday, summer, 4th quarter hour, 202nd day -> dynamization factor 0.7847 ) forAll(params) { ( timestamp: String, loadProfile: StandardLoadProfile, - paramValue: Double + paramValue: Double, ) => val time = ZonedDateTime.parse(timestamp) val param = Watts(paramValue) @@ -86,7 +86,7 @@ class LoadProfileStoreSpec ("profile", "maxParamValue"), (H0, 268.6d), (L0, 240.4d), - (G0, 240.4d) + (G0, 240.4d), ) forAll(maxParams) { @@ -110,7 +110,7 @@ class LoadProfileStoreSpec H0 -> KilowattHours(1000.0), L0 -> KilowattHours(1002.0), /* TODO: Check, if this is correct */ - G0 -> KilowattHours(1022.0) + G0 -> KilowattHours(1022.0), ) /* Collect all available time steps in 2020 */ diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala index 948ec4ce80..a66aac0a78 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/ProfileLoadModelSpec.scala @@ -15,7 +15,7 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, - EnergyConsumption + EnergyConsumption, } import edu.ie3.simona.model.participant.load.profile.ProfileLoadModel import edu.ie3.simona.test.common.UnitSpec @@ -48,14 +48,14 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), - 0.95 + 0.95, ) val simulationStartDate = @@ -66,7 +66,7 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - loadInput.getOperationTime + loadInput.getOperationTime, ) "instantiating it" should { @@ -77,46 +77,46 @@ class ProfileLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { ( BdewStandardLoadProfile.H0, ActivePower(Watts(268.6)), - Watts(282.74d) + Watts(282.74d), ), ( BdewStandardLoadProfile.H0, EnergyConsumption( KilowattHours(3000d) ), - Watts(848.22d) + Watts(848.22d), ), ( BdewStandardLoadProfile.L0, ActivePower(Watts(268.6)), - Watts(282.74d) + Watts(282.74d), ), ( BdewStandardLoadProfile.L0, EnergyConsumption( KilowattHours(3000d) ), - Watts(759.158d) + Watts(759.158d), ), ( BdewStandardLoadProfile.G0, ActivePower(Watts(268.6)), - Watts(282.74d) + Watts(282.74d), ), ( BdewStandardLoadProfile.G0, EnergyConsumption( KilowattHours(3000d) ), - Watts(759.158d) - ) + Watts(759.158d), + ), ) ) { (profile, reference, expectedSRated) => val actual = ProfileLoadModel( loadInput.copy().loadprofile(profile).build(), foreSeenOperationInterval, 1.0, - reference + reference, ) actual.sRated should approximate(expectedSRated) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala index 497812c662..393657f9d8 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadModelSpec.scala @@ -17,11 +17,11 @@ import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.control.QControl import edu.ie3.simona.model.participant.load.LoadReference.{ ActivePower, - EnergyConsumption + EnergyConsumption, } import edu.ie3.simona.model.participant.load.random.{ RandomLoadModel, - RandomLoadParameters + RandomLoadParameters, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -51,14 +51,14 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ), new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), BdewStandardLoadProfile.H0, false, Quantities.getQuantity(3000d, PowerSystemUnits.KILOWATTHOUR), Quantities.getQuantity(282.74d, PowerSystemUnits.VOLTAMPERE), - 0.95 + 0.95, ) val simulationStartDate = @@ -69,7 +69,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - loadInput.getOperationTime + loadInput.getOperationTime, ) "instantiating it" should { @@ -78,7 +78,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { val testData = Table( ("reference", "expectedSRated"), (ActivePower(Watts(268.6)), Watts(311.0105263157895d)), - (EnergyConsumption(KilowattHours(2000d)), Watts(513.871737d)) + (EnergyConsumption(KilowattHours(2000d)), Watts(513.871737d)), ) forAll(testData) { (reference, expectedSRated: Power) => @@ -86,7 +86,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { loadInput, foreSeenOperationInterval, 1.0, - reference + reference, ) actual.sRated should approximate(expectedSRated) @@ -110,7 +110,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { .doubleValue() ), loadInput.getCosPhiRated, - ActivePower(Watts(268.6)) + ActivePower(Watts(268.6)), ) /* Working day, 61th quarter hour */ val queryDate = @@ -118,7 +118,7 @@ class RandomLoadModelSpec extends UnitSpec with TableDrivenPropertyChecks { val expectedParams = new RandomLoadParameters( 0.405802458524704, 0.0671483352780342, - 0.0417016632854939 + 0.0417016632854939, ) /* First query leeds to generation of distribution */ diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadParamStoreSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadParamStoreSpec.scala index 2bbe997702..7af564121a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadParamStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/RandomLoadParamStoreSpec.scala @@ -11,7 +11,7 @@ import java.io.InputStreamReader import edu.ie3.simona.model.participant.load.random.{ RandomLoadParamStore, RandomLoadParameters, - TypeDayParameters + TypeDayParameters, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -40,25 +40,25 @@ class RandomLoadParamStoreSpec "sigmaSa", "sigmaSu", "sigmaWd", - "quarterHour" + "quarterHour", ) ) val expected = Map( DayType.weekday -> Map( RandomLoadParameters.K -> 2, RandomLoadParameters.MY -> 5, - RandomLoadParameters.SIGMA -> 8 + RandomLoadParameters.SIGMA -> 8, ), DayType.saturday -> Map( RandomLoadParameters.K -> 0, RandomLoadParameters.MY -> 3, - RandomLoadParameters.SIGMA -> 6 + RandomLoadParameters.SIGMA -> 6, ), DayType.sunday -> Map( RandomLoadParameters.K -> 1, RandomLoadParameters.MY -> 4, - RandomLoadParameters.SIGMA -> 7 - ) + RandomLoadParameters.SIGMA -> 7, + ), ) actual shouldBe expected @@ -91,31 +91,31 @@ class RandomLoadParamStoreSpec RandomLoadParameters( 0.146539300680161, 0.0430354326963425, - 0.0201929099857807 - ) + 0.0201929099857807, + ), ), // Weekday ( "2019-06-02 00:00:00", RandomLoadParameters( 0.295997023582459, 0.0630703344941139, - 0.0370676517486572 - ) + 0.0370676517486572, + ), ), // Sunday ( "2019-01-05 02:15:00", RandomLoadParameters( 0.132398754358292, 0.0439879409968853, - 0.0208074823021889 - ) - ) // Saturday + 0.0208074823021889, + ), + ), // Saturday ) forAll(params) { ( timestamp: String, - expected: RandomLoadParameters + expected: RandomLoadParameters, ) => val time = TimeUtil.withDefaults.toZonedDateTime(timestamp) randomParameterStore.parameters(time) shouldBe expected diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/TypeDayParametersSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/TypeDayParametersSpec.scala index e8af1101ba..4f0a119297 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/TypeDayParametersSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/TypeDayParametersSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.model.participant.load import edu.ie3.simona.model.participant.load.random.{ RandomLoadParameters, - TypeDayParameters + TypeDayParameters, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.TimeUtil @@ -21,7 +21,7 @@ class TypeDayParametersSpec extends UnitSpec { RandomLoadParameters( cnt.toDouble, (cnt + 1).toDouble, - (cnt + 2).toDouble + (cnt + 2).toDouble, ) ) .toArray @@ -37,7 +37,7 @@ class TypeDayParametersSpec extends UnitSpec { RandomLoadParameters( cnt.toDouble, (cnt + 1).toDouble, - (cnt + 2).toDouble + (cnt + 2).toDouble, ) ) .toArray diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala index efe070abae..e4c1c14c70 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala @@ -83,11 +83,11 @@ class ThermalGridSpec extends UnitSpec { "deliver proper results" in { val energyDemand1 = ThermalEnergyDemand( MegawattHours(45d), - MegawattHours(47d) + MegawattHours(47d), ) val energyDemand2 = ThermalEnergyDemand( MegawattHours(23d), - MegawattHours(28d) + MegawattHours(28d), ) val totalDemand = energyDemand1 + energyDemand2 diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala index bbcaa52207..a7af090fb6 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridTestData.scala @@ -19,7 +19,7 @@ trait ThermalGridTestData { UUID.randomUUID(), "Thermal Bus", OperatorInput.NO_OPERATOR_ASSIGNED, - OperationTime.notLimited() + OperationTime.notLimited(), ) protected val testGridambientTemperature: Temperature = Celsius(12d) protected val testGridQDotInfeed: Power = Kilowatts(15d) diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala index 5a09e20c34..6955b3c705 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -11,12 +11,12 @@ import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureLowerBoundaryReached, - HouseTemperatureUpperBoundaryReached + HouseTemperatureUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.{ StorageEmpty, - StorageFull + StorageFull, } import edu.ie3.simona.test.common.UnitSpec import squants.energy._ @@ -41,13 +41,13 @@ class ThermalGridWithHouseAndStorageSpec new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set(thermalHouseInput).asJava, - Set[ThermalStorageInput](thermalStorageInput).asJava + Set[ThermalStorageInput](thermalStorageInput).asJava, ) ThermalGrid(thermalGridInput) match { case ThermalGrid( Some(thermalHouseGenerated), - Some(thermalStorageGenerated) + Some(thermalStorageGenerated), ) => thermalHouseGenerated shouldBe thermalHouse thermalStorageGenerated shouldBe thermalStorage @@ -62,7 +62,7 @@ class ThermalGridWithHouseAndStorageSpec new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set(thermalHouseInput).asJava, - Set[ThermalStorageInput](thermalStorageInput).asJava + Set[ThermalStorageInput](thermalStorageInput).asJava, ) ) @@ -73,7 +73,7 @@ class ThermalGridWithHouseAndStorageSpec Some(ThermalHouseState(houseTick, innerTemperature, qDotHouse)), Some( ThermalStorageState(storageTick, storedEnergy, qDotStorage) - ) + ), ) => houseTick shouldBe expectedHouseStartingState.tick storageTick shouldBe expectedHouseStartingState.tick @@ -99,7 +99,7 @@ class ThermalGridWithHouseAndStorageSpec val gridDemand = thermalGrid.energyDemand( tick, testGridambientTemperature, - ThermalGrid.startingState(thermalGrid) + ThermalGrid.startingState(thermalGrid), ) gridDemand.required should approximate(KilowattHours(0d)) @@ -119,7 +119,7 @@ class ThermalGridWithHouseAndStorageSpec startingState.houseState.map( _.copy(innerTemperature = Celsius(16d)) ) - ) + ), ) gridDemand.required should approximate(KilowattHours(0d)) @@ -137,7 +137,7 @@ class ThermalGridWithHouseAndStorageSpec startingState.houseState.map( _.copy(innerTemperature = Celsius(3d)) ) - ) + ), ) gridDemand.required should approximate(KilowattHours(8.64987499999)) gridDemand.possible should approximate(KilowattHours(1418.64987499999)) @@ -166,7 +166,7 @@ class ThermalGridWithHouseAndStorageSpec tick, testGridambientTemperature, gridState, - externalQDot + externalQDot, ) updatedGridState match { @@ -174,7 +174,7 @@ class ThermalGridWithHouseAndStorageSpec _, Some( ThermalStorageState(storageTick, storedEnergy, qDotStorage) - ) + ), ) => storageTick shouldBe 0L storedEnergy should approximate(initialLoading) @@ -202,7 +202,7 @@ class ThermalGridWithHouseAndStorageSpec tick, testGridambientTemperature, gridState, - externalQDot + externalQDot, ) updatedGridState match { @@ -210,7 +210,7 @@ class ThermalGridWithHouseAndStorageSpec Some(ThermalHouseState(houseTick, innerTemperature, qDotHouse)), Some( ThermalStorageState(storageTick, storedEnergy, qDotStorage) - ) + ), ) => houseTick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -240,9 +240,9 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - zeroInflux + zeroInflux, ), - None + None, ) ) val maybeStorageState = None @@ -254,7 +254,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), None, testGridambientTemperature, - testGridQDotConsumption + testGridQDotConsumption, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => maybeRevisedHouseState shouldBe maybeHouseState @@ -273,9 +273,9 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - zeroInflux + zeroInflux, ), - None + None, ) ) val maybeStorageState = Some( @@ -283,9 +283,9 @@ class ThermalGridWithHouseAndStorageSpec ThermalStorageState( tick, KilowattHours(50d), - zeroInflux + zeroInflux, ), - None + None, ) ) @@ -296,7 +296,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, - zeroInflux + zeroInflux, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => maybeRevisedHouseState shouldBe maybeHouseState @@ -315,9 +315,9 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - testGridQDotInfeed + testGridQDotInfeed, ), - Some(HouseTemperatureUpperBoundaryReached(3600L)) + Some(HouseTemperatureUpperBoundaryReached(3600L)), ) ) val maybeStorageState = Some( @@ -325,9 +325,9 @@ class ThermalGridWithHouseAndStorageSpec ThermalStorageState( tick, KilowattHours(50d), - zeroInflux + zeroInflux, ), - None + None, ) ) @@ -338,7 +338,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, - testGridQDotInfeed + testGridQDotInfeed, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => maybeRevisedHouseState shouldBe maybeHouseState @@ -357,9 +357,9 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - zeroInflux + zeroInflux, ), - Some(HouseTemperatureLowerBoundaryReached(tick)) + Some(HouseTemperatureLowerBoundaryReached(tick)), ) ) val maybeStorageState = Some( @@ -367,9 +367,9 @@ class ThermalGridWithHouseAndStorageSpec ThermalStorageState( tick, KilowattHours(50d), - testGridQDotInfeed + testGridQDotInfeed, ), - Some(StorageEmpty(tick)) + Some(StorageEmpty(tick)), ) ) @@ -380,7 +380,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, - zeroInflux + zeroInflux, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => maybeRevisedHouseState shouldBe maybeHouseState @@ -399,9 +399,9 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - zeroInflux + zeroInflux, ), - Some(HouseTemperatureLowerBoundaryReached(tick)) + Some(HouseTemperatureLowerBoundaryReached(tick)), ) ) val maybeStorageState = Some( @@ -409,9 +409,9 @@ class ThermalGridWithHouseAndStorageSpec ThermalStorageState( tick, KilowattHours(250d), - testGridQDotInfeed + testGridQDotInfeed, ), - None + None, ) ) val formerHouseState = Some( @@ -423,14 +423,14 @@ class ThermalGridWithHouseAndStorageSpec .getValue .doubleValue ), - zeroInflux + zeroInflux, ) ) val formerStorageState = Some( ThermalStorageState( 0L, KilowattHours(300d), - Kilowatts(-50d) + Kilowatts(-50d), ) ) @@ -441,21 +441,21 @@ class ThermalGridWithHouseAndStorageSpec formerHouseState, formerStorageState, ambientTemperature, - zeroInflux + zeroInflux, ) match { case ( Some( ( ThermalHouseState(houseTick, _, revisedQDotHouse), - Some(HouseTemperatureUpperBoundaryReached(houseColdTick)) + Some(HouseTemperatureUpperBoundaryReached(houseColdTick)), ) ), Some( ( ThermalStorageState(storageTick, _, revisedQDotStorage), - Some(StorageEmpty(storageEmptyTick)) + Some(StorageEmpty(storageEmptyTick)), ) - ) + ), ) => houseTick shouldBe tick storageTick shouldBe tick @@ -488,7 +488,7 @@ class ThermalGridWithHouseAndStorageSpec tick, testGridambientTemperature, initialGridState, - externalQDot + externalQDot, ) updatedGridState match { @@ -496,7 +496,7 @@ class ThermalGridWithHouseAndStorageSpec Some(ThermalHouseState(houseTick, innerTemperature, qDotHouse)), Some( ThermalStorageState(storageTick, storedEnergy, qDotStorage) - ) + ), ) => houseTick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -533,7 +533,7 @@ class ThermalGridWithHouseAndStorageSpec tick, testGridambientTemperature, gridState, - externalQDot + externalQDot, ) updatedGridState match { @@ -541,7 +541,7 @@ class ThermalGridWithHouseAndStorageSpec Some(ThermalHouseState(houseTick, innerTemperature, qDotHouse)), Some( ThermalStorageState(storageTick, storedEnergy, qDotStorage) - ) + ), ) => houseTick shouldBe 0L innerTemperature should approximate(Celsius(20.99999167d)) diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala index 4869a65df2..ac96c4c541 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseState import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureLowerBoundaryReached, - HouseTemperatureUpperBoundaryReached + HouseTemperatureUpperBoundaryReached, } import edu.ie3.simona.test.common.UnitSpec import squants.energy.{Kilowatts, Megawatts, WattHours, Watts} @@ -32,7 +32,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set(thermalHouseInput).asJava, - Set.empty[ThermalStorageInput].asJava + Set.empty[ThermalStorageInput].asJava, ) ThermalGrid(thermalGridInput) match { @@ -49,7 +49,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set(thermalHouseInput).asJava, - Set.empty[ThermalStorageInput].asJava + Set.empty[ThermalStorageInput].asJava, ) ) @@ -58,7 +58,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { ThermalGrid.startingState(thermalGrid) match { case ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, thermalInfeed)), - None + None, ) => tick shouldBe expectedHouseStartingState.tick innerTemperature should approximate( @@ -77,13 +77,13 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { val houseDemand = thermalHouse.energyDemand( tick, testGridambientTemperature, - expectedHouseStartingState + expectedHouseStartingState, ) val gridDemand = thermalGrid.energyDemand( tick, testGridambientTemperature, - ThermalGrid.startingState(thermalGrid) + ThermalGrid.startingState(thermalGrid), ) gridDemand.required should approximate(houseDemand.required) @@ -107,13 +107,13 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { tick, testGridambientTemperature, gridState, - externalQDot + externalQDot, ) updatedGridState match { case ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -134,13 +134,13 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { tick, testGridambientTemperature, gridState, - testGridQDotConsumption + testGridQDotConsumption, ) updatedGridState match { case ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -168,13 +168,13 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { tick, testGridambientTemperature, gridState, - testGridQDotInfeed + testGridQDotInfeed, ) updatedGridState match { case ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -193,14 +193,14 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridambientTemperature, - testGridQDotInfeed + testGridQDotInfeed, ) match { case ( ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ), - Some(HouseTemperatureUpperBoundaryReached(thresholdTick)) + Some(HouseTemperatureUpperBoundaryReached(thresholdTick)), ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -215,14 +215,14 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridambientTemperature, - testGridQDotConsumption + testGridQDotConsumption, ) match { case ( ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ), - Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) + Some(HouseTemperatureLowerBoundaryReached(thresholdTick)), ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) @@ -237,14 +237,14 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridambientTemperature, - Megawatts(0d) + Megawatts(0d), ) match { case ( ThermalGridState( Some(ThermalHouseState(tick, innerTemperature, qDot)), - None + None, ), - Some(HouseTemperatureLowerBoundaryReached(thresholdTick)) + Some(HouseTemperatureLowerBoundaryReached(thresholdTick)), ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala index 5476321e2d..fe4276909f 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -8,13 +8,13 @@ package edu.ie3.simona.model.thermal import edu.ie3.datamodel.models.input.thermal.{ ThermalHouseInput, - ThermalStorageInput + ThermalStorageInput, } import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.{ StorageEmpty, - StorageFull + StorageFull, } import edu.ie3.simona.test.common.UnitSpec import squants.energy._ @@ -37,7 +37,7 @@ class ThermalGridWithStorageOnlySpec new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set.empty[ThermalHouseInput].asJava, - Set[ThermalStorageInput](thermalStorageInput).asJava + Set[ThermalStorageInput](thermalStorageInput).asJava, ) ThermalGrid(thermalGridInput) match { @@ -54,7 +54,7 @@ class ThermalGridWithStorageOnlySpec new edu.ie3.datamodel.models.input.container.ThermalGrid( thermalBusInput, Set.empty[ThermalHouseInput].asJava, - Set[ThermalStorageInput](thermalStorageInput).asJava + Set[ThermalStorageInput](thermalStorageInput).asJava, ) ) @@ -63,7 +63,7 @@ class ThermalGridWithStorageOnlySpec ThermalGrid.startingState(thermalGrid) match { case ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ) => tick shouldBe expectedStorageStartingState.tick storedEnergy should approximate( @@ -83,7 +83,7 @@ class ThermalGridWithStorageOnlySpec val gridDemand = thermalGrid.energyDemand( tick, testGridambientTemperature, - ThermalGrid.startingState(thermalGrid) + ThermalGrid.startingState(thermalGrid), ) gridDemand.required should approximate(MegawattHours(0d)) @@ -106,7 +106,7 @@ class ThermalGridWithStorageOnlySpec ThermalStorageState( 0L, KilowattHours(430d), - Kilowatts(0d) + Kilowatts(0d), ) ) ) @@ -116,13 +116,13 @@ class ThermalGridWithStorageOnlySpec tick, testGridambientTemperature, gridState, - testGridQDotConsumptionHigh + testGridQDotConsumptionHigh, ) updatedGridState match { case ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ) => tick shouldBe 0L storedEnergy should approximate(KilowattHours(430d)) @@ -148,13 +148,13 @@ class ThermalGridWithStorageOnlySpec tick, testGridambientTemperature, gridState, - testGridQDotInfeed + testGridQDotInfeed, ) updatedGridState match { case ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ) => tick shouldBe 0L storedEnergy should approximate(KilowattHours(230d)) @@ -171,7 +171,7 @@ class ThermalGridWithStorageOnlySpec 0L, ThermalGrid.startingState(thermalGrid), testGridambientTemperature, - testGridQDotInfeed + testGridQDotInfeed, ) nextThreshold shouldBe Some(StorageFull(220800L)) @@ -179,7 +179,7 @@ class ThermalGridWithStorageOnlySpec updatedState match { case ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ) => tick shouldBe 0L storedEnergy should approximate(KilowattHours(230d)) @@ -198,19 +198,19 @@ class ThermalGridWithStorageOnlySpec ThermalStorageState( 0L, KilowattHours(430d), - Kilowatts(0d) + Kilowatts(0d), ) ) ), testGridambientTemperature, - testGridQDotConsumptionHigh + testGridQDotConsumptionHigh, ) match { case ( ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ), - Some(StorageEmpty(thresholdTick)) + Some(StorageEmpty(thresholdTick)), ) => tick shouldBe 0L storedEnergy should approximate(KilowattHours(430d)) @@ -225,15 +225,15 @@ class ThermalGridWithStorageOnlySpec 0L, ThermalGrid.startingState(thermalGrid), testGridambientTemperature, - Kilowatts(0d) + Kilowatts(0d), ) updatedState match { case ( ThermalGridState( None, - Some(ThermalStorageState(tick, storedEnergy, qDot)) + Some(ThermalStorageState(tick, storedEnergy, qDot)), ), - None + None, ) => tick shouldBe 0L storedEnergy should approximate(KilowattHours(230d)) diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseTestData.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseTestData.scala index 78b186296d..2b12dab681 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseTestData.scala @@ -25,7 +25,7 @@ trait ThermalHouseTestData extends ThermalGridTestData { getQuantity(15.0, StandardUnits.HEAT_CAPACITY), getQuantity(19d, Units.CELSIUS), getQuantity(21d, Units.CELSIUS), - getQuantity(18d, Units.CELSIUS) + getQuantity(18d, Units.CELSIUS), ) protected val thermalHouse: ThermalHouse = ThermalHouse(thermalHouseInput) @@ -34,6 +34,6 @@ trait ThermalHouseTestData extends ThermalGridTestData { ThermalHouseState( -1L, Celsius(19d), - Megawatts(0d) + Megawatts(0d), ) } diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalStorageTestData.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalStorageTestData.scala index 582ff025cb..b5434bbb17 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalStorageTestData.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalStorageTestData.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.model.thermal import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.thermal.{ CylindricalStorageInput, - ThermalBusInput + ThermalBusInput, } import tech.units.indriya.quantity.Quantities.getQuantity @@ -22,13 +22,13 @@ trait ThermalStorageTestData extends ThermalGridTestData { "ThermalStorage", new ThermalBusInput( UUID.fromString("ad2db5ab-8f90-4bc1-aa2c-30b31b843ab2"), - "TestThermalBus" + "TestThermalBus", ), getQuantity(100, StandardUnits.VOLUME), getQuantity(20, StandardUnits.VOLUME), getQuantity(30, StandardUnits.TEMPERATURE), getQuantity(40, StandardUnits.TEMPERATURE), - getQuantity(1.15, StandardUnits.SPECIFIC_HEAT_CAPACITY) + getQuantity(1.15, StandardUnits.SPECIFIC_HEAT_CAPACITY), ) protected val thermalStorage: CylindricalThermalStorage = diff --git a/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala b/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala index 6602614262..63da1cbfa2 100644 --- a/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala +++ b/src/test/scala/edu/ie3/simona/ontology/messages/flex/MinMaxFlexibilityMessageTest.scala @@ -20,7 +20,7 @@ class MinMaxFlexibilityMessageTest extends UnitSpec { "succeed if there is no flexibility" in { val res = ProvideMinMaxFlexOptions.noFlexOption( modelUuid = UUID.randomUUID(), - power = Watts(1) + power = Watts(1), ) res.ref shouldBe Watts(1) @@ -33,7 +33,7 @@ class MinMaxFlexibilityMessageTest extends UnitSpec { modelUuid = UUID.randomUUID(), ref = Watts(1), min = Watts(0), - max = Watts(2) + max = Watts(2), ) res.ref shouldBe Watts(1) @@ -47,7 +47,7 @@ class MinMaxFlexibilityMessageTest extends UnitSpec { modelUuid = UUID.randomUUID(), ref = Watts(1), min = Watts(2), - max = Watts(2) + max = Watts(2), ) }.getMessage should include("is greater than reference power") } @@ -58,7 +58,7 @@ class MinMaxFlexibilityMessageTest extends UnitSpec { modelUuid = UUID.randomUUID(), ref = Watts(1), min = Watts(1), - max = Watts(0) + max = Watts(0), ) }.getMessage should include("is greater than maximum power") } diff --git a/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala index b2c6dae582..9adb5a707e 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/PhaseSwitchSchedulerSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.scheduler import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.core.PhaseSwitchCore @@ -16,7 +16,7 @@ import edu.ie3.simona.util.ActorUtils.RichActivatedActor import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, - TestProbe + TestProbe, } import org.scalatest.matchers.should import org.scalatest.wordspec.AnyWordSpecLike @@ -145,7 +145,7 @@ class PhaseSwitchSchedulerSpec scheduler ! ScheduleActivation( agent2.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) // waiting for next phase @@ -221,7 +221,7 @@ class PhaseSwitchSchedulerSpec scheduler ! ScheduleActivation( agent1.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) val sa1 = parent.expectMessageType[ScheduleActivation] @@ -230,7 +230,7 @@ class PhaseSwitchSchedulerSpec scheduler ! ScheduleActivation( agent2.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) // TICK -1 @@ -240,7 +240,7 @@ class PhaseSwitchSchedulerSpec agent1.expectActivationAndComplete( scheduler, INIT_SIM_TICK, - Some(0) + Some(0), ) parent.expectNoMessage() @@ -248,7 +248,7 @@ class PhaseSwitchSchedulerSpec agent2.expectActivationAndComplete( scheduler, INIT_SIM_TICK, - Some(0) + Some(0), ) parent.expectMessage(Completion(schedulerActivation, Some(0))) @@ -262,7 +262,7 @@ class PhaseSwitchSchedulerSpec agent1.expectActivationAndComplete( scheduler, 0, - Some(900) + Some(900), ) parent.expectNoMessage() @@ -270,7 +270,7 @@ class PhaseSwitchSchedulerSpec agent2.expectActivationAndComplete( scheduler, 0, - Some(300) + Some(300), ) parent.expectMessage(Completion(schedulerActivation, Some(300))) @@ -281,7 +281,7 @@ class PhaseSwitchSchedulerSpec agent2.expectActivationAndComplete( scheduler, 300, - Some(900) + Some(900), ) parent.expectMessage(Completion(schedulerActivation, Some(900))) @@ -295,7 +295,7 @@ class PhaseSwitchSchedulerSpec agent1.expectActivationAndComplete( scheduler, 900, - Some(3600) + Some(3600), ) parent.expectNoMessage() @@ -303,7 +303,7 @@ class PhaseSwitchSchedulerSpec agent2.expectActivationAndComplete( scheduler, 900, - Some(1800) + Some(1800), ) parent.expectMessage(Completion(schedulerActivation, Some(1800))) @@ -362,7 +362,7 @@ class PhaseSwitchSchedulerSpec agent1.expectActivationAndComplete( scheduler, 900, - Some(1800) + Some(1800), ) parent.expectMessage(Completion(schedulerActivation, Some(1800))) diff --git a/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockIT.scala b/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockIT.scala index af4586e56e..e001a45a8b 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockIT.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockIT.scala @@ -8,11 +8,11 @@ package edu.ie3.simona.scheduler import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, - TestProbe + TestProbe, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.test.common.TestSpawnerTyped @@ -35,17 +35,17 @@ class ScheduleLockIT val parentScheduler = spawn( Scheduler(timeAdvancer.ref), - "parentScheduler" + "parentScheduler", ) val childScheduler = spawn( Scheduler(parentScheduler), - "childScheduler" + "childScheduler", ) // first, we normally schedule some activation for our agent1 childScheduler ! ScheduleActivation( agent1.ref, - 30 + 30, ) val sa1 = timeAdvancer.expectMessageType[ScheduleActivation] sa1.tick shouldBe 30 @@ -63,7 +63,7 @@ class ScheduleLockIT childScheduler ! ScheduleActivation( agent2.ref, 30, - Some(scheduleKey) + Some(scheduleKey), ) // because of activated agents, child/parentScheduler should not be able to complete yet @@ -72,11 +72,11 @@ class ScheduleLockIT // completing agent activations agent1.expectActivationAndComplete( childScheduler, - 30 + 30, ) agent2.expectActivationAndComplete( childScheduler, - 30 + 30, ) timeAdvancer.expectMessage(Completion(lockActivation)) @@ -96,7 +96,7 @@ class ScheduleLockIT // first, we normally schedule some activation childScheduler ! ScheduleActivation( agent.ref, - 30 + 30, ) val sa1 = timeAdvancer.expectMessageType[ScheduleActivation] sa1.tick shouldBe 30 @@ -112,7 +112,7 @@ class ScheduleLockIT // completing the agent activation agent.expectActivationAndComplete( childScheduler, - 30 + 30, ) // because of the lock, parentScheduler should not be able to complete yet @@ -122,7 +122,7 @@ class ScheduleLockIT childScheduler ! ScheduleActivation( agent.ref, 40, - Some(scheduleKey) + Some(scheduleKey), ) timeAdvancer.expectMessage(Completion(lockActivation, Some(40))) diff --git a/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockSpec.scala index e79a4c8c6e..b075c077dd 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/ScheduleLockSpec.scala @@ -8,12 +8,12 @@ package edu.ie3.simona.scheduler import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, - TestProbe + TestProbe, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.test.common.TestSpawnerTyped import org.scalatest.matchers.should diff --git a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala index 072fc80f32..5c610eb18d 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/SchedulerSpec.scala @@ -8,11 +8,11 @@ package edu.ie3.simona.scheduler import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, - TestProbe + TestProbe, } import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock.{LockMsg, ScheduleKey, Unlock} @@ -90,7 +90,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent2.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) // activation is sent right away @@ -159,7 +159,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent1.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) val sa1 = parent.expectMessageType[ScheduleActivation] @@ -168,7 +168,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent2.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) // TICK -1 @@ -177,7 +177,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, INIT_SIM_TICK, - Some(0) + Some(0), ) parent.expectNoMessage() @@ -185,7 +185,7 @@ class SchedulerSpec agent2.expectActivationAndComplete( scheduler, INIT_SIM_TICK, - Some(0) + Some(0), ) parent.expectMessage(Completion(schedulerActivation, Some(0))) @@ -199,7 +199,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, 0, - Some(300) + Some(300), ) parent.expectNoMessage() @@ -207,7 +207,7 @@ class SchedulerSpec agent2.expectActivationAndComplete( scheduler, 0, - Some(900) + Some(900), ) parent.expectMessage(Completion(schedulerActivation, Some(300))) @@ -218,7 +218,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, 300, - Some(900) + Some(900), ) parent.expectMessage(Completion(schedulerActivation, Some(900))) @@ -232,7 +232,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, 900, - Some(3600) + Some(3600), ) parent.expectNoMessage() @@ -240,7 +240,7 @@ class SchedulerSpec agent2.expectActivationAndComplete( scheduler, 900, - Some(1800) + Some(1800), ) parent.expectMessage(Completion(schedulerActivation, Some(1800))) @@ -263,7 +263,7 @@ class SchedulerSpec // send to init activation to scheduler scheduler ! ScheduleActivation( actor.ref, - INIT_SIM_TICK + INIT_SIM_TICK, ) ) @@ -278,7 +278,7 @@ class SchedulerSpec _.expectActivationAndComplete( scheduler, tick, - Some(tick + 1) + Some(tick + 1), ) } @@ -310,7 +310,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent2.ref, 120, - Some(ScheduleKey(lock.ref, key)) + Some(ScheduleKey(lock.ref, key)), ) // no new scheduling when active @@ -338,7 +338,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent1.ref, 60, - Some(ScheduleKey(lock.ref, key)) + Some(ScheduleKey(lock.ref, key)), ) // no new scheduling for same tick @@ -367,7 +367,7 @@ class SchedulerSpec scheduler ! ScheduleActivation( agent1.ref, 59, - Some(ScheduleKey(lock.ref, key)) + Some(ScheduleKey(lock.ref, key)), ) // lock should not receive unlock message by scheduler @@ -378,7 +378,7 @@ class SchedulerSpec ScheduleActivation( schedulerActivation, 59, - Some(ScheduleKey(lock.ref, key)) + Some(ScheduleKey(lock.ref, key)), ) ) } @@ -432,7 +432,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, 900, - Some(1800) + Some(1800), ) parent.expectMessage(Completion(schedulerActivation, Some(1800))) @@ -553,7 +553,7 @@ class SchedulerSpec agent1.expectActivationAndComplete( scheduler, INIT_SIM_TICK, - Some(0) + Some(0), ) parent.expectMessage(Completion(schedulerActivation.ref, Some(0))) diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index d85cf910e5..3ad6cda04a 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.scheduler import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, - TestProbe + TestProbe, } import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import edu.ie3.simona.event.RuntimeEvent @@ -16,7 +16,7 @@ import edu.ie3.simona.event.RuntimeEvent._ import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.scheduler.TimeAdvancer.{StartSimMessage, Stop} import edu.ie3.simona.sim.SimMessage @@ -49,7 +49,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 7200 + 7200, ) ) @@ -199,7 +199,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 3600 + 3600, ) ) @@ -273,7 +273,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 5400 + 5400, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, INIT_SIM_TICK) @@ -361,7 +361,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 3600 + 3600, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, INIT_SIM_TICK) @@ -439,7 +439,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(1800), - 3600 + 3600, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) @@ -489,7 +489,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 3600 + 3600, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) @@ -549,7 +549,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(1800), - 3600 + 3600, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) @@ -599,7 +599,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 1800 + 1800, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) @@ -652,7 +652,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 1800 + 1800, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) @@ -739,7 +739,7 @@ class TimeAdvancerSpec simulation.ref.toClassic, Some(listener.ref), Some(900), - 1800 + 1800, ) ) timeAdvancer ! ScheduleActivation(scheduler.ref, 0) diff --git a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala index 10a1be82c7..5eed45eb46 100644 --- a/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/ev/ExtEvDataServiceSpec.scala @@ -19,7 +19,7 @@ import edu.ie3.simona.model.participant.evcs.EvModelWrapper import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.EvMessage._ import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage @@ -29,7 +29,7 @@ import edu.ie3.simona.service.ev.ExtEvDataService.InitExtEvData import edu.ie3.simona.test.common.{ EvTestData, TestKitWithShutdown, - TestSpawnerClassic + TestSpawnerClassic, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.quantities.PowerSystemUnits @@ -48,7 +48,7 @@ class ExtEvDataServiceSpec .parseString(""" |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel = "INFO" - |""".stripMargin) + |""".stripMargin), ) ) with AnyWordSpecLike @@ -61,7 +61,7 @@ class ExtEvDataServiceSpec private val extEvData = (dataService: ActorRef) => new ExtEvData( dataService, - extSimAdapter.ref + extSimAdapter.ref, ) private val evcs1UUID = @@ -79,7 +79,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extEvData(evService)), key) + SimonaService.Create(InitExtEvData(extEvData(evService)), key), ) scheduler.expectMsg( ScheduleActivation(evService.toTyped, INIT_SIM_TICK, Some(key)) @@ -106,7 +106,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extEvData(evService)), key) + SimonaService.Create(InitExtEvData(extEvData(evService)), key), ) scheduler.expectMsg( ScheduleActivation(evService.toTyped, INIT_SIM_TICK, Some(key)) @@ -130,7 +130,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extEvData(evService)), key) + SimonaService.Create(InitExtEvData(extEvData(evService)), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -161,7 +161,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extEvData(evService)), key) + SimonaService.Create(InitExtEvData(extEvData(evService)), key), ) scheduler.expectMsg( ScheduleActivation(evService.toTyped, INIT_SIM_TICK, Some(key)) @@ -174,7 +174,7 @@ class ExtEvDataServiceSpec assertThrows[ServiceException] { evService.receive( Activation(0), - scheduler.ref + scheduler.ref, ) } @@ -192,7 +192,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -238,8 +238,8 @@ class ExtEvDataServiceSpec evService, FreeLotsResponse( evcs1UUID, - 2 - ) + 2, + ), ) // nothing should happen yet, waiting for second departed ev @@ -249,8 +249,8 @@ class ExtEvDataServiceSpec evService, FreeLotsResponse( evcs2UUID, - 0 - ) + 0, + ), ) // ev service should recognize that all evcs that are expected are returned, @@ -258,7 +258,7 @@ class ExtEvDataServiceSpec awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveTriggerQueue.size() shouldBe 1 // only evcs 1 should be included, the other one is full @@ -278,7 +278,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -302,7 +302,7 @@ class ExtEvDataServiceSpec awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveTriggerQueue.size() shouldBe 1 extData.receiveTriggerQueue.take() shouldBe new ProvideEvcsFreeLots() @@ -319,7 +319,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -337,7 +337,7 @@ class ExtEvDataServiceSpec val departures = Map( evcs1UUID -> List(evA.getUuid).asJava, - evcs2UUID -> List(evB.getUuid).asJava + evcs2UUID -> List(evB.getUuid).asJava, ).asJava extData.sendExtMsg( @@ -369,7 +369,7 @@ class ExtEvDataServiceSpec evcs1.send( evService, - DepartingEvsResponse(evcs1UUID, Seq(EvModelWrapper(updatedEvA))) + DepartingEvsResponse(evcs1UUID, Seq(EvModelWrapper(updatedEvA))), ) // nothing should happen yet, waiting for second departed ev @@ -381,7 +381,7 @@ class ExtEvDataServiceSpec evcs2.send( evService, - DepartingEvsResponse(evcs2UUID, Seq(EvModelWrapper(updatedEvB))) + DepartingEvsResponse(evcs2UUID, Seq(EvModelWrapper(updatedEvB))), ) // ev service should recognize that all evs that are expected are returned, @@ -389,7 +389,7 @@ class ExtEvDataServiceSpec awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveTriggerQueue.size() shouldBe 1 extData.receiveTriggerQueue.take() shouldBe new ProvideDepartingEvs( @@ -408,7 +408,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -434,7 +434,7 @@ class ExtEvDataServiceSpec awaitCond( !extData.receiveTriggerQueue.isEmpty, max = 3.seconds, - message = "No message received" + message = "No message received", ) extData.receiveTriggerQueue.size() shouldBe 1 extData.receiveTriggerQueue.take() shouldBe new ProvideDepartingEvs( @@ -453,7 +453,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -471,7 +471,7 @@ class ExtEvDataServiceSpec val arrivals = Map( evcs1UUID -> List[EvModel](evA).asJava, - evcs2UUID -> List[EvModel](evB).asJava + evcs2UUID -> List[EvModel](evB).asJava, ).asJava extData.sendExtMsg( @@ -516,7 +516,7 @@ class ExtEvDataServiceSpec scheduler.send( evService, - SimonaService.Create(InitExtEvData(extData), key) + SimonaService.Create(InitExtEvData(extData), key), ) scheduler.expectMsgType[ScheduleActivation] @@ -530,7 +530,7 @@ class ExtEvDataServiceSpec val arrivals = Map( evcs1UUID -> List[EvModel](evA).asJava, - evcs2UUID -> List[EvModel](evB).asJava + evcs2UUID -> List[EvModel](evB).asJava, ).asJava extData.sendExtMsg( diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala index 008cc0c1fc..43a64da1ce 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySpec.scala @@ -20,34 +20,34 @@ import edu.ie3.datamodel.models.value.{SValue, Value} import edu.ie3.simona.config.SimonaConfig.PrimaryDataCsvParams import edu.ie3.simona.config.SimonaConfig.Simona.Input.Primary.{ CouchbaseParams, - InfluxDb1xParams + InfluxDb1xParams, } import edu.ie3.simona.config.SimonaConfig.Simona.Input.{ Primary => PrimaryConfig } import edu.ie3.simona.exceptions.{ InitializationException, - InvalidConfigParameterException + InvalidConfigParameterException, } import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationFailedMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ PrimaryServiceRegistrationMessage, - WorkerRegistrationMessage + WorkerRegistrationMessage, } import edu.ie3.simona.service.SimonaService import edu.ie3.simona.service.primary.PrimaryServiceProxy.{ InitPrimaryServiceProxyStateData, PrimaryServiceStateData, - SourceRef + SourceRef, } import edu.ie3.simona.service.primary.PrimaryServiceWorker.{ CsvInitPrimaryServiceStateData, - InitPrimaryServiceStateData + InitPrimaryServiceStateData, } import edu.ie3.simona.test.common.input.TimeSeriesTestData import edu.ie3.simona.test.common.{AgentSpec, TestSpawnerClassic} @@ -71,7 +71,7 @@ class PrimaryServiceProxySpec .parseString(""" |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with TableDrivenPropertyChecks @@ -97,16 +97,16 @@ class PrimaryServiceProxySpec csvSep, baseDirectoryPath.toString, isHierarchic = false, - TimeUtil.withDefaults.getDtfPattern + TimeUtil.withDefaults.getDtfPattern, ) ), None, - None + None, ) val mappingSource = new CsvTimeSeriesMappingSource( csvSep, baseDirectoryPath, - fileNamingStrategy + fileNamingStrategy, ) val workerId: String = "PrimaryService_" + uuidPq val modelUuid: UUID = UUID.fromString("c7ebcc6c-55fc-479b-aa6b-6fa82ccac6b8") @@ -116,15 +116,15 @@ class PrimaryServiceProxySpec Map( UUID.fromString("b86e95b0-e579-4a80-a534-37c7a470a409") -> uuidP, modelUuid -> uuidPq, - UUID.fromString("90a96daa-012b-4fea-82dc-24ba7a7ab81c") -> uuidPq + UUID.fromString("90a96daa-012b-4fea-82dc-24ba7a7ab81c") -> uuidPq, ), Map( uuidP -> SourceRef(metaP, None), - uuidPq -> SourceRef(metaPq, None) + uuidPq -> SourceRef(metaPq, None), ), simulationStart, validPrimaryConfig, - mappingSource + mappingSource, ) private val scheduler: TestProbe = TestProbe("scheduler") @@ -135,7 +135,7 @@ class PrimaryServiceProxySpec Some(CouchbaseParams("", "", "", "", "", "", "")), Some(PrimaryDataCsvParams("", "", isHierarchic = false, "")), None, - None + None, ) val exception = intercept[InvalidConfigParameterException]( @@ -149,7 +149,7 @@ class PrimaryServiceProxySpec None, None, None, - None + None, ) val exception = intercept[InvalidConfigParameterException]( @@ -163,7 +163,7 @@ class PrimaryServiceProxySpec Some(CouchbaseParams("", "", "", "", "", "", "")), None, None, - None + None, ) val exception = intercept[InvalidConfigParameterException]( @@ -177,7 +177,7 @@ class PrimaryServiceProxySpec None, Some(PrimaryDataCsvParams("", "", isHierarchic = false, "")), None, - None + None, ) noException shouldBe thrownBy { @@ -190,7 +190,7 @@ class PrimaryServiceProxySpec None, None, Some(InfluxDb1xParams("", 0, "", "")), - None + None, ) val exception = intercept[InvalidConfigParameterException]( @@ -204,7 +204,7 @@ class PrimaryServiceProxySpec None, Some(PrimaryDataCsvParams("", "", isHierarchic = false, "xYz")), None, - None + None, ) intercept[InvalidConfigParameterException]( @@ -222,11 +222,11 @@ class PrimaryServiceProxySpec "", "", isHierarchic = false, - "yyyy-MM-dd'T'HH:mm'Z[UTC]'" + "yyyy-MM-dd'T'HH:mm'Z[UTC]'", ) ), None, - None + None, ) noException shouldBe thrownBy { @@ -238,7 +238,7 @@ class PrimaryServiceProxySpec val initStateData: InitPrimaryServiceProxyStateData = InitPrimaryServiceProxyStateData( validPrimaryConfig, - simulationStart + simulationStart, ) val proxyRef: TestActorRef[PrimaryServiceProxy] = TestActorRef( new PrimaryServiceProxy(scheduler.ref, initStateData, simulationStart) @@ -254,12 +254,12 @@ class PrimaryServiceProxySpec None, None, None, - None + None, ) proxy invokePrivate prepareStateData( maliciousConfig, - simulationStart + simulationStart, ) match { case Success(_) => fail("Building state data with missing config should fail") @@ -274,12 +274,12 @@ class PrimaryServiceProxySpec None, None, Some(InfluxDb1xParams("", -1, "", "")), - None + None, ) proxy invokePrivate prepareStateData( maliciousConfig, - simulationStart + simulationStart, ) match { case Success(_) => fail("Building state data with missing config should fail") @@ -292,7 +292,7 @@ class PrimaryServiceProxySpec "result in correct data" in { proxy invokePrivate prepareStateData( validPrimaryConfig, - simulationStart + simulationStart, ) match { case Success( PrimaryServiceStateData( @@ -300,13 +300,13 @@ class PrimaryServiceProxySpec timeSeriesToSourceRef, simulationStart, primaryConfig, - mappingSource + mappingSource, ) ) => modelToTimeSeries shouldBe Map( UUID.fromString("b86e95b0-e579-4a80-a534-37c7a470a409") -> uuidP, UUID.fromString("c7ebcc6c-55fc-479b-aa6b-6fa82ccac6b8") -> uuidPq, - UUID.fromString("90a96daa-012b-4fea-82dc-24ba7a7ab81c") -> uuidPq + UUID.fromString("90a96daa-012b-4fea-82dc-24ba7a7ab81c") -> uuidPq, ) timeSeriesToSourceRef.get(uuidP) match { case Some(SourceRef(metaInformation, worker)) => @@ -334,7 +334,7 @@ class PrimaryServiceProxySpec case Failure(failure) => fail( "Building state data with correct config should not fail, but failed with:", - failure + failure, ) } } @@ -363,7 +363,7 @@ class PrimaryServiceProxySpec val workerRef = proxy invokePrivate classToWorkerRef( testClass, - workerId + workerId, ) Objects.nonNull(workerRef) shouldBe true @@ -377,13 +377,13 @@ class PrimaryServiceProxySpec ) val metaInformation = new CsvIndividualTimeSeriesMetaInformation( metaPq, - Paths.get("its_pq_" + uuidPq) + Paths.get("its_pq_" + uuidPq), ) proxy invokePrivate toInitData( metaInformation, simulationStart, - validPrimaryConfig + validPrimaryConfig, ) match { case Success( CsvInitPrimaryServiceStateData( @@ -393,7 +393,7 @@ class PrimaryServiceProxySpec directoryPath, filePath, fileNamingStrategy, - timePattern + timePattern, ) ) => actualTimeSeriesUuid shouldBe uuidPq @@ -410,7 +410,7 @@ class PrimaryServiceProxySpec case Failure(exception) => fail( "Creation of init data failed, although it was meant to succeed.", - exception + exception, ) } } @@ -420,12 +420,12 @@ class PrimaryServiceProxySpec Some(CouchbaseParams("", "", "", "", "", "", "")), None, None, - None + None, ) proxy invokePrivate initializeWorker( metaPq, simulationStart, - maliciousPrimaryConfig + maliciousPrimaryConfig, ) match { case Failure(exception) => /* Check the exception */ @@ -459,11 +459,11 @@ class PrimaryServiceProxySpec new PrimaryServiceProxy( scheduler.ref, initStateData, - simulationStart + simulationStart, ) { override protected def classToWorkerRef[V <: Value]( valueClass: Class[V], - timeSeriesUuid: String + timeSeriesUuid: String, ): ActorRef = worker.ref // needs to be overwritten as to make it available to the private method tester @@ -471,19 +471,19 @@ class PrimaryServiceProxySpec override protected def initializeWorker( metaInformation: IndividualTimeSeriesMetaInformation, simulationStart: ZonedDateTime, - primaryConfig: PrimaryConfig + primaryConfig: PrimaryConfig, ): Try[ActorRef] = super.initializeWorker( metaInformation, simulationStart, - primaryConfig + primaryConfig, ) } ) val fakeProxy: PrimaryServiceProxy = fakeProxyRef.underlyingActor val metaInformation = new CsvIndividualTimeSeriesMetaInformation( metaPq, - Paths.get("its_pq_" + uuidPq) + Paths.get("its_pq_" + uuidPq), ) scheduler.expectNoMessage() @@ -491,7 +491,7 @@ class PrimaryServiceProxySpec fakeProxy invokePrivate initializeWorker( metaInformation, simulationStart, - validPrimaryConfig + validPrimaryConfig, ) match { case Success(workerRef) => /* Check, if expected init message has been sent */ @@ -506,9 +506,9 @@ class PrimaryServiceProxySpec directoryPath, filePath, fileNamingStrategy, - timePattern + timePattern, ), - _ + _, ) => actualTimeSeriesUuid shouldBe uuidPq actualSimulationStart shouldBe simulationStart @@ -530,7 +530,7 @@ class PrimaryServiceProxySpec case Failure(exception) => fail( "Spinning off a worker with correct input data should be successful, but failed with:", - exception + exception, ) } } @@ -544,7 +544,7 @@ class PrimaryServiceProxySpec proxy invokePrivate updateStateData( proxyStateData, UUID.fromString("394fd072-832c-4c36-869b-c574ee37afe1"), - self + self, ) } exception.getMessage shouldBe "Cannot update entry for time series '394fd072-832c-4c36-869b-c574ee37afe1', as it hasn't been part of it before." @@ -554,19 +554,19 @@ class PrimaryServiceProxySpec proxy invokePrivate updateStateData( proxyStateData, uuidPq, - self + self, ) match { case PrimaryServiceStateData( modelToTimeSeries, timeSeriesToSourceRef, simulationStart, primaryConfig, - mappingSource + mappingSource, ) => modelToTimeSeries shouldBe proxyStateData.modelToTimeSeries timeSeriesToSourceRef shouldBe Map( uuidP -> SourceRef(metaP, None), - uuidPq -> SourceRef(metaPq, Some(self)) + uuidPq -> SourceRef(metaPq, Some(self)), ) simulationStart shouldBe proxyStateData.simulationStart primaryConfig shouldBe proxyStateData.primaryConfig @@ -586,7 +586,7 @@ class PrimaryServiceProxySpec modelUuid, uuidPq, maliciousStateData, - self + self, ) expectMsg(RegistrationFailedMessage(proxyRef)) } @@ -602,7 +602,7 @@ class PrimaryServiceProxySpec modelUuid, uuidPq, adaptedStateData, - self + self, ) expectMsg(WorkerRegistrationMessage(self)) } @@ -613,7 +613,7 @@ class PrimaryServiceProxySpec Some(CouchbaseParams("", "", "", "", "", "", "")), None, None, - None + None, ) ) @@ -621,7 +621,7 @@ class PrimaryServiceProxySpec modelUuid, uuidPq, maliciousStateData, - self + self, ) expectMsg(RegistrationFailedMessage(proxyRef)) } @@ -634,12 +634,12 @@ class PrimaryServiceProxySpec new PrimaryServiceProxy( scheduler.ref, initStateData, - simulationStart + simulationStart, ) { override protected def initializeWorker( metaInformation: IndividualTimeSeriesMetaInformation, simulationStart: ZonedDateTime, - primaryConfig: PrimaryConfig + primaryConfig: PrimaryConfig, ): Try[ActorRef] = Success(worker.ref) // needs to be overwritten as to make it available to the private method tester @@ -648,13 +648,13 @@ class PrimaryServiceProxySpec modelUuid: UUID, timeSeriesUuid: UUID, stateData: PrimaryServiceStateData, - requestingActor: ActorRef + requestingActor: ActorRef, ): Unit = super.handleCoveredModel( modelUuid, timeSeriesUuid, stateData, - requestingActor + requestingActor, ) } ) @@ -664,7 +664,7 @@ class PrimaryServiceProxySpec modelUuid, uuidPq, proxyStateData, - self + self, ) worker.expectMsg(WorkerRegistrationMessage(self)) } @@ -688,12 +688,12 @@ class PrimaryServiceProxySpec new PrimaryServiceProxy( scheduler.ref, initStateData, - simulationStart + simulationStart, ) { override protected def initializeWorker( metaInformation: IndividualTimeSeriesMetaInformation, simulationStart: ZonedDateTime, - primaryConfig: PrimaryConfig + primaryConfig: PrimaryConfig, ): Try[ActorRef] = Success(worker.ref) } ) @@ -701,7 +701,7 @@ class PrimaryServiceProxySpec /* Initialize the fake proxy */ scheduler.send( fakeProxyRef, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) scheduler.expectMsg(Completion(fakeProxyRef.toTyped)) diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala index 91d3ccb5a5..b451036391 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceProxySqlIT.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.service.primary import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.typed.scaladsl.adapter.{ ClassicActorRefOps, - TypedActorRefOps + TypedActorRefOps, } import org.apache.pekko.testkit.{TestActorRef, TestProbe} import com.dimafeng.testcontainers.{ForAllTestContainer, PostgreSQLContainer} @@ -19,12 +19,12 @@ import edu.ie3.simona.config.SimonaConfig.Simona.Input.Primary.SqlParams import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.service.primary.PrimaryServiceProxy.InitPrimaryServiceProxyStateData import edu.ie3.simona.test.common.{AgentSpec, TestSpawnerClassic} @@ -43,7 +43,7 @@ class PrimaryServiceProxySqlIT ConfigFactory .parseString(""" |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with ForAllTestContainer @@ -68,7 +68,7 @@ class PrimaryServiceProxySqlIT Iterable( "time_series_p.sql", "time_series_pqh.sql", - "time_series_mapping.sql" + "time_series_mapping.sql", ).foreach { file => val res = container.execInContainer("psql", "-Utest", "-f/home/" + file) res.getStderr shouldBe empty @@ -88,7 +88,7 @@ class PrimaryServiceProxySqlIT userName = container.username, password = container.password, schemaName = schemaName, - timePattern = "yyyy-MM-dd HH:mm:ss" + timePattern = "yyyy-MM-dd HH:mm:ss", ) private def createProxy(): TestActorRef[PrimaryServiceProxy] = { @@ -97,16 +97,16 @@ class PrimaryServiceProxySqlIT None, None, None, - sqlParams = Some(sqlParams) + sqlParams = Some(sqlParams), ), - simulationStart + simulationStart, ) TestActorRef( PrimaryServiceProxy.props( scheduler.ref, initData, - simulationStart + simulationStart, ) ) } @@ -132,7 +132,7 @@ class PrimaryServiceProxySqlIT proxyRef, PrimaryServiceRegistrationMessage( UUID.fromString("b86e95b0-e579-4a80-a534-37c7a470a409") - ) + ), ) scheduler.expectMsgType[ScheduleActivation] // lock activation scheduled @@ -144,7 +144,7 @@ class PrimaryServiceProxySqlIT val workerRef = initActivation.actor scheduler.send( workerRef.toClassic, - Activation(INIT_SIM_TICK) + Activation(INIT_SIM_TICK), ) scheduler.expectMsg(Completion(workerRef, Some(0))) @@ -166,7 +166,7 @@ class PrimaryServiceProxySqlIT proxyRef, PrimaryServiceRegistrationMessage( UUID.fromString("db958617-e49d-44d3-b546-5f7b62776afd") - ) + ), ) scheduler.expectNoMessage() diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala index a185b1edf1..b54fa8a41f 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSpec.scala @@ -19,7 +19,7 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ActivePower import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.WorkerRegistrationMessage @@ -30,7 +30,7 @@ import edu.ie3.simona.service.primary.PrimaryServiceWorker.{ CsvInitPrimaryServiceStateData, InitPrimaryServiceStateData, PrimaryServiceInitializedStateData, - ProvidePrimaryDataMessage + ProvidePrimaryDataMessage, } import edu.ie3.simona.service.primary.PrimaryServiceWorkerSpec.WrongInitPrimaryServiceStateData import edu.ie3.simona.test.common.{AgentSpec, TestSpawnerClassic} @@ -54,7 +54,7 @@ class PrimaryServiceWorkerSpec ConfigFactory .parseString(""" |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with TimeSeriesTestData @@ -78,7 +78,7 @@ class PrimaryServiceWorkerSpec fileNamingStrategy = new FileNamingStrategy(), simulationStart = TimeUtil.withDefaults.toZonedDateTime("2020-01-01 00:00:00"), - timePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'" + timePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", ) private implicit val powerTolerance: squants.Power = Watts(0.1) @@ -90,7 +90,7 @@ class PrimaryServiceWorkerSpec TestActorRef( new PrimaryServiceWorker[PValue]( scheduler.ref, - classOf[PValue] + classOf[PValue], ) ) val service = serviceRef.underlyingActor @@ -114,7 +114,7 @@ class PrimaryServiceWorkerSpec directoryPath = baseDirectoryPath, filePath = Paths.get("its_pq_" + uuidPq), fileNamingStrategy = new FileNamingStrategy(), - timePattern = TimeUtil.withDefaults.getDtfPattern + timePattern = TimeUtil.withDefaults.getDtfPattern, ) service.init(maliciousInitData) match { case Failure(exception) => @@ -135,12 +135,12 @@ class PrimaryServiceWorkerSpec activationTicks, simulationStart, source, - subscribers + subscribers, ) => nextActivationTick shouldBe Some(0L) activationTicks.toVector shouldBe Vector( 900L, - 1800L + 1800L, ) // The first tick should already been popped simulationStart shouldBe validInitData.simulationStart source.getClass shouldBe classOf[CsvTimeSeriesSource[PValue]] @@ -160,7 +160,7 @@ class PrimaryServiceWorkerSpec scheduler.send( serviceRef, - SimonaService.Create(validInitData, key) + SimonaService.Create(validInitData, key), ) scheduler.expectMsg( ScheduleActivation(serviceRef.toTyped, INIT_SIM_TICK, Some(key)) @@ -204,16 +204,16 @@ class PrimaryServiceWorkerSpec uuidP, Paths.get("its_p_" + uuidP), classOf[PValue], - new TimeBasedSimpleValueFactory[PValue](classOf[PValue]) + new TimeBasedSimpleValueFactory[PValue](classOf[PValue]), ), - Vector(self) + Vector(self), ) "correctly distribute proper primary data" in { val announcePrimaryData = PrivateMethod[ ( PrimaryServiceInitializedStateData[PValue], - Option[Long] + Option[Long], ) ](Symbol("announcePrimaryData")) val tick = 0L @@ -223,7 +223,7 @@ class PrimaryServiceWorkerSpec service invokePrivate announcePrimaryData( tick, primaryData, - serviceStateData + serviceStateData, ) match { case (updatedStateData, maybeNextTick) => /* Check updated state data */ @@ -233,7 +233,7 @@ class PrimaryServiceWorkerSpec activationTicks, _, _, - _ + _, ) => nextActivationTick shouldBe Some(900L) activationTicks.size shouldBe 0 @@ -248,7 +248,7 @@ class PrimaryServiceWorkerSpec actualServiceRef, actualData, actualNextDataTick, - unlockKey + unlockKey, ) => actualTick shouldBe 0L actualServiceRef shouldBe serviceRef @@ -261,7 +261,7 @@ class PrimaryServiceWorkerSpec val processDataAndAnnounce = PrivateMethod[ ( PrimaryServiceInitializedStateData[PValue], - Option[Long] + Option[Long], ) ](Symbol("processDataAndAnnounce")) @@ -277,7 +277,7 @@ class PrimaryServiceWorkerSpec service invokePrivate processDataAndAnnounce( tick, maliciousValue, - stateData + stateData, ) match { case ( PrimaryServiceInitializedStateData( @@ -285,9 +285,9 @@ class PrimaryServiceWorkerSpec _, _, _, - _ + _, ), - maybeNextTick + maybeNextTick, ) => nextActivationTick shouldBe Some(900L) maybeNextTick shouldBe Some(900L) @@ -306,7 +306,7 @@ class PrimaryServiceWorkerSpec service invokePrivate processDataAndAnnounce( tick, value, - serviceStateData + serviceStateData, ) match { case (updatedStateData, _) => inside(updatedStateData) { @@ -315,7 +315,7 @@ class PrimaryServiceWorkerSpec activationTicks, _, _, - _ + _, ) => nextActivationTick shouldBe Some(900L) activationTicks.size shouldBe 0 @@ -328,7 +328,7 @@ class PrimaryServiceWorkerSpec tick, serviceRef, ActivePower(Kilowatts(50.0)), - Some(900L) + Some(900L), ) ) } @@ -353,7 +353,7 @@ class PrimaryServiceWorkerSpec actualServiceRef, data, nextDataTick, - unlockKey + unlockKey, ) => tick shouldBe 900L actualServiceRef shouldBe serviceRef @@ -372,14 +372,14 @@ class PrimaryServiceWorkerSpec object PrimaryServiceWorkerSpec { final case class WrongInitPrimaryServiceStateData( override val simulationStart: ZonedDateTime, - override val timeSeriesUuid: UUID + override val timeSeriesUuid: UUID, ) extends InitPrimaryServiceStateData object WrongInitPrimaryServiceStateData { def apply(): WrongInitPrimaryServiceStateData = new WrongInitPrimaryServiceStateData( ZonedDateTime.now(), - UUID.randomUUID() + UUID.randomUUID(), ) } } diff --git a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala index fd79c2fc9d..f85def148c 100644 --- a/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala +++ b/src/test/scala/edu/ie3/simona/service/primary/PrimaryServiceWorkerSqlIT.scala @@ -15,13 +15,13 @@ import edu.ie3.datamodel.io.naming.DatabaseNamingStrategy import edu.ie3.datamodel.models.value.{HeatAndSValue, PValue} import edu.ie3.simona.agent.participant.data.Data.PrimaryData.{ ActivePower, - ApparentPowerAndHeat + ApparentPowerAndHeat, } import edu.ie3.simona.config.SimonaConfig.Simona.Input.Primary.SqlParams import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.WorkerRegistrationMessage @@ -29,7 +29,7 @@ import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.service.SimonaService import edu.ie3.simona.service.primary.PrimaryServiceWorker.{ ProvidePrimaryDataMessage, - SqlInitPrimaryServiceStateData + SqlInitPrimaryServiceStateData, } import edu.ie3.simona.test.common.input.TimeSeriesTestData import edu.ie3.simona.test.common.{AgentSpec, TestSpawnerClassic} @@ -51,7 +51,7 @@ class PrimaryServiceWorkerSqlIT ConfigFactory .parseString(""" |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) with ForAllTestContainer @@ -98,34 +98,34 @@ class PrimaryServiceWorkerSqlIT "uuid", "firstTick", "firstData", - "maybeNextTick" + "maybeNextTick", ), ( PrimaryServiceWorker.props( scheduler.ref, - classOf[HeatAndSValue] + classOf[HeatAndSValue], ), uuidPqh, 0L, ApparentPowerAndHeat( Kilowatts(1000.0), Kilovars(329.0), - Kilowatts(8000.0) + Kilowatts(8000.0), ), - Some(900L) + Some(900L), ), ( PrimaryServiceWorker.props( scheduler.ref, - classOf[PValue] + classOf[PValue], ), uuidP, 0L, ActivePower( Kilowatts(1000.0) ), - Some(900L) - ) + Some(900L), + ), ) forAll(cases) { @@ -134,7 +134,7 @@ class PrimaryServiceWorkerSqlIT uuid, firstTick, firstData, - maybeNextTick + maybeNextTick, ) => val serviceRef = TestActorRef(service) @@ -146,15 +146,15 @@ class PrimaryServiceWorkerSqlIT userName = container.username, password = container.password, schemaName = schemaName, - timePattern = "yyyy-MM-dd HH:mm:ss" + timePattern = "yyyy-MM-dd HH:mm:ss", ), - new DatabaseNamingStrategy() + new DatabaseNamingStrategy(), ) val key1 = ScheduleKey(lock.ref.toTyped, UUID.randomUUID()) scheduler.send( serviceRef, - SimonaService.Create(initData, key1) + SimonaService.Create(initData, key1), ) scheduler.expectMsg( ScheduleActivation(serviceRef.toTyped, INIT_SIM_TICK, Some(key1)) @@ -167,7 +167,7 @@ class PrimaryServiceWorkerSqlIT participant.send( serviceRef, - WorkerRegistrationMessage(participant.ref) + WorkerRegistrationMessage(participant.ref), ) participant.expectMsg( RegistrationSuccessfulMessage(serviceRef, Some(firstTick)) diff --git a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala index 36ad06427c..0d61932603 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/SampleWeatherSourceSpec.scala @@ -10,7 +10,7 @@ import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherSource.{ AgentCoordinates, - WeightedCoordinates + WeightedCoordinates, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.util.TickUtil._ @@ -40,12 +40,12 @@ class SampleWeatherSourceSpec "always return the queried coordinate itself as nearest coordinate" in { val queryCoordinate = AgentCoordinates( NodeInput.DEFAULT_GEO_POSITION.getY, - NodeInput.DEFAULT_GEO_POSITION.getX + NodeInput.DEFAULT_GEO_POSITION.getX, ) source.getWeightedCoordinates( queryCoordinate, - 4 + 4, ) match { case Success(WeightedCoordinates(weighting)) => weighting.corresponds( @@ -58,7 +58,7 @@ class SampleWeatherSourceSpec case Failure(exception) => fail( "Querying the nearest coordinates was supposed to pass.", - exception + exception, ) } } @@ -69,7 +69,7 @@ class SampleWeatherSourceSpec (0L, 86400L, (0L to 86400L by 3600L).toArray), (1L, 86400L, (3600L to 86400L by 3600L).toArray), (0L, 86399L, (0L to 82800L by 3600L).toArray), - (1L, 86399L, (3600L to 82800L by 3600L).toArray) + (1L, 86399L, (3600L to 82800L by 3600L).toArray), ) testData.forEvery { diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala index 1f5c0ddc12..ea38f702cf 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherServiceSpec.scala @@ -12,11 +12,11 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, - ScheduleActivation + ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.{ RegistrationFailedMessage, - RegistrationSuccessfulMessage + RegistrationSuccessfulMessage, } import edu.ie3.simona.ontology.messages.services.WeatherMessage._ import edu.ie3.simona.scheduler.ScheduleLock @@ -26,7 +26,7 @@ import edu.ie3.simona.service.weather.WeatherSource.AgentCoordinates import edu.ie3.simona.test.common.{ ConfigTestData, TestKitWithShutdown, - TestSpawnerClassic + TestSpawnerClassic, } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil @@ -37,7 +37,7 @@ import org.apache.pekko.testkit.{ EventFilter, ImplicitSender, TestActorRef, - TestProbe + TestProbe, } import org.scalatest.PrivateMethodTester import org.scalatest.wordspec.AnyWordSpecLike @@ -52,7 +52,7 @@ class WeatherServiceSpec .parseString(""" |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel = "INFO" - """.stripMargin) + """.stripMargin), ) ) with ImplicitSender @@ -105,7 +105,7 @@ class WeatherServiceSpec TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime ), - 4 + 4, ) ) @@ -121,8 +121,8 @@ class WeatherServiceSpec InitWeatherServiceStateData( simonaConfig.simona.input.weather.datasource ), - key - ) + key, + ), ) scheduler.expectMsg( ScheduleActivation(weatherActor.toTyped, INIT_SIM_TICK, Some(key)) @@ -137,12 +137,12 @@ class WeatherServiceSpec .error( pattern = "\\[.*] Unable to obtain necessary information to register for coordinate AgentCoordinates\\(180\\.5,90\\.5\\)\\.", - occurrences = 1 + occurrences = 1, ) .intercept { weatherActor ! RegisterForWeatherMessage( invalidCoordinate.latitude, - invalidCoordinate.longitude + invalidCoordinate.longitude, ) } @@ -153,7 +153,7 @@ class WeatherServiceSpec /* The successful registration stems from the test above */ weatherActor ! RegisterForWeatherMessage( validCoordinate.latitude, - validCoordinate.longitude + validCoordinate.longitude, ) expectMsg(RegistrationSuccessfulMessage(weatherActor.ref, Some(0L))) @@ -164,12 +164,12 @@ class WeatherServiceSpec EventFilter .warning( pattern = "Sending actor Actor\\[.*] is already registered", - occurrences = 1 + occurrences = 1, ) .intercept { weatherActor ! RegisterForWeatherMessage( validCoordinate.latitude, - validCoordinate.longitude + validCoordinate.longitude, ) } expectNoMessage() @@ -189,9 +189,9 @@ class WeatherServiceSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(-2.3719999999999573), - MetersPerSecond(4.16474) + MetersPerSecond(4.16474), ), - Some(3600L) + Some(3600L), ) ) @@ -211,9 +211,9 @@ class WeatherServiceSpec WattsPerSquareMeter(0d), WattsPerSquareMeter(0d), Celsius(-2.5259999999999536), - MetersPerSecond(4.918092) + MetersPerSecond(4.918092), ), - None + None, ) ) } diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceSpec.scala index 063e46d1f7..5490e26ea1 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceSpec.scala @@ -9,17 +9,17 @@ package edu.ie3.simona.service.weather import edu.ie3.datamodel.io.factory.timeseries.{ CosmoIdCoordinateFactory, IconIdCoordinateFactory, - IdCoordinateFactory + IdCoordinateFactory, } import edu.ie3.datamodel.io.source.IdCoordinateSource import edu.ie3.simona.exceptions.{ InvalidConfigParameterException, - ServiceException + ServiceException, } import edu.ie3.simona.ontology.messages.services.WeatherMessage import edu.ie3.simona.service.weather.WeatherSource.{ AgentCoordinates, - WeightedCoordinates + WeightedCoordinates, } import edu.ie3.simona.service.weather.WeatherSourceSpec._ import edu.ie3.simona.test.common.UnitSpec @@ -44,7 +44,7 @@ class WeatherSourceSpec extends UnitSpec { "issue a ServiceException, if there are not enough coordinates available" in { DummyWeatherSource.getNearestCoordinatesWithDistances( AgentCoordinates(coordinate0.getY, coordinate0.getX), - 9 + 9, ) match { case Failure(exception: ServiceException) => exception.getMessage shouldBe "There are not enough coordinates for averaging. Found 8 within the given distance of 400000 m but need 9. Please make sure that there are enough coordinates within the given distance." @@ -54,7 +54,7 @@ class WeatherSourceSpec extends UnitSpec { "issue a ServiceException, if there are not enough coordinates in max distance available" in { DummyWeatherSource.getNearestCoordinatesWithDistances( AgentCoordinates(coordinate0.getY, coordinate0.getX), - 9 + 9, ) match { case Failure(exception: ServiceException) => exception.getMessage shouldBe "There are not enough coordinates for averaging. Found 8 within the given distance of 400000 m but need 9. Please make sure that there are enough coordinates within the given distance." @@ -66,7 +66,7 @@ class WeatherSourceSpec extends UnitSpec { val agentCoordinates = AgentCoordinates(51.3, 7.3) DummyWeatherSource.getNearestCoordinatesWithDistances( agentCoordinates, - 4 + 4, ) match { case Failure(exception: ServiceException) => exception.getMessage shouldBe "The queried point shall be surrounded by 4 weather coordinates, which are in each quadrant. This is not the case." @@ -80,12 +80,12 @@ class WeatherSourceSpec extends UnitSpec { agentCoordinates.latitude, agentCoordinates.longitude, coordinate551525.getY, - coordinate551525.getX + coordinate551525.getX, ) DummyWeatherSource.getNearestCoordinatesWithDistances( agentCoordinates, - 4 + 4, ) match { case Success(coordinateDistances) => coordinateDistances.size shouldBe 1 @@ -95,14 +95,14 @@ class WeatherSourceSpec extends UnitSpec { coordinateDistance.getCoordinateB shouldBe coordinate551525 QuantityUtil.isEquivalentAbs( coordinateDistance.getDistance, - distance + distance, ) shouldBe true case None => fail("Somebody stole the first result >:-(") } case Failure(exception) => fail( "Determining the nearest coordinates was meant to succeed.", - exception + exception, ) } } @@ -113,25 +113,25 @@ class WeatherSourceSpec extends UnitSpec { val expectedCoordinateDistances = Vector( new CoordinateDistance( coordinate0, - coordinate67775 + coordinate67775, ), new CoordinateDistance( coordinate0, - coordinate551525 + coordinate551525, ), new CoordinateDistance( coordinate0, - coordinate531137 + coordinate531137, ), new CoordinateDistance( coordinate0, - coordinate278150 - ) + coordinate278150, + ), ) DummyWeatherSource.getNearestCoordinatesWithDistances( agentCoordinates, - 4 + 4, ) match { case Success(coordinateDistances) => coordinateDistances.size shouldBe 4 @@ -144,7 +144,7 @@ class WeatherSourceSpec extends UnitSpec { case Failure(exception) => fail( "Determining the nearest coordinates was meant to succeed.", - exception + exception, ) } } @@ -153,7 +153,7 @@ class WeatherSourceSpec extends UnitSpec { val coordinates = Vector( new CoordinateDistance( coordinate0, - coordinate67775 + coordinate67775, ) ) @@ -165,7 +165,7 @@ class WeatherSourceSpec extends UnitSpec { case Failure(exception) => fail( "Determining the weight of coordinates was meant to succeed.", - exception + exception, ) } } @@ -174,12 +174,12 @@ class WeatherSourceSpec extends UnitSpec { val coordinates = Vector( new CoordinateDistance( coordinate0, - coordinate0 + coordinate0, ), new CoordinateDistance( coordinate0, - coordinate0 - ) + coordinate0, + ), ) DummyWeatherSource.determineWeights(coordinates) match { @@ -198,26 +198,26 @@ class WeatherSourceSpec extends UnitSpec { val coordinates = Vector( new CoordinateDistance( coordinate0, - coordinate67775 + coordinate67775, ), new CoordinateDistance( coordinate0, - coordinate531137 + coordinate531137, ), new CoordinateDistance( coordinate0, - coordinate551525 + coordinate551525, ), new CoordinateDistance( coordinate0, - coordinate278150 - ) + coordinate278150, + ), ) val expectedWeights = Map( coordinate67775 -> 0.254626046882988, coordinate531137 -> 0.249222038996929, coordinate551525 -> 0.250659514620527, - coordinate278150 -> 0.245492399499556 + coordinate278150 -> 0.245492399499556, ) DummyWeatherSource.determineWeights(coordinates) match { @@ -230,7 +230,7 @@ class WeatherSourceSpec extends UnitSpec { case Failure(exception) => fail( "Determining the weight of coordinates was meant to succeed.", - exception + exception, ) } } @@ -239,7 +239,7 @@ class WeatherSourceSpec extends UnitSpec { /* Query more coordinates, than are apparent */ DummyWeatherSource.getWeightedCoordinates( AgentCoordinates(coordinate0.getY, coordinate0.getX), - 9 + 9, ) match { case Failure(exception: ServiceException) => exception.getMessage shouldBe "Determination of coordinate weights failed." @@ -255,18 +255,18 @@ class WeatherSourceSpec extends UnitSpec { DummyWeatherSource.getWeightedCoordinates( agentCoordinates, - 4 + 4, ) match { case Success(WeightedCoordinates(weighting)) => weighting.size shouldBe 1 weighting.getOrElse( coordinate551525, - fail("Expected coordinate wasn't found") + fail("Expected coordinate wasn't found"), ) shouldBe 1d case Failure(exception) => fail( "Determining the nearest weighted coordinates was meant to succeed.", - exception + exception, ) } } @@ -278,12 +278,12 @@ class WeatherSourceSpec extends UnitSpec { coordinate67775 -> 0.254626046882988, coordinate531137 -> 0.249222038996929, coordinate551525 -> 0.250659514620527, - coordinate278150 -> 0.245492399499556 + coordinate278150 -> 0.245492399499556, ) DummyWeatherSource.getWeightedCoordinates( agentCoordinates, - 4 + 4, ) match { case Success(WeightedCoordinates(weighting)) => weighting.corresponds(expectedWeighting) { @@ -295,7 +295,7 @@ class WeatherSourceSpec extends UnitSpec { case Failure(exception) => fail( "Determining the nearest weighted coordinates was meant to succeed.", - exception + exception, ) } } @@ -309,15 +309,15 @@ class WeatherSourceSpec extends UnitSpec { ( "", classOf[InvalidConfigParameterException], - "No grid model defined!" + "No grid model defined!", ), ("icon", classOf[IconIdCoordinateFactory], ""), ("cosmo", classOf[CosmoIdCoordinateFactory], ""), ( "else", classOf[InvalidConfigParameterException], - "Grid model 'else' is not supported!" - ) + "Grid model 'else' is not supported!", + ), ) forAll(cases) { (gridModel, expectedClass, failureMessage) => @@ -365,7 +365,7 @@ case object WeatherSourceSpec { */ override def getWeather( tick: Long, - weightedCoordinates: WeightedCoordinates + weightedCoordinates: WeightedCoordinates, ): WeatherMessage.WeatherData = throw new UnsupportedOperationException( "This is not supported by the dummy source." @@ -384,7 +384,7 @@ case object WeatherSourceSpec { */ override def getDataTicks( requestFrameStart: Long, - requestFrameEnd: Long + requestFrameEnd: Long, ): Array[Long] = throw new UnsupportedOperationException( "This is not supported by the dummy source." @@ -400,7 +400,7 @@ case object WeatherSourceSpec { 477295 -> coordinate477295, 537947 -> coordinate537947, 144112 -> coordinate144112, - 165125 -> coordinate165125 + 165125 -> coordinate165125, ) private val coordinateToId = idToCoordinate.map { case (key, value) => @@ -422,7 +422,7 @@ case object WeatherSourceSpec { def getClosestCoordinates( coordinate: Point, n: Int, - distance: ComparableQuantity[Length] + distance: ComparableQuantity[Length], ): util.List[CoordinateDistance] = { val points: Set[Point] = coordinateToId.keySet @@ -442,7 +442,7 @@ case object WeatherSourceSpec { override def getNearestCoordinates( coordinate: Point, - n: Int + n: Int, ): util.List[CoordinateDistance] = { calculateCoordinateDistances(coordinate, n, coordinateToId.keySet.asJava) } diff --git a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala index a6fe3b9dab..96eb6df6ee 100644 --- a/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala +++ b/src/test/scala/edu/ie3/simona/service/weather/WeatherSourceWrapperSpec.scala @@ -9,18 +9,18 @@ package edu.ie3.simona.service.weather import edu.ie3.datamodel.io.factory.timeseries.IconTimeBasedWeatherValueFactory import edu.ie3.datamodel.io.source.{ IdCoordinateSource, - WeatherSource => PsdmWeatherSource + WeatherSource => PsdmWeatherSource, } import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.timeseries.individual.{ IndividualTimeSeries, - TimeBasedValue + TimeBasedValue, } import edu.ie3.datamodel.models.value.WeatherValue import edu.ie3.simona.ontology.messages.services.WeatherMessage.WeatherData import edu.ie3.simona.service.weather.WeatherSource.{ EMPTY_WEATHER_DATA, - WeightedCoordinates + WeightedCoordinates, } import edu.ie3.simona.service.weather.WeatherSourceSpec.DummyIdCoordinateSource import edu.ie3.simona.service.weather.WeatherSourceWrapper.WeightSum @@ -55,7 +55,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { classOf[IdCoordinateSource], classOf[Long], classOf[ComparableQuantity[Length]], - classOf[ZonedDateTime] + classOf[ZonedDateTime], ) actor.setAccessible(true) val source = actor.newInstance( @@ -63,7 +63,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { DummyIdCoordinateSource, 360L, Quantities.getQuantity(10000, Units.METRE), - ZonedDateTime.now() + ZonedDateTime.now(), ) val date = ZonedDateTime.of(2021, 1, 15, 18, 0, 0, 0, ZoneId.of("UTC")) @@ -73,7 +73,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { coordinate1a -> 0.25, coordinate1b -> 0.25, coordinate1c -> 0.25, - coordinate13 -> 0.25 + coordinate13 -> 0.25, ) ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) @@ -91,7 +91,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { coordinate1a -> 0.25, coordinate1b -> 0.25, coordinate1c -> 0.25, - coordinate13NoTemp -> 0.25 + coordinate13NoTemp -> 0.25, ) ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) @@ -108,7 +108,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { coordinate1a -> 0.25, coordinate1b -> 0.25, coordinate1c -> 0.25, - coordinateEmpty -> 0.25 + coordinateEmpty -> 0.25, ) ) val result = source.getWeather(date.toEpochSecond, weightedCoordinates) @@ -155,13 +155,13 @@ class WeatherSourceWrapperSpec extends UnitSpec { (0.5, 0.75, 291d, 10d), (12.3, 1.2, 293d, 12d), (25.0, 5.7, 290d, 9d), - (26.3, 1.7, 289d, 11d) + (26.3, 1.7, 289d, 11d), ) val weights = Seq( (0.1, 0.2, 0.3, 0.4), (0.25, 0.2, 0.25, 0.1), (0.3, 0.4, 0.15, 0.05), - (0.35, 0.2, 0.3, 0.45) + (0.35, 0.2, 0.3, 0.45), ) val (weightedWeather, weightSum) = @@ -182,13 +182,13 @@ class WeatherSourceWrapperSpec extends UnitSpec { (0.5, 0.75, 291d, 10d), (12.3, 1.2, 293d, 12d), (25.0, 5.7, 290d, 9d), - (26.3, 1.7, 289d, 11d) + (26.3, 1.7, 289d, 11d), ) val weights = Seq( (0.1, 0.2, 0d, 0.4), (0.25, 0.2, 0d, 0.1), (0.3, 0.4, 0d, 0.05), - (0.35, 0.2, 0d, 0.45) + (0.35, 0.2, 0d, 0.45), ) val (weightedWeather, weightSum) = @@ -205,13 +205,13 @@ class WeatherSourceWrapperSpec extends UnitSpec { (0.5, 0.75, 291d, 10d), (12.3, 1.2, 0d, 12d), (25.0, 5.7, 290d, 9d), - (26.3, 1.7, 289d, 11d) + (26.3, 1.7, 289d, 11d), ) val weights = Seq( (0.1, 0.2, 0.3, 0.4), (0.25, 0.2, 0d, 0.1), (0.3, 0.4, 0.15, 0.05), - (0.35, 0.2, 0.3, 0.45) + (0.35, 0.2, 0.3, 0.45), ) val (weightedWeather, weightSum) = @@ -228,7 +228,7 @@ class WeatherSourceWrapperSpec extends UnitSpec { WattsPerSquareMeter(1.0), WattsPerSquareMeter(1.0), Kelvin(1.0d), - MetersPerSecond(1.0d) + MetersPerSecond(1.0d), ) val weightSum = WeightSum(0.25, 0.5, 0.8, 1.0) @@ -256,7 +256,7 @@ object WeatherSourceWrapperSpec { case object DummyPsdmWeatherSource extends PsdmWeatherSource( DummyIdCoordinateSource, - new IconTimeBasedWeatherValueFactory() + new IconTimeBasedWeatherValueFactory(), ) { private val dummyValues = Map( @@ -266,7 +266,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(1d, StandardUnits.SOLAR_IRRADIANCE), Quantities.getQuantity(1d, StandardUnits.TEMPERATURE), Quantities.getQuantity(1d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY), ), coordinate1b -> new WeatherValue( coordinate1b, @@ -274,7 +274,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(1d, StandardUnits.SOLAR_IRRADIANCE), Quantities.getQuantity(1d, StandardUnits.TEMPERATURE), Quantities.getQuantity(1d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY), ), coordinate1c -> new WeatherValue( coordinate1c, @@ -282,7 +282,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(1d, StandardUnits.SOLAR_IRRADIANCE), Quantities.getQuantity(1d, StandardUnits.TEMPERATURE), Quantities.getQuantity(1d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY), ), coordinate1d -> new WeatherValue( coordinate1d, @@ -290,7 +290,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(1d, StandardUnits.SOLAR_IRRADIANCE), Quantities.getQuantity(1d, StandardUnits.TEMPERATURE), Quantities.getQuantity(1d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(1d, StandardUnits.WIND_VELOCITY), ), coordinate13 -> new WeatherValue( coordinate13, @@ -298,7 +298,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(13d, StandardUnits.SOLAR_IRRADIANCE), Quantities.getQuantity(13d, StandardUnits.TEMPERATURE), Quantities.getQuantity(13d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(13d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(13d, StandardUnits.WIND_VELOCITY), ), coordinate13NoTemp -> new WeatherValue( coordinate13NoTemp, @@ -306,7 +306,7 @@ object WeatherSourceWrapperSpec { Quantities.getQuantity(13d, StandardUnits.SOLAR_IRRADIANCE), null, Quantities.getQuantity(13d, StandardUnits.WIND_DIRECTION), - Quantities.getQuantity(13d, StandardUnits.WIND_VELOCITY) + Quantities.getQuantity(13d, StandardUnits.WIND_VELOCITY), ), coordinateEmpty -> new WeatherValue( coordinateEmpty, @@ -314,8 +314,8 @@ object WeatherSourceWrapperSpec { null, null, null, - null - ) + null, + ), ) override def getWeather( @@ -330,15 +330,15 @@ object WeatherSourceWrapperSpec { point, new IndividualTimeSeries[WeatherValue]( UUID.randomUUID(), - ticks.map(tick => new TimeBasedValue(tick, data)).toSet.asJava - ) + ticks.map(tick => new TimeBasedValue(tick, data)).toSet.asJava, + ), ) }.asJava } override def getWeather( timeInterval: ClosedInterval[ZonedDateTime], - coordinates: util.Collection[Point] + coordinates: util.Collection[Point], ): util.Map[Point, IndividualTimeSeries[WeatherValue]] = { val ticks = LazyList .iterate(timeInterval.getLower)(_.plusHours(1)) @@ -351,8 +351,8 @@ object WeatherSourceWrapperSpec { point, new IndividualTimeSeries[WeatherValue]( UUID.randomUUID(), - ticks.map(tick => new TimeBasedValue(tick, data)).toSet.asJava - ) + ticks.map(tick => new TimeBasedValue(tick, data)).toSet.asJava, + ), ) } .asJava @@ -360,7 +360,7 @@ object WeatherSourceWrapperSpec { override def getWeather( date: ZonedDateTime, - coordinate: Point + coordinate: Point, ): Optional[TimeBasedValue[WeatherValue]] = { dummyValues.get(coordinate) match { case Some(value) => Optional.of(new TimeBasedValue(date, value)) @@ -381,14 +381,14 @@ object WeatherSourceWrapperSpec { */ private def prepareWeightTestData( weatherSeq: Seq[(Double, Double, Double, Double)], - weights: Seq[(Double, Double, Double, Double)] + weights: Seq[(Double, Double, Double, Double)], ): (WeatherData, WeightSum) = { val weatherData = weatherSeq.map { case (diff, dir, temp, wVel) => WeatherData( WattsPerSquareMeter(diff), WattsPerSquareMeter(dir), Kelvin(temp), - MetersPerSecond(wVel) + MetersPerSecond(wVel), ) } @@ -398,14 +398,14 @@ object WeatherSourceWrapperSpec { currentSum, ( WeatherData(diffIrr, dirIrr, temp, windVel), - (diffWeight, dirWeight, tempWeight, wVelWeight) - ) + (diffWeight, dirWeight, tempWeight, wVelWeight), + ), ) => currentSum.copy( diffIrr = currentSum.diffIrr + (diffIrr * diffWeight), dirIrr = currentSum.dirIrr + (dirIrr * dirWeight), temp = currentSum.temp + temp * tempWeight, - windVel = currentSum.windVel + windVel * wVelWeight + windVel = currentSum.windVel + windVel * wVelWeight, ) } val weightSum = weights.foldLeft(WeightSum.EMPTY_WEIGHT_SUM) { @@ -414,7 +414,7 @@ object WeatherSourceWrapperSpec { currentWeight._1, currentWeight._2, currentWeight._3, - currentWeight._4 + currentWeight._4, ) } diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala index 27c6c80fae..e9ad87efff 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala @@ -8,14 +8,14 @@ package edu.ie3.simona.sim import org.apache.pekko.actor.typed.scaladsl.adapter.{ ClassicActorRefOps, - ClassicActorSystemOps + ClassicActorSystemOps, } import org.apache.pekko.actor.{ Actor, ActorContext, ActorRef, ActorSystem, - Props + Props, } import org.apache.pekko.testkit.{TestActorRef, TestProbe} import com.typesafe.config.ConfigFactory @@ -36,7 +36,7 @@ class SimonaSimFailSpec .parseString(""" |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] |pekko.loglevel="OFF" - """.stripMargin) + """.stripMargin), ) ) { "A SimonaSim" should { @@ -48,9 +48,9 @@ class SimonaSimFailSpec Props( new FailSim( system, - timeAdvancer.ref.toTyped + timeAdvancer.ref.toTyped, ) - ) + ), ) /* Init the simulation */ @@ -70,11 +70,11 @@ class SimonaSimFailSpec object SimonaSimFailSpec { class FailSim( actorSystem: ActorSystem, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], ) extends SimonaSim( new DummySetup( actorSystem, - timeAdvancer + timeAdvancer, ) ) { val child: ActorRef = context.actorOf(Props(new Loser)) @@ -94,7 +94,7 @@ object SimonaSimFailSpec { timeAdvancer: org.apache.pekko.actor.typed.ActorRef[ TimeAdvancer.Incoming ], - override val args: Array[String] = Array.empty[String] + override val args: Array[String] = Array.empty[String], ) extends SimonaSetup { override val buildActorSystem: () => ActorSystem = () => actorSystem @@ -112,13 +112,13 @@ object SimonaSimFailSpec { override def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = TestProbe("primaryService")(actorSystem).ref override def weatherService( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = TestProbe("weatherService")(actorSystem).ref @@ -127,7 +127,7 @@ object SimonaSimFailSpec { simulation: ActorRef, runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[ RuntimeEvent - ] + ], ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = timeAdvancer @@ -135,18 +135,18 @@ object SimonaSimFailSpec { context: ActorContext, timeAdvancer: org.apache.pekko.actor.typed.ActorRef[ TimeAdvancer.Incoming - ] + ], ): ActorRef = TestProbe("scheduler")(actorSystem).ref override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] + systemParticipantListener: Seq[ActorRef], ): Iterable[ActorRef] = Iterable.empty override def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ExtSimSetupData = ExtSimSetupData(Iterable.empty, Map.empty) } diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala index 93ae23d06b..d0bbcf39b3 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala @@ -13,11 +13,11 @@ import org.apache.pekko.testkit.TestException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.connector.{ Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ JointGridContainer, - RawGridElements + RawGridElements, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.input.GridInputTestData @@ -42,7 +42,7 @@ class SetupHelperSpec extends UnitSpec with GridInputTestData { adaptedTransformerInputModel.getParallelDevices, adaptedTransformerInputModel.getType, adaptedTransformerInputModel.getTapPos, - adaptedTransformerInputModel.isAutoTap + adaptedTransformerInputModel.isAutoTap, ) val adaptedTransformers = transformers + secondTransformer @@ -52,14 +52,14 @@ class SetupHelperSpec extends UnitSpec with GridInputTestData { adaptedTransformers.asJava, Set.empty[Transformer3WInput].asJava, switches.asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) val gridModel = new JointGridContainer( "TestGrid", rawGridElements, validTestGridInputModel.getSystemParticipants, - validTestGridInputModel.getGraphics + validTestGridInputModel.getGraphics, ) val subGrids = gridModel.getSubGridTopologyGraph @@ -73,13 +73,13 @@ class SetupHelperSpec extends UnitSpec with GridInputTestData { val superiorGrid = subGrids .getOrElse( 1, - throw TestException("Cannot get subGrid with id 1 from test data!") + throw TestException("Cannot get subGrid with id 1 from test data!"), ) val inferiorGrid = subGrids .getOrElse( 100, - throw TestException("Cannot get subGrid with id 100 from test data!") + throw TestException("Cannot get subGrid with id 100 from test data!"), ) val subGridToActorRefMap = @@ -102,14 +102,14 @@ class SetupHelperSpec extends UnitSpec with GridInputTestData { .buildGateToActorRef( subGridToActorRefMap, subGridGates, - superiorGrid.getSubnet + superiorGrid.getSubnet, ) .size shouldBe 1 SetupHelperInstance .buildGateToActorRef( subGridToActorRefMap, subGridGates, - inferiorGrid.getSubnet + inferiorGrid.getSubnet, ) .size shouldBe 1 diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 26b6246e42..671ebad4e9 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -10,7 +10,7 @@ import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import edu.ie3.datamodel.exceptions.NotImplementedException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, - Transformer3WInput + Transformer3WInput, } import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.event.RuntimeEvent @@ -38,38 +38,38 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def primaryServiceProxy( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = throw new NotImplementedException("This is a dummy setup") override def weatherService( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ActorRef = throw new NotImplementedException("This is a dummy setup") override def extSimulations( context: ActorContext, - scheduler: ActorRef + scheduler: ActorRef, ): ExtSimSetupData = throw new NotImplementedException("This is a dummy setup") override def timeAdvancer( context: ActorContext, simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] + runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException("This is a dummy setup") override def scheduler( context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], ): ActorRef = throw new NotImplementedException("This is a dummy setup") override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef] + systemParticipantListener: Seq[ActorRef], ): Iterable[ActorRef] = throw new NotImplementedException("This is a dummy setup") @@ -94,7 +94,7 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { 2, nodeCUuid, 3, - ConnectorPort.C + ConnectorPort.C, ) val internalNode = subGridGate.link match { case input: Transformer3WInput => input.getNodeInternal diff --git a/src/test/scala/edu/ie3/simona/test/KafkaSpecLike.scala b/src/test/scala/edu/ie3/simona/test/KafkaSpecLike.scala index d228185517..15962057cf 100644 --- a/src/test/scala/edu/ie3/simona/test/KafkaSpecLike.scala +++ b/src/test/scala/edu/ie3/simona/test/KafkaSpecLike.scala @@ -38,7 +38,7 @@ trait KafkaSpecLike extends BeforeAndAfterAll { new NewTopic( topic.name, topic.partitions, - topic.replicationFactor + topic.replicationFactor, ) }.asJava ) @@ -58,6 +58,6 @@ object KafkaSpecLike { final case class Topic( name: String, partitions: Int, - replicationFactor: Short + replicationFactor: Short, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala b/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala index 4334c91c59..f989f9082b 100644 --- a/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/DefaultTestData.scala @@ -46,7 +46,7 @@ trait DefaultTestData { SystemComponent.determineOperationInterval( defaultSimulationStart, defaultSimulationEnd, - defaultOperationTime + defaultOperationTime, ) // default Lat/Long @@ -60,7 +60,7 @@ trait DefaultTestData { protected val default400Kva10KvRefSystem: RefSystem = RefSystem( Kilowatts(400d), - Kilovolts(10d) + Kilovolts(10d), ) /** Creates a [[SimonaConfig]], that provides the desired participant model @@ -75,7 +75,7 @@ trait DefaultTestData { */ def createSimonaConfig( modelBehaviour: LoadModelBehaviour.Value, - reference: LoadReference + reference: LoadReference, ): SimonaConfig = { val typesafeConfig: Config = ConfigFactory.parseString( s""" diff --git a/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala b/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala index a339890968..ca77f35553 100644 --- a/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/EvTestData.scala @@ -19,7 +19,7 @@ trait EvTestData { Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(58d, PowerSystemUnits.KILOWATTHOUR), - 200 + 200, ) protected val evB: MockEvModel = new MockEvModel( UUID.fromString("6d7d27a1-5cbb-4b73-aecb-dfcc5a6fb22e"), @@ -27,6 +27,6 @@ trait EvTestData { Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(11d, PowerSystemUnits.KILOWATT), Quantities.getQuantity(80d, PowerSystemUnits.KILOWATTHOUR), - 200 + 200, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/SilentTestEventListener.scala b/src/test/scala/edu/ie3/simona/test/common/SilentTestEventListener.scala index f3acaeeddd..0c960b230c 100644 --- a/src/test/scala/edu/ie3/simona/test/common/SilentTestEventListener.scala +++ b/src/test/scala/edu/ie3/simona/test/common/SilentTestEventListener.scala @@ -28,7 +28,7 @@ class SilentTestEventListener extends TestEventListener with LazyLogging { Warning( simpleName(this), this.getClass, - "received unexpected event of class " + e.getClass + ": " + e + "received unexpected event of class " + e.getClass + ": " + e, ) ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/ThreeWindingTestData.scala b/src/test/scala/edu/ie3/simona/test/common/ThreeWindingTestData.scala index 075ad05670..ad497696ba 100644 --- a/src/test/scala/edu/ie3/simona/test/common/ThreeWindingTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/ThreeWindingTestData.scala @@ -12,16 +12,16 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ JointGridContainer, - RawGridElements + RawGridElements, } import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.util.TestGridFactory @@ -44,7 +44,7 @@ trait ThreeWindingTestData extends DefaultTestData { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.EHV_380KV, - 1 + 1, ) private val nodeB = new NodeInput( UUID.fromString("3d4c66a3-dc11-4ec8-857a-53d77beb15ee"), @@ -55,7 +55,7 @@ trait ThreeWindingTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 2 + 2, ) private val nodeC = new NodeInput( UUID.fromString("a865a429-615e-44be-9d00-d384298986f6"), @@ -66,7 +66,7 @@ trait ThreeWindingTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_10KV, - 3 + 3, ) private val transformerType = new Transformer3WTypeInput( @@ -90,7 +90,7 @@ trait ThreeWindingTestData extends DefaultTestData { Quantities.getQuantity(0d, DEGREE_GEOM), 0, -10, - 10 + 10, ) private val transformer = new Transformer3WInput( @@ -104,7 +104,7 @@ trait ThreeWindingTestData extends DefaultTestData { 1, transformerType, 0, - true + true, ) protected val threeWindingTestGrid: JointGridContainer = { @@ -114,11 +114,11 @@ trait ThreeWindingTestData extends DefaultTestData { Set.empty[Transformer2WInput].asJava, Set(transformer).asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createJointGrid( gridName = "threeWindingTestGrid", - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ) } } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/CylindricalStorageInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/CylindricalStorageInputTestData.scala index a1483310a5..b7c0f678ce 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/CylindricalStorageInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/CylindricalStorageInputTestData.scala @@ -11,7 +11,7 @@ import java.util.UUID import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.thermal.{ CylindricalStorageInput, - ThermalBusInput + ThermalBusInput, } import tech.units.indriya.quantity.Quantities.getQuantity @@ -25,6 +25,6 @@ trait CylindricalStorageInputTestData { getQuantity(20, StandardUnits.VOLUME), getQuantity(30, StandardUnits.TEMPERATURE), getQuantity(40, StandardUnits.TEMPERATURE), - getQuantity(1.15, StandardUnits.SPECIFIC_HEAT_CAPACITY) + getQuantity(1.15, StandardUnits.SPECIFIC_HEAT_CAPACITY), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala index 4100d2041d..1ed1312d92 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/EvcsInputTestData.scala @@ -30,7 +30,7 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { 2, 0.95, EvcsLocationType.HOME, - true + true, ) protected val evcsStandardModel: EvcsModel = EvcsModel( @@ -39,7 +39,7 @@ trait EvcsInputTestData extends DefaultTestData with NodeInputTestData { defaultSimulationStart, defaultSimulationEnd, "maxPower", - lowestEvSoc = 0.2 + lowestEvSoc = 0.2, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/FixedFeedInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/FixedFeedInputTestData.scala index 7fc9e2d6f3..6c86b34869 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/FixedFeedInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/FixedFeedInputTestData.scala @@ -30,6 +30,6 @@ trait FixedFeedInputTestData extends NodeInputTestData { nodeInputNoSlackNs04KvA, new CosPhiFixed("cosPhiFixed:{(0.0,0.95)}"), Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 + 0.95, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/GridInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/GridInputTestData.scala index 5095730cba..d9cdbb2681 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/GridInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/GridInputTestData.scala @@ -10,16 +10,16 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ RawGridElements, - SubGridContainer + SubGridContainer, } import edu.ie3.datamodel.models.input.{MeasurementUnitInput, NodeInput} import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils.{ HV, - MV_10KV + MV_10KV, } import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.test.common.DefaultTestData @@ -90,7 +90,7 @@ trait GridInputTestData inputNode15, inputNode16, inputNode17, - inputNode18 + inputNode18, ) // create the lines @@ -120,7 +120,7 @@ trait GridInputTestData line1_13, line14_2, line0_15, - line16_3 + line16_3, ) // create the switches @@ -144,7 +144,7 @@ trait GridInputTestData transformerInput.getParallelDevices, transformerInput.getType, transformerInput.getTapPos, - transformerInput.isAutoTap + transformerInput.isAutoTap, ) val transformers: Set[Transformer2WInput] = Set(adaptedTransformerInputModel) @@ -163,7 +163,7 @@ trait GridInputTestData transformers.asJava, Set.empty[Transformer3WInput].asJava, switches.asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createSubGrid( rawGridElements = rawGridElements diff --git a/src/test/scala/edu/ie3/simona/test/common/input/LineInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/LineInputTestData.scala index 621516d2a7..cd011673f3 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/LineInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/LineInputTestData.scala @@ -18,7 +18,7 @@ import edu.ie3.util.quantities.PowerSystemUnits.{ KILOMETRE, KILOVOLT, OHM_PER_KILOMETRE, - SIEMENS_PER_KILOMETRE + SIEMENS_PER_KILOMETRE, } import tech.units.indriya.quantity.Quantities import tech.units.indriya.unit.Units.AMPERE @@ -40,7 +40,7 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(0.437, OHM_PER_KILOMETRE), Quantities.getQuantity(0.356, OHM_PER_KILOMETRE), Quantities.getQuantity(300d, AMPERE), - Quantities.getQuantity(10, KILOVOLT) + Quantities.getQuantity(10, KILOVOLT), ) // / 10 kV line models @@ -56,9 +56,9 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(0.75, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackMs10Kv, - nodeInputNoSlackMs10Kv + nodeInputNoSlackMs10Kv, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) // 20 kV line input models @@ -71,7 +71,7 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(0.207000002264977, OHM_PER_KILOMETRE), Quantities.getQuantity(0.0691149979829788, OHM_PER_KILOMETRE), Quantities.getQuantity(300, AMPERE), - Quantities.getQuantity(20, KILOVOLT) + Quantities.getQuantity(20, KILOVOLT), ) // / 20 kV line models @@ -87,9 +87,9 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackMs20Kv, - nodeInputNoSlackMs20Kv + nodeInputNoSlackMs20Kv, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val lineInputWithTooHighVoltLvlA = new LineInput( UUID.fromString("da55ed58-e3b1-4cc3-b9e7-997082a2a624"), @@ -103,9 +103,9 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackNs04KvA, - nodeInputNoSlackMs20Kv + nodeInputNoSlackMs20Kv, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val lineInputWithTooLowVoltLvlA = new LineInput( UUID.fromString("8c712c17-2f6f-4ae3-beb9-eb66563ffd32"), @@ -119,9 +119,9 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackNs04KvA, - nodeInputNoSlackMs20Kv + nodeInputNoSlackMs20Kv, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val lineInputWithTooHighVoltLvlB = new LineInput( UUID.fromString("cc9d9547-42ab-4613-93c0-17e6ac11cd9c"), @@ -135,9 +135,9 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackMs20Kv, - nodeInputNoSlackNs04KvA + nodeInputNoSlackNs04KvA, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val lineInputWithTooLowVoltLvlB = new LineInput( UUID.fromString("cb910fee-b7cb-4b14-8609-f85e83c6973b"), @@ -151,8 +151,8 @@ trait LineInputTestData extends DefaultTestData with NodeInputTestData { Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes( nodeInputNoSlackMs20Kv, - nodeInputNoSlackNs04KvA + nodeInputNoSlackNs04KvA, ), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/LoadInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/LoadInputTestData.scala index b99c09fc8f..d77a6762e7 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/LoadInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/LoadInputTestData.scala @@ -33,6 +33,6 @@ trait LoadInputTestData extends NodeInputTestData { false, Quantities.getQuantity(3000d, KILOWATTHOUR), Quantities.getQuantity(282.74d, VOLTAMPERE), - 0.95 + 0.95, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/NodeInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/NodeInputTestData.scala index 4d63805474..27ace499de 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/NodeInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/NodeInputTestData.scala @@ -31,7 +31,7 @@ trait NodeInputTestData extends DefaultTestData { false, defaultLatLong, GermanVoltageLevelUtils.LV, - -1 + -1, ) protected val nodeInputNoSlackNs04KvB = new NodeInput( UUID.fromString("ad39d0b9-5ad6-4588-8d92-74c7d7de9ace"), @@ -42,7 +42,7 @@ trait NodeInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ) protected val nodeInputNoSlackNs04KvWrongVTarget = new NodeInput( UUID.fromString("7be605eb-fc14-4fdc-a580-a2c2a9abd5f7"), @@ -53,7 +53,7 @@ trait NodeInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - -1 + -1, ) // 10 kV node input models @@ -66,7 +66,7 @@ trait NodeInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_10KV, - -1 + -1, ) // 20 kV node input models @@ -80,7 +80,7 @@ trait NodeInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_20KV, - 1 + 1, ) // 110 kV node input models @@ -94,6 +94,6 @@ trait NodeInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala index 431bb33135..28769ee202 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/PvInputTestData.scala @@ -51,6 +51,6 @@ trait PvInputTestData 11, false, Quantities.getQuantity(10, StandardUnits.S_RATED), - 0.95 + 0.95, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/SwitchInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/SwitchInputTestData.scala index 3bd7d0990a..138edf8219 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/SwitchInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/SwitchInputTestData.scala @@ -26,7 +26,7 @@ trait SwitchInputTestData extends NodeInputTestData with DefaultTestData { defaultOperationTime, nodeInputNoSlackNs04KvA, nodeInputNoSlackNs04KvB, - true + true, ) protected val loopSwitchInput: SwitchInput = new SwitchInput( @@ -36,7 +36,7 @@ trait SwitchInputTestData extends NodeInputTestData with DefaultTestData { defaultOperationTime, nodeInputNoSlackNs04KvA, nodeInputNoSlackNs04KvA, - true + true, ) protected val invalidSwitchInput: SwitchInput = new SwitchInput( @@ -46,6 +46,6 @@ trait SwitchInputTestData extends NodeInputTestData with DefaultTestData { defaultOperationTime, nodeInputNoSlackNs04KvA, nodeInputNoSlackMs10Kv, - true + true, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/TimeSeriesTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/TimeSeriesTestData.scala index ecbced6214..026d92c4be 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/TimeSeriesTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/TimeSeriesTestData.scala @@ -24,18 +24,18 @@ trait TimeSeriesTestData { new CsvIndividualTimeSeriesMetaInformation( uuidP, ColumnScheme.ACTIVE_POWER, - Paths.get("its_p_" + uuidP) + Paths.get("its_p_" + uuidP), ) protected val metaPq: CsvIndividualTimeSeriesMetaInformation = new CsvIndividualTimeSeriesMetaInformation( uuidPq, ColumnScheme.APPARENT_POWER, - Paths.get("its_pq_" + uuidPq) + Paths.get("its_pq_" + uuidPq), ) protected val metaPqh: CsvIndividualTimeSeriesMetaInformation = new CsvIndividualTimeSeriesMetaInformation( uuidPqh, ColumnScheme.APPARENT_POWER_AND_HEAT_DEMAND, - Paths.get("its_pqh_" + uuidPqh) + Paths.get("its_pqh_" + uuidPqh), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/Transformer3wTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/Transformer3wTestData.scala index 91da9daba4..9c14017bc7 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/Transformer3wTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/Transformer3wTestData.scala @@ -12,16 +12,16 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ JointGridContainer, - RawGridElements + RawGridElements, } import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.grid.{RefSystem, Transformer3wModel} @@ -67,7 +67,7 @@ trait Transformer3wTestData extends DefaultTestData { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.EHV_380KV, - 1 + 1, ) private val nodeB = new NodeInput( UUID.fromString("dd037896-d2e0-4cdd-a4a1-c9e2b5e8366a"), @@ -78,7 +78,7 @@ trait Transformer3wTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 2 + 2, ) private val nodeC = new NodeInput( UUID.fromString("c838f8a5-03d4-40d3-94fa-815e1bcd0aa0"), @@ -89,7 +89,7 @@ trait Transformer3wTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_20KV, - 3 + 3, ) protected val transformer3wType = new Transformer3WTypeInput( @@ -113,7 +113,7 @@ trait Transformer3wTestData extends DefaultTestData { Quantities.getQuantity(0d, DEGREE_GEOM), 0, -10, - 10 + 10, ) protected val transformer3wInput: Transformer3WInput = new Transformer3WInput( @@ -127,7 +127,7 @@ trait Transformer3wTestData extends DefaultTestData { 1, transformer3wType, 0, - false + false, ) protected val transformer3wInputPostponed: Transformer3WInput = @@ -142,7 +142,7 @@ trait Transformer3wTestData extends DefaultTestData { 1, transformer3wType, 0, - false + false, ) protected val transformer3wInputTapped: Transformer3WInput = @@ -157,7 +157,7 @@ trait Transformer3wTestData extends DefaultTestData { 1, transformer3wType, 10, - false + false, ) protected def transformerModelEhv: Transformer3wModel = @@ -166,7 +166,7 @@ trait Transformer3wTestData extends DefaultTestData { mainRefSystemEhv, 1, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) protected def transformerModelHv: Transformer3wModel = @@ -175,7 +175,7 @@ trait Transformer3wTestData extends DefaultTestData { mainRefSystemHv, 2, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) protected def transformerModelLv: Transformer3wModel = @@ -184,7 +184,7 @@ trait Transformer3wTestData extends DefaultTestData { mainRefSystemHv, 3, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) protected val transformer3wTestGrid: JointGridContainer = { @@ -194,11 +194,11 @@ trait Transformer3wTestData extends DefaultTestData { Set.empty[Transformer2WInput].asJava, Set(transformer3wInput).asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createJointGrid( gridName = "transformer3WTestGrid", - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ) } @@ -209,128 +209,128 @@ trait Transformer3wTestData extends DefaultTestData { -10, Complex(0.0441648321658824, -7.07226179085529), Complex.zero, - Complex(-0.00662285051288235, 1.06076425571629) + Complex(-0.00662285051288235, 1.06076425571629), ), ( -9, Complex(0.0433989680242775, -6.94962141297919), Complex.zero, - Complex(-0.00585698637127746, 0.938123877840191) + Complex(-0.00585698637127746, 0.938123877840191), ), ( -8, Complex(0.0426592128875, -6.83116195707614), Complex.zero, - Complex(-0.0051172312345, 0.819664421937137) + Complex(-0.0051172312345, 0.819664421937137), ), ( -7, Complex(0.0419442540122905, -6.71667320919218), Complex.zero, - Complex(-0.0044022723592905, 0.705175674053178) + Complex(-0.0044022723592905, 0.705175674053178), ), ( -6, Complex(0.0412528652098901, -6.60595881563407), Complex.zero, - Complex(-0.00371088355689011, 0.594461280495065) + Complex(-0.00371088355689011, 0.594461280495065), ), ( -5, Complex(0.0405838998281081, -6.49883515916432), Complex.zero, - Complex(-0.0030419181751081, 0.487337624025323) + Complex(-0.0030419181751081, 0.487337624025323), ), ( -4, Complex(0.0399362844053192, -6.39513034279468), Complex.zero, - Complex(-0.00239430275231915, 0.383632807655681) + Complex(-0.00239430275231915, 0.383632807655681), ), ( -3, Complex(0.0393090129225131, -6.29468326934764), Complex.zero, - Complex(-0.00176703126951309, 0.283185734208644) + Complex(-0.00176703126951309, 0.283185734208644), ), ( -2, Complex(0.0387011415886598, -6.19734280641959), Complex.zero, - Complex(-0.0011591599356598, 0.185845271280588) + Complex(-0.0011591599356598, 0.185845271280588), ), ( -1, Complex(0.0381117841025381, -6.10296702764162), Complex.zero, - Complex(-0.000569802449538069, 0.091469492502624) + Complex(-0.000569802449538069, 0.091469492502624), ), ( 0, Complex(0.037540107341, -6.011422522227), Complex.zero, - Complex(0.000001874312, -0.000075012912) + Complex(0.000001874312, -0.000075012912), ), ( 1, Complex(0.0369853274295567, -5.92258376574089), Complex.zero, - Complex(0.000556654223443345, -0.0889137693981125) + Complex(0.000556654223443345, -0.0889137693981125), ), ( 2, Complex(0.0364467061563107, -5.83633254585146), Complex.zero, - Complex(0.00109527549668932, -0.175164989287544) + Complex(0.00109527549668932, -0.175164989287544), ), ( 3, Complex(0.0359235476947368, -5.7525574375378), Complex.zero, - Complex(0.00161843395826315, -0.2589400976012) + Complex(0.00161843395826315, -0.2589400976012), ), ( 4, Complex(0.035415195604717, -5.67115332285566), Complex.zero, - Complex(0.00212678604828302, -0.34034421228334) + Complex(0.00212678604828302, -0.34034421228334), ), ( 5, Complex(0.0349210300846512, -5.59202095090884), Complex.zero, - Complex(0.00262095156834884, -0.419476584230163) + Complex(0.00262095156834884, -0.419476584230163), ), ( 6, Complex(0.0344404654504587, -5.51506653415321), Complex.zero, - Complex(0.00310151620254129, -0.496431000985789) + Complex(0.00310151620254129, -0.496431000985789), ), ( 7, Complex(0.0339729478199095, -5.440201377581), Complex.zero, - Complex(0.0035690338330905, -0.571296157558004) + Complex(0.0035690338330905, -0.571296157558004), ), ( 8, Complex(0.0335179529830357, -5.36734153770268), Complex.zero, - Complex(0.00402402866996429, -0.644155997436322) + Complex(0.00402402866996429, -0.644155997436322), ), ( 9, Complex(0.0330749844414097, -5.29640750857004), Complex.zero, - Complex(0.00446699721159031, -0.715090026568956) + Complex(0.00446699721159031, -0.715090026568956), ), ( 10, Complex(0.0326435716008696, -5.22732393237131), Complex.zero, - Complex(0.00489841005213043, -0.784173602767695) - ) + Complex(0.00489841005213043, -0.784173602767695), + ), ) val tapDependentVoltRatioEhv: TableFor2[Int, String] = Table( @@ -355,6 +355,6 @@ trait Transformer3wTestData extends DefaultTestData { (7, "1.105"), (8, "1.12"), (9, "1.135"), - (10, "1.15") + (10, "1.15"), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/TransformerInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/TransformerInputTestData.scala index a99035aaca..0ddd591c9e 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/TransformerInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/TransformerInputTestData.scala @@ -12,16 +12,16 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ JointGridContainer, - RawGridElements + RawGridElements, } import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.test.common.DefaultTestData @@ -55,7 +55,7 @@ trait TransformerInputTestData extends DefaultTestData { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) private val nodeB = new NodeInput( UUID.fromString("d46ac046-70c0-478f-8ab1-92d70f0ba172"), @@ -66,7 +66,7 @@ trait TransformerInputTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_10KV, - 2 + 2, ) protected val transformerType = new Transformer2WTypeInput( @@ -84,7 +84,7 @@ trait TransformerInputTestData extends DefaultTestData { false, 0, -13, - 13 + 13, ) val transformerInput = new Transformer2WInput( @@ -97,7 +97,7 @@ trait TransformerInputTestData extends DefaultTestData { 1, transformerType, 10, - false + false, ) protected val gridContainer: JointGridContainer = { @@ -107,11 +107,11 @@ trait TransformerInputTestData extends DefaultTestData { Set(transformerInput).asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createJointGrid( gridName = "twoWindingTestGrid", - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ) } } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/WecInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/WecInputTestData.scala index f3923c370d..f5b41a9a5e 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/WecInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/WecInputTestData.scala @@ -26,7 +26,7 @@ trait WecInputTestData extends WecTypeInputTestData { nodeInputNoSlackNs04KvB, CosPhiFixed.CONSTANT_CHARACTERISTIC, wecTypeInputEnerconE82, - false + false, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/input/WecTypeInputTestData.scala b/src/test/scala/edu/ie3/simona/test/common/input/WecTypeInputTestData.scala index 1f2a1a54bf..7e272db12d 100644 --- a/src/test/scala/edu/ie3/simona/test/common/input/WecTypeInputTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/input/WecTypeInputTestData.scala @@ -40,7 +40,7 @@ trait WecTypeInputTestData extends DefaultTestData with NodeInputTestData { ), Quantities.getQuantity(15, StandardUnits.EFFICIENCY), Quantities.getQuantity(5281, StandardUnits.ROTOR_AREA), - Quantities.getQuantity(98, StandardUnits.HUB_HEIGHT) + Quantities.getQuantity(98, StandardUnits.HUB_HEIGHT), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGrid.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGrid.scala index dc05ed3cda..959a3074f7 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGrid.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGrid.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.test.common.model.grid import edu.ie3.simona.model.grid.{ NodeModel, TransformerModel, - TransformerTappingModel + TransformerTappingModel, } import edu.ie3.simona.test.common.DefaultTestData import edu.ie3.util.quantities.PowerSystemUnits._ @@ -67,7 +67,7 @@ trait BasicGrid extends FiveLinesWithNodes with DefaultTestData { "node0", "5f2b9b3e-faa6-493b-a6ee-22a4a516ad0e", false, - linesRatedVoltage + linesRatedVoltage, ) // / create transformer HV node @ 110kV def node6: NodeModel = @@ -75,7 +75,7 @@ trait BasicGrid extends FiveLinesWithNodes with DefaultTestData { "node6", "3d2d3626-5043-4ec7-892d-cead983c046e", true, - transformerHvVoltLvl + transformerHvVoltLvl, ) override protected def nodes: Seq[NodeModel] = @@ -95,7 +95,7 @@ trait BasicGrid extends FiveLinesWithNodes with DefaultTestData { 13, -13, 0, - autoTap = true + autoTap = true, ) // / electric params in pu @@ -129,7 +129,7 @@ trait BasicGrid extends FiveLinesWithNodes with DefaultTestData { transformerRInPu, transformerXInPu, transformerGInPu, - transformerBInPu + transformerBInPu, ) // init transformer tapping diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index c9270e0888..f8e5bb2a03 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -12,7 +12,7 @@ import edu.ie3.simona.model.grid.{ LineModel, NodeModel, SwitchModel, - Transformer3wModel + Transformer3wModel, } import edu.ie3.util.quantities.PowerSystemUnits._ import tech.units.indriya.quantity.Quantities @@ -47,42 +47,42 @@ trait BasicGridWithSwitches extends BasicGrid { "node13", "69f08e1d-725d-4bae-80c3-5b5a472493c9", false, - linesRatedVoltage + linesRatedVoltage, ) def node14: NodeModel = _nodeCreator( "node14", "c09cb11f-4e2c-4871-84c6-a22dc6702679", false, - linesRatedVoltage + linesRatedVoltage, ) def node15: NodeModel = _nodeCreator( "node15", "2b45e1e2-591e-49c1-bcbe-0e4ceed79c9b", false, - linesRatedVoltage + linesRatedVoltage, ) def node16: NodeModel = _nodeCreator( "node16", "8aec5998-9c8a-453d-8556-e8630f4c053a", false, - linesRatedVoltage + linesRatedVoltage, ) def node17: NodeModel = _nodeCreator( "node17", "e1002827-0430-4ba0-950f-8107fefc09fa", false, - linesRatedVoltage + linesRatedVoltage, ) def node18: NodeModel = _nodeCreator( "node18", "4ab4904e-dde3-4591-8eb5-3e0ca4fd8e3d", false, - linesRatedVoltage + linesRatedVoltage, ) // add nodes to nodes list @@ -97,7 +97,7 @@ trait BasicGridWithSwitches extends BasicGrid { node15.uuid -> 9, node16.uuid -> 10, node17.uuid -> 11, - node18.uuid -> 12 + node18.uuid -> 12, ) // rebuild lines @@ -109,7 +109,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.0013109999999999999, PU), Quantities.getQuantity(0.0010680000000000002, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000048375, PU) + Quantities.getQuantity(0.0000048375, PU), ) def line18To1: LineModel = _lineCreator( "line18To1", @@ -119,7 +119,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.0013109999999999999, PU), Quantities.getQuantity(0.0010680000000000002, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000048375, PU) + Quantities.getQuantity(0.0000048375, PU), ) def line1To13: LineModel = _lineCreator( "line1To13", @@ -129,7 +129,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.001748, PU), Quantities.getQuantity(0.001424, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.00000645, PU) + Quantities.getQuantity(0.00000645, PU), ) def line14To2: LineModel = _lineCreator( "line14To2", @@ -139,7 +139,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.001748, PU), Quantities.getQuantity(0.001424, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.00000645, PU) + Quantities.getQuantity(0.00000645, PU), ) def line0To15: LineModel = _lineCreator( "line0To15", @@ -149,7 +149,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.000874, PU), Quantities.getQuantity(0.000712, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.000003225, PU) + Quantities.getQuantity(0.000003225, PU), ) def line16To3: LineModel = _lineCreator( "line16To3", @@ -159,7 +159,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.000874, PU), Quantities.getQuantity(0.000712, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.000003225, PU) + Quantities.getQuantity(0.000003225, PU), ) def line2To3: LineModel = _lineCreator( @@ -170,7 +170,7 @@ trait BasicGridWithSwitches extends BasicGrid { Quantities.getQuantity(0.0013109999999999999, PU), Quantities.getQuantity(0.0010680000000000002, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000048375, PU) + Quantities.getQuantity(0.0000048375, PU), ) override protected val lines: Set[LineModel] = Set( @@ -182,7 +182,7 @@ trait BasicGridWithSwitches extends BasicGrid { line16To3, line3To4, line3To5, - line2To3 + line2To3, ) // switches @@ -191,21 +191,21 @@ trait BasicGridWithSwitches extends BasicGrid { "TestSwitch1", defaultOperationInterval, node13.uuid, - node14.uuid + node14.uuid, ) val switch2 = new SwitchModel( UUID.fromString("e9eb5598-1611-46ad-a44f-fde689c3f558"), "TestSwitch2", defaultOperationInterval, node15.uuid, - node16.uuid + node16.uuid, ) val switch3 = new SwitchModel( UUID.fromString("01731a4a-7801-4656-96c9-26d002ff52da"), "TestSwitch3", defaultOperationInterval, node17.uuid, - node18.uuid + node18.uuid, ) def switches: Set[SwitchModel] = Set(switch1, switch2, switch3) @@ -228,8 +228,8 @@ trait BasicGridWithSwitches extends BasicGrid { gridLines, Set(transformer2wModel), Set.empty[Transformer3wModel], - gridSwitches - ) + gridSwitches, + ), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGrid.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGrid.scala index 6a91877773..07a2ef7f8f 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGrid.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGrid.scala @@ -11,14 +11,14 @@ import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.connector.`type`.{ LineTypeInput, - Transformer2WTypeInput + Transformer2WTypeInput, } import edu.ie3.datamodel.models.input.container.RawGridElements import edu.ie3.datamodel.models.input.system.characteristic.OlmCharacteristicInput import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.datamodel.utils.GridAndGeoUtils @@ -58,7 +58,7 @@ trait DbfsTestGrid extends SubGridGateMokka { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) protected val node2 = new NodeInput( UUID.fromString("e364ef00-e6ca-46b1-ba2b-bb73c0c6fee0"), @@ -69,7 +69,7 @@ trait DbfsTestGrid extends SubGridGateMokka { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) protected val node3 = new NodeInput( UUID.fromString("47ef9983-8fcf-4713-be90-093fc27864ae"), @@ -80,7 +80,7 @@ trait DbfsTestGrid extends SubGridGateMokka { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) protected val node4 = new NodeInput( UUID.fromString("d44ba8ed-81db-4a22-a40d-f7c0d0808a75"), @@ -91,7 +91,7 @@ trait DbfsTestGrid extends SubGridGateMokka { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) protected val supNodeA = new NodeInput( UUID.fromString("9fe5fa33-6d3b-4153-a829-a16f4347bc4e"), @@ -102,7 +102,7 @@ trait DbfsTestGrid extends SubGridGateMokka { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.EHV_380KV, - 1000 + 1000, ) protected val supNodeB = new NodeInput( UUID.fromString("fb4272fa-5a31-4218-9a46-0a37ac5b34a4"), @@ -113,7 +113,7 @@ trait DbfsTestGrid extends SubGridGateMokka { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.EHV_380KV, - 1000 + 1000, ) /* Mocking table of nodes of underlying grids @@ -133,7 +133,7 @@ trait DbfsTestGrid extends SubGridGateMokka { Quantities.getQuantity(0.1094, OHM_PER_KILOMETRE), Quantities.getQuantity(0.4, OHM_PER_KILOMETRE), Quantities.getQuantity(680.0, AMPERE), - Quantities.getQuantity(110.0, KILOVOLT) + Quantities.getQuantity(110.0, KILOVOLT), ) protected val lineType2 = new LineTypeInput( @@ -144,7 +144,7 @@ trait DbfsTestGrid extends SubGridGateMokka { Quantities.getQuantity(0.0283, OHM_PER_KILOMETRE), Quantities.getQuantity(0.11, OHM_PER_KILOMETRE), Quantities.getQuantity(800.0, AMPERE), - Quantities.getQuantity(110.0, KILOVOLT) + Quantities.getQuantity(110.0, KILOVOLT), ) protected val lineType3 = new LineTypeInput( @@ -155,7 +155,7 @@ trait DbfsTestGrid extends SubGridGateMokka { Quantities.getQuantity(0.0547, OHM_PER_KILOMETRE), Quantities.getQuantity(0.4, OHM_PER_KILOMETRE), Quantities.getQuantity(1360.0, AMPERE), - Quantities.getQuantity(110.0, KILOVOLT) + Quantities.getQuantity(110.0, KILOVOLT), ) protected val lineType4 = new LineTypeInput( @@ -166,7 +166,7 @@ trait DbfsTestGrid extends SubGridGateMokka { Quantities.getQuantity(0.109999999403954, OHM_PER_KILOMETRE), Quantities.getQuantity(0.379999995231628, OHM_PER_KILOMETRE), Quantities.getQuantity(550.0, AMPERE), - Quantities.getQuantity(110.0, KILOVOLT) + Quantities.getQuantity(110.0, KILOVOLT), ) protected val line3To4 = new LineInput( @@ -180,7 +180,7 @@ trait DbfsTestGrid extends SubGridGateMokka { lineType1, Quantities.getQuantity(20, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes(node3, node4), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val line2To3 = new LineInput( @@ -194,7 +194,7 @@ trait DbfsTestGrid extends SubGridGateMokka { lineType2, Quantities.getQuantity(20.0, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes(node3, node2), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val line1To2 = new LineInput( @@ -208,7 +208,7 @@ trait DbfsTestGrid extends SubGridGateMokka { lineType3, Quantities.getQuantity(24.0, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes(node1, node2), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val line1To3 = new LineInput( @@ -222,7 +222,7 @@ trait DbfsTestGrid extends SubGridGateMokka { lineType4, Quantities.getQuantity(40, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes(node1, node3), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) protected val line1To4 = new LineInput( @@ -236,7 +236,7 @@ trait DbfsTestGrid extends SubGridGateMokka { lineType2, Quantities.getQuantity(30, KILOMETRE), GridAndGeoUtils.buildSafeLineStringBetweenNodes(node4, node1), - OlmCharacteristicInput.CONSTANT_CHARACTERISTIC + OlmCharacteristicInput.CONSTANT_CHARACTERISTIC, ) // 1 transformer from HS to HöS @@ -255,7 +255,7 @@ trait DbfsTestGrid extends SubGridGateMokka { false, 0, -5, - 5 + 5, ) protected val transformer1 = new Transformer2WInput( @@ -268,7 +268,7 @@ trait DbfsTestGrid extends SubGridGateMokka { 1, trafoType, 0, - false + false, ) protected val transformer2 = new Transformer2WInput( UUID.fromString("ceccd8cb-29dc-45d6-8a13-4b0033c5f1ef"), @@ -280,7 +280,7 @@ trait DbfsTestGrid extends SubGridGateMokka { 1, trafoType, 0, - false + false, ) protected val (hvGridContainer, hvSubGridGates) = { @@ -296,7 +296,7 @@ trait DbfsTestGrid extends SubGridGateMokka { transformers.asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) /* Sub grid gates are the apparent gates to superior grids + artificial one to underlying grids */ @@ -306,42 +306,42 @@ trait DbfsTestGrid extends SubGridGateMokka { ) ++ rawGridElements.getTransformer3Ws.asScala.flatMap(transformer => Seq( SubGridGate.fromTransformer3W(transformer, ConnectorPort.B), - SubGridGate.fromTransformer3W(transformer, ConnectorPort.C) + SubGridGate.fromTransformer3W(transformer, ConnectorPort.C), ) ) ++ Seq( build2wSubGridGate( node4.getUuid, 1, UUID.fromString("1129b00d-3d89-4a4a-8ae1-2a56041b95aa"), - 13 + 13, ), build2wSubGridGate( node2.getUuid, 1, UUID.fromString("139c435d-e550-48d8-b590-ee897621f42a"), - 12 + 12, ), build2wSubGridGate( node1.getUuid, 1, UUID.fromString("1676e48c-5353-4f06-b671-c579cf6a7072"), - 11 + 11, ), build2wSubGridGate( node3.getUuid, 1, UUID.fromString("9237e237-01e9-446f-899f-c3b5cf69d288"), - 13 - ) + 13, + ), ) ( TestGridFactory.createSubGrid( gridName = "centerGrid", subgrid = 1, - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ), - subGridGates + subGridGates, ) } @@ -357,7 +357,7 @@ trait DbfsTestGrid extends SubGridGateMokka { transformers.asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) /* Sub grid gates are the apparent gates to superior grids + artificial one to underlying grids */ @@ -367,14 +367,14 @@ trait DbfsTestGrid extends SubGridGateMokka { ) ++ rawGridElements.getTransformer3Ws.asScala.flatMap(transformer => Seq( SubGridGate.fromTransformer3W(transformer, ConnectorPort.B), - SubGridGate.fromTransformer3W(transformer, ConnectorPort.C) + SubGridGate.fromTransformer3W(transformer, ConnectorPort.C), ) ) ++ Seq( build2wSubGridGate( node1.getUuid, 1, UUID.fromString("1676e48c-5353-4f06-b671-c579cf6a7072"), - 11 + 11, ) ) @@ -382,9 +382,9 @@ trait DbfsTestGrid extends SubGridGateMokka { TestGridFactory.createSubGrid( gridName = "centerGrid", subgrid = 1, - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ), - subGridGates + subGridGates, ) } @@ -396,7 +396,7 @@ trait DbfsTestGrid extends SubGridGateMokka { Set.empty[Transformer2WInput].asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) val subGridGates: Seq[SubGridGate] = @@ -408,9 +408,9 @@ trait DbfsTestGrid extends SubGridGateMokka { TestGridFactory.createSubGrid( gridName = "superiorGrid", subgrid = 1000, - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ), - subGridGates + subGridGates, ) } } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGridWithParticipants.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGridWithParticipants.scala index eb0208adbd..3e2445ecc1 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGridWithParticipants.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/DbfsTestGridWithParticipants.scala @@ -12,14 +12,14 @@ import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.connector.`type`.Transformer2WTypeInput import edu.ie3.datamodel.models.input.container.{ RawGridElements, - SystemParticipants + SystemParticipants, } import edu.ie3.datamodel.models.input.system.characteristic.CosPhiFixed import edu.ie3.datamodel.models.input.system._ import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.profile.LoadProfile import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils @@ -48,7 +48,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.HV, - 1 + 1, ) protected val supNodeA = new NodeInput( @@ -60,7 +60,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.EHV_380KV, - 1000 + 1000, ) // 1 transformer from hv to ehv @@ -79,7 +79,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { false, 0, -5, - 5 + 5, ) private val transformer1 = new Transformer2WInput( @@ -92,7 +92,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { 1, trafoType, 0, - false + false, ) protected val load1 = new LoadInput( @@ -106,7 +106,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { false, Quantities.getQuantity(300000, KILOWATTHOUR): ComparableQuantity[Energy], Quantities.getQuantity(150, MEGAVOLTAMPERE): ComparableQuantity[Power], - 0.9 + 0.9, ) protected val (hvGridContainer, hvSubGridGates) = { @@ -121,7 +121,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { transformers.asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) val systemParticipants = new SystemParticipants( @@ -135,7 +135,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { Set.empty[PvInput].asJava, Set.empty[StorageInput].asJava, Set.empty[WecInput].asJava, - Set.empty[EmInput].asJava + Set.empty[EmInput].asJava, ) /* Sub grid gates are the apparent gates to superior grids + artificial one to underlying grids */ @@ -145,7 +145,7 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { ) ++ rawGridElements.getTransformer3Ws.asScala.flatMap(transformer => Seq( SubGridGate.fromTransformer3W(transformer, ConnectorPort.B), - SubGridGate.fromTransformer3W(transformer, ConnectorPort.C) + SubGridGate.fromTransformer3W(transformer, ConnectorPort.C), ) ) @@ -154,9 +154,9 @@ trait DbfsTestGridWithParticipants extends SubGridGateMokka { gridName = "gridAgentWithParticipants", subgrid = 1, rawGridElements = rawGridElements, - systemParticipants = systemParticipants + systemParticipants = systemParticipants, ), - subGridGates + subGridGates, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/FiveLinesWithNodes.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/FiveLinesWithNodes.scala index d76bd254fe..830b77f7f7 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/FiveLinesWithNodes.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/FiveLinesWithNodes.scala @@ -51,7 +51,7 @@ trait FiveLinesWithNodes { String, String, Boolean, - ComparableQuantity[ElectricPotential] + ComparableQuantity[ElectricPotential], ) => NodeModel = { (nodeId, uuid, isSlack, vNominal) => new NodeModel( UUID.fromString(uuid), @@ -59,7 +59,7 @@ trait FiveLinesWithNodes { OperationInterval(0L, 7200L), isSlack, Each(1.0d), - GermanVoltageLevelUtils.parse(vNominal) + GermanVoltageLevelUtils.parse(vNominal), ) } @@ -71,7 +71,7 @@ trait FiveLinesWithNodes { Quantity[Dimensionless], Quantity[Dimensionless], Quantity[Dimensionless], - Quantity[Dimensionless] + Quantity[Dimensionless], ) => LineModel = { (lineId, uuid, nodeA, nodeB, r, x, g, b) => new LineModel( UUID.fromString(uuid), @@ -84,7 +84,7 @@ trait FiveLinesWithNodes { Each(r.getValue.doubleValue()), Each(x.getValue.doubleValue()), Each(g.getValue.doubleValue()), - Each(b.getValue.doubleValue()) + Each(b.getValue.doubleValue()), ) } @@ -93,42 +93,42 @@ trait FiveLinesWithNodes { "node0", "51c03963-f28b-4892-9053-c6bb58d20a45", true, - linesRatedVoltage + linesRatedVoltage, ) def node1: NodeModel = _nodeCreator( "node1", "890fb76c-2c6c-4eea-a47d-cf0244750718", false, - linesRatedVoltage + linesRatedVoltage, ) def node2: NodeModel = _nodeCreator( "node2", "be77fa50-613e-4fc9-854a-cfb694443e2f", false, - linesRatedVoltage + linesRatedVoltage, ) def node3: NodeModel = _nodeCreator( "node3", "9a41fd03-fb9a-4966-925e-d847a28ca97d", false, - linesRatedVoltage + linesRatedVoltage, ) def node4: NodeModel = _nodeCreator( "node4", "7f058275-476a-4d84-b1fa-12381204ac4f", false, - linesRatedVoltage + linesRatedVoltage, ) def node5: NodeModel = _nodeCreator( "node5", "ea93feca-0947-4869-a961-9cf942143feb", false, - linesRatedVoltage + linesRatedVoltage, ) protected def nodes: Seq[NodeModel] = @@ -142,7 +142,7 @@ trait FiveLinesWithNodes { Quantities.getQuantity(0.0013109999999999999, PU), Quantities.getQuantity(0.0010680000000000002, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000048375, PU) + Quantities.getQuantity(0.0000048375, PU), ) val line1To2: LineModel = _lineCreator( @@ -153,7 +153,7 @@ trait FiveLinesWithNodes { Quantities.getQuantity(0.001748, PU), Quantities.getQuantity(0.001424, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.00000645, PU) + Quantities.getQuantity(0.00000645, PU), ) val line0To3: LineModel = _lineCreator( @@ -164,7 +164,7 @@ trait FiveLinesWithNodes { Quantities.getQuantity(0.000874, PU), Quantities.getQuantity(0.000712, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.000003225, PU) + Quantities.getQuantity(0.000003225, PU), ) val line3To4: LineModel = _lineCreator( @@ -175,7 +175,7 @@ trait FiveLinesWithNodes { Quantities.getQuantity(0.000437, PU), Quantities.getQuantity(0.000356, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000016125, PU) + Quantities.getQuantity(0.0000016125, PU), ) val line3To5: LineModel = _lineCreator( @@ -186,7 +186,7 @@ trait FiveLinesWithNodes { Quantities.getQuantity(0.002185, PU), Quantities.getQuantity(0.00178, PU), Quantities.getQuantity(0, PU), - Quantities.getQuantity(0.0000080625, PU) + Quantities.getQuantity(0.0000080625, PU), ) protected val lines: Set[LineModel] = @@ -200,7 +200,7 @@ trait FiveLinesWithNodes { node2.uuid -> 2, node3.uuid -> 3, node4.uuid -> 4, - node5.uuid -> 5 + node5.uuid -> 5, ) // corresponding admittance matrix @@ -211,7 +211,7 @@ trait FiveLinesWithNodes { C.zero, C(-687.7449206024457, 560.2681733054249), C.zero, - C.zero + C.zero, ), ( C(-458.4966137349637, 373.5121155369499), @@ -219,7 +219,7 @@ trait FiveLinesWithNodes { C(-343.8724603012229, 280.1340866527124), C.zero, C.zero, - C.zero + C.zero, ), ( C.zero, @@ -227,7 +227,7 @@ trait FiveLinesWithNodes { C(343.8724603012229, -280.1340834277124), C.zero, C.zero, - C.zero + C.zero, ), ( C(-687.7449206024457, 560.2681733054249), @@ -235,7 +235,7 @@ trait FiveLinesWithNodes { C.zero, C(2338.3327300483156, -1904.9117827884445), C(-1375.4898412048915, 1120.5363466108497), - C(-275.0979682409783, 224.10726932216994) + C(-275.0979682409783, 224.10726932216994), ), ( C.zero, @@ -243,7 +243,7 @@ trait FiveLinesWithNodes { C.zero, C(-1375.4898412048915, 1120.5363466108497), C(1375.4898412048915, -1120.5363458045997), - C.zero + C.zero, ), ( C.zero, @@ -251,8 +251,8 @@ trait FiveLinesWithNodes { C.zero, C(-275.0979682409783, 224.10726932216994), C.zero, - C(275.0979682409783, -224.10726529091994) - ) + C(275.0979682409783, -224.10726529091994), + ), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/SubGridGateMokka.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/SubGridGateMokka.scala index 19f3966a23..6cf1b682d4 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/SubGridGateMokka.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/SubGridGateMokka.scala @@ -12,7 +12,7 @@ import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import org.mockito.Mockito._ import org.scalatestplus.mockito.MockitoSugar @@ -49,7 +49,7 @@ trait SubGridGateMokka extends MockitoSugar { */ protected def mockTransformer2w( nodeA: NodeInput, - nodeB: NodeInput + nodeB: NodeInput, ): Transformer2WInput = { val transformer = mock[Transformer2WInput] when(transformer.getNodeA).thenReturn(nodeA) @@ -75,7 +75,7 @@ trait SubGridGateMokka extends MockitoSugar { nodeA: NodeInput, nodeASubnet: Int, nodeB: NodeInput, - nodeC: NodeInput + nodeC: NodeInput, ): Transformer3WInput = { val internalNode = mock[NodeInput] when(internalNode.getUuid).thenReturn(UUID.randomUUID()) @@ -106,7 +106,7 @@ trait SubGridGateMokka extends MockitoSugar { nodeAUuid: UUID, subGridA: Int, nodeBUuud: UUID, - subGridB: Int + subGridB: Int, ): SubGridGate = { val nodeA = mockNode(nodeAUuid, subGridA) val nodeB = mockNode(nodeBUuud, subGridB) @@ -140,7 +140,7 @@ trait SubGridGateMokka extends MockitoSugar { subGridB: Int, nodeCUuid: UUID, subGridC: Int, - inferiorPort: ConnectorPort + inferiorPort: ConnectorPort, ): SubGridGate = { val nodeA = mockNode(nodeAUuid, subGridA) val nodeB = mockNode(nodeBUuid, subGridB) diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/TapTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/TapTestData.scala index b8949dda1a..b2ede4ea43 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/TapTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/TapTestData.scala @@ -20,295 +20,295 @@ trait TapTestData extends TransformerTestGrid { -10, Complex(15.208258743, -50.248897222), Complex(5.069419581, -16.752965741), - Complex(-3.802064686, 12.560349306) + Complex(-3.802064686, 12.560349306), ), ( ConnectorPort.A, -9, Complex(14.717669751, -48.627965054), Complex(4.272871863, -14.120918054), - Complex(-3.311475694, 10.939417137) + Complex(-3.311475694, 10.939417137), ), ( ConnectorPort.A, -8, Complex(14.257742572, -47.108341146), Complex(3.564435643, -11.780014974), - Complex(-2.851548514, 9.419793229) + Complex(-2.851548514, 9.419793229), ), ( ConnectorPort.A, -7, Complex(13.825689766, -45.680815656), Complex(2.932722072, -9.692624809), - Complex(-2.419495709, 7.992267740) + Complex(-2.419495709, 7.992267740), ), ( ConnectorPort.A, -6, Complex(13.419051832, -44.337262255), Complex(2.368067970, -7.826817907), - Complex(-2.012857775, 6.648714338) + Complex(-2.012857775, 6.648714338), ), ( ConnectorPort.A, -5, Complex(13.035650351, -43.070483333), Complex(1.862235764, -6.155375170), - Complex(-1.629456294, 5.381935417) + Complex(-1.629456294, 5.381935417), ), ( ConnectorPort.A, -4, Complex(12.673548952, -41.874081018), Complex(1.408172106, -4.654990484), - Complex(-1.267354895, 4.185533102) + Complex(-1.267354895, 4.185533102), ), ( ConnectorPort.A, -3, Complex(12.331020602, -40.742349099), Complex(0.999812481, -3.305625091), - Complex(-0.924826545, 3.053801182) + Complex(-0.924826545, 3.053801182), ), ( ConnectorPort.A, -2, Complex(12.006520060, -39.670182017), Complex(0.631922108, -2.089981879), - Complex(-0.600326003, 1.981634101) + Complex(-0.600326003, 1.981634101), ), ( ConnectorPort.A, -1, Complex(11.698660571, -38.652997863), Complex(0.299965656, -0.993074896), - Complex(-0.292466514, 0.964449947) + Complex(-0.292466514, 0.964449947), ), ( ConnectorPort.A, 0, Complex(11.406194057, -37.686672917), Complex(0.000000000, -0.001875000), - Complex(0.000000000, -0.001875000) + Complex(0.000000000, -0.001875000), ), ( ConnectorPort.A, 1, Complex(11.127994202, -36.767485772), Complex(-0.271414493, 0.894983294), - Complex(0.278199855, -0.921062144) + Complex(0.278199855, -0.921062144), ), ( ConnectorPort.A, 2, Complex(10.863041959, -35.892069444), Complex(-0.517287712, 1.707445484), - Complex(0.543152098, -1.796478472) + Complex(0.543152098, -1.796478472), ), ( ConnectorPort.A, 3, Complex(10.610413076, -35.057370155), Complex(-0.740261377, 2.444240535), - Complex(0.795780981, -2.631177762) + Complex(0.795780981, -2.631177762), ), ( ConnectorPort.A, 4, Complex(10.369267325, -34.260611742), Complex(-0.942660666, 3.113051481), - Complex(1.036926732, -3.427936174) + Complex(1.036926732, -3.427936174), ), ( ConnectorPort.A, 5, Complex(10.138839162, -33.499264815), Complex(-1.126537685, 3.720659053), - Complex(1.267354895, -4.189283102) + Complex(1.267354895, -4.189283102), ), ( ConnectorPort.A, 6, Complex(9.918429615, -32.771019927), Complex(-1.293708211, 4.273063091), - Complex(1.487764442, -4.917527989) + Complex(1.487764442, -4.917527989), ), ( ConnectorPort.A, 7, Complex(9.707399198, -32.073764184), Complex(-1.445782859, 4.775585521), - Complex(1.698794860, -5.614783732) + Complex(1.698794860, -5.614783732), ), ( ConnectorPort.A, 8, Complex(9.505161714, -31.405560764), Complex(-1.584193619, 5.232958044), - Complex(1.901032343, -6.282987153) + Complex(1.901032343, -6.282987153), ), ( ConnectorPort.A, 9, Complex(9.311178822, -30.764630952), Complex(-1.710216518, 5.649397022), - Complex(2.095015235, -6.923916964) + Complex(2.095015235, -6.923916964), ), ( ConnectorPort.A, 10, Complex(9.124955246, -30.149338333), Complex(-1.824991049, 6.028667667), - Complex(2.281238811, -7.539209583) + Complex(2.281238811, -7.539209583), ), ( ConnectorPort.B, -10, Complex(15.208258743, -50.248897222), Complex(-3.802064686, 12.560349306), - Complex(5.069419581, -16.752965741) + Complex(5.069419581, -16.752965741), ), ( ConnectorPort.B, -9, Complex(14.717669751, -48.627965054), Complex(-3.311475694, 10.939417137), - Complex(4.272871863, -14.120918054) + Complex(4.272871863, -14.120918054), ), ( ConnectorPort.B, -8, Complex(14.257742572, -47.108341146), Complex(-2.851548514, 9.419793229), - Complex(3.564435643, -11.780014974) + Complex(3.564435643, -11.780014974), ), ( ConnectorPort.B, -7, Complex(13.825689766, -45.680815656), Complex(-2.419495709, 7.992267740), - Complex(2.932722072, -9.692624809) + Complex(2.932722072, -9.692624809), ), ( ConnectorPort.B, -6, Complex(13.419051832, -44.337262255), Complex(-2.012857775, 6.648714338), - Complex(2.368067970, -7.826817907) + Complex(2.368067970, -7.826817907), ), ( ConnectorPort.B, -5, Complex(13.035650351, -43.070483333), Complex(-1.629456294, 5.381935417), - Complex(1.862235764, -6.155375170) + Complex(1.862235764, -6.155375170), ), ( ConnectorPort.B, -4, Complex(12.673548952, -41.874081018), Complex(-1.267354895, 4.185533102), - Complex(1.408172106, -4.654990484) + Complex(1.408172106, -4.654990484), ), ( ConnectorPort.B, -3, Complex(12.331020602, -40.742349099), Complex(-0.924826545, 3.053801182), - Complex(0.999812481, -3.305625091) + Complex(0.999812481, -3.305625091), ), ( ConnectorPort.B, -2, Complex(12.006520060, -39.670182017), Complex(-0.600326003, 1.981634101), - Complex(0.631922108, -2.089981879) + Complex(0.631922108, -2.089981879), ), ( ConnectorPort.B, -1, Complex(11.698660571, -38.652997863), Complex(-0.292466514, 0.964449947), - Complex(0.299965656, -0.993074896) + Complex(0.299965656, -0.993074896), ), ( ConnectorPort.B, 0, Complex(11.406194057, -37.686672917), Complex(0.000000000, -0.001875000), - Complex(0.000000000, -0.001875000) + Complex(0.000000000, -0.001875000), ), ( ConnectorPort.B, 1, Complex(11.127994202, -36.767485772), Complex(0.278199855, -0.921062144), - Complex(-0.271414493, 0.894983294) + Complex(-0.271414493, 0.894983294), ), ( ConnectorPort.B, 2, Complex(10.863041959, -35.892069444), Complex(0.543152098, -1.796478472), - Complex(-0.517287712, 1.707445484) + Complex(-0.517287712, 1.707445484), ), ( ConnectorPort.B, 3, Complex(10.610413076, -35.057370155), Complex(0.795780981, -2.631177762), - Complex(-0.740261377, 2.444240535) + Complex(-0.740261377, 2.444240535), ), ( ConnectorPort.B, 4, Complex(10.369267325, -34.260611742), Complex(1.036926732, -3.427936174), - Complex(-0.942660666, 3.113051481) + Complex(-0.942660666, 3.113051481), ), ( ConnectorPort.B, 5, Complex(10.138839162, -33.499264815), Complex(1.267354895, -4.189283102), - Complex(-1.126537685, 3.720659053) + Complex(-1.126537685, 3.720659053), ), ( ConnectorPort.B, 6, Complex(9.918429615, -32.771019927), Complex(1.487764442, -4.917527989), - Complex(-1.293708211, 4.273063091) + Complex(-1.293708211, 4.273063091), ), ( ConnectorPort.B, 7, Complex(9.707399198, -32.073764184), Complex(1.698794860, -5.614783732), - Complex(-1.445782859, 4.775585521) + Complex(-1.445782859, 4.775585521), ), ( ConnectorPort.B, 8, Complex(9.505161714, -31.405560764), Complex(1.901032343, -6.282987153), - Complex(-1.584193619, 5.232958044) + Complex(-1.584193619, 5.232958044), ), ( ConnectorPort.B, 9, Complex(9.311178822, -30.764630952), Complex(2.095015235, -6.923916964), - Complex(-1.710216518, 5.649397022) + Complex(-1.710216518, 5.649397022), ), ( ConnectorPort.B, 10, Complex(9.124955246, -30.149338333), Complex(2.281238811, -7.539209583), - Complex(-1.824991049, 6.028667667) - ) + Complex(-1.824991049, 6.028667667), + ), ) val tapDependentVoltRatio: TableFor2[Int, String] = Table( @@ -339,6 +339,6 @@ trait TapTestData extends TransformerTestGrid { (10, "12.65000"), (11, "12.81500"), (12, "12.98000"), - (13, "13.14500") + (13, "13.14500"), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestData.scala index c5211f1b19..26f26cc141 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestData.scala @@ -31,7 +31,7 @@ trait TransformerTestData extends TransformerTestGrid { val refSystem: RefSystem = RefSystem( Kilowatts(400d), - Kilovolts(0.4d) + Kilovolts(0.4d), ) val nodeUuidToIndexMap: Map[UUID, Int] = gridTapHv.getRawGrid.getNodes.asScala @@ -46,581 +46,581 @@ trait TransformerTestData extends TransformerTestGrid { -10, BigDecimal("-1"), 1.33851987070328, - 0.0182494793139813 + 0.0182494793139813, ), ( ConnectorPort.A, -10, BigDecimal("-0.9"), 1.33801926371388, - 0.0164263707976911 + 0.0164263707976911, ), ( ConnectorPort.A, -10, BigDecimal("-0.8"), 1.3375133288976, - 0.0146032622079102 + 0.0146032622079102, ), ( ConnectorPort.A, -10, BigDecimal("-0.7"), 1.33700205419089, - 0.0127801535444722 + 0.0127801535444722, ), ( ConnectorPort.A, -10, BigDecimal("-0.6"), 1.33648542736584, - 0.0109570448072086 + 0.0109570448072086, ), ( ConnectorPort.A, -10, BigDecimal("-0.5"), 1.33596343602858, - 0.00913393599594799 + 0.00913393599594799, ), ( ConnectorPort.A, -10, BigDecimal("-0.4"), 1.33543606761768, - 0.00731082711051762 + 0.00731082711051762, ), ( ConnectorPort.A, -10, BigDecimal("-0.3"), 1.33490330940244, - 0.00548771815074156 + 0.00548771815074156, ), ( ConnectorPort.A, -10, BigDecimal("-0.2"), 1.33436514848123, - 0.00366460911644194 + 0.00366460911644194, ), ( ConnectorPort.A, -10, BigDecimal("-0.1"), 1.33382157177974, - 0.00184150000743841 + 0.00184150000743841, ), ( ConnectorPort.A, -10, BigDecimal("0"), 1.33327256604926, - 0.0000183908235482318 + 0.0000183908235482318, ), ( ConnectorPort.A, -10, BigDecimal("0.1"), 1.33271811786481, - -0.00180471843541367 + -0.00180471843541367, ), ( ConnectorPort.A, -10, BigDecimal("0.2"), 1.33215821362343, - -0.0036278277696351 + -0.0036278277696351, ), ( ConnectorPort.A, -10, BigDecimal("0.3"), 1.33159283954222, - -0.00545093717930617 + -0.00545093717930617, ), ( ConnectorPort.A, -10, BigDecimal("0.4"), 1.33102198165651, - -0.00727404666461941 + -0.00727404666461941, ), ( ConnectorPort.A, -10, BigDecimal("0.5"), 1.3304456258179, - -0.00909715622576998 + -0.00909715622576998, ), ( ConnectorPort.A, -10, BigDecimal("0.6"), 1.32986375769233, - -0.0109202658629557 + -0.0109202658629557, ), ( ConnectorPort.A, -10, BigDecimal("0.7"), 1.32927636275805, - -0.0127433755763768 + -0.0127433755763768, ), ( ConnectorPort.A, -10, BigDecimal("0.8"), 1.3286834263036, - -0.0145664853662362 + -0.0145664853662362, ), ( ConnectorPort.A, -10, BigDecimal("0.9"), 1.32808493342574, - -0.0163895952327395 + -0.0163895952327395, ), ( ConnectorPort.A, -10, BigDecimal("1"), 1.32748086902734, - -0.0182127051760949 + -0.0182127051760949, ), ( ConnectorPort.A, -9, BigDecimal("-1"), 1.29566723975357, - 0.0188565887526757 + 0.0188565887526757, ), ( ConnectorPort.A, -9, BigDecimal("-0.9"), 1.29515348415399, - 0.0169727100013154 + 0.0169727100013154, ), ( ConnectorPort.A, -9, BigDecimal("-0.8"), 1.29463385801716, - 0.0150888311689785 + 0.0150888311689785, ), ( ConnectorPort.A, -9, BigDecimal("-0.7"), 1.29410834724102, - 0.0132049522554703 + 0.0132049522554703, ), ( ConnectorPort.A, -9, BigDecimal("-0.6"), 1.29357693751783, - 0.0113210732605935 + 0.0113210732605935, ), ( ConnectorPort.A, -9, BigDecimal("-0.5"), 1.29303961433205, - 0.00943719418414793 + 0.00943719418414793, ), ( ConnectorPort.A, -9, BigDecimal("-0.4"), 1.29249636295816, - 0.00755331502593053 + 0.00755331502593053, ), ( ConnectorPort.A, -9, BigDecimal("-0.3"), 1.29194716845844, - 0.00566943578573499 + 0.00566943578573499, ), ( ConnectorPort.A, -9, BigDecimal("-0.2"), 1.29139201568068, - 0.00378555646335253 + 0.00378555646335253, ), ( ConnectorPort.A, -9, BigDecimal("-0.1"), 1.29083088925591, - 0.00190167705857116 + 0.00190167705857116, ), ( ConnectorPort.A, -9, BigDecimal("0"), 1.29026377359605, - 0.0000177975711757692 + 0.0000177975711757692, ), ( ConnectorPort.A, -9, BigDecimal("0.1"), 1.28969065289147, - -0.00186608199905174 + -0.00186608199905174, ), ( ConnectorPort.A, -9, BigDecimal("0.2"), 1.28911151110854, - -0.00374996165233242 + -0.00374996165233242, ), ( ConnectorPort.A, -9, BigDecimal("0.3"), 1.28852633198721, - -0.00563384138889061 + -0.00563384138889061, ), ( ConnectorPort.A, -9, BigDecimal("0.4"), 1.28793509903837, - -0.00751772120895373 + -0.00751772120895373, ), ( ConnectorPort.A, -9, BigDecimal("0.5"), 1.2873377955413, - -0.00940160111275256 + -0.00940160111275256, ), ( ConnectorPort.A, -9, BigDecimal("0.6"), 1.28673440454104, - -0.0112854811005208 + -0.0112854811005208, ), ( ConnectorPort.A, -9, BigDecimal("0.7"), 1.28612490884563, - -0.0131693611724957 + -0.0131693611724957, ), ( ConnectorPort.A, -9, BigDecimal("0.8"), 1.28550929102345, - -0.0150532413289176 + -0.0150532413289176, ), ( ConnectorPort.A, -9, BigDecimal("0.9"), 1.2848875334003, - -0.0169371215700303 + -0.0169371215700303, ), ( ConnectorPort.A, -9, BigDecimal("1"), 1.28425961805663, - -0.0188210018960812 + -0.0188210018960812, ), ( ConnectorPort.A, -8, BigDecimal("-1"), 1.25550083502857, - 0.0194637352444932 + 0.0194637352444932, ), ( ConnectorPort.A, -8, BigDecimal("-0.9"), 1.25497427336787, - 0.0175190862627879 + 0.0175190862627879, ), ( ConnectorPort.A, -8, BigDecimal("-0.8"), 1.25444126357415, - 0.0155744371921388 + 0.0155744371921388, ), ( ConnectorPort.A, -8, BigDecimal("-0.7"), 1.25390178925247, - 0.0136297880323194 + 0.0136297880323194, ), ( ConnectorPort.A, -8, BigDecimal("-0.6"), 1.25335583375242, - 0.0116851387831005 + 0.0116851387831005, ), ( ConnectorPort.A, -8, BigDecimal("-0.5"), 1.2528033801653, - 0.00974048944424847 + 0.00974048944424847, ), ( ConnectorPort.A, -8, BigDecimal("-0.4"), 1.25224441132123, - 0.00779584001552676 + 0.00779584001552676, ), ( ConnectorPort.A, -8, BigDecimal("-0.3"), 1.25167890978624, - 0.00585119049669465 + 0.00585119049669465, ), ( ConnectorPort.A, -8, BigDecimal("-0.2"), 1.25110685785927, - 0.00390654088750816 + 0.00390654088750816, ), ( ConnectorPort.A, -8, BigDecimal("-0.1"), 1.25052823756908, - 0.00196189118771932 + 0.00196189118771932, ), ( ConnectorPort.A, -8, BigDecimal("0"), 1.24994303067118, - 0.0000172413970765007 + 0.0000172413970765007, ), ( ConnectorPort.A, -8, BigDecimal("0.1"), 1.2493512186446, - -0.00192740848467577 + -0.00192740848467577, ), ( ConnectorPort.A, -8, BigDecimal("0.2"), 1.24875278268866, - -0.00387205845779691 + -0.00387205845779691, ), ( ConnectorPort.A, -8, BigDecimal("0.3"), 1.24814770371962, - -0.00581670852255001 + -0.00581670852255001, ), ( ConnectorPort.A, -8, BigDecimal("0.4"), 1.24753596236732, - -0.00776135867920239 + -0.00776135867920239, ), ( ConnectorPort.A, -8, BigDecimal("0.5"), 1.24691753897167, - -0.00970600892802513 + -0.00970600892802513, ), ( ConnectorPort.A, -8, BigDecimal("0.6"), 1.24629241357918, - -0.0116506592692935 + -0.0116506592692935, ), ( ConnectorPort.A, -8, BigDecimal("0.7"), 1.24566056593925, - -0.0135953097032869 + -0.0135953097032869, ), ( ConnectorPort.A, -8, BigDecimal("0.8"), 1.24502197550058, - -0.0155399602302888 + -0.0155399602302888, ), ( ConnectorPort.A, -8, BigDecimal("0.9"), 1.24437662140734, - -0.0174846108505867 + -0.0174846108505867, ), ( ConnectorPort.A, -8, BigDecimal("1"), 1.24372448249533, - -0.0194292615644728 + -0.0194292615644728, ), ( ConnectorPort.A, -7, BigDecimal("-1"), 1.21777623277092, - 0.0200709154179146 + 0.0200709154179146, ), ( ConnectorPort.A, -7, BigDecimal("-0.9"), 1.21723721781891, - 0.0180654962107302 + 0.0180654962107302, ), ( ConnectorPort.A, -7, BigDecimal("-0.8"), 1.21669114127808, - 0.0160600769061402 + 0.0160600769061402, ), ( ConnectorPort.A, -7, BigDecimal("-0.7"), 1.21613798418596, - 0.0140546575038827 + 0.0140546575038827, ), ( ConnectorPort.A, -7, BigDecimal("-0.6"), 1.21557772726497, - 0.0120492380036921 + 0.0120492380036921, ), ( ConnectorPort.A, -7, BigDecimal("-0.5"), 1.21501035091869, - 0.0100438184052979 + 0.0100438184052979, ), ( ConnectorPort.A, -7, BigDecimal("-0.4"), 1.21443583522813, - 0.00803839870842536 + 0.00803839870842536, ), ( ConnectorPort.A, -7, BigDecimal("-0.3"), 1.2138541599479, - 0.00603297891279538 + 0.00603297891279538, ), ( ConnectorPort.A, -7, BigDecimal("-0.2"), 1.21326530450224, - 0.00402755901812385 + 0.00402755901812385, ), ( ConnectorPort.A, -7, BigDecimal("-0.1"), 1.21266924798103, - 0.00202213902412263 + 0.00202213902412263, ), ( ConnectorPort.A, -7, BigDecimal("0"), 1.21206596913569, - 0.0000167189304984079 + 0.0000167189304984079, ), ( ConnectorPort.A, -7, BigDecimal("0.1"), 1.21145544637497, - -0.00198870126304644 + -0.00198870126304644, ), ( ConnectorPort.A, -7, BigDecimal("0.2"), 1.21083765776068, - -0.00399412155681467 + -0.00399412155681467, ), ( ConnectorPort.A, -7, BigDecimal("0.3"), 1.21021258100326, - -0.00599954195111372 + -0.00599954195111372, ), ( ConnectorPort.A, -7, BigDecimal("0.4"), 1.20958019345734, - -0.00800496244625593 + -0.00800496244625593, ), ( ConnectorPort.A, -7, BigDecimal("0.5"), 1.20894047211713, - -0.0100103830425586 + -0.0100103830425586, ), ( ConnectorPort.A, -7, BigDecimal("0.6"), 1.20829339361172, - -0.0120158037403442 + -0.0120158037403442, ), ( ConnectorPort.A, -7, BigDecimal("0.7"), 1.20763893420033, - -0.0140212245399401 + -0.0140212245399401, ), ( ConnectorPort.A, -7, BigDecimal("0.8"), 1.20697706976735, - -0.016026645441679 + -0.016026645441679, ), ( ConnectorPort.A, -7, BigDecimal("0.9"), 1.20630777581736, - -0.0180320664458987 + -0.0180320664458987, ), (ConnectorPort.A, -7, BigDecimal("1"), 1.20563102747, -0.0200374875529425), ( @@ -628,147 +628,147 @@ trait TransformerTestData extends TransformerTestGrid { -6, BigDecimal("-1"), 1.18227775868577, - 0.0206781262979832 + 0.0206781262979832, ), ( ConnectorPort.A, -6, BigDecimal("-0.9"), 1.18172665336576, - 0.0186119368703259 + 0.0186119368703259, ), ( ConnectorPort.A, -6, BigDecimal("-0.8"), 1.18116783617761, - 0.0165457473362931 + 0.0165457473362931, ), ( ConnectorPort.A, -6, BigDecimal("-0.7"), 1.18060128529589, - 0.0144795576955837 + 0.0144795576955837, ), ( ConnectorPort.A, -6, BigDecimal("-0.6"), 1.18002697850897, - 0.0124133679478913 + 0.0124133679478913, ), ( ConnectorPort.A, -6, BigDecimal("-0.5"), 1.17944489321428, - 0.010347178092904 + 0.010347178092904, ), ( ConnectorPort.A, -6, BigDecimal("-0.4"), 1.17885500641342, - 0.00828098813030484 + 0.00828098813030484, ), ( ConnectorPort.A, -6, BigDecimal("-0.3"), 1.17825729470715, - 0.00621479805977096 + 0.00621479805977096, ), ( ConnectorPort.A, -6, BigDecimal("-0.2"), 1.17765173429035, - 0.00414860788097387 + 0.00414860788097387, ), ( ConnectorPort.A, -6, BigDecimal("-0.1"), 1.17703830094672, - 0.00208241759357962 + 0.00208241759357962, ), ( ConnectorPort.A, -6, BigDecimal("0"), 1.17641697004346, - 0.0000162271972485072 + 0.0000162271972485072, ), ( ConnectorPort.A, -6, BigDecimal("0.1"), 1.17578771652579, - -0.00204996330836518 + -0.00204996330836518, ), ( ConnectorPort.A, -6, BigDecimal("0.2"), 1.17515051491134, - -0.00411615392361289 + -0.00411615392361289, ), ( ConnectorPort.A, -6, BigDecimal("0.3"), 1.17450533928438, - -0.00618234464885208 + -0.00618234464885208, ), ( ConnectorPort.A, -6, BigDecimal("0.4"), 1.17385216328999, - -0.00824853548444636 + -0.00824853548444636, ), ( ConnectorPort.A, -6, BigDecimal("0.5"), 1.173190960128, - -0.0103147264307653 + -0.0103147264307653, ), ( ConnectorPort.A, -6, BigDecimal("0.6"), 1.17252170254683, - -0.0123809174881849 + -0.0123809174881849, ), ( ConnectorPort.A, -6, BigDecimal("0.7"), 1.17184436283718, - -0.0144471086570874 + -0.0144471086570874, ), ( ConnectorPort.A, -6, BigDecimal("0.8"), 1.17115891282558, - -0.0165132999378612 + -0.0165132999378612, ), ( ConnectorPort.A, -6, BigDecimal("0.9"), 1.17046532386777, - -0.0185794913309016 + -0.0185794913309016, ), ( ConnectorPort.A, -6, BigDecimal("1"), 1.16976356684192, - -0.0206456828366103 + -0.0206456828366103, ), (ConnectorPort.A, -5, BigDecimal("-1"), 1.1488143809165, 0.021285365249654), ( @@ -776,280 +776,280 @@ trait TransformerTestData extends TransformerTestGrid { -5, BigDecimal("-0.9"), 1.14825155823767, - 0.0191584056066691 + 0.0191584056066691, ), ( ConnectorPort.A, -5, BigDecimal("-0.8"), 1.14768033563545, - 0.0170314458478176 + 0.0170314458478176, ), ( ConnectorPort.A, -5, BigDecimal("-0.7"), 1.14710068810469, - 0.0149044859727549 + 0.0149044859727549, ), ( ConnectorPort.A, -5, BigDecimal("-0.6"), 1.14651259016991, - 0.0127775259811294 + 0.0127775259811294, ), ( ConnectorPort.A, -5, BigDecimal("-0.5"), 1.14591601587918, - 0.0106505658725832 + 0.0106505658725832, ), ( ConnectorPort.A, -5, BigDecimal("-0.4"), 1.14531093879785, - 0.00852360564675163 + 0.00852360564675163, ), ( ConnectorPort.A, -5, BigDecimal("-0.3"), 1.14469733200211, - 0.00639664530326336 + 0.00639664530326336, ), ( ConnectorPort.A, -5, BigDecimal("-0.2"), 1.14407516807242, - 0.00426968484174022 + 0.00426968484174022, ), ( ConnectorPort.A, -5, BigDecimal("-0.1"), 1.14344441908675, - 0.00214272426179696 + 0.00214272426179696, ), ( ConnectorPort.A, -5, BigDecimal("0"), 1.14280505661365, - 0.0000157635630414583 + 0.0000157635630414583, ), ( ConnectorPort.A, -5, BigDecimal("0.1"), 1.14215705170516, - -0.00211119725492569 + -0.00211119725492569, ), ( ConnectorPort.A, -5, BigDecimal("0.2"), 1.14150037488952, - -0.00423815819251083 + -0.00423815819251083, ), ( ConnectorPort.A, -5, BigDecimal("0.3"), 1.14083499616373, - -0.00636511925012798 + -0.00636511925012798, ), ( ConnectorPort.A, -5, BigDecimal("0.4"), 1.14016088498588, - -0.00849208042819832 + -0.00849208042819832, ), ( ConnectorPort.A, -5, BigDecimal("0.5"), 1.13947801026731, - -0.0106190417271507 + -0.0106190417271507, ), ( ConnectorPort.A, -5, BigDecimal("0.6"), 1.13878634036457, - -0.0127460031474217 + -0.0127460031474217, ), ( ConnectorPort.A, -5, BigDecimal("0.7"), 1.1380858430712, - -0.0148729646894554 + -0.0148729646894554, ), ( ConnectorPort.A, -5, BigDecimal("0.8"), 1.13737648560922, - -0.016999926353704 + -0.016999926353704, ), ( ConnectorPort.A, -5, BigDecimal("0.9"), 1.13665823462052, - -0.0191268881406277 + -0.0191268881406277, ), ( ConnectorPort.A, -5, BigDecimal("1"), 1.13593105615792, - -0.0212538500506947 + -0.0212538500506947, ), ( ConnectorPort.A, -4, BigDecimal("-1"), 1.11721628752459, - 0.0218926299305844 + 0.0218926299305844, ), ( ConnectorPort.A, -4, BigDecimal("-0.9"), 1.11664213051416, - 0.0197049000775551 + 0.0197049000775551, ), ( ConnectorPort.A, -4, BigDecimal("-0.8"), 1.11605884680756, - 0.0175171700986343 + 0.0175171700986343, ), ( ConnectorPort.A, -4, BigDecimal("-0.7"), 1.11546640788156, - 0.0153294399934289 + 0.0153294399934289, ), ( ConnectorPort.A, -4, BigDecimal("-0.6"), 1.11486478464348, - 0.0131417097615372 + 0.0131417097615372, ), ( ConnectorPort.A, -4, BigDecimal("-0.5"), 1.11425394742336, - 0.0109539794025504 + 0.0109539794025504, ), ( ConnectorPort.A, -4, BigDecimal("-0.4"), 1.11363386596595, - 0.00876624891605077 + 0.00876624891605077, ), ( ConnectorPort.A, -4, BigDecimal("-0.3"), 1.11300450942251, - 0.00657851830161297 + 0.00657851830161297, ), ( ConnectorPort.A, -4, BigDecimal("-0.2"), 1.1123658463424, - 0.00439078755880325 + 0.00439078755880325, ), ( ConnectorPort.A, -4, BigDecimal("-0.1"), 1.11171784466437, - 0.00220305668717925 + 0.00220305668717925, ), ( ConnectorPort.A, -4, BigDecimal("0"), 1.11106047170771, - 0.0000153256862902373 + 0.0000153256862902373, ), ( ConnectorPort.A, -4, BigDecimal("0.1"), 1.1103936941631, - -0.00217240544432333 + -0.00217240544432333, ), ( ConnectorPort.A, -4, BigDecimal("0.2"), 1.10971747808323, - -0.0043601367051296 + -0.0043601367051296, ), ( ConnectorPort.A, -4, BigDecimal("0.3"), 1.10903178887323, - -0.00654786809660587 + -0.00654786809660587, ), ( ConnectorPort.A, -4, BigDecimal("0.4"), 1.10833659128073, - -0.00873559961923841 + -0.00873559961923841, ), ( ConnectorPort.A, -4, BigDecimal("0.5"), 1.10763184938575, - -0.0109233312735225 + -0.0109233312735225, ), ( ConnectorPort.A, -4, BigDecimal("0.6"), 1.10691752659028, - -0.0131110630599632 + -0.0131110630599632, ), ( ConnectorPort.A, -4, BigDecimal("0.7"), 1.10619358560756, - -0.0152987949790748 + -0.0152987949790748, ), ( ConnectorPort.A, -4, BigDecimal("0.8"), 1.10545998845117, - -0.017486527031381 + -0.017486527031381, ), ( ConnectorPort.A, -4, BigDecimal("0.9"), 1.10471669642365, - -0.019674259217416 + -0.019674259217416, ), (ConnectorPort.A, -4, BigDecimal("1"), 1.103963670105, -0.0218619915377232), (ConnectorPort.A, -3, BigDecimal("-1"), 1.08733201897279, 0.02249991825158), @@ -1058,3815 +1058,3815 @@ trait TransformerTestData extends TransformerTestGrid { -3, BigDecimal("-0.9"), 1.08674692060804, - 0.0202514181939269 + 0.0202514181939269, ), ( ConnectorPort.A, -3, BigDecimal("-0.8"), 1.08615192912595, - 0.0180029179998106 + 0.0180029179998106, ), ( ConnectorPort.A, -3, BigDecimal("-0.7"), 1.08554701212492, - 0.0157544176687841 + 0.0157544176687841, ), ( ConnectorPort.A, -3, BigDecimal("-0.6"), 1.08493213651765, - 0.0135059172003913 + 0.0135059172003913, ), ( ConnectorPort.A, -3, BigDecimal("-0.5"), 1.08430726852129, - 0.011257416594166 + 0.011257416594166, ), ( ConnectorPort.A, -3, BigDecimal("-0.4"), 1.08367237364723, - 0.00900891584963238 + 0.00900891584963238, ), ( ConnectorPort.A, -3, BigDecimal("-0.3"), 1.08302741669076, - 0.00676041496630505 + 0.00676041496630505, ), ( ConnectorPort.A, -3, BigDecimal("-0.2"), 1.08237236172029, - 0.0045119139436882 + 0.0045119139436882, ), ( ConnectorPort.A, -3, BigDecimal("-0.1"), 1.08170717206634, - 0.00226341278127613 + 0.00226341278127613, ), ( ConnectorPort.A, -3, BigDecimal("0"), 1.08103181031021, - 0.0000149114785526847 + 0.0000149114785526847, ), ( ConnectorPort.A, -3, BigDecimal("0.1"), 1.08034623827232, - -0.00223358996500881 + -0.00223358996500881, ), ( ConnectorPort.A, -3, BigDecimal("0.2"), 1.07965041700025, - -0.00448209154994563 + -0.00448209154994563, ), ( ConnectorPort.A, -3, BigDecimal("0.3"), 1.07894430675637, - -0.006730593276806 + -0.006730593276806, ), ( ConnectorPort.A, -3, BigDecimal("0.4"), 1.07822786700521, - -0.00897909514614891 + -0.00897909514614891, ), ( ConnectorPort.A, -3, BigDecimal("0.5"), 1.07750105640042, - -0.0112275971585447 + -0.0112275971585447, ), ( ConnectorPort.A, -3, BigDecimal("0.6"), 1.07676383277138, - -0.0134760993145751 + -0.0134760993145751, ), ( ConnectorPort.A, -3, BigDecimal("0.7"), 1.0760161531094, - -0.0157246016148335 + -0.0157246016148335, ), ( ConnectorPort.A, -3, BigDecimal("0.8"), 1.07525797355358, - -0.0179731040599247 + -0.0179731040599247, ), ( ConnectorPort.A, -3, BigDecimal("0.9"), 1.07448924937621, - -0.0202216066504656 + -0.0202216066504656, ), ( ConnectorPort.A, -3, BigDecimal("1"), 1.0737099349678, - -0.0224701093870857 + -0.0224701093870857, ), ( ConnectorPort.A, -2, BigDecimal("-1"), 1.05902605337401, - 0.023107228343286 + 0.023107228343286, ), ( ConnectorPort.A, -2, BigDecimal("-0.9"), 1.05843041651441, - 0.0207979580865661 + 0.0207979580865661, ), ( ConnectorPort.A, -2, BigDecimal("-0.8"), 1.05782407954748, - 0.0184886876822516 + 0.0184886876822516, ), ( ConnectorPort.A, -2, BigDecimal("-0.7"), 1.05720700581082, - 0.0161794171298368 + 0.0161794171298368, ), ( ConnectorPort.A, -2, BigDecimal("-0.6"), 1.05657915782069, - 0.0138701464288047 + 0.0138701464288047, ), ( ConnectorPort.A, -2, BigDecimal("-0.5"), 1.05594049725962, - 0.0115608755786267 + 0.0115608755786267, ), ( ConnectorPort.A, -2, BigDecimal("-0.4"), 1.05529098496362, - 0.00925160457876267 + 0.00925160457876267, ), ( ConnectorPort.A, -2, BigDecimal("-0.3"), 1.05463058090905, - 0.00694233342866044 + 0.00694233342866044, ), ( ConnectorPort.A, -2, BigDecimal("-0.2"), 1.0539592441991, - 0.00463306212775601 + 0.00463306212775601, ), ( ConnectorPort.A, -2, BigDecimal("-0.1"), 1.0532769330498, - 0.00232379067547291 + 0.00232379067547291, ), ( ConnectorPort.A, -2, BigDecimal("0"), 1.05258360477573, - 0.0000145190712223228 + 0.0000145190712223228, ), ( ConnectorPort.A, -2, BigDecimal("0.1"), 1.05187921577518, - -0.00229475268559709 + -0.00229475268559709, ), ( ConnectorPort.A, -2, BigDecimal("0.2"), 1.05116372151496, - -0.00460402459559959 + -0.00460402459559959, ), ( ConnectorPort.A, -2, BigDecimal("0.3"), 1.05043707651473, - -0.00691329665941254 + -0.00691329665941254, ), ( ConnectorPort.A, -2, BigDecimal("0.4"), 1.0496992343308, - -0.00922256887767665 + -0.00922256887767665, ), ( ConnectorPort.A, -2, BigDecimal("0.5"), 1.04895014753959, - -0.011531841251046 + -0.011531841251046, ), ( ConnectorPort.A, -2, BigDecimal("0.6"), 1.04818976772044, - -0.0138411137801886 + -0.0138411137801886, ), ( ConnectorPort.A, -2, BigDecimal("0.7"), 1.04741804543799, - -0.0161503864657862 + -0.0161503864657862, ), ( ConnectorPort.A, -2, BigDecimal("0.8"), 1.04663493022402, - -0.018459659308535 + -0.018459659308535, ), ( ConnectorPort.A, -2, BigDecimal("0.9"), 1.04584037055874, - -0.0207689323091456 + -0.0207689323091456, ), ( ConnectorPort.A, -2, BigDecimal("1"), 1.0450343138515, - -0.0230782054683436 + -0.0230782054683436, ), ( ConnectorPort.A, -1, BigDecimal("-1"), 1.03217676324027, - 0.0237145585280039 + 0.0237145585280039, ), ( ConnectorPort.A, -1, BigDecimal("-0.9"), 1.03157100055975, - 0.0213445180779095 + 0.0213445180779095, ), ( ConnectorPort.A, -1, BigDecimal("-0.8"), 1.03095368930288, - 0.0189744774685169 + 0.0189744774685169, ), ( ConnectorPort.A, -1, BigDecimal("-0.7"), 1.03032478814181, - 0.0166044366992562 + 0.0166044366992562, ), ( ConnectorPort.A, -1, BigDecimal("-0.6"), 1.02968425476971, - 0.0142343957695436 + 0.0142343957695436, ), ( ConnectorPort.A, -1, BigDecimal("-0.5"), 1.0290320458854, - 0.0118643546787821 + 0.0118643546787821, ), ( ConnectorPort.A, -1, BigDecimal("-0.4"), 1.02836811717731, - 0.00949431342636016 + 0.00949431342636016, ), ( ConnectorPort.A, -1, BigDecimal("-0.3"), 1.02769242330705, - 0.00712427201165266 + 0.00712427201165266, ), ( ConnectorPort.A, -1, BigDecimal("-0.2"), 1.02700491789239, - 0.00475423043401966 + 0.00475423043401966, ), ( ConnectorPort.A, -1, BigDecimal("-0.1"), 1.0263055534898, - 0.00238418869280686 + 0.00238418869280686, ), ( ConnectorPort.A, -1, BigDecimal("0"), 1.02559428157635, - 0.0000141467873448151 + 0.0000141467873448151, ), ( ConnectorPort.A, -1, BigDecimal("0.1"), 1.02487105253106, - -0.00235589528305081 + -0.00235589528305081, ), ( ConnectorPort.A, -1, BigDecimal("0.2"), 1.02413581561573, - -0.00472593751908002 + -0.00472593751908002, ), ( ConnectorPort.A, -1, BigDecimal("0.3"), 1.02338851895507, - -0.00709597992145828 + -0.00709597992145828, ), ( ConnectorPort.A, -1, BigDecimal("0.4"), 1.0226291095163, - -0.00946602249091709 + -0.00946602249091709, ), ( ConnectorPort.A, -1, BigDecimal("0.5"), 1.02185753308803, - -0.0118360652282043 + -0.0118360652282043, ), ( ConnectorPort.A, -1, BigDecimal("0.6"), 1.02107373425853, - -0.0142061081340842 + -0.0142061081340842, ), ( ConnectorPort.A, -1, BigDecimal("0.7"), 1.02027765639326, - -0.016576151209338 + -0.016576151209338, ), ( ConnectorPort.A, -1, BigDecimal("0.8"), 1.01946924161175, - -0.0189461944547642 + -0.0189461944547642, ), ( ConnectorPort.A, -1, BigDecimal("0.9"), 1.01864843076367, - -0.0213162378711784 + -0.0213162378711784, ), ( ConnectorPort.A, -1, BigDecimal("1"), 1.01781516340425, - -0.0236862814594147 + -0.0236862814594147, ), ( ConnectorPort.A, 0, BigDecimal("-1"), 1.00667467871911, - 0.0243219072957343 + 0.0243219072957343, ), ( ConnectorPort.A, 0, BigDecimal("-0.9"), 1.00605921263868, - 0.0218910966580921 + 0.0218910966580921, ), ( ConnectorPort.A, 0, BigDecimal("-0.8"), 1.00543130713357, - 0.0194602858488637 + 0.0194602858488637, ), ( ConnectorPort.A, 0, BigDecimal("-0.7"), 1.0047909157835, - 0.0170294748674087 + 0.0170294748674087, ), ( ConnectorPort.A, 0, BigDecimal("-0.6"), 1.00413799100698, - 0.0145986637130708 + 0.0145986637130708, ), ( ConnectorPort.A, 0, BigDecimal("-0.5"), 1.00347248404206, - 0.0121678523851774 + 0.0121678523851774, ), ( ConnectorPort.A, 0, BigDecimal("-0.4"), 1.00279434492653, - 0.00973704088303931 + 0.00973704088303931, ), ( ConnectorPort.A, 0, BigDecimal("-0.3"), 1.00210352247738, - 0.00730622920595051 + 0.00730622920595051, ), ( ConnectorPort.A, 0, BigDecimal("-0.2"), 1.00139996426967, - 0.00487541735318787 + 0.00487541735318787, ), ( ConnectorPort.A, 0, BigDecimal("-0.1"), 1.00068361661459, - 0.00244460532401091 + 0.00244460532401091, ), ( ConnectorPort.A, 0, BigDecimal("0"), 0.999954424536941, - 0.0000137931176612275 + 0.0000137931176612275, ), ( ConnectorPort.A, 0, BigDecimal("0.1"), 0.999212331751719, - -0.00241701926663761 + -0.00241701926663761, ), ( ConnectorPort.A, 0, BigDecimal("0.2"), 0.99845728064004, - -0.00484783182968026 + -0.00484783182968026, ), ( ConnectorPort.A, 0, BigDecimal("0.3"), 0.997689212224214, - -0.00727864457228031 + -0.00727864457228031, ), ( ConnectorPort.A, 0, BigDecimal("0.4"), 0.996908066142007, - -0.00970945749527035 + -0.00970945749527035, ), ( ConnectorPort.A, 0, BigDecimal("0.5"), 0.996113780620051, - -0.0121402705995025 + -0.0121402705995025, ), ( ConnectorPort.A, 0, BigDecimal("0.6"), 0.995306292446364, - -0.0145710838858487 + -0.0145710838858487, ), ( ConnectorPort.A, 0, BigDecimal("0.7"), 0.994485536941961, - -0.0170018973552011 + -0.0170018973552011, ), ( ConnectorPort.A, 0, BigDecimal("0.8"), 0.993651447931513, - -0.0194327110084725 + -0.0194327110084725, ), ( ConnectorPort.A, 0, BigDecimal("0.9"), 0.99280395771303, - -0.0218635248465967 + -0.0218635248465967, ), ( ConnectorPort.A, 0, BigDecimal("1"), 0.99194299702652, - -0.0242943388705291 + -0.0242943388705291, ), ( ConnectorPort.A, 1, BigDecimal("-1"), 0.98242100499016, - 0.0249292732837263 + 0.0249292732837263, ), ( ConnectorPort.A, 1, BigDecimal("-0.9"), 0.981796267611054, - 0.0224376924644968 + 0.0224376924644968, ), ( ConnectorPort.A, 1, BigDecimal("-0.8"), 0.981158156688823, - 0.019946111460796 + 0.019946111460796, ), ( ConnectorPort.A, 1, BigDecimal("-0.7"), 0.980506620261764, - 0.0174545302719071 + 0.0174545302719071, ), ( ConnectorPort.A, 1, BigDecimal("-0.6"), 0.979841604996861, - 0.0149629488970946 + 0.0149629488970946, ), ( ConnectorPort.A, 1, BigDecimal("-0.5"), 0.979163056166092, - 0.0124713673356035 + 0.0124713673356035, ), ( ConnectorPort.A, 1, BigDecimal("-0.4"), 0.978470917621914, - 0.00997978558665933 + 0.00997978558665933, ), ( ConnectorPort.A, 1, BigDecimal("-0.3"), 0.977765131771884, - 0.00748820364946775 + 0.00748820364946775, ), ( ConnectorPort.A, 1, BigDecimal("-0.2"), 0.977045639552417, - 0.00499662152321397 + 0.00499662152321397, ), ( ConnectorPort.A, 1, BigDecimal("-0.1"), 0.976312380401615, - 0.00250503920706258 + 0.00250503920706258, ), ( ConnectorPort.A, 1, BigDecimal("0"), 0.975565292231162, - 0.0000134567001572926 + 0.0000134567001572926, ), ( ConnectorPort.A, 1, BigDecimal("0.1"), 0.974804311397244, - -0.00247812599838001 + -0.00247812599838001, ), ( ConnectorPort.A, 1, BigDecimal("0.2"), 0.974029372670451, - -0.0049697088894488 + -0.0049697088894488, ), ( ConnectorPort.A, 1, BigDecimal("0.3"), 0.973240409204641, - -0.00746129197397136 + -0.00746129197397136, ), ( ConnectorPort.A, 1, BigDecimal("0.4"), 0.972437352504711, - -0.00995287525289237 + -0.00995287525289237, ), ( ConnectorPort.A, 1, BigDecimal("0.5"), 0.971620132393254, - -0.0124444587271799 + -0.0124444587271799, ), ( ConnectorPort.A, 1, BigDecimal("0.6"), 0.97078867697604, - -0.0149360423978257 + -0.0149360423978257, ), ( ConnectorPort.A, 1, BigDecimal("0.7"), 0.969942912606292, - -0.0174276262658455 + -0.0174276262658455, ), ( ConnectorPort.A, 1, BigDecimal("0.8"), 0.969082763847711, - -0.0199192103322799 + -0.0199192103322799, ), ( ConnectorPort.A, 1, BigDecimal("0.9"), 0.968208153436193, - -0.0224107945981947 + -0.0224107945981947, ), ( ConnectorPort.A, 1, BigDecimal("1"), 0.967319002240194, - -0.0249023790646814 + -0.0249023790646814, ), ( ConnectorPort.A, 2, BigDecimal("-1"), 0.959326351461916, - 0.025536655258949 + 0.025536655258949, ), ( ConnectorPort.A, 2, BigDecimal("-0.9"), 0.958692784499275, - 0.022984304264225 + 0.022984304264225, ), ( ConnectorPort.A, 2, BigDecimal("-0.8"), 0.958044865723424, - 0.0204319530715357 + 0.0204319530715357, ), ( ConnectorPort.A, 2, BigDecimal("-0.7"), 0.957382537160275, - 0.0178796016800814 + 0.0178796016800814, ), ( ConnectorPort.A, 2, BigDecimal("-0.6"), 0.956705739223261, - 0.0153272500890402 + 0.0153272500890402, ), ( ConnectorPort.A, 2, BigDecimal("-0.5"), 0.956014410684269, - 0.0127748982975676 + 0.0127748982975676, ), ( ConnectorPort.A, 2, BigDecimal("-0.4"), 0.955308488643518, - 0.0102225463047959 + 0.0102225463047959, ), ( ConnectorPort.A, 2, BigDecimal("-0.3"), 0.954587908498331, - 0.0076701941098341 + 0.0076701941098341, ), ( ConnectorPort.A, 2, BigDecimal("-0.2"), 0.953852603910776, - 0.00511784171176699 + 0.00511784171176699, ), ( ConnectorPort.A, 2, BigDecimal("-0.1"), 0.953102506774115, - 0.00256548910965531 + 0.00256548910965531, ), ( ConnectorPort.A, 2, BigDecimal("0"), 0.952337547178039, - 0.0000131363025345216 + 0.0000131363025345216, ), ( ConnectorPort.A, 2, BigDecimal("0.1"), 0.951557653372631, - -0.00253921671058493 + -0.00253921671058493, ), ( ConnectorPort.A, 2, BigDecimal("0.2"), 0.950762751731016, - -0.00509156993071863 + -0.00509156993071863, ), ( ConnectorPort.A, 2, BigDecimal("0.3"), 0.949952766710642, - -0.00764392335890866 + -0.00764392335890866, ), ( ConnectorPort.A, 2, BigDecimal("0.4"), 0.949127620813153, - -0.0101962769962239 + -0.0101962769962239, ), ( ConnectorPort.A, 2, BigDecimal("0.5"), 0.948287234542783, - -0.0127486308437611 + -0.0127486308437611, ), ( ConnectorPort.A, 2, BigDecimal("0.6"), 0.947431526363226, - -0.0153009849026448 + -0.0153009849026448, ), ( ConnectorPort.A, 2, BigDecimal("0.7"), 0.946560412652918, - -0.0178533391740284 + -0.0178533391740284, ), ( ConnectorPort.A, 2, BigDecimal("0.8"), 0.945673807658669, - -0.0204056936590949 + -0.0204056936590949, ), ( ConnectorPort.A, 2, BigDecimal("0.9"), 0.944771623447575, - -0.0229580483590572 + -0.0229580483590572, ), ( ConnectorPort.A, 2, BigDecimal("1"), 0.943853769857146, - -0.0255104032751589 + -0.0255104032751589, ), ( ConnectorPort.A, 3, BigDecimal("-1"), 0.937309638289396, - 0.0261440521030076 + 0.0261440521030076, ), ( ConnectorPort.A, 3, BigDecimal("-0.9"), 0.936667693006795, - 0.0235309309390136 + 0.0235309309390136, ), ( ConnectorPort.A, 3, BigDecimal("-0.8"), 0.936010372616478, - 0.0209178095629393 + 0.0209178095629393, ), ( ConnectorPort.A, 3, BigDecimal("-0.7"), 0.93533761263946, - 0.0183046879738953 + 0.0183046879738953, ), ( ConnectorPort.A, 3, BigDecimal("-0.6"), 0.934649346708417, - 0.015691566170966 + 0.015691566170966, ), ( ConnectorPort.A, 3, BigDecimal("-0.5"), 0.933945506532227, - 0.0130784441532096 + 0.0130784441532096, ), ( ConnectorPort.A, 3, BigDecimal("-0.4"), 0.933226021859156, - 0.0104653219196569 + 0.0104653219196569, ), ( ConnectorPort.A, 3, BigDecimal("-0.3"), 0.932490820438636, - 0.00785219946931139 + 0.00785219946931139, ), ( ConnectorPort.A, 3, BigDecimal("-0.2"), 0.931739827981568, - 0.00523907680114834 + 0.00523907680114834, ), ( ConnectorPort.A, 3, BigDecimal("-0.1"), 0.930972968119121, - 0.00262595391411435 + 0.00262595391411435, ), ( ConnectorPort.A, 3, BigDecimal("0"), 0.930190162359945, - 0.0000128308071266819 + 0.0000128308071266819, ), ( ConnectorPort.A, 3, BigDecimal("0.1"), 0.929391330045746, - -0.00260029252092719 + -0.00260029252092719, ), ( ConnectorPort.A, 3, BigDecimal("0.2"), 0.928576388305162, - -0.00521341607119046 + -0.00521341607119046, ), ( ConnectorPort.A, 3, BigDecimal("0.3"), 0.927745252005883, - -0.00782653984483726 + -0.00782653984483726, ), ( ConnectorPort.A, 3, BigDecimal("0.4"), 0.92689783370491, - -0.010439663843074 + -0.010439663843074, ), ( ConnectorPort.A, 3, BigDecimal("0.5"), 0.926034043596923, - -0.0130527880671392 + -0.0130527880671392, ), ( ConnectorPort.A, 3, BigDecimal("0.6"), 0.925153789460646, - -0.0156659125183051 + -0.0156659125183051, ), ( ConnectorPort.A, 3, BigDecimal("0.7"), 0.924256976603146, - -0.0182790371978777 + -0.0182790371978777, ), ( ConnectorPort.A, 3, BigDecimal("0.8"), 0.923343507801969, - -0.0208921621071982 + -0.0208921621071982, ), ( ConnectorPort.A, 3, BigDecimal("0.9"), 0.922413283245032, - -0.0235052872476434 + -0.0235052872476434, ), ( ConnectorPort.A, 3, BigDecimal("1"), 0.921466200468159, - -0.0261184126206265 + -0.0261184126206265, ), ( ConnectorPort.A, 4, BigDecimal("-1"), 0.916297152002557, - 0.0267514627991171 + 0.0267514627991171, ), ( ConnectorPort.A, 4, BigDecimal("-0.9"), 0.915647289147419, - 0.0240775714722086 + 0.0240775714722086, ), ( ConnectorPort.A, 4, BigDecimal("-0.8"), 0.914980982001204, - 0.0214036799184718 + 0.0214036799184718, ), ( ConnectorPort.A, 4, BigDecimal("-0.7"), 0.914298159066424, - 0.0187297881369204 + 0.0187297881369204, ), ( ConnectorPort.A, 4, BigDecimal("-0.6"), 0.913598746642793, - 0.0160558961265377 + 0.0160558961265377, ), ( ConnectorPort.A, 4, BigDecimal("-0.5"), 0.912882668784197, - 0.0133820038862763 + 0.0133820038862763, ), ( ConnectorPort.A, 4, BigDecimal("-0.4"), 0.912149847253943, - 0.010708111415057 + 0.010708111415057, ), ( ConnectorPort.A, 4, BigDecimal("-0.3"), 0.911400201478191, - 0.00803421871176822 + 0.00803421871176822, ), ( ConnectorPort.A, 4, BigDecimal("-0.2"), 0.910633648497533, - 0.00536032577526581 + 0.00536032577526581, ), ( ConnectorPort.A, 4, BigDecimal("-0.1"), 0.909850102916617, - 0.00268643260437178 + 0.00268643260437178, ), ( ConnectorPort.A, 4, BigDecimal("0"), 0.909049476851765, - 0.0000125391978738261 + 0.0000125391978738261, ), ( ConnectorPort.A, 4, BigDecimal("0.1"), 0.908231679876474, - -0.00266135444547526 + -0.00266135444547526, ), ( ConnectorPort.A, 4, BigDecimal("0.2"), 0.907396618964748, - -0.00533524832695871 + -0.00533524832695871, ), ( ConnectorPort.A, 4, BigDecimal("0.3"), 0.90654419843214, - -0.00800914244789641 + -0.00800914244789641, ), ( ConnectorPort.A, 4, BigDecimal("0.4"), 0.905674319874432, - -0.0106830368096457 + -0.0106830368096457, ), ( ConnectorPort.A, 4, BigDecimal("0.5"), 0.904786882103834, - -0.0133569314136022 + -0.0133569314136022, ), ( ConnectorPort.A, 4, BigDecimal("0.6"), 0.903881781082618, - -0.0160308262612012 + -0.0160308262612012, ), ( ConnectorPort.A, 4, BigDecimal("0.7"), 0.902958909854047, - -0.0187047213539179 + -0.0187047213539179, ), ( ConnectorPort.A, 4, BigDecimal("0.8"), 0.902018158470513, - -0.0213786166932688 + -0.0213786166932688, ), ( ConnectorPort.A, 4, BigDecimal("0.9"), 0.901059413918729, - -0.0240525122808131 + -0.0240525122808131, ), ( ConnectorPort.A, 4, BigDecimal("1"), 0.900082560041867, - -0.0267264081181527 + -0.0267264081181527, ), ( ConnectorPort.A, 5, BigDecimal("-1"), 0.896221727050347, - 0.0273588864208129 + 0.0273588864208129, ), ( ConnectorPort.A, 5, BigDecimal("-0.9"), 0.895564416790433, - 0.0246242249374753 + 0.0246242249374753, ), ( ConnectorPort.A, 5, BigDecimal("-0.8"), 0.894889546310647, - 0.0218895632119166 + 0.0218895632119166, ), ( ConnectorPort.A, 5, BigDecimal("-0.7"), 0.894197036560895, - 0.0191549012430461 + 0.0191549012430461, ), ( ConnectorPort.A, 5, BigDecimal("-0.6"), 0.893486805931015, - 0.0164202390297385 + 0.0164202390297385, ), ( ConnectorPort.A, 5, BigDecimal("-0.5"), 0.892758770198814, - 0.0136855765708318 + 0.0136855765708318, ), ( ConnectorPort.A, 5, BigDecimal("-0.4"), 0.892012842475918, - 0.0109509138651274 + 0.0109509138651274, ), ( ConnectorPort.A, 5, BigDecimal("-0.3"), 0.891248933151341, - 0.00821625091138941 + 0.00821625091138941, ), ( ConnectorPort.A, 5, BigDecimal("-0.2"), 0.890466949832678, - 0.00548158770834329 + 0.00548158770834329, ), ( ConnectorPort.A, 5, BigDecimal("-0.1"), 0.889666797284832, - 0.00274692425467551 + 0.00274692425467551, ), ( ConnectorPort.A, 5, BigDecimal("0"), 0.88884837736617, - 0.0000122605490321726 + 0.0000122605490321726, ), ( ConnectorPort.A, 5, BigDecimal("0.1"), 0.888011588961992, - -0.00272240340998137 + -0.00272240340998137, ), ( ConnectorPort.A, 5, BigDecimal("0.2"), 0.887156327915216, - -0.0054570676238018 + -0.0054570676238018, ), ( ConnectorPort.A, 5, BigDecimal("0.3"), 0.886282486954139, - -0.00819173209390892 + -0.00819173209390892, ), ( ConnectorPort.A, 5, BigDecimal("0.4"), 0.885389955617163, - -0.0109263968218263 + -0.0109263968218263, ), ( ConnectorPort.A, 5, BigDecimal("0.5"), 0.884478620174337, - -0.0136610618091228 + -0.0136610618091228, ), ( ConnectorPort.A, 5, BigDecimal("0.6"), 0.883548363545585, - -0.0163957270574133 + -0.0163957270574133, ), ( ConnectorPort.A, 5, BigDecimal("0.7"), 0.882599065215458, - -0.0191303925683602 + -0.0191303925683602, ), ( ConnectorPort.A, 5, BigDecimal("0.8"), 0.881630601144261, - -0.0218650583436745 + -0.0218650583436745, ), ( ConnectorPort.A, 5, BigDecimal("0.9"), 0.880642843675374, - -0.024599724385117 + -0.024599724385117, ), ( ConnectorPort.A, 5, BigDecimal("1"), 0.879635661438599, - -0.0273343906944998 + -0.0273343906944998, ), ( ConnectorPort.A, 6, BigDecimal("-1"), 0.877022034099252, - 0.0279663221221337 + 0.0279663221221337, ), ( ConnectorPort.A, 6, BigDecimal("-0.9"), 0.876357755960366, - 0.0251708904889815 + 0.0251708904889815, ), ( ConnectorPort.A, 6, BigDecimal("-0.8"), 0.875674754078128, - 0.0223754585975588 + 0.0223754585975588, ), ( ConnectorPort.A, 6, BigDecimal("-0.7"), 0.874972941295997, - 0.0195800264466633 + 0.0195800264466633, ), ( ConnectorPort.A, 6, BigDecimal("-0.6"), 0.874252227492712, - 0.0167845940350519 + 0.0167845940350519, ), ( ConnectorPort.A, 6, BigDecimal("-0.5"), 0.873512519519852, - 0.0139891613614397 + 0.0139891613614397, ), ( ConnectorPort.A, 6, BigDecimal("-0.4"), 0.872753721136625, - 0.0111937284244993 + 0.0111937284244993, ), ( ConnectorPort.A, 6, BigDecimal("-0.3"), 0.871975732941789, - 0.00839829522285939 + 0.00839829522285939, ), ( ConnectorPort.A, 6, BigDecimal("-0.2"), 0.871178452302574, - 0.00560286175510445 + 0.00560286175510445, ), ( ConnectorPort.A, 6, BigDecimal("-0.1"), 0.870361773280489, - 0.00280742801977313 + 0.00280742801977313, ), ( ConnectorPort.A, 6, BigDecimal("0"), 0.869525586553862, - 0.0000119940153575949 + 0.0000119940153575949, ), ( ConnectorPort.A, 6, BigDecimal("0.1"), 0.868669779336989, - -0.00278344025969814 + -0.00278344025969814, ), ( ConnectorPort.A, 6, BigDecimal("0.2"), 0.867794235295722, - -0.00557887480699857 + -0.00557887480699857, ), ( ConnectorPort.A, 6, BigDecimal("0.3"), 0.866898834459354, - -0.00837430962819862 + -0.00837430962819862, ), ( ConnectorPort.A, 6, BigDecimal("0.4"), 0.865983453128614, - -0.0111697447250045 + -0.0111697447250045, ), ( ConnectorPort.A, 6, BigDecimal("0.5"), 0.865047963779603, - -0.0139651800991754 + -0.0139651800991754, ), ( ConnectorPort.A, 6, BigDecimal("0.6"), 0.864092234963478, - -0.0167606157525242 + -0.0167606157525242, ), ( ConnectorPort.A, 6, BigDecimal("0.7"), 0.863116131201677, - -0.0195560516869199 + -0.0195560516869199, ), ( ConnectorPort.A, 6, BigDecimal("0.8"), 0.862119512876472, - -0.0223514879042882 + -0.0223514879042882, ), ( ConnectorPort.A, 6, BigDecimal("0.9"), 0.861102236116629, - -0.0251469244066139 + -0.0251469244066139, ), ( ConnectorPort.A, 6, BigDecimal("1"), 0.860064152677919, - -0.0279423611959415 + -0.0279423611959415, ), ( ConnectorPort.A, 7, BigDecimal("-1"), 0.858641959186664, - 0.0285737691290579 + 0.0285737691290579, ), ( ConnectorPort.A, 7, BigDecimal("-0.9"), 0.857971201991724, - 0.0257175673528338 + 0.0257175673528338, ), ( ConnectorPort.A, 7, BigDecimal("-0.8"), 0.857280509092796, - 0.0228613653016216 + 0.0228613653016216, ), ( ConnectorPort.A, 7, BigDecimal("-0.7"), 0.856569784654187, - 0.0200051629740995 + 0.0200051629740995, ), ( ConnectorPort.A, 7, BigDecimal("-0.6"), 0.855838929418557, - 0.0171489603688983 + 0.0171489603688983, ), ( ConnectorPort.A, 7, BigDecimal("-0.5"), 0.855087840632218, - 0.0142927574846006 + 0.0142927574846006, ), ( ConnectorPort.A, 7, BigDecimal("-0.4"), 0.854316411966964, - 0.0114365543197398 + 0.0114365543197398, ), ( ConnectorPort.A, 7, BigDecimal("-0.3"), 0.853524533438308, - 0.00858035087279871 + 0.00858035087279871, ), ( ConnectorPort.A, 7, BigDecimal("-0.2"), 0.852712091319953, - 0.00572414714220867 + 0.00572414714220867, ), ( ConnectorPort.A, 7, BigDecimal("-0.1"), 0.851878968054342, - 0.00286794312634817 + 0.00286794312634817, ), ( ConnectorPort.A, 7, BigDecimal("0"), 0.851025042159099, - 0.0000117388235414818 + 0.0000117388235414818, ), ( ConnectorPort.A, 7, BigDecimal("0.1"), 0.850150188129183, - -0.00284446576794258 + -0.00284446576794258, ), ( ConnectorPort.A, 7, BigDecimal("0.2"), 0.849254276334546, - -0.00570067064989212 + -0.00570067064989212, ), ( ConnectorPort.A, 7, BigDecimal("0.3"), 0.848337172913088, - -0.00855687582415354 + -0.00855687582415354, ), ( ConnectorPort.A, 7, BigDecimal("0.4"), 0.847398739658691, - -0.0114130812926333 + -0.0114130812926333, ), ( ConnectorPort.A, 7, BigDecimal("0.5"), 0.846438833904073, - -0.0142692870572994 + -0.0142692870572994, ), ( ConnectorPort.A, 7, BigDecimal("0.6"), 0.845457308398231, - -0.0171254931201827 + -0.0171254931201827, ), ( ConnectorPort.A, 7, BigDecimal("0.7"), 0.844454011178183, - -0.0199816994833795 + -0.0199816994833795, ), ( ConnectorPort.A, 7, BigDecimal("0.8"), 0.843428785434739, - -0.0228379061490529 + -0.0228379061490529, ), ( ConnectorPort.A, 7, BigDecimal("0.9"), 0.842381469371976, - -0.0256941131194345 + -0.0256941131194345, ), ( ConnectorPort.A, 7, BigDecimal("1"), 0.841311896060106, - -0.0285503203968269 + -0.0285503203968269, ), ( ConnectorPort.A, 8, BigDecimal("-1"), 0.841030060479342, - 0.0291812267320097 + 0.0291812267320097, ), ( ConnectorPort.A, 8, BigDecimal("-0.9"), 0.840353322288959, - 0.0262642548195838 + 0.0262642548195838, ), ( ConnectorPort.A, 8, BigDecimal("-0.8"), 0.83965538716051, - 0.0233472826147727 + 0.0233472826147727, ), ( ConnectorPort.A, 8, BigDecimal("-0.7"), 0.838936149988622, - 0.0204303101161266 + 0.0204303101161266, ), ( ConnectorPort.A, 8, BigDecimal("-0.6"), 0.838195501731806, - 0.0175133373221414 + 0.0175133373221414, ), ( ConnectorPort.A, 8, BigDecimal("-0.5"), 0.83743332932346, - 0.0145963642312576 + 0.0145963642312576, ), ( ConnectorPort.A, 8, BigDecimal("-0.4"), 0.836649515578583, - 0.0116793908418586 + 0.0116793908418586, ), ( ConnectorPort.A, 8, BigDecimal("-0.3"), 0.835843939095994, - 0.00876241715226996 + 0.00876241715226996, ), ( ConnectorPort.A, 8, BigDecimal("-0.2"), 0.835016474155855, - 0.0058454431607575 + 0.0058454431607575, ), ( ConnectorPort.A, 8, BigDecimal("-0.1"), 0.834166990612276, - 0.00292846886552601 + 0.00292846886552601, ), ( ConnectorPort.A, 8, BigDecimal("0"), 0.833295353780784, - 0.0000114942647176662 + 0.0000114942647176662, ), ( ConnectorPort.A, 8, BigDecimal("0.1"), 0.8324014243204, - -0.00290548064358957 + -0.00290548064358957, ), ( ConnectorPort.A, 8, BigDecimal("0.2"), 0.831485058110058, - -0.00582245586138358 + -0.00582245586138358, ), ( ConnectorPort.A, 8, BigDecimal("0.3"), 0.830546106119103, - -0.00873943139072012 + -0.00873943139072012, ), ( ConnectorPort.A, 8, BigDecimal("0.4"), 0.829584414271562, - -0.0116564072337245 + -0.0116564072337245, ), ( ConnectorPort.A, 8, BigDecimal("0.5"), 0.828599823303866, - -0.0145733833925936 + -0.0145733833925936, ), ( ConnectorPort.A, 8, BigDecimal("0.6"), 0.827592168615705, - -0.0174903598695977 + -0.0174903598695977, ), ( ConnectorPort.A, 8, BigDecimal("0.7"), 0.826561280113639, - -0.0204073366670832 + -0.0204073366670832, ), ( ConnectorPort.A, 8, BigDecimal("0.8"), 0.825506982047084, - -0.0233243137874742 + -0.0233243137874742, ), ( ConnectorPort.A, 8, BigDecimal("0.9"), 0.824429092836285, - -0.0262412912332756 + -0.0262412912332756, ), ( ConnectorPort.A, 8, BigDecimal("1"), 0.823327424891804, - -0.0291582690070747 + -0.0291582690070747, ), ( ConnectorPort.A, 9, BigDecimal("-1"), 0.824139091550437, - 0.0297886942792841 + 0.0297886942792841, ), ( ConnectorPort.A, 9, BigDecimal("-0.9"), 0.823456879605168, - 0.026810952237653 + 0.026810952237653, ), ( ConnectorPort.A, 9, BigDecimal("-0.8"), 0.822752159383568, - 0.0238332098855486 + 0.0238332098855486, ), ( ConnectorPort.A, 9, BigDecimal("-0.7"), 0.822024815903447, - 0.0208554672213847 + 0.0208554672213847, ), ( ConnectorPort.A, 9, BigDecimal("-0.6"), 0.821274729668807, - 0.017877724243513 + 0.017877724243513, ), ( ConnectorPort.A, 9, BigDecimal("-0.5"), 0.820501776564291, - 0.0148999809502215 + 0.0148999809502215, ), ( ConnectorPort.A, 9, BigDecimal("-0.4"), 0.819705827744304, - 0.0119222373397329 + 0.0119222373397329, ), ( ConnectorPort.A, 9, BigDecimal("-0.3"), 0.818886749516568, - 0.00894449341020311 + 0.00894449341020311, ), ( ConnectorPort.A, 9, BigDecimal("-0.2"), 0.818044403219829, - 0.0059667491597195 + 0.0059667491597195, ), ( ConnectorPort.A, 9, BigDecimal("-0.1"), 0.817178645095452, - 0.00298900458629903 + 0.00298900458629903, ), ( ConnectorPort.A, 9, BigDecimal("0"), 0.816289326152605, - 0.0000112596878866997 + 0.0000112596878866997, ), ( ConnectorPort.A, 9, BigDecimal("0.1"), 0.815376292026695, - -0.0029664855376469 + -0.0029664855376469, ), ( ConnectorPort.A, 9, BigDecimal("0.2"), 0.81443938283074, - -0.00594423109250713 + -0.00594423109250713, ), ( ConnectorPort.A, 9, BigDecimal("0.3"), 0.813478432999293, - -0.00892197697897786 + -0.00892197697897786, ), ( ConnectorPort.A, 9, BigDecimal("0.4"), 0.812493271124543, - -0.0118997231994233 + -0.0118997231994233, ), ( ConnectorPort.A, 9, BigDecimal("0.5"), 0.811483719784173, - -0.0148774697562908 + -0.0148774697562908, ), ( ConnectorPort.A, 9, BigDecimal("0.6"), 0.810449595360531, - -0.0178552166521133 + -0.0178552166521133, ), ( ConnectorPort.A, 9, BigDecimal("0.7"), 0.809390707850645, - -0.0208329638895114 + -0.0208329638895114, ), ( ConnectorPort.A, 9, BigDecimal("0.8"), 0.808306860666568, - -0.023810711471197 + -0.023810711471197, ), ( ConnectorPort.A, 9, BigDecimal("0.9"), 0.807197850425516, - -0.0267884593999754 + -0.0267884593999754, ), ( ConnectorPort.A, 9, BigDecimal("1"), 0.806063466729219, - -0.0297662076787489 + -0.0297662076787489, ), ( ConnectorPort.A, 10, BigDecimal("-1"), 0.807925581862439, - 0.0303961711712593 + 0.0303961711712593, ), ( ConnectorPort.A, 10, BigDecimal("-0.9"), 0.80723841252684, - 0.0273576590075458 + 0.0273576590075458, ), ( ConnectorPort.A, 10, BigDecimal("-0.8"), 0.806527372646608, - 0.0243191465145681 + 0.0243191465145681, ), ( ConnectorPort.A, 10, BigDecimal("-0.7"), 0.805792336740328, - 0.0212806336905953 + 0.0212806336905953, ), ( ConnectorPort.A, 10, BigDecimal("-0.6"), 0.80503317416582, - 0.0182421205338254 + 0.0182421205338254, ), ( ConnectorPort.A, 10, BigDecimal("-0.5"), 0.80424974899546, - 0.0152036070423834 + 0.0152036070423834, ), ( ConnectorPort.A, 10, BigDecimal("-0.4"), 0.803441919884922, - 0.0121650932143196 + 0.0121650932143196, ), ( ConnectorPort.A, 10, BigDecimal("-0.3"), 0.802609539935054, - 0.0091265790476078 + 0.0091265790476078, ), ( ConnectorPort.A, 10, BigDecimal("-0.2"), 0.801752456546514, - 0.00608806454014298 + 0.00608806454014298, ), ( ConnectorPort.A, 10, BigDecimal("-0.1"), 0.800870511266842, - 0.0030495496897396 + 0.0030495496897396, ), ( ConnectorPort.A, 10, BigDecimal("0"), 0.799963539629553, - 0.0000110344941289201 + 0.0000110344941289201, ), ( ConnectorPort.A, 10, BigDecimal("0.1"), 0.799031370984863, - -0.0030274810490428 + -0.0030274810490428, ), ( ConnectorPort.A, 10, BigDecimal("0.2"), 0.798073828321583, - -0.00606599694221734 + -0.00606599694221734, ), ( ConnectorPort.A, 10, BigDecimal("0.3"), 0.797090728079733, - -0.00910451318792664 + -0.00910451318792664, ), ( ConnectorPort.A, 10, BigDecimal("0.4"), 0.796081879953352, - -0.0121430297887958 + -0.0121430297887958, ), ( ConnectorPort.A, 10, BigDecimal("0.5"), 0.79504708668297, - -0.0151815467475456 + -0.0151815467475456, ), ( ConnectorPort.A, 10, BigDecimal("0.6"), 0.793986143837166, - -0.018220064066996 + -0.018220064066996, ), ( ConnectorPort.A, 10, BigDecimal("0.7"), 0.792898839582582, - -0.021258581750069 + -0.021258581750069, ), ( ConnectorPort.A, 10, BigDecimal("0.8"), 0.791784954441728, - -0.024297099799792 + -0.024297099799792, ), ( ConnectorPort.A, 10, BigDecimal("0.9"), 0.790644261037859, - -0.0273356182193014 + -0.0273356182193014, ), ( ConnectorPort.A, 10, BigDecimal("1"), 0.789476523826166, - -0.0303741370118462 + -0.0303741370118462, ), ( ConnectorPort.B, -10, BigDecimal("-1"), 0.755006009039332, - 0.0182414304718007 + 0.0182414304718007, ), ( ConnectorPort.B, -10, BigDecimal("-0.9"), 0.754544409479012, - 0.0164183224935691 + 0.0164183224935691, ), ( ConnectorPort.B, -10, BigDecimal("-0.8"), 0.754073480350179, - 0.0145952143866478 + 0.0145952143866478, ), ( ConnectorPort.B, -10, BigDecimal("-0.7"), 0.753593186837628, - 0.0127721061505565 + 0.0127721061505565, ), ( ConnectorPort.B, -10, BigDecimal("-0.6"), 0.753103493255236, - 0.0109489977848031 + 0.0109489977848031, ), ( ConnectorPort.B, -10, BigDecimal("-0.5"), 0.752604363031546, - 0.00912588928888304 + 0.00912588928888304, ), ( ConnectorPort.B, -10, BigDecimal("-0.4"), 0.752095758694897, - 0.00730278066227947 + 0.00730278066227947, ), ( ConnectorPort.B, -10, BigDecimal("-0.3"), 0.751577641858037, - 0.00547967190446287 + 0.00547967190446287, ), ( ConnectorPort.B, -10, BigDecimal("-0.2"), 0.75104997320225, - 0.00365656301489095 + 0.00365656301489095, ), ( ConnectorPort.B, -10, BigDecimal("-0.1"), 0.750512712460944, - 0.00183345399300819 + 0.00183345399300819, ), ( ConnectorPort.B, -10, BigDecimal("0"), 0.749965818402706, - 0.0000103448382458858 + 0.0000103448382458858, ), ( ConnectorPort.B, -10, BigDecimal("0.1"), 0.749409248813789, - -0.00181276444997821 + -0.00181276444997821, ), ( ConnectorPort.B, -10, BigDecimal("0.2"), 0.74884296048003, - -0.00363587387226018 + -0.00363587387226018, ), ( ConnectorPort.B, -10, BigDecimal("0.3"), 0.74826690916816, - -0.00545898342921021 + -0.00545898342921021, ), ( ConnectorPort.B, -10, BigDecimal("0.4"), 0.747681049606505, - -0.00728209312145274 + -0.00728209312145274, ), ( ConnectorPort.B, -10, BigDecimal("0.5"), 0.747085335465038, - -0.00910520294962691 + -0.00910520294962691, ), ( ConnectorPort.B, -10, BigDecimal("0.6"), 0.746479719334773, - -0.0109283129143865 + -0.0109283129143865, ), ( ConnectorPort.B, -10, BigDecimal("0.7"), 0.74586415270647, - -0.0127514230164008 + -0.0127514230164008, ), ( ConnectorPort.B, -10, BigDecimal("0.8"), 0.745238585948635, - -0.0145745332563544 + -0.0145745332563544, ), ( ConnectorPort.B, -10, BigDecimal("0.9"), 0.744602968284773, - -0.0163976436349476 + -0.0163976436349476, ), ( ConnectorPort.B, -10, BigDecimal("1"), 0.74395724776989, - -0.0182207541528969 + -0.0182207541528969, ), ( ConnectorPort.B, -9, BigDecimal("-1"), 0.78017287600731, - 0.018849478154194 + 0.018849478154194, ), ( ConnectorPort.B, -9, BigDecimal("-0.9"), 0.779695889794979, - 0.0169655999100214 + 0.0169655999100214, ), ( ConnectorPort.B, -9, BigDecimal("-0.8"), 0.779209263028518, - 0.0150817215328694 + 0.0150817215328694, ), ( ConnectorPort.B, -9, BigDecimal("-0.7"), 0.778712959732216, - 0.0131978430222418 + 0.0131978430222418, ), ( ConnectorPort.B, -9, BigDecimal("-0.6"), 0.77820694303041, - 0.0113139643776299 + 0.0113139643776299, ), ( ConnectorPort.B, -9, BigDecimal("-0.5"), 0.777691175132598, - 0.00943008559851245 + 0.00943008559851245, ), ( ConnectorPort.B, -9, BigDecimal("-0.4"), 0.77716561731806, - 0.00754620668435543 + 0.00754620668435543, ), ( ConnectorPort.B, -9, BigDecimal("-0.3"), 0.776630229919971, - 0.00566232763461165 + 0.00566232763461165, ), ( ConnectorPort.B, -9, BigDecimal("-0.2"), 0.776084972308991, - 0.00377844844872068 + 0.00377844844872068, ), ( ConnectorPort.B, -9, BigDecimal("-0.1"), 0.775529802876309, - 0.00189456912610848 + 0.00189456912610848, ), ( ConnectorPort.B, -9, BigDecimal("0"), 0.77496467901613, - 0.0000106896661874416 + 0.0000106896661874416, ), ( ConnectorPort.B, -9, BigDecimal("0.1"), 0.774389557107582, - -0.00187318993164411 + -0.00187318993164411, ), ( ConnectorPort.B, -9, BigDecimal("0.2"), 0.773804392496031, - -0.00375706966800219 + -0.00375706966800219, ), ( ConnectorPort.B, -9, BigDecimal("0.3"), 0.773209139473766, - -0.00564094954351721 + -0.00564094954351721, ), ( ConnectorPort.B, -9, BigDecimal("0.4"), 0.772603751260056, - -0.00752482955883452 + -0.00752482955883452, ), ( ConnectorPort.B, -9, BigDecimal("0.5"), 0.77198817998054, - -0.00940870971461444 + -0.00940870971461444, ), ( ConnectorPort.B, -9, BigDecimal("0.6"), 0.771362376645932, - -0.0112925900115327 + -0.0112925900115327, ), ( ConnectorPort.B, -9, BigDecimal("0.7"), 0.770726291130019, - -0.0131764704502808 + -0.0131764704502808, ), ( ConnectorPort.B, -9, BigDecimal("0.8"), 0.770079872146923, - -0.0150603510315661 + -0.0150603510315661, ), ( ConnectorPort.B, -9, BigDecimal("0.9"), 0.769423067227599, - -0.0169442317561124 + -0.0169442317561124, ), ( ConnectorPort.B, -9, BigDecimal("1"), 0.768755822695553, - -0.0188281126246601 + -0.0188281126246601, ), ( ConnectorPort.B, -8, BigDecimal("-1"), 0.805339742975287, - 0.0194575258365874 + 0.0194575258365874, ), ( ConnectorPort.B, -8, BigDecimal("-0.9"), 0.804847370110946, - 0.0175128773264737 + 0.0175128773264737, ), ( ConnectorPort.B, -8, BigDecimal("-0.8"), 0.804345045706857, - 0.015568228679091 + 0.015568228679091, ), ( ConnectorPort.B, -8, BigDecimal("-0.7"), 0.803832732626804, - 0.0136235798939269 + 0.0136235798939269, ), ( ConnectorPort.B, -8, BigDecimal("-0.6"), 0.803310392805585, - 0.0116789309704566 + 0.0116789309704566, ), ( ConnectorPort.B, -8, BigDecimal("-0.5"), 0.802777987233649, - 0.00973428190814192 + 0.00973428190814192, ), ( ConnectorPort.B, -8, BigDecimal("-0.4"), 0.802235475941223, - 0.00778963270643144 + 0.00778963270643144, ), ( ConnectorPort.B, -8, BigDecimal("-0.3"), 0.801682817981906, - 0.0058449833647604 + 0.0058449833647604, ), ( ConnectorPort.B, -8, BigDecimal("-0.2"), 0.801119971415733, - 0.00390033388255032 + 0.00390033388255032, ), ( ConnectorPort.B, -8, BigDecimal("-0.1"), 0.800546893291674, - 0.00195568425920872 + 0.00195568425920872, ), ( ConnectorPort.B, -8, BigDecimal("0"), 0.799963539629553, - 0.0000110344941289503 + 0.0000110344941289503, ), ( ConnectorPort.B, -8, BigDecimal("0.1"), 0.799369865401375, - -0.00193361541331008 + -0.00193361541331008, ), ( ConnectorPort.B, -8, BigDecimal("0.2"), 0.798765824512032, - -0.0038782654637442 + -0.0038782654637442, ), ( ConnectorPort.B, -8, BigDecimal("0.3"), 0.798151369779371, - -0.00582291565782424 + -0.00582291565782424, ), ( ConnectorPort.B, -8, BigDecimal("0.4"), 0.797526452913606, - -0.00776756599621625 + -0.00776756599621625, ), ( ConnectorPort.B, -8, BigDecimal("0.5"), 0.796891024496041, - -0.00971221647960199 + -0.00971221647960199, ), ( ConnectorPort.B, -8, BigDecimal("0.6"), 0.796245033957091, - -0.011656867108679 + -0.011656867108679, ), ( ConnectorPort.B, -8, BigDecimal("0.7"), 0.795588429553568, - -0.0136015178841608 + -0.0136015178841608, ), ( ConnectorPort.B, -8, BigDecimal("0.8"), 0.79492115834521, - -0.015546168806778 + -0.015546168806778, ), ( ConnectorPort.B, -8, BigDecimal("0.9"), 0.794243166170425, - -0.0174908198772774 + -0.0174908198772774, ), ( ConnectorPort.B, -8, BigDecimal("1"), 0.793554397621216, - -0.0194354710964233 + -0.0194354710964233, ), ( ConnectorPort.B, -7, BigDecimal("-1"), 0.830506609943265, - 0.0200655735189807 + 0.0200655735189807, ), ( ConnectorPort.B, -7, BigDecimal("-0.9"), 0.829998850426913, - 0.018060154742926 + 0.018060154742926, ), ( ConnectorPort.B, -7, BigDecimal("-0.8"), 0.829480828385196, - 0.0160547358253125 + 0.0160547358253125, ), ( ConnectorPort.B, -7, BigDecimal("-0.7"), 0.828952505521391, - 0.0140493167656122 + 0.0140493167656122, ), ( ConnectorPort.B, -7, BigDecimal("-0.6"), 0.828413842580759, - 0.0120438975632834 + 0.0120438975632834, ), ( ConnectorPort.B, -7, BigDecimal("-0.5"), 0.827864799334701, - 0.0100384782177713 + 0.0100384782177713, ), ( ConnectorPort.B, -7, BigDecimal("-0.4"), 0.827305334564386, - 0.00803305872850738 + 0.00803305872850738, ), ( ConnectorPort.B, -7, BigDecimal("-0.3"), 0.82673540604384, - 0.00602763909490915 + 0.00602763909490915, ), ( ConnectorPort.B, -7, BigDecimal("-0.2"), 0.826154970522475, - 0.00402221931638 + 0.00402221931638, ), ( ConnectorPort.B, -7, BigDecimal("-0.1"), 0.825563983707039, - 0.00201679939230899 + 0.00201679939230899, ), ( ConnectorPort.B, -7, BigDecimal("0"), 0.824962400242977, - 0.0000113793220704718 + 0.0000113793220704718, ), ( ConnectorPort.B, -7, BigDecimal("0.1"), 0.824350173695168, - -0.00199404089497599 + -0.00199404089497599, ), ( ConnectorPort.B, -7, BigDecimal("0.2"), 0.823727256528033, - -0.00399946125948622 + -0.00399946125948622, ), ( ConnectorPort.B, -7, BigDecimal("0.3"), 0.823093600084976, - -0.00600488177213127 + -0.00600488177213127, ), ( ConnectorPort.B, -7, BigDecimal("0.4"), 0.822449154567156, - -0.00801030243359804 + -0.00801030243359804, ), ( ConnectorPort.B, -7, BigDecimal("0.5"), 0.821793869011542, - -0.0100157232445896 + -0.0100157232445896, ), ( ConnectorPort.B, -7, BigDecimal("0.6"), 0.82112769126825, - -0.0120211442058252 + -0.0120211442058252, ), ( ConnectorPort.B, -7, BigDecimal("0.7"), 0.820450567977117, - -0.0140265653180409 + -0.0140265653180409, ), ( ConnectorPort.B, -7, BigDecimal("0.8"), 0.819762444543498, - -0.0160319865819898 + -0.0160319865819898, ), ( ConnectorPort.B, -7, BigDecimal("0.9"), 0.81906326511325, - -0.0180374079984423 + -0.0180374079984423, ), ( ConnectorPort.B, -7, BigDecimal("1"), 0.818352972546879, - -0.0200428295681866 + -0.0200428295681866, ), ( ConnectorPort.B, -6, BigDecimal("-1"), 0.855673476911243, - 0.0206736212013741 + 0.0206736212013741, ), ( ConnectorPort.B, -6, BigDecimal("-0.9"), 0.85515033074288, - 0.0186074321593783 + 0.0186074321593783, ), ( ConnectorPort.B, -6, BigDecimal("-0.8"), 0.854616611063536, - 0.0165412429715342 + 0.0165412429715342, ), ( ConnectorPort.B, -6, BigDecimal("-0.7"), 0.854072278415979, - 0.0144750536372974 + 0.0144750536372974, ), ( ConnectorPort.B, -6, BigDecimal("-0.6"), 0.853517292355934, - 0.0124088641561102 + 0.0124088641561102, ), ( ConnectorPort.B, -6, BigDecimal("-0.5"), 0.852951611435753, - 0.0103426745274008 + 0.0103426745274008, ), ( ConnectorPort.B, -6, BigDecimal("-0.4"), 0.852375193187549, - 0.0082764847505834 + 0.0082764847505834, ), ( ConnectorPort.B, -6, BigDecimal("-0.3"), 0.851787994105775, - 0.00621029482505794 + 0.00621029482505794, ), ( ConnectorPort.B, -6, BigDecimal("-0.2"), 0.851189969629216, - 0.00414410475020971 + 0.00414410475020971, ), ( ConnectorPort.B, -6, BigDecimal("-0.1"), 0.850581074122403, - 0.00207791452540928 + 0.00207791452540928, ), ( ConnectorPort.B, -6, BigDecimal("0"), 0.8499612608564, - 0.0000117241500120423 + 0.0000117241500120423, ), ( ConnectorPort.B, -6, BigDecimal("0.1"), 0.849330481988961, - -0.00205446637664193 + -0.00205446637664193, ), ( ConnectorPort.B, -6, BigDecimal("0.2"), 0.848688688544034, - -0.0041206570552282 + -0.0041206570552282, ), ( ConnectorPort.B, -6, BigDecimal("0.3"), 0.848035830390582, - -0.00618684788643825 + -0.00618684788643825, ), ( ConnectorPort.B, -6, BigDecimal("0.4"), 0.847371856220706, - -0.00825303887097983 + -0.00825303887097983, ), ( ConnectorPort.B, -6, BigDecimal("0.5"), 0.846696713527044, - -0.0103192300095771 + -0.0103192300095771, ), ( ConnectorPort.B, -6, BigDecimal("0.6"), 0.84601034857941, - -0.0123854213029714 + -0.0123854213029714, ), ( ConnectorPort.B, -6, BigDecimal("0.7"), 0.845312706400666, - -0.0144516127519209 + -0.0144516127519209, ), ( ConnectorPort.B, -6, BigDecimal("0.8"), 0.844603730741786, - -0.0165178043572016 + -0.0165178043572016, ), ( ConnectorPort.B, -6, BigDecimal("0.9"), 0.843883364056076, - -0.0185839961196072 + -0.0185839961196072, ), ( ConnectorPort.B, -6, BigDecimal("1"), 0.843151547472542, - -0.0206501880399498 + -0.0206501880399498, ), ( ConnectorPort.B, -5, BigDecimal("-1"), 0.88084034387922, - 0.0212816688837675 + 0.0212816688837675, ), ( ConnectorPort.B, -5, BigDecimal("-0.9"), 0.880301811058847, - 0.0191547095758306 + 0.0191547095758306, ), ( ConnectorPort.B, -5, BigDecimal("-0.8"), 0.879752393741875, - 0.0170277501177557 + 0.0170277501177557, ), ( ConnectorPort.B, -5, BigDecimal("-0.7"), 0.879192051310566, - 0.0149007905089826 + 0.0149007905089826, ), ( ConnectorPort.B, -5, BigDecimal("-0.6"), 0.878620742131108, - 0.0127738307489369 + 0.0127738307489369, ), ( ConnectorPort.B, -5, BigDecimal("-0.5"), 0.878038423536804, - 0.0106468708370302 + 0.0106468708370302, ), ( ConnectorPort.B, -5, BigDecimal("-0.4"), 0.877445051810713, - 0.00851991077265941 + 0.00851991077265941, ), ( ConnectorPort.B, -5, BigDecimal("-0.3"), 0.876840582167709, - 0.00639295055520668 + 0.00639295055520668, ), ( ConnectorPort.B, -5, BigDecimal("-0.2"), 0.876224968735958, - 0.00426599018403942 + 0.00426599018403942, ), ( ConnectorPort.B, -5, BigDecimal("-0.1"), 0.875598164537768, - 0.00213902965850952 + 0.00213902965850952, ), ( ConnectorPort.B, -5, BigDecimal("0"), 0.874960121469824, - 0.0000120689779535628 + 0.0000120689779535628, ), ( ConnectorPort.B, -5, BigDecimal("0.1"), 0.874310790282754, - -0.00211489185830792 + -0.00211489185830792, ), ( ConnectorPort.B, -5, BigDecimal("0.2"), 0.873650120560035, - -0.00424185285097023 + -0.00424185285097023, ), ( ConnectorPort.B, -5, BigDecimal("0.3"), 0.872978060696187, - -0.00636881400074527 + -0.00636881400074527, ), ( ConnectorPort.B, -5, BigDecimal("0.4"), 0.872294557874257, - -0.0084957753083616 + -0.0084957753083616, ), ( ConnectorPort.B, -5, BigDecimal("0.5"), 0.871599558042545, - -0.0106227367745647 + -0.0106227367745647, ), ( ConnectorPort.B, -5, BigDecimal("0.6"), 0.870893005890569, - -0.0127496984001176 + -0.0127496984001176, ), ( ConnectorPort.B, -5, BigDecimal("0.7"), 0.870174844824216, - -0.014876660185801 + -0.014876660185801, ), ( ConnectorPort.B, -5, BigDecimal("0.8"), 0.869445016940074, - -0.0170036221324134 + -0.0170036221324134, ), ( ConnectorPort.B, -5, BigDecimal("0.9"), 0.868703462998902, - -0.0191305842407722 + -0.0191305842407722, ), ( ConnectorPort.B, -5, BigDecimal("1"), 0.867950122398205, - -0.0212575465117131 + -0.0212575465117131, ), ( ConnectorPort.B, -4, BigDecimal("-1"), 0.906007210847198, - 0.0218897165661608 + 0.0218897165661608, ), ( ConnectorPort.B, -4, BigDecimal("-0.9"), 0.905453291374814, - 0.0197019869922829 + 0.0197019869922829, ), ( ConnectorPort.B, -4, BigDecimal("-0.8"), 0.904888176420214, - 0.0175142572639773 + 0.0175142572639773, ), ( ConnectorPort.B, -4, BigDecimal("-0.7"), 0.904311824205154, - 0.0153265273806679 + 0.0153265273806679, ), ( ConnectorPort.B, -4, BigDecimal("-0.6"), 0.903724191906283, - 0.0131387973417637 + 0.0131387973417637, ), ( ConnectorPort.B, -4, BigDecimal("-0.5"), 0.903125235637856, - 0.0109510671466597 + 0.0109510671466597, ), ( ConnectorPort.B, -4, BigDecimal("-0.4"), 0.902514910433876, - 0.00876333679473538 + 0.00876333679473538, ), ( ConnectorPort.B, -4, BigDecimal("-0.3"), 0.901893170229644, - 0.00657560628535547 + 0.00657560628535547, ), ( ConnectorPort.B, -4, BigDecimal("-0.2"), 0.901259967842699, - 0.00438787561786912 + 0.00438787561786912, ), ( ConnectorPort.B, -4, BigDecimal("-0.1"), 0.900615254953133, - 0.00220014479160983 + 0.00220014479160983, ), ( ConnectorPort.B, -4, BigDecimal("0"), 0.899958982083247, - 0.0000124138058950773 + 0.0000124138058950773, ), ( ConnectorPort.B, -4, BigDecimal("0.1"), 0.899291098576547, - -0.0021753173399738 + -0.0021753173399738, ), ( ConnectorPort.B, -4, BigDecimal("0.2"), 0.898611552576036, - -0.00436304864671219 + -0.00436304864671219, ), ( ConnectorPort.B, -4, BigDecimal("0.3"), 0.897920291001792, - -0.00655078011505222 + -0.00655078011505222, ), ( ConnectorPort.B, -4, BigDecimal("0.4"), 0.897217259527807, - -0.00873851174574332 + -0.00873851174574332, ), ( ConnectorPort.B, -4, BigDecimal("0.5"), 0.896502402558046, - -0.0109262435395523 + -0.0109262435395523, ), ( ConnectorPort.B, -4, BigDecimal("0.6"), 0.895775663201728, - -0.0131139754972638 + -0.0131139754972638, ), ( ConnectorPort.B, -4, BigDecimal("0.7"), 0.895036983247764, - -0.015301707619681 + -0.015301707619681, ), ( ConnectorPort.B, -4, BigDecimal("0.8"), 0.894286303138362, - -0.0174894399076252 + -0.0174894399076252, ), ( ConnectorPort.B, -4, BigDecimal("0.9"), 0.893523561941728, - -0.019677172361937 + -0.019677172361937, ), ( ConnectorPort.B, -4, BigDecimal("1"), 0.892748697323868, - -0.0218649049834762 + -0.0218649049834762, ), ( ConnectorPort.B, -3, BigDecimal("-1"), 0.931174077815176, - 0.0224977642485542 + 0.0224977642485542, ), ( ConnectorPort.B, -3, BigDecimal("-0.9"), 0.930604771690782, - 0.0202492644087352 + 0.0202492644087352, ), ( ConnectorPort.B, -3, BigDecimal("-0.8"), 0.930023959098554, - 0.018000764410199 + 0.018000764410199, ), ( ConnectorPort.B, -3, BigDecimal("-0.7"), 0.929431597099742, - 0.0157522642523531 + 0.0157522642523531, ), ( ConnectorPort.B, -3, BigDecimal("-0.6"), 0.928827641681457, - 0.0135037639345905 + 0.0135037639345905, ), ( ConnectorPort.B, -3, BigDecimal("-0.5"), 0.928212047738907, - 0.0112552634562891 + 0.0112552634562891, ), ( ConnectorPort.B, -3, BigDecimal("-0.4"), 0.927584769057039, - 0.00900676281681138 + 0.00900676281681138, ), ( ConnectorPort.B, -3, BigDecimal("-0.3"), 0.926945758291578, - 0.00675826201550427 + 0.00675826201550427, ), ( ConnectorPort.B, -3, BigDecimal("-0.2"), 0.926294966949441, - 0.00450976105169881 + 0.00450976105169881, ), ( ConnectorPort.B, -3, BigDecimal("-0.1"), 0.925632345368498, - 0.00226125992471011 + 0.00226125992471011, ), ( ConnectorPort.B, -3, BigDecimal("0"), 0.924957842696671, - 0.0000127586338366326 + 0.0000127586338366326, ), ( ConnectorPort.B, -3, BigDecimal("0.1"), 0.92427140687034, - -0.00223574282163975 + -0.00223574282163975, ), ( ConnectorPort.B, -3, BigDecimal("0.2"), 0.923572984592037, - -0.00448424444245421 + -0.00448424444245421, ), ( ConnectorPort.B, -3, BigDecimal("0.3"), 0.922862521307398, - -0.00673274622935925 + -0.00673274622935925, ), ( ConnectorPort.B, -3, BigDecimal("0.4"), 0.922139961181357, - -0.00898124818312505 + -0.00898124818312505, ), ( ConnectorPort.B, -3, BigDecimal("0.5"), 0.921405247073547, - -0.0112297503045398 + -0.0112297503045398, ), ( ConnectorPort.B, -3, BigDecimal("0.6"), 0.920658320512887, - -0.0134782525944101 + -0.0134782525944101, ), ( ConnectorPort.B, -3, BigDecimal("0.7"), 0.919899121671314, - -0.015726755053561 + -0.015726755053561, ), ( ConnectorPort.B, -3, BigDecimal("0.8"), 0.91912758933665, - -0.017975257682837 + -0.017975257682837, ), ( ConnectorPort.B, -3, BigDecimal("0.9"), 0.918343660884553, - -0.0202237604831019 + -0.0202237604831019, ), ( ConnectorPort.B, -3, BigDecimal("1"), 0.917547272249531, - -0.0224722634552394 + -0.0224722634552394, ), ( ConnectorPort.B, -2, BigDecimal("-1"), 0.956340944783154, - 0.0231058119309475 + 0.0231058119309475, ), ( ConnectorPort.B, -2, BigDecimal("-0.9"), 0.955756252006749, - 0.0207965418251875 + 0.0207965418251875, ), ( ConnectorPort.B, -2, BigDecimal("-0.8"), 0.955159741776893, - 0.0184872715564205 + 0.0184872715564205, ), ( ConnectorPort.B, -2, BigDecimal("-0.7"), 0.954551369994329, - 0.0161780011240382 + 0.0161780011240382, ), ( ConnectorPort.B, -2, BigDecimal("-0.6"), 0.953931091456632, - 0.0138687305274172 + 0.0138687305274172, ), ( ConnectorPort.B, -2, BigDecimal("-0.5"), 0.953298859839959, - 0.0115594597659185 + 0.0115594597659185, ), ( ConnectorPort.B, -2, BigDecimal("-0.4"), 0.952654627680202, - 0.00925018883888728 + 0.00925018883888728, ), ( ConnectorPort.B, -2, BigDecimal("-0.3"), 0.951998346353513, - 0.00694091774565297 + 0.00694091774565297, ), ( ConnectorPort.B, -2, BigDecimal("-0.2"), 0.951329966056183, - 0.00463164648552851 + 0.00463164648552851, ), ( ConnectorPort.B, -2, BigDecimal("-0.1"), 0.950649435783863, - 0.00232237505781035 + 0.00232237505781035, ), ( ConnectorPort.B, -2, BigDecimal("0"), 0.949956703310094, - 0.000013103461778146 + 0.000013103461778146, ), ( ConnectorPort.B, -2, BigDecimal("0.1"), 0.949251715164133, - -0.00229616830330571 + -0.00229616830330571, ), ( ConnectorPort.B, -2, BigDecimal("0.2"), 0.948534416608038, - -0.00460544023819623 + -0.00460544023819623, ), ( ConnectorPort.B, -2, BigDecimal("0.3"), 0.947804751613003, - -0.00691471234366629 + -0.00691471234366629, ), ( ConnectorPort.B, -2, BigDecimal("0.4"), 0.947062662834907, - -0.00922398462050684 + -0.00922398462050684, ), ( ConnectorPort.B, -2, BigDecimal("0.5"), 0.946308091589049, - -0.0115332570695274 + -0.0115332570695274, ), ( ConnectorPort.B, -2, BigDecimal("0.6"), 0.945540977824046, - -0.0138425296915563 + -0.0138425296915563, ), ( ConnectorPort.B, -2, BigDecimal("0.7"), 0.944761260094862, - -0.0161518024874411 + -0.0161518024874411, ), ( ConnectorPort.B, -2, BigDecimal("0.8"), 0.943968875534937, - -0.0184610754580489 + -0.0184610754580489, ), ( ConnectorPort.B, -2, BigDecimal("0.9"), 0.943163759827379, - -0.0207703486042669 + -0.0207703486042669, ), ( ConnectorPort.B, -2, BigDecimal("1"), 0.942345847175194, - -0.0230796219270027 + -0.0230796219270027, ), ( ConnectorPort.B, -1, BigDecimal("-1"), 0.981507811751131, - 0.023713859613341 + 0.023713859613341, ), ( ConnectorPort.B, -1, BigDecimal("-0.9"), 0.980907732322716, - 0.0213438192416398 + 0.0213438192416398, ), ( ConnectorPort.B, -1, BigDecimal("-0.8"), 0.980295524455232, - 0.0189737787026421 + 0.0189737787026421, ), ( ConnectorPort.B, -1, BigDecimal("-0.7"), 0.979671142888917, - 0.0166037379957236 + 0.0166037379957236, ), ( ConnectorPort.B, -1, BigDecimal("-0.6"), 0.979034541231806, - 0.0142336971202441 + 0.0142336971202441, ), ( ConnectorPort.B, -1, BigDecimal("-0.5"), 0.97838567194101, - 0.0118636560755479 + 0.0118636560755479, ), ( ConnectorPort.B, -1, BigDecimal("-0.4"), 0.977724486303365, - 0.00949361486096332 + 0.00949361486096332, ), ( ConnectorPort.B, -1, BigDecimal("-0.3"), 0.977050934415447, - 0.00712357347580179 + 0.00712357347580179, ), ( ConnectorPort.B, -1, BigDecimal("-0.2"), 0.976364965162924, - 0.00475353191935825 + 0.00475353191935825, ), ( ConnectorPort.B, -1, BigDecimal("-0.1"), 0.975666526199227, - 0.00238349019091072 + 0.00238349019091072, ), ( ConnectorPort.B, -1, BigDecimal("0"), 0.974955563923518, - 0.0000134482897197081 + 0.0000134482897197081, ), ( ConnectorPort.B, -1, BigDecimal("0.1"), 0.974232023457926, - -0.0023565937849716 + -0.0023565937849716, ), ( ConnectorPort.B, -1, BigDecimal("0.2"), 0.973495848624039, - -0.00472663603393815 + -0.00472663603393815, ), ( ConnectorPort.B, -1, BigDecimal("0.3"), 0.972746981918608, - -0.00709667845797326 + -0.00709667845797326, ), ( ConnectorPort.B, -1, BigDecimal("0.4"), 0.971985364488457, - -0.00946672105788853 + -0.00946672105788853, ), ( ConnectorPort.B, -1, BigDecimal("0.5"), 0.97121093610455, - -0.0118367638345149 + -0.0118367638345149, ), ( ConnectorPort.B, -1, BigDecimal("0.6"), 0.970423635135205, - -0.0142068067887024 + -0.0142068067887024, ), ( ConnectorPort.B, -1, BigDecimal("0.7"), 0.969623398518412, - -0.016576849921321 + -0.016576849921321, ), ( ConnectorPort.B, -1, BigDecimal("0.8"), 0.968810161733225, - -0.0189468932332606 + -0.0189468932332606, ), ( ConnectorPort.B, -1, BigDecimal("0.9"), 0.967983858770205, - -0.0213169367254318 + -0.0213169367254318, ), ( ConnectorPort.B, -1, BigDecimal("1"), 0.967144422100857, - -0.0236869803987659 + -0.0236869803987659, ), ( ConnectorPort.B, 0, BigDecimal("-1"), 1.00667467871911, - 0.0243219072957343 + 0.0243219072957343, ), ( ConnectorPort.B, 0, BigDecimal("-0.9"), 1.00605921263868, - 0.0218910966580921 + 0.0218910966580921, ), ( ConnectorPort.B, 0, BigDecimal("-0.8"), 1.00543130713357, - 0.0194602858488637 + 0.0194602858488637, ), ( ConnectorPort.B, 0, BigDecimal("-0.7"), 1.0047909157835, - 0.0170294748674087 + 0.0170294748674087, ), ( ConnectorPort.B, 0, BigDecimal("-0.6"), 1.00413799100698, - 0.0145986637130708 + 0.0145986637130708, ), ( ConnectorPort.B, 0, BigDecimal("-0.5"), 1.00347248404206, - 0.0121678523851774 + 0.0121678523851774, ), ( ConnectorPort.B, 0, BigDecimal("-0.4"), 1.00279434492653, - 0.00973704088303931 + 0.00973704088303931, ), ( ConnectorPort.B, 0, BigDecimal("-0.3"), 1.00210352247738, - 0.00730622920595051 + 0.00730622920595051, ), ( ConnectorPort.B, 0, BigDecimal("-0.2"), 1.00139996426967, - 0.00487541735318787 + 0.00487541735318787, ), ( ConnectorPort.B, 0, BigDecimal("-0.1"), 1.00068361661459, - 0.00244460532401091 + 0.00244460532401091, ), ( ConnectorPort.B, 0, BigDecimal("0"), 0.999954424536941, - 0.0000137931176612275 + 0.0000137931176612275, ), ( ConnectorPort.B, 0, BigDecimal("0.1"), 0.999212331751719, - -0.00241701926663761 + -0.00241701926663761, ), ( ConnectorPort.B, 0, BigDecimal("0.2"), 0.99845728064004, - -0.00484783182968026 + -0.00484783182968026, ), ( ConnectorPort.B, 0, BigDecimal("0.3"), 0.997689212224214, - -0.00727864457228031 + -0.00727864457228031, ), ( ConnectorPort.B, 0, BigDecimal("0.4"), 0.996908066142007, - -0.00970945749527035 + -0.00970945749527035, ), ( ConnectorPort.B, 0, BigDecimal("0.5"), 0.996113780620051, - -0.0121402705995025 + -0.0121402705995025, ), ( ConnectorPort.B, 0, BigDecimal("0.6"), 0.995306292446364, - -0.0145710838858487 + -0.0145710838858487, ), ( ConnectorPort.B, 0, BigDecimal("0.7"), 0.994485536941961, - -0.0170018973552011 + -0.0170018973552011, ), ( ConnectorPort.B, 0, BigDecimal("0.8"), 0.993651447931513, - -0.0194327110084725 + -0.0194327110084725, ), ( ConnectorPort.B, 0, BigDecimal("0.9"), 0.99280395771303, - -0.0218635248465967 + -0.0218635248465967, ), ( ConnectorPort.B, 0, BigDecimal("1"), 0.99194299702652, - -0.0242943388705291 + -0.0242943388705291, ), ( ConnectorPort.B, 1, BigDecimal("-1"), 1.03184154568709, - 0.0249299549781277 + 0.0249299549781277, ), ( ConnectorPort.B, 1, BigDecimal("-0.9"), 1.03121069295465, - 0.0224383740745444 + 0.0224383740745444, ), ( ConnectorPort.B, 1, BigDecimal("-0.8"), 1.03056708981191, - 0.0199467929950853 + 0.0199467929950853, ), ( ConnectorPort.B, 1, BigDecimal("-0.7"), 1.02991068867809, - 0.0174552117390939 + 0.0174552117390939, ), ( ConnectorPort.B, 1, BigDecimal("-0.6"), 1.02924144078216, - 0.0149636303058977 + 0.0149636303058977, ), ( ConnectorPort.B, 1, BigDecimal("-0.5"), 1.02855929614311, - 0.0124720486948069 + 0.0124720486948069, ), ( ConnectorPort.B, 1, BigDecimal("-0.4"), 1.02786420354969, - 0.00998046690511528 + 0.00998046690511528, ), ( ConnectorPort.B, 1, BigDecimal("-0.3"), 1.02715611053932, - 0.00748888493609935 + 0.00748888493609935, ), ( ConnectorPort.B, 1, BigDecimal("-0.2"), 1.02643496337641, - 0.00499730278701767 + 0.00499730278701767, ), ( ConnectorPort.B, 1, BigDecimal("-0.1"), 1.02570070702996, - 0.00250572045711118 + 0.00250572045711118, ), ( ConnectorPort.B, 1, BigDecimal("0"), 1.02495328515036, - 0.0000141379456027874 + 0.0000141379456027874, ), ( ConnectorPort.B, 1, BigDecimal("0.1"), 1.02419264004551, - -0.00247744474830352 + -0.00247744474830352, ), ( ConnectorPort.B, 1, BigDecimal("0.2"), 1.02341871265604, - -0.00496902762542224 + -0.00496902762542224, ), ( ConnectorPort.B, 1, BigDecimal("0.3"), 1.02263144252982, - -0.00746061068658732 + -0.00746061068658732, ), ( ConnectorPort.B, 1, BigDecimal("0.4"), 1.02183076779556, - -0.00995219393265205 + -0.00995219393265205, ), ( ConnectorPort.B, 1, BigDecimal("0.5"), 1.02101662513555, - -0.01244377736449 + -0.01244377736449, ), ( ConnectorPort.B, 1, BigDecimal("0.6"), 1.02018894975752, - -0.0149353609829949 + -0.0149353609829949, ), ( ConnectorPort.B, 1, BigDecimal("0.7"), 1.01934767536551, - -0.0174269447890811 + -0.0174269447890811, ), ( ConnectorPort.B, 1, BigDecimal("0.8"), 1.0184927341298, - -0.0199185287836842 + -0.0199185287836842, ), ( ConnectorPort.B, 1, BigDecimal("0.9"), 1.01762405665586, - -0.0224101129677615 + -0.0224101129677615, ), ( ConnectorPort.B, 1, BigDecimal("1"), 1.01674157195218, - -0.0249016973422923 + -0.0249016973422923, ), (ConnectorPort.B, 2, BigDecimal("-1"), 1.05700841265506, 0.025538002660521), ( @@ -4874,434 +4874,434 @@ trait TransformerTestData extends TransformerTestGrid { 2, BigDecimal("-0.9"), 1.05636217327062, - 0.0229856514909967 + 0.0229856514909967, ), ( ConnectorPort.B, 2, BigDecimal("-0.8"), 1.05570287249025, - 0.0204333001413069 + 0.0204333001413069, ), ( ConnectorPort.B, 2, BigDecimal("-0.7"), 1.05503046157268, - 0.0178809486107791 + 0.0178809486107791, ), ( ConnectorPort.B, 2, BigDecimal("-0.6"), 1.05434489055733, - 0.0153285968987244 + 0.0153285968987244, ), ( ConnectorPort.B, 2, BigDecimal("-0.5"), 1.05364610824416, - 0.0127762450044363 + 0.0127762450044363, ), ( ConnectorPort.B, 2, BigDecimal("-0.4"), 1.05293406217286, - 0.0102238929271913 + 0.0102238929271913, ), ( ConnectorPort.B, 2, BigDecimal("-0.3"), 1.05220869860125, - 0.00767154066624801 + 0.00767154066624801, ), ( ConnectorPort.B, 2, BigDecimal("-0.2"), 1.05146996248315, - 0.00511918822084738 + 0.00511918822084738, ), ( ConnectorPort.B, 2, BigDecimal("-0.1"), 1.05071779744532, - 0.00256683559021147 + 0.00256683559021147, ), ( ConnectorPort.B, 2, BigDecimal("0"), 1.04995214576379, - 0.0000144827735443296 + 0.0000144827735443296, ), ( ConnectorPort.B, 2, BigDecimal("0.1"), 1.04917294833931, - -0.00253787022996945 + -0.00253787022996945, ), ( ConnectorPort.B, 2, BigDecimal("0.2"), 1.04838014467204, - -0.00509022342116422 + -0.00509022342116422, ), ( ConnectorPort.B, 2, BigDecimal("0.3"), 1.04757367283542, - -0.00764257680089427 + -0.00764257680089427, ), ( ConnectorPort.B, 2, BigDecimal("0.4"), 1.04675346944911, - -0.0101949303700338 + -0.0101949303700338, ), ( ConnectorPort.B, 2, BigDecimal("0.5"), 1.04591946965105, - -0.0127472841294777 + -0.0127472841294777, ), ( ConnectorPort.B, 2, BigDecimal("0.6"), 1.04507160706868, - -0.0152996380801412 + -0.0152996380801412, ), ( ConnectorPort.B, 2, BigDecimal("0.7"), 1.04420981378906, - -0.0178519922229611 + -0.0178519922229611, ), ( ConnectorPort.B, 2, BigDecimal("0.8"), 1.04333402032809, - -0.0204043465588961 + -0.0204043465588961, ), ( ConnectorPort.B, 2, BigDecimal("0.9"), 1.04244415559868, - -0.0229567010889265 + -0.0229567010889265, ), ( ConnectorPort.B, 2, BigDecimal("1"), 1.04154014687785, - -0.0255090558140557 + -0.0255090558140557, ), ( ConnectorPort.B, 3, BigDecimal("-1"), 1.08217527962304, - 0.0261460503429143 + 0.0261460503429143, ), ( ConnectorPort.B, 3, BigDecimal("-0.9"), 1.08151365358658, - 0.023532928907449 + 0.023532928907449, ), ( ConnectorPort.B, 3, BigDecimal("-0.8"), 1.08083865516859, - 0.0209198072875285 + 0.0209198072875285, ), ( ConnectorPort.B, 3, BigDecimal("-0.7"), 1.08015023446727, - 0.0183066854824644 + 0.0183066854824644, ), ( ConnectorPort.B, 3, BigDecimal("-0.6"), 1.0794483403325, - 0.0156935634915511 + 0.0156935634915511, ), ( ConnectorPort.B, 3, BigDecimal("-0.5"), 1.07873292034522, - 0.0130804413140657 + 0.0130804413140657, ), ( ConnectorPort.B, 3, BigDecimal("-0.4"), 1.07800392079602, - 0.0104673189492672 + 0.0104673189492672, ), ( ConnectorPort.B, 3, BigDecimal("-0.3"), 1.07726128666319, - 0.00785419639639677 + 0.00785419639639677, ), ( ConnectorPort.B, 3, BigDecimal("-0.2"), 1.07650496158989, - 0.00524107365467694 + 0.00524107365467694, ), ( ConnectorPort.B, 3, BigDecimal("-0.1"), 1.07573488786069, - 0.00262795072331172 + 0.00262795072331172, ), ( ConnectorPort.B, 3, BigDecimal("0"), 1.07495100637721, - 0.0000148276014858161 + 0.0000148276014858161, ), ( ConnectorPort.B, 3, BigDecimal("0.1"), 1.0741532566331, - -0.00259829571163542 + -0.00259829571163542, ), ( ConnectorPort.B, 3, BigDecimal("0.2"), 1.07334157668804, - -0.00521141921690625 + -0.00521141921690625, ), ( ConnectorPort.B, 3, BigDecimal("0.3"), 1.07251590314103, - -0.00782454291520131 + -0.00782454291520131, ), ( ConnectorPort.B, 3, BigDecimal("0.4"), 1.07167617110266, - -0.0104376668074156 + -0.0104376668074156, ), ( ConnectorPort.B, 3, BigDecimal("0.5"), 1.07082231416656, - -0.0130507908944652 + -0.0130507908944652, ), ( ConnectorPort.B, 3, BigDecimal("0.6"), 1.06995426437984, - -0.0156639151772874 + -0.0156639151772874, ), ( ConnectorPort.B, 3, BigDecimal("0.7"), 1.06907195221261, - -0.0182770396568411 + -0.0182770396568411, ), ( ConnectorPort.B, 3, BigDecimal("0.8"), 1.06817530652638, - -0.0208901643341079 + -0.0208901643341079, ), ( ConnectorPort.B, 3, BigDecimal("0.9"), 1.06726425454151, - -0.0235032892100915 + -0.0235032892100915, ), ( ConnectorPort.B, 3, BigDecimal("1"), 1.06633872180351, - -0.0261164142858189 + -0.0261164142858189, ), ( ConnectorPort.B, 4, BigDecimal("-1"), 1.10734214659102, - 0.0267540980253077 + 0.0267540980253077, ), ( ConnectorPort.B, 4, BigDecimal("-0.9"), 1.10666513390255, - 0.0240802063239013 + 0.0240802063239013, ), ( ConnectorPort.B, 4, BigDecimal("-0.8"), 1.10597443784693, - 0.0214063144337501 + 0.0214063144337501, ), ( ConnectorPort.B, 4, BigDecimal("-0.7"), 1.10527000736186, - 0.0187324223541496 + 0.0187324223541496, ), ( ConnectorPort.B, 4, BigDecimal("-0.6"), 1.10455179010768, - 0.016058530084378 + 0.016058530084378, ), ( ConnectorPort.B, 4, BigDecimal("-0.5"), 1.10381973244627, - 0.0133846376236952 + 0.0133846376236952, ), ( ConnectorPort.B, 4, BigDecimal("-0.4"), 1.10307377941918, - 0.0107107449713433 + 0.0107107449713433, ), ( ConnectorPort.B, 4, BigDecimal("-0.3"), 1.10231387472512, - 0.00803685212654552 + 0.00803685212654552, ), ( ConnectorPort.B, 4, BigDecimal("-0.2"), 1.10153996069663, - 0.00536295908850669 + 0.00536295908850669, ), ( ConnectorPort.B, 4, BigDecimal("-0.1"), 1.10075197827605, - 0.00268906585641202 + 0.00268906585641202, ), ( ConnectorPort.B, 4, BigDecimal("0"), 1.09994986699064, - 0.0000151724294273726 + 0.0000151724294273726, ), ( ConnectorPort.B, 4, BigDecimal("0.1"), 1.09913356492689, - -0.00265872119330126 + -0.00265872119330126, ), ( ConnectorPort.B, 4, BigDecimal("0.2"), 1.09830300870404, - -0.00533261501264826 + -0.00533261501264826, ), ( ConnectorPort.B, 4, BigDecimal("0.3"), 1.09745813344664, - -0.00800650902950831 + -0.00800650902950831, ), ( ConnectorPort.B, 4, BigDecimal("0.4"), 1.09659887275621, - -0.0106804032447974 + -0.0106804032447974, ), ( ConnectorPort.B, 4, BigDecimal("0.5"), 1.09572515868206, - -0.0133542976594527 + -0.0133542976594527, ), ( ConnectorPort.B, 4, BigDecimal("0.6"), 1.094836921691, - -0.0160281922744335 + -0.0160281922744335, ), ( ConnectorPort.B, 4, BigDecimal("0.7"), 1.09393409063616, - -0.0187020870907211 + -0.0187020870907211, ), ( ConnectorPort.B, 4, BigDecimal("0.8"), 1.09301659272466, - -0.0213759821093196 + -0.0213759821093196, ), ( ConnectorPort.B, 4, BigDecimal("0.9"), 1.09208435348433, - -0.0240498773312563 + -0.0240498773312563, ), ( ConnectorPort.B, 4, BigDecimal("1"), 1.09113729672917, - -0.0267237727575821 + -0.0267237727575821, ), (ConnectorPort.B, 5, BigDecimal("-1"), 1.132509013559, 0.027362145707701), ( @@ -5309,280 +5309,280 @@ trait TransformerTestData extends TransformerTestGrid { 5, BigDecimal("-0.9"), 1.13181661421852, - 0.0246274837403537 + 0.0246274837403537, ), ( ConnectorPort.B, 5, BigDecimal("-0.8"), 1.13111022052527, - 0.0218928215799717 + 0.0218928215799717, ), ( ConnectorPort.B, 5, BigDecimal("-0.7"), 1.13038978025644, - 0.0191581592258348 + 0.0191581592258348, ), ( ConnectorPort.B, 5, BigDecimal("-0.6"), 1.12965523988285, - 0.0164234966772046 + 0.0164234966772046, ), ( ConnectorPort.B, 5, BigDecimal("-0.5"), 1.12890654454732, - 0.0136888339333246 + 0.0136888339333246, ), ( ConnectorPort.B, 5, BigDecimal("-0.4"), 1.12814363804234, - 0.0109541709934192 + 0.0109541709934192, ), ( ConnectorPort.B, 5, BigDecimal("-0.3"), 1.12736646278705, - 0.00821950785669432 + 0.00821950785669432, ), ( ConnectorPort.B, 5, BigDecimal("-0.2"), 1.12657495980337, - 0.00548484452233641 + 0.00548484452233641, ), ( ConnectorPort.B, 5, BigDecimal("-0.1"), 1.12576906869142, - 0.00275018098951233 + 0.00275018098951233, ), ( ConnectorPort.B, 5, BigDecimal("0"), 1.12494872760406, - 0.0000155172573689131 + 0.0000155172573689131, ), ( ConnectorPort.B, 5, BigDecimal("0.1"), 1.12411387322068, - -0.00271914667496727 + -0.00271914667496727, ), ( ConnectorPort.B, 5, BigDecimal("0.2"), 1.12326444072004, - -0.00545381080839021 + -0.00545381080839021, ), ( ConnectorPort.B, 5, BigDecimal("0.3"), 1.12240036375224, - -0.00818847514381527 + -0.00818847514381527, ), ( ConnectorPort.B, 5, BigDecimal("0.4"), 1.12152157440976, - -0.0109231396821791 + -0.0109231396821791, ), ( ConnectorPort.B, 5, BigDecimal("0.5"), 1.12062800319756, - -0.0136578044244403 + -0.0136578044244403, ), ( ConnectorPort.B, 5, BigDecimal("0.6"), 1.11971957900216, - -0.0163924693715797 + -0.0163924693715797, ), ( ConnectorPort.B, 5, BigDecimal("0.7"), 1.11879622905971, - -0.0191271345246012 + -0.0191271345246012, ), ( ConnectorPort.B, 5, BigDecimal("0.8"), 1.11785787892295, - -0.0218617998845315 + -0.0218617998845315, ), ( ConnectorPort.B, 5, BigDecimal("0.9"), 1.11690445242716, - -0.0245964654524212 + -0.0245964654524212, ), ( ConnectorPort.B, 5, BigDecimal("1"), 1.11593587165483, - -0.0273311312293454 + -0.0273311312293454, ), ( ConnectorPort.B, 6, BigDecimal("-1"), 1.15767588052698, - 0.0279701933900944 + 0.0279701933900944, ), ( ConnectorPort.B, 6, BigDecimal("-0.9"), 1.15696809453449, - 0.0251747611568059 + 0.0251747611568059, ), ( ConnectorPort.B, 6, BigDecimal("-0.8"), 1.15624600320361, - 0.0223793287261932 + 0.0223793287261932, ), ( ConnectorPort.B, 6, BigDecimal("-0.7"), 1.15550955315103, - 0.01958389609752 + 0.01958389609752, ), ( ConnectorPort.B, 6, BigDecimal("-0.6"), 1.15475868965803, - 0.0167884632700314 + 0.0167884632700314, ), ( ConnectorPort.B, 6, BigDecimal("-0.5"), 1.15399335664837, - 0.0139930302429539 + 0.0139930302429539, ), ( ConnectorPort.B, 6, BigDecimal("-0.4"), 1.15321349666551, - 0.0111975970154952 + 0.0111975970154952, ), ( ConnectorPort.B, 6, BigDecimal("-0.3"), 1.15241905084899, - 0.00840216358684306 + 0.00840216358684306, ), ( ConnectorPort.B, 6, BigDecimal("-0.2"), 1.15160995891012, - 0.00560672995616601 + 0.00560672995616601, ), ( ConnectorPort.B, 6, BigDecimal("-0.1"), 1.15078615910678, - 0.00281129612261251 + 0.00281129612261251, ), ( ConnectorPort.B, 6, BigDecimal("0"), 1.14994758821748, - 0.0000158620853104297 + 0.0000158620853104297, ), ( ConnectorPort.B, 6, BigDecimal("0.1"), 1.14909418151448, - -0.00277957215663318 + -0.00277957215663318, ), ( ConnectorPort.B, 6, BigDecimal("0.2"), 1.14822587273605, - -0.0055750066041323 + -0.0055750066041323, ), ( ConnectorPort.B, 6, BigDecimal("0.3"), 1.14734259405785, - -0.00837044125812234 + -0.00837044125812234, ), ( ConnectorPort.B, 6, BigDecimal("0.4"), 1.14644427606331, - -0.0111658761195609 + -0.0111658761195609, ), ( ConnectorPort.B, 6, BigDecimal("0.5"), 1.14553084771306, - -0.0139613111894279 + -0.0139613111894279, ), ( ConnectorPort.B, 6, BigDecimal("0.6"), 1.14460223631332, - -0.016756746468726 + -0.016756746468726, ), ( ConnectorPort.B, 6, BigDecimal("0.7"), 1.14365836748325, - -0.0195521819584812 + -0.0195521819584812, ), ( ConnectorPort.B, 6, BigDecimal("0.8"), 1.14269916512124, - -0.0223476176597433 + -0.0223476176597433, ), ( ConnectorPort.B, 6, BigDecimal("0.9"), 1.14172455136999, - -0.0251430535735862 + -0.0251430535735862, ), (ConnectorPort.B, 6, BigDecimal("1"), 1.1407344465805, -0.0279384897011086), ( @@ -5590,287 +5590,287 @@ trait TransformerTestData extends TransformerTestGrid { 7, BigDecimal("-1"), 1.18284274749495, - 0.0285782410724878 + 0.0285782410724878, ), ( ConnectorPort.B, 7, BigDecimal("-0.9"), 1.18211957485045, - 0.0257220385732582 + 0.0257220385732582, ), ( ConnectorPort.B, 7, BigDecimal("-0.8"), 1.18138178588195, - 0.0228658358724148 + 0.0228658358724148, ), ( ConnectorPort.B, 7, BigDecimal("-0.7"), 1.18062932604562, - 0.0200096329692052 + 0.0200096329692052, ), ( ConnectorPort.B, 7, BigDecimal("-0.6"), 1.1798621394332, - 0.0171534298628582 + 0.0171534298628582, ), ( ConnectorPort.B, 7, BigDecimal("-0.5"), 1.17908016874942, - 0.0142972265525834 + 0.0142972265525834, ), ( ConnectorPort.B, 7, BigDecimal("-0.4"), 1.17828335528867, - 0.0114410230375711 + 0.0114410230375711, ), ( ConnectorPort.B, 7, BigDecimal("-0.3"), 1.17747163891092, - 0.00858481931699185 + 0.00858481931699185, ), ( ConnectorPort.B, 7, BigDecimal("-0.2"), 1.17664495801686, - 0.00572861538999577 + 0.00572861538999577, ), ( ConnectorPort.B, 7, BigDecimal("-0.1"), 1.17580324952215, - 0.00287241125571286 + 0.00287241125571286, ), ( ConnectorPort.B, 7, BigDecimal("0"), 1.17494644883091, - 0.0000162069132519891 + 0.0000162069132519891, ), ( ConnectorPort.B, 7, BigDecimal("0.1"), 1.17407448980827, - -0.00283999763829914 + -0.00283999763829914, ), ( ConnectorPort.B, 7, BigDecimal("0.2"), 1.17318730475205, - -0.00569620239987423 + -0.00569620239987423, ), ( ConnectorPort.B, 7, BigDecimal("0.3"), 1.17228482436345, - -0.0085524073724293 + -0.0085524073724293, ), ( ConnectorPort.B, 7, BigDecimal("0.4"), 1.17136697771686, - -0.0114086125569427 + -0.0114086125569427, ), ( ConnectorPort.B, 7, BigDecimal("0.5"), 1.17043369222856, - -0.0142648179544154 + -0.0142648179544154, ), ( ConnectorPort.B, 7, BigDecimal("0.6"), 1.16948489362448, - -0.0171210235658722 + -0.0171210235658722, ), ( ConnectorPort.B, 7, BigDecimal("0.7"), 1.1685205059068, - -0.0199772293923612 + -0.0199772293923612, ), ( ConnectorPort.B, 7, BigDecimal("0.8"), 1.16754045131953, - -0.0228334354349551 + -0.0228334354349551, ), ( ConnectorPort.B, 7, BigDecimal("0.9"), 1.16654465031281, - -0.0256896416947511 + -0.0256896416947511, ), ( ConnectorPort.B, 7, BigDecimal("1"), 1.16553302150616, - -0.0285458481728718 + -0.0285458481728718, ), ( ConnectorPort.B, 8, BigDecimal("-1"), 1.20800961446293, - 0.0291862887548811 + 0.0291862887548811, ), ( ConnectorPort.B, 8, BigDecimal("-0.9"), 1.20727105516642, - 0.0262693159897105 + 0.0262693159897105, ), ( ConnectorPort.B, 8, BigDecimal("-0.8"), 1.20651756856029, - 0.0233523430186365 + 0.0233523430186365, ), ( ConnectorPort.B, 8, BigDecimal("-0.7"), 1.20574909894021, - 0.0204353698408905 + 0.0204353698408905, ), ( ConnectorPort.B, 8, BigDecimal("-0.6"), 1.20496558920838, - 0.017518396455685 + 0.017518396455685, ), ( ConnectorPort.B, 8, BigDecimal("-0.5"), 1.20416698085047, - 0.0146014228622129 + 0.0146014228622129, ), ( ConnectorPort.B, 8, BigDecimal("-0.4"), 1.20335321391183, - 0.0116844490596472 + 0.0116844490596472, ), ( ConnectorPort.B, 8, BigDecimal("-0.3"), 1.20252422697286, - 0.00876747504714063 + 0.00876747504714063, ), ( ConnectorPort.B, 8, BigDecimal("-0.2"), 1.2016799571236, - 0.00585050082382552 + 0.00585050082382552, ), ( ConnectorPort.B, 8, BigDecimal("-0.1"), 1.20082033993751, - 0.00293352638881315 + 0.00293352638881315, ), ( ConnectorPort.B, 8, BigDecimal("0"), 1.19994530944433, - 0.0000165517411934878 + 0.0000165517411934878, ), ( ConnectorPort.B, 8, BigDecimal("0.1"), 1.19905479810206, - -0.00290042311996509 + -0.00290042311996509, ), ( ConnectorPort.B, 8, BigDecimal("0.2"), 1.19814873676805, - -0.00581739819561628 + -0.00581739819561628, ), ( ConnectorPort.B, 8, BigDecimal("0.3"), 1.19722705466906, - -0.00873437348673637 + -0.00873437348673637, ), ( ConnectorPort.B, 8, BigDecimal("0.4"), 1.19628967937041, - -0.0116513489943244 + -0.0116513489943244, ), ( ConnectorPort.B, 8, BigDecimal("0.5"), 1.19533653674406, - -0.014568324719403 + -0.014568324719403, ), ( ConnectorPort.B, 8, BigDecimal("0.6"), 1.19436755093564, - -0.0174853006630184 + -0.0174853006630184, ), ( ConnectorPort.B, 8, BigDecimal("0.7"), 1.19338264433035, - -0.0204022768262413 + -0.0204022768262413, ), ( ConnectorPort.B, 8, BigDecimal("0.8"), 1.19238173751782, - -0.0233192532101669 + -0.0233192532101669, ), ( ConnectorPort.B, 8, BigDecimal("0.9"), 1.19136474925564, - -0.026236229815916 + -0.026236229815916, ), (ConnectorPort.B, 8, BigDecimal("1"), 1.19033159643182, -0.029153206644635), ( @@ -5878,295 +5878,295 @@ trait TransformerTestData extends TransformerTestGrid { 9, BigDecimal("-1"), 1.23317648143091, - 0.0297943364372745 + 0.0297943364372745, ), ( ConnectorPort.B, 9, BigDecimal("-0.9"), 1.23242253548239, - 0.0268165934061628 + 0.0268165934061628, ), ( ConnectorPort.B, 9, BigDecimal("-0.8"), 1.23165335123863, - 0.0238388501648581 + 0.0238388501648581, ), ( ConnectorPort.B, 9, BigDecimal("-0.7"), 1.23086887183479, - 0.0208611067125756 + 0.0208611067125756, ), ( ConnectorPort.B, 9, BigDecimal("-0.6"), 1.23006903898355, - 0.0178833630485118 + 0.0178833630485118, ), ( ConnectorPort.B, 9, BigDecimal("-0.5"), 1.22925379295153, - 0.0149056191718423 + 0.0149056191718423, ), ( ConnectorPort.B, 9, BigDecimal("-0.4"), 1.228423072535, - 0.0119278750817232 + 0.0119278750817232, ), ( ConnectorPort.B, 9, BigDecimal("-0.3"), 1.22757681503479, - 0.00895013077728943 + 0.00895013077728943, ), ( ConnectorPort.B, 9, BigDecimal("-0.2"), 1.22671495623034, - 0.00597238625765516 + 0.00597238625765516, ), ( ConnectorPort.B, 9, BigDecimal("-0.1"), 1.22583743035288, - 0.00299464152191339 + 0.00299464152191339, ), ( ConnectorPort.B, 9, BigDecimal("0"), 1.22494417005775, - 0.0000168965691349742 + 0.0000168965691349742, ), ( ConnectorPort.B, 9, BigDecimal("0.1"), 1.22403510639586, - -0.00296084860163105 + -0.00296084860163105, ), ( ConnectorPort.B, 9, BigDecimal("0.2"), 1.22311016878405, - -0.0059385939913583 + -0.0059385939913583, ), ( ConnectorPort.B, 9, BigDecimal("0.3"), 1.22216928497466, - -0.00891633960104338 + -0.00891633960104338, ), ( ConnectorPort.B, 9, BigDecimal("0.4"), 1.22121238102396, - -0.0118940854317062 + -0.0118940854317062, ), ( ConnectorPort.B, 9, BigDecimal("0.5"), 1.22023938125956, - -0.0148718314843905 + -0.0148718314843905, ), ( ConnectorPort.B, 9, BigDecimal("0.6"), 1.2192502082468, - -0.0178495777601646 + -0.0178495777601646, ), ( ConnectorPort.B, 9, BigDecimal("0.7"), 1.2182447827539, - -0.0208273242601213 + -0.0208273242601213, ), ( ConnectorPort.B, 9, BigDecimal("0.8"), 1.2172230237161, - -0.0238050709853787 + -0.0238050709853787, ), ( ConnectorPort.B, 9, BigDecimal("0.9"), 1.21618484819846, - -0.0267828179370809 + -0.0267828179370809, ), ( ConnectorPort.B, 9, BigDecimal("1"), 1.21513017135749, - -0.0297605651163982 + -0.0297605651163982, ), ( ConnectorPort.B, 10, BigDecimal("-1"), 1.25834334839889, - 0.0304023841196678 + 0.0304023841196678, ), ( ConnectorPort.B, 10, BigDecimal("-0.9"), 1.25757401579835, - 0.0273638708226152 + 0.0273638708226152, ), ( ConnectorPort.B, 10, BigDecimal("-0.8"), 1.25678913391696, - 0.0243253573110796 + 0.0243253573110796, ), ( ConnectorPort.B, 10, BigDecimal("-0.7"), 1.25598864472938, - 0.0212868435842609 + 0.0212868435842609, ), ( ConnectorPort.B, 10, BigDecimal("-0.6"), 1.25517248875873, - 0.0182483296413385 + 0.0182483296413385, ), ( ConnectorPort.B, 10, BigDecimal("-0.5"), 1.25434060505258, - 0.0152098154814717 + 0.0152098154814717, ), ( ConnectorPort.B, 10, BigDecimal("-0.4"), 1.25349293115816, - 0.0121713011037991 + 0.0121713011037991, ), ( ConnectorPort.B, 10, BigDecimal("-0.3"), 1.25262940309673, - 0.00913278650743818 + 0.00913278650743818, ), ( ConnectorPort.B, 10, BigDecimal("-0.2"), 1.25174995533708, - 0.00609427169148496 + 0.00609427169148496, ), ( ConnectorPort.B, 10, BigDecimal("-0.1"), 1.25085452076824, - 0.00305575665501359 + 0.00305575665501359, ), ( ConnectorPort.B, 10, BigDecimal("0"), 1.24994303067118, - 0.0000172413970765587 + 0.0000172413970765587, ), ( ConnectorPort.B, 10, BigDecimal("0.1"), 1.24901541468965, - -0.00302127408329697 + -0.00302127408329697, ), ( ConnectorPort.B, 10, BigDecimal("0.2"), 1.24807160080005, - -0.00605978978710035 + -0.00605978978710035, ), ( ConnectorPort.B, 10, BigDecimal("0.3"), 1.24711151528027, - -0.00909830571535039 + -0.00909830571535039, ), ( ConnectorPort.B, 10, BigDecimal("0.4"), 1.24613508267751, - -0.0121368218690879 + -0.0121368218690879, ), ( ConnectorPort.B, 10, BigDecimal("0.5"), 1.24514222577506, - -0.0151753382493781 + -0.0151753382493781, ), ( ConnectorPort.B, 10, BigDecimal("0.6"), 1.24413286555796, - -0.0182138548573108 + -0.0182138548573108, ), ( ConnectorPort.B, 10, BigDecimal("0.7"), 1.24310692117745, - -0.0212523716940014 + -0.0212523716940014, ), ( ConnectorPort.B, 10, BigDecimal("0.8"), 1.24206430991439, - -0.0242908887605906 + -0.0242908887605906, ), ( ConnectorPort.B, 10, BigDecimal("0.9"), 1.24100494714129, - -0.0273294060582459 + -0.0273294060582459, ), ( ConnectorPort.B, 10, BigDecimal("1"), 1.23992874628315, - -0.0303679235881615 - ) + -0.0303679235881615, + ), ) val tapDependentPortCurrents: TableFor9[ @@ -6178,7 +6178,7 @@ trait TransformerTestData extends TransformerTestGrid { Double, Double, Double, - Double + Double, ] = Table( ( "tapSide", @@ -6189,7 +6189,7 @@ trait TransformerTestData extends TransformerTestGrid { "iAMag", "iAAng", "iBMag", - "iBAng" + "iBAng", ), ( ConnectorPort.A, @@ -6200,7 +6200,7 @@ trait TransformerTestData extends TransformerTestGrid { 23.003954085118, -178.834651058510, 431.294763182407, - 0.781125259497 + 0.781125259497, ), ( ConnectorPort.A, @@ -6211,7 +6211,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.525560223429, -178.842119238276, 216.075065421917, - 0.391722549446 + 0.391722549446, ), ( ConnectorPort.A, @@ -6222,7 +6222,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.153959642453, -89.999604838591, 0.000000000011, - -63.434948822922 + -63.434948822922, ), ( ConnectorPort.A, @@ -6233,7 +6233,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.625629756310, -2.062621156246, 86.678612785391, - -180.156031274941 + -180.156031274941, ), ( ConnectorPort.A, @@ -6244,7 +6244,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.540232162149, -1.103088525750, 347.601584970335, - -180.628112995813 + -180.628112995813, ), ( ConnectorPort.A, @@ -6255,7 +6255,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.971640550171, -178.655670795668, 502.475593932476, - 1.061459638084 + 1.061459638084, ), ( ConnectorPort.A, @@ -6266,7 +6266,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.516767368719, -178.903976192179, 251.905603222771, - 0.532511914342 + 0.532511914342, ), ( ConnectorPort.A, @@ -6277,7 +6277,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.113113206667, -89.999604843751, 0.000000000777, - -73.119669834476 + -73.119669834476, ), ( ConnectorPort.A, @@ -6288,7 +6288,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.625851685250, -1.613085600310, 101.155690258838, - -180.212726208353 + -180.212726208353, ), ( ConnectorPort.A, @@ -6299,7 +6299,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.563349939554, -1.204609465931, 406.047287157229, - -180.856312689835 + -180.856312689835, ), ( ConnectorPort.A, @@ -6310,7 +6310,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405069071, -178.398896556822, 573.354864130381, - 1.384031350735 + 1.384031350735, ), ( ConnectorPort.A, @@ -6321,7 +6321,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053462181, -178.873309313946, 287.655034835151, - 0.694718904051 + 0.694718904051, ), ( ConnectorPort.A, @@ -6332,7 +6332,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602298880, -89.999604838507, 0.000000000005, - -90.000000000000 + -90.000000000000, ), ( ConnectorPort.A, @@ -6343,7 +6343,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903589562, -1.349856236502, 115.647100480956, - -180.278184711145 + -180.278184711145, ), ( ConnectorPort.A, @@ -6354,7 +6354,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741530558, -1.386445189457, 464.742359900663, - -181.120381398034 + -181.120381398034, ), ( ConnectorPort.A, @@ -6365,7 +6365,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.919874893106, -178.278100673998, 601.615721696539, - 1.524814468172 + 1.524814468172, ), ( ConnectorPort.A, @@ -6376,7 +6376,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.502886546947, -178.842403214648, 301.929928522615, - 0.765577315227 + 0.765577315227, ), ( ConnectorPort.A, @@ -6387,7 +6387,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.078550816962, -89.999609475535, 0.000000576609, - -73.176741233690 + -73.176741233690, ), ( ConnectorPort.A, @@ -6398,7 +6398,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.627473005039, -1.278661221495, 121.448172109735, - -180.306829295407 + -180.306829295407, ), ( ConnectorPort.A, @@ -6409,7 +6409,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.602925214424, -1.477216350318, 488.300222258160, - -181.236130852830 + -181.236130852830, ), ( ConnectorPort.A, @@ -6420,7 +6420,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.870025241112, -177.861439802860, 686.067080644780, - 1.987191673501 + 1.987191673501, ), ( ConnectorPort.A, @@ -6431,7 +6431,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.489409416903, -178.700787286039, 344.661815409481, - 0.998555958661 + 0.998555958661, ), ( ConnectorPort.A, @@ -6442,7 +6442,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.060140485118, -89.999604900530, 0.000000006742, - -73.172405921417 + -73.172405921417, ), ( ConnectorPort.A, @@ -6453,7 +6453,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.629556005151, -1.144721361043, 138.868669271316, - -180.401205209677 + -180.401205209677, ), ( ConnectorPort.A, @@ -6464,7 +6464,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.643871513939, -1.802390457726, 559.287783590753, - -181.618432259161 + -181.618432259161, ), ( ConnectorPort.B, @@ -6475,7 +6475,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405088363, -178.398896932957, 764.473152835885, - 1.384030974747 + 1.384030974747, ), ( ConnectorPort.B, @@ -6486,7 +6486,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053497806, -178.873310168971, 383.540047677483, - 0.694718050283 + 0.694718050283, ), ( ConnectorPort.B, @@ -6497,7 +6497,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602095802, -89.999645497660, 0.000007072753, - -73.163406799512 + -73.163406799512, ), ( ConnectorPort.B, @@ -6508,7 +6508,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903666866, -1.349855603483, 154.196136582985, - -180.278184095994 + -180.278184095994, ), ( ConnectorPort.B, @@ -6519,7 +6519,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741530561, -1.386445189467, 619.656479867641, - -181.120381398044 + -181.120381398044, ), ( ConnectorPort.B, @@ -6530,7 +6530,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405069060, -178.398896556791, 655.262701863002, - 1.384031350765 + 1.384031350765, ), ( ConnectorPort.B, @@ -6541,7 +6541,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053462181, -178.873309313955, 328.748611240179, - 0.694718904041 + 0.694718904041, ), ( ConnectorPort.B, @@ -6552,7 +6552,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602298877, -89.999604839117, 0.000000000096, - -73.739795291688 + -73.739795291688, ), ( ConnectorPort.B, @@ -6563,7 +6563,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903745261, -1.349858306013, 132.168119193982, - -180.278186816939 + -180.278186816939, ), ( ConnectorPort.B, @@ -6574,7 +6574,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741530557, -1.386445189446, 531.134125600727, - -181.120381398021 + -181.120381398021, ), ( ConnectorPort.B, @@ -6585,7 +6585,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405069071, -178.398896556822, 573.354864130381, - 1.384031350735 + 1.384031350735, ), ( ConnectorPort.B, @@ -6596,7 +6596,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053462181, -178.873309313946, 287.655034835151, - 0.694718904051 + 0.694718904051, ), ( ConnectorPort.B, @@ -6607,7 +6607,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602298880, -89.999604838507, 0.000000000005, - -90.000000000000 + -90.000000000000, ), ( ConnectorPort.B, @@ -6618,7 +6618,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903589562, -1.349856236502, 115.647100480956, - -180.278184711145 + -180.278184711145, ), ( ConnectorPort.B, @@ -6629,7 +6629,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741530558, -1.386445189457, 464.742359900663, - -181.120381398034 + -181.120381398034, ), ( ConnectorPort.B, @@ -6640,7 +6640,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405170891, -178.398896948562, 546.052253991224, - 1.384030959920 + 1.384030959920, ), ( ConnectorPort.B, @@ -6651,7 +6651,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053496248, -178.873309646778, 273.957176856597, - 0.694718572467 + 0.694718572467, ), ( ConnectorPort.B, @@ -6662,7 +6662,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602265146, -89.999611600556, 0.000000839270, - -73.144433757855 + -73.144433757855, ), ( ConnectorPort.B, @@ -6673,7 +6673,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903738866, -1.349857959049, 110.140099188552, - -180.278186468467 + -180.278186468467, ), ( ConnectorPort.B, @@ -6684,7 +6684,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741530489, -1.386445115448, 442.611771334987, - -181.120381324018 + -181.120381324018, ), ( ConnectorPort.B, @@ -6695,7 +6695,7 @@ trait TransformerTestData extends TransformerTestGrid { 22.935405072746, -178.398896583674, 477.795720186062, - 1.384031323914 + 1.384031323914, ), ( ConnectorPort.B, @@ -6706,7 +6706,7 @@ trait TransformerTestData extends TransformerTestGrid { 11.507053464629, -178.873309352293, 239.712529081517, - 0.694718865792 + 0.694718865792, ), ( ConnectorPort.B, @@ -6717,7 +6717,7 @@ trait TransformerTestData extends TransformerTestGrid { 0.086602293201, -89.999605976054, 0.000000123615, - -73.155567956978 + -73.155567956978, ), ( ConnectorPort.B, @@ -6728,7 +6728,7 @@ trait TransformerTestData extends TransformerTestGrid { 4.626903743678, -1.349858243420, 96.372586881264, - -180.278186753973 + -180.278186753973, ), ( ConnectorPort.B, @@ -6739,7 +6739,7 @@ trait TransformerTestData extends TransformerTestGrid { 18.590741529536, -1.386445177723, 387.285299896290, - -181.120381386284 - ) + -181.120381386284, + ), ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestGrid.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestGrid.scala index 9f0fc77394..aff8b1f3a8 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestGrid.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/TransformerTestGrid.scala @@ -12,16 +12,16 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ RawGridElements, - SubGridContainer + SubGridContainer, } import edu.ie3.datamodel.models.input.{ MeasurementUnitInput, NodeInput, - OperatorInput + OperatorInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.model.SystemComponent @@ -60,7 +60,7 @@ trait TransformerTestGrid { SystemComponent.determineOperationInterval( defaultSimulationStart, defaultSimulationEnd, - defaultOperationTime + defaultOperationTime, ) def mainRefSystem: RefSystem = { @@ -85,7 +85,7 @@ trait TransformerTestGrid { false, 0, -10, - 10 + 10, ) val transformerTypeTapLv = new Transformer2WTypeInput( @@ -103,7 +103,7 @@ trait TransformerTestGrid { true, 0, -10, - 10 + 10, ) val nodeA = new NodeInput( @@ -115,7 +115,7 @@ trait TransformerTestGrid { true, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.MV_10KV, - 0 + 0, ) val nodeB = new NodeInput( @@ -127,7 +127,7 @@ trait TransformerTestGrid { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - 1 + 1, ) val transformerInputTapHv = new Transformer2WInput( @@ -140,14 +140,14 @@ trait TransformerTestGrid { 1, transformerTypeTapHv, 0, - false + false, ) val transformerModelTapHv: TransformerModel = TransformerModel( transformerInputTapHv, mainRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val transformerInputTapLv = new Transformer2WInput( @@ -160,14 +160,14 @@ trait TransformerTestGrid { 1, transformerTypeTapLv, 0, - false + false, ) val transformerModelTapLv: TransformerModel = TransformerModel( transformerInputTapLv, mainRefSystem, defaultSimulationStart, - defaultSimulationEnd + defaultSimulationEnd, ) val gridTapHv: SubGridContainer = { @@ -177,12 +177,12 @@ trait TransformerTestGrid { Set(transformerInputTapHv).asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createSubGrid( gridName = "transformer_test_grid", subgrid = 1, - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ) } @@ -193,12 +193,12 @@ trait TransformerTestGrid { Set(transformerInputTapLv).asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) TestGridFactory.createSubGrid( gridName = "transformer_test_grid", subgrid = 1, - rawGridElements = rawGridElements + rawGridElements = rawGridElements, ) } } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala index 39873e9ece..60750607b4 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/participant/HpTestData.scala @@ -15,7 +15,7 @@ import edu.ie3.datamodel.models.input.system.characteristic.ReactivePowerCharact import edu.ie3.datamodel.models.input.thermal.{ ThermalBusInput, ThermalHouseInput, - ThermalStorageInput + ThermalStorageInput, } import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.test.common.DefaultTestData @@ -34,12 +34,12 @@ trait HpTestData extends DefaultTestData { false, NodeInput.DEFAULT_GEO_POSITION, GermanVoltageLevelUtils.LV, - 2 + 2, ) protected val thermalBusInput = new ThermalBusInput( UUID.fromString("48fa6e8d-c07f-45cd-9ad7-094a1f2a7489"), - "thermal bus" + "thermal bus", ) protected val typeInput = new HpTypeInput( @@ -49,7 +49,7 @@ trait HpTestData extends DefaultTestData { Quantities.getQuantity(0.0, StandardUnits.ENERGY_PRICE), Quantities.getQuantity(15.0, StandardUnits.ACTIVE_POWER_IN), 0.97, - Quantities.getQuantity(11.0, StandardUnits.ACTIVE_POWER_IN) + Quantities.getQuantity(11.0, StandardUnits.ACTIVE_POWER_IN), ) protected val hpInputModel = new HpInput( @@ -60,7 +60,7 @@ trait HpTestData extends DefaultTestData { nodeInput, thermalBusInput, ReactivePowerCharacteristic.parse("cosPhiFixed:{(0.00,0.98)}"), - typeInput + typeInput, ) protected val thermalHouse = new ThermalHouseInput( @@ -71,12 +71,12 @@ trait HpTestData extends DefaultTestData { Quantities.getQuantity(75, StandardUnits.HEAT_CAPACITY), Quantities.getQuantity(21.0, StandardUnits.TEMPERATURE), Quantities.getQuantity(22.0, StandardUnits.TEMPERATURE), - Quantities.getQuantity(20.0, StandardUnits.TEMPERATURE) + Quantities.getQuantity(20.0, StandardUnits.TEMPERATURE), ) protected val thermalGrid = new ThermalGrid( thermalBusInput, Seq(thermalHouse).asJava, - Seq.empty[ThermalStorageInput].asJava + Seq.empty[ThermalStorageInput].asJava, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/participant/LoadTestData.scala b/src/test/scala/edu/ie3/simona/test/common/model/participant/LoadTestData.scala index 1aeb8adc5e..c0985612ba 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/participant/LoadTestData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/participant/LoadTestData.scala @@ -30,6 +30,6 @@ trait LoadTestData extends LoadInputTestData { SystemComponent.determineOperationInterval( simulationStartDate, simulationEndDate, - operationTime + operationTime, ) } diff --git a/src/test/scala/edu/ie3/simona/test/common/result/PowerFlowResultData.scala b/src/test/scala/edu/ie3/simona/test/common/result/PowerFlowResultData.scala index c04999be92..9b51cb3b86 100644 --- a/src/test/scala/edu/ie3/simona/test/common/result/PowerFlowResultData.scala +++ b/src/test/scala/edu/ie3/simona/test/common/result/PowerFlowResultData.scala @@ -13,7 +13,7 @@ import edu.ie3.datamodel.models.result.NodeResult import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, - Transformer2WResult + Transformer2WResult, } import edu.ie3.datamodel.models.result.system.PvResult import edu.ie3.util.TimeUtil @@ -33,7 +33,7 @@ trait PowerFlowResultData { dummyTime, dummyInputModel, Quantities.getQuantity(10, StandardUnits.ACTIVE_POWER_IN), - Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN) + Quantities.getQuantity(10, StandardUnits.REACTIVE_POWER_IN), ) val dummyPvResultDataString = @@ -44,7 +44,7 @@ trait PowerFlowResultData { dummyTime, dummyInputModel, Quantities.getQuantity(1.0, PowerSystemUnits.PU), - Quantities.getQuantity(10, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(10, PowerSystemUnits.DEGREE_GEOM), ) val dummyNodeResultString = @@ -54,7 +54,7 @@ trait PowerFlowResultData { UUID.fromString("647efb19-ec38-4e01-812b-0d751f0150e8"), dummyTime, dummyInputModel, - true + true, ) val dummySwitchResultString = @@ -68,7 +68,7 @@ trait PowerFlowResultData { Quantities.getQuantity(100, PowerSystemUnits.DEGREE_GEOM), Quantities.getQuantity(100, Units.AMPERE), Quantities.getQuantity(100, PowerSystemUnits.DEGREE_GEOM), - 0 + 0, ) val dummyTrafo2wResultDataString = @@ -81,7 +81,7 @@ trait PowerFlowResultData { Quantities.getQuantity(100, Units.AMPERE), Quantities.getQuantity(100, PowerSystemUnits.DEGREE_GEOM), Quantities.getQuantity(100, Units.AMPERE), - Quantities.getQuantity(100, PowerSystemUnits.DEGREE_GEOM) + Quantities.getQuantity(100, PowerSystemUnits.DEGREE_GEOM), ) val dummyLineResultDataString = diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala index 50c8d4776e..1cae268736 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchers.scala @@ -8,7 +8,7 @@ package edu.ie3.simona.test.matchers import edu.ie3.simona.test.matchers.QuantityMatchers.{ QuantityEqualityMatcher, - QuantityEquivalenceMatcher + QuantityEquivalenceMatcher, } import edu.ie3.util.quantities.QuantityUtil @@ -20,12 +20,12 @@ import org.scalatest.matchers.{MatchResult, Matcher} trait QuantityMatchers { def equalWithTolerance[Q <: Quantity[Q]]( right: Quantity[Q], - tolerance: Double = 1e-10 + tolerance: Double = 1e-10, ) = new QuantityEqualityMatcher(right, tolerance) def beEquivalentTo[Q <: Quantity[Q]]( right: Quantity[Q], - tolerance: Double = 1e-10 + tolerance: Double = 1e-10, ) = new QuantityEquivalenceMatcher(right, tolerance) } @@ -34,37 +34,37 @@ object QuantityMatchers { class QuantityEqualityMatcher[Q <: Quantity[Q]]( right: Quantity[Q], - tolerance: Double + tolerance: Double, ) extends Matcher[Quantity[Q]] with QuantityMatchers { override def apply(left: Quantity[Q]): MatchResult = MatchResult( QuantityUtil.equals(left, right, tolerance), QuantityMatchers.assembleRawFailureMessage(left, right, tolerance), - QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance) + QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance), ) } class QuantityEquivalenceMatcher[Q <: Quantity[Q]]( right: Quantity[Q], - tolerance: Double + tolerance: Double, ) extends Matcher[Quantity[Q]] with QuantityMatchers { override def apply(left: Quantity[Q]): MatchResult = MatchResult( QuantityUtil.isEquivalentAbs(left, right, tolerance), QuantityMatchers.assembleRawFailureMessage(left, right, tolerance), - QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance) + QuantityMatchers.assembleNegatedFailureMessage(left, right, tolerance), ) } private def assembleRawFailureMessage[Q <: Quantity[Q]]( lhs: Quantity[Q], rhs: Quantity[Q], - tolerance: Double + tolerance: Double, ) = s"The quantities $lhs and $rhs differ more than $tolerance in value" private def assembleNegatedFailureMessage[Q <: Quantity[Q]]( lhs: Quantity[Q], rhs: Quantity[Q], - tolerance: Double + tolerance: Double, ) = s"The quantities $lhs and $rhs differ less than $tolerance in value" } diff --git a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala index ef1662da07..86f2d9ede8 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/QuantityMatchersSpec.scala @@ -25,7 +25,7 @@ class QuantityMatchersSpec extends UnitSpec { "pass if quantities are approximately the same" in { quant should equalWithTolerance( quant.add(toleranceQuantity.multiply(0.9)), - testTolerance + testTolerance, ) } @@ -33,7 +33,7 @@ class QuantityMatchersSpec extends UnitSpec { quant should not( equalWithTolerance( quant.add(toleranceQuantity.multiply(1.1)), - testTolerance + testTolerance, ) ) } diff --git a/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala index 1fdeb01349..54cd678ed2 100644 --- a/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala +++ b/src/test/scala/edu/ie3/simona/test/matchers/SquantsMatchers.scala @@ -16,7 +16,7 @@ trait SquantsMatchers { override def apply(left: Quantity[Q]): MatchResult = MatchResult( left =~ right, s"The quantities $left and $right differ more than $tolerance in value", - s"The quantities $left and $right differ less than $tolerance in value" + s"The quantities $left and $right differ less than $tolerance in value", ) } diff --git a/src/test/scala/edu/ie3/simona/util/ActorUtils.scala b/src/test/scala/edu/ie3/simona/util/ActorUtils.scala index a7466c126a..986a7b6de7 100644 --- a/src/test/scala/edu/ie3/simona/util/ActorUtils.scala +++ b/src/test/scala/edu/ie3/simona/util/ActorUtils.scala @@ -20,7 +20,7 @@ object ActorUtils { def expectActivationAndComplete( scheduler: ActorRef[SchedulerMessage], expectedTick: Long, - newTick: Option[Long] = None + newTick: Option[Long] = None, ): Unit = { val receivedTrigger = triggeredActor.expectMessageType[Activation] @@ -29,7 +29,7 @@ object ActorUtils { scheduler ! Completion( triggeredActor.ref, - newTick + newTick, ) } diff --git a/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala b/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala index 2553818567..d96c5da9af 100644 --- a/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala +++ b/src/test/scala/edu/ie3/simona/util/CollectionUtilsSpec.scala @@ -29,7 +29,7 @@ class CollectionUtilsSpec extends UnitSpec { List( (Each(1d), Each(2d)), (Each(2d), Each(4d)), - (Each(3d), Each(8d)) + (Each(3d), Each(8d)), ) ) @@ -45,11 +45,11 @@ class CollectionUtilsSpec extends UnitSpec { returnedSequence1 shouldBe Seq( (Each(1d), Each(2d)), - (Each(2d), Each(4d)) + (Each(2d), Each(4d)), ) returnedSequence2 shouldBe Seq( (Each(2d), Each(4d)), - (Each(3d), Each(8d)) + (Each(3d), Each(8d)), ) returnedSequence3 shouldBe Seq((Each(3d), Each(8d))) } diff --git a/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala b/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala index f9d98acc0d..c04877efeb 100644 --- a/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala +++ b/src/test/scala/edu/ie3/simona/util/ConfigUtilSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.datamodel.models.result.connector.{ LineResult, SwitchResult, Transformer2WResult, - Transformer3WResult + Transformer3WResult, } import edu.ie3.datamodel.models.result.system.{ChpResult, LoadResult} import edu.ie3.datamodel.models.result.{NodeResult, ResultEntity} @@ -25,7 +25,7 @@ import edu.ie3.simona.util.ConfigUtil.{ GridOutputConfigUtil, NotifierIdentifier, ParticipantConfigUtil, - OutputConfigUtil + OutputConfigUtil, } import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor2} @@ -67,7 +67,7 @@ class ConfigUtilSpec scaling, uuids, modelBehaviour, - reference + reference, ) ) => calculateMissingReactivePowerWithModel shouldBe false @@ -126,7 +126,7 @@ class ConfigUtilSpec scaling, uuids, modelBehaviour, - reference + reference, ) ) => calculateMissingReactivePowerWithModel shouldBe false @@ -242,7 +242,7 @@ class ConfigUtilSpec 1.3, List("49f250fa-41ff-4434-a083-79c98d260a76"), "profile", - "power" + "power", ) actual.getOrDefault[LoadRuntimeConfig]( UUID.fromString("fb8f1443-1843-4ecd-a94a-59be8148397f") @@ -252,7 +252,7 @@ class ConfigUtilSpec 1.5, List("fb8f1443-1843-4ecd-a94a-59be8148397f"), "random", - "energy" + "energy", ) } } @@ -286,7 +286,7 @@ class ConfigUtilSpec FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) ) => calculateMissingReactivePowerWithModel shouldBe false @@ -337,7 +337,7 @@ class ConfigUtilSpec FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel, scaling, - uuids + uuids, ) ) => calculateMissingReactivePowerWithModel shouldBe false @@ -439,7 +439,7 @@ class ConfigUtilSpec FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel = false, 1.3, - List("49f250fa-41ff-4434-a083-79c98d260a76") + List("49f250fa-41ff-4434-a083-79c98d260a76"), ) actual.getOrDefault[FixedFeedInRuntimeConfig]( UUID.fromString("fb8f1443-1843-4ecd-a94a-59be8148397f") @@ -447,7 +447,7 @@ class ConfigUtilSpec FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel = false, 1.5, - List("fb8f1443-1843-4ecd-a94a-59be8148397f") + List("fb8f1443-1843-4ecd-a94a-59be8148397f"), ) } } @@ -538,7 +538,7 @@ class ConfigUtilSpec FixedFeedInRuntimeConfig( calculateMissingReactivePowerWithModel = false, 1.0, - List("default") + List("default"), ) // return default if a request for load is done, but fixed feed is found @@ -550,7 +550,7 @@ class ConfigUtilSpec 1.0, List("default"), "profile", - "power" + "power", ) // return default if a request for pv is done, but fixed feed is found @@ -560,7 +560,7 @@ class ConfigUtilSpec PvRuntimeConfig( calculateMissingReactivePowerWithModel = false, 1.0, - List("default") + List("default"), ) } } @@ -572,27 +572,27 @@ class ConfigUtilSpec ("config", "expected"), ( new GridOutputConfig(false, false, "grid", false, false, false), - Set.empty[Class[_ <: ResultEntity]] + Set.empty[Class[_ <: ResultEntity]], ), ( new GridOutputConfig(true, false, "grid", false, false, false), - Set(classOf[LineResult]) + Set(classOf[LineResult]), ), ( new GridOutputConfig(false, true, "grid", false, false, false), - Set(classOf[NodeResult]) + Set(classOf[NodeResult]), ), ( new GridOutputConfig(false, false, "grid", true, false, false), - Set(classOf[SwitchResult]) + Set(classOf[SwitchResult]), ), ( new GridOutputConfig(false, false, "grid", false, true, false), - Set(classOf[Transformer2WResult]) + Set(classOf[Transformer2WResult]), ), ( new GridOutputConfig(false, false, "grid", false, false, true), - Set(classOf[Transformer3WResult]) + Set(classOf[Transformer3WResult]), ), ( new GridOutputConfig(true, true, "grid", true, true, true), @@ -601,9 +601,9 @@ class ConfigUtilSpec classOf[NodeResult], classOf[SwitchResult], classOf[Transformer2WResult], - classOf[Transformer3WResult] - ) - ) + classOf[Transformer3WResult], + ), + ), ) forAll(ddt) { @@ -621,28 +621,28 @@ class ConfigUtilSpec notifier = "default", powerRequestReply = false, simulationResult = false, - flexResult = false + flexResult = false, ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = false, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = false, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = false, simulationResult = false, - flexResult = false - ) - ) + flexResult = false, + ), + ), ) "build the correct map on valid input" in { @@ -651,24 +651,24 @@ class ConfigUtilSpec default shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) configs shouldBe Map( Load -> NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ), PvPlant -> NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ), ChpPlant -> NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false - ) + flexResult = false, + ), ) } } @@ -679,7 +679,7 @@ class ConfigUtilSpec actual shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) } @@ -687,7 +687,7 @@ class ConfigUtilSpec configUtil.getOrDefault(Wec) shouldBe NotifierConfig( simulationResultInfo = false, powerRequestReply = false, - flexResult = false + flexResult = false, ) } @@ -697,28 +697,28 @@ class ConfigUtilSpec notifier = "default", powerRequestReply = false, simulationResult = true, - flexResult = false + flexResult = false, ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, simulationResult = true, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, simulationResult = true, - flexResult = false - ) - ) + flexResult = false, + ), + ), ) val configUtil = OutputConfigUtil(inputConfig) val expectedResult: Set[Value] = NotifierIdentifier.values -- Vector( @@ -734,28 +734,28 @@ class ConfigUtilSpec notifier = "default", powerRequestReply = false, simulationResult = false, - flexResult = false + flexResult = false, ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, simulationResult = true, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, simulationResult = true, - flexResult = false - ) - ) + flexResult = false, + ), + ), ) val configUtil = OutputConfigUtil(inputConfig) val expectedResult: Set[Value] = @@ -770,28 +770,28 @@ class ConfigUtilSpec notifier = "default", powerRequestReply = false, simulationResult = false, - flexResult = false + flexResult = false, ), List( SimonaConfig.ParticipantBaseOutputConfig( notifier = "load", powerRequestReply = true, simulationResult = true, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "pv", powerRequestReply = true, simulationResult = false, - flexResult = false + flexResult = false, ), SimonaConfig.ParticipantBaseOutputConfig( notifier = "chp", powerRequestReply = true, simulationResult = true, - flexResult = false - ) - ) + flexResult = false, + ), + ), ) val configUtil = OutputConfigUtil(inputConfig) val expectedResult: Set[Class[_ <: ResultEntity]] = @@ -810,9 +810,9 @@ class ConfigUtilSpec 0, "-not-a-uuid-", "https://reg:123", - "topic" + "topic", ), - Seq("topic") + Seq("topic"), ) }.getMessage shouldBe "The UUID '-not-a-uuid-' cannot be parsed as it is invalid." } @@ -825,9 +825,9 @@ class ConfigUtilSpec 0, "00000000-0000-0000-0000-000000000000", "https://reg:123", - "topic" + "topic", ), - Seq("topic") + Seq("topic"), ) }.getMessage shouldBe "Exception creating kafka client for broker not#a#server." } @@ -840,9 +840,9 @@ class ConfigUtilSpec 0, "00000000-0000-0000-0000-000000000000", "https://reg:123", - "topic" + "topic", ), - Seq("topic") + Seq("topic"), ) }.getMessage shouldBe "Connection with kafka broker localhost:12345 failed." } diff --git a/src/test/scala/edu/ie3/simona/util/TestGridFactory.scala b/src/test/scala/edu/ie3/simona/util/TestGridFactory.scala index 89f0cdf57e..df7be2d0a4 100644 --- a/src/test/scala/edu/ie3/simona/util/TestGridFactory.scala +++ b/src/test/scala/edu/ie3/simona/util/TestGridFactory.scala @@ -11,18 +11,18 @@ import edu.ie3.datamodel.models.input.connector.{ LineInput, SwitchInput, Transformer2WInput, - Transformer3WInput + Transformer3WInput, } import edu.ie3.datamodel.models.input.container.{ GraphicElements, JointGridContainer, RawGridElements, SubGridContainer, - SystemParticipants + SystemParticipants, } import edu.ie3.datamodel.models.input.graphics.{ LineGraphicInput, - NodeGraphicInput + NodeGraphicInput, } import edu.ie3.datamodel.models.input.system._ @@ -51,13 +51,13 @@ object TestGridFactory { gridName: String = "TestGrid", rawGridElements: RawGridElements = createEmptyRawGridElements(), systemParticipants: SystemParticipants = createEmptySystemParticipants(), - graphicElements: GraphicElements = createEmptyGraphicElements() + graphicElements: GraphicElements = createEmptyGraphicElements(), ): JointGridContainer = new JointGridContainer( gridName, rawGridElements, systemParticipants, - graphicElements + graphicElements, ) /** Creates a sub grid container for testing purposes. @@ -84,14 +84,14 @@ object TestGridFactory { subgrid: Int = 100, rawGridElements: RawGridElements = createEmptyRawGridElements(), systemParticipants: SystemParticipants = createEmptySystemParticipants(), - graphicElements: GraphicElements = createEmptyGraphicElements() + graphicElements: GraphicElements = createEmptyGraphicElements(), ): SubGridContainer = new SubGridContainer( gridName, subgrid, rawGridElements, systemParticipants, - graphicElements + graphicElements, ) def createEmptyRawGridElements(): RawGridElements = @@ -101,7 +101,7 @@ object TestGridFactory { Set.empty[Transformer2WInput].asJava, Set.empty[Transformer3WInput].asJava, Set.empty[SwitchInput].asJava, - Set.empty[MeasurementUnitInput].asJava + Set.empty[MeasurementUnitInput].asJava, ) def createEmptySystemParticipants(): SystemParticipants = @@ -116,12 +116,12 @@ object TestGridFactory { Set.empty[PvInput].asJava, Set.empty[StorageInput].asJava, Set.empty[WecInput].asJava, - Set.empty[EmInput].asJava + Set.empty[EmInput].asJava, ) def createEmptyGraphicElements(): GraphicElements = new GraphicElements( Set.empty[NodeGraphicInput].asJava, - Set.empty[LineGraphicInput].asJava + Set.empty[LineGraphicInput].asJava, ) } diff --git a/src/test/scala/edu/ie3/util/quantities/IrradianceSpec.scala b/src/test/scala/edu/ie3/util/quantities/IrradianceSpec.scala index 37759008e5..a9c9eabe7c 100644 --- a/src/test/scala/edu/ie3/util/quantities/IrradianceSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/IrradianceSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.util.quantities import edu.ie3.util.scala.quantities.{ WattHoursPerSquareMeter, - WattsPerSquareMeter + WattsPerSquareMeter, } import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers diff --git a/src/test/scala/edu/ie3/util/quantities/IrradiationSpec.scala b/src/test/scala/edu/ie3/util/quantities/IrradiationSpec.scala index a2e7663864..30a2e0bff6 100644 --- a/src/test/scala/edu/ie3/util/quantities/IrradiationSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/IrradiationSpec.scala @@ -8,7 +8,7 @@ package edu.ie3.util.quantities import edu.ie3.util.scala.quantities.{ WattHoursPerSquareMeter, - WattsPerSquareMeter + WattsPerSquareMeter, } import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers diff --git a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala index 55755258c0..1c1edb1f44 100644 --- a/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/QuantityUtilSpec.scala @@ -24,7 +24,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { 2L -> unit(5d), 4L -> unit(15d), 6L -> unit(-5d), - 8L -> unit(-10d) + 8L -> unit(-10d), ) "Integrating over quantities" when { @@ -36,7 +36,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { intercept[QuantityException] { QuantityUtil invokePrivate startingValue( Map.empty[Long, Power], - 1L + 1L, ) }.getMessage shouldBe "Unable to determine unit for dummy starting value." } @@ -44,7 +44,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { "bring default value, if there is nothing before window starts" in { QuantityUtil invokePrivate startingValue( values, - 1L + 1L, ) should be unit(0d) @@ -53,7 +53,7 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { "bring correct value, if there is something before window starts" in { QuantityUtil invokePrivate startingValue( values, - 2L + 2L, ) should be unit(5d) @@ -86,14 +86,14 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { (1L, 3L, integrationUnit(5d)), (2L, 4L, integrationUnit(10d)), (2L, 8L, integrationUnit(30d)), - (0L, 12L, integrationUnit(-10d)) + (0L, 12L, integrationUnit(-10d)), ) forAll(cases) { (windowStart, windowEnd, expectedResult) => QuantityUtil.integrate[Power, Energy]( values, windowStart, - windowEnd + windowEnd, ) =~ expectedResult } } @@ -106,14 +106,14 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { QuantityUtil.average[Power, Energy]( values, 0L, - 0L + 0L, ) match { case Failure(exception: IllegalArgumentException) => exception.getMessage shouldBe "Cannot average over trivial time window." case Failure(exception) => fail( "Averaging over values failed with wrong exception.", - exception + exception, ) case Success(_) => fail("Averaging with trivial window length should fail") @@ -124,14 +124,14 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { QuantityUtil.average[Power, Energy]( values, 3L, - 0L + 0L, ) match { case Failure(exception: IllegalArgumentException) => exception.getMessage shouldBe "Window end is before window start." case Failure(exception) => fail( "Averaging over values failed with wrong exception.", - exception + exception, ) case Success(_) => fail("Averaging with flipped window start / end should fail") @@ -146,21 +146,21 @@ class QuantityUtilSpec extends UnitSpec with TableDrivenPropertyChecks { (1L, 3L, unit(2.5d)), (2L, 4L, unit(5d)), (2L, 8L, unit(5d)), - (0L, 12L, unit(-0.8333333)) + (0L, 12L, unit(-0.8333333)), ) forAll(cases) { (windowStart, windowEnd, expectedResult) => QuantityUtil.average[Power, Energy]( values, windowStart, - windowEnd + windowEnd, ) match { case Success(result) => result should approximate(expectedResult) case Failure(exception) => fail( "Averaging with fine input should pass, but failed.", - exception + exception, ) } } diff --git a/src/test/scala/edu/ie3/util/quantities/SpecificHeatCapacitySpec.scala b/src/test/scala/edu/ie3/util/quantities/SpecificHeatCapacitySpec.scala index d2a5aef2f8..adf15f89b6 100644 --- a/src/test/scala/edu/ie3/util/quantities/SpecificHeatCapacitySpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/SpecificHeatCapacitySpec.scala @@ -39,7 +39,7 @@ class SpecificHeatCapacitySpec extends AnyFlatSpec with Matchers { KilowattHoursPerKelvinCubicMeters(1000).calcEnergy( Kelvin(10), Kelvin(20), - CubicMeters(5) + CubicMeters(5), ) should be(KilowattHours(50000.0)) } @@ -47,7 +47,7 @@ class SpecificHeatCapacitySpec extends AnyFlatSpec with Matchers { KilowattHoursPerKelvinCubicMeters(1000).calcEnergy( Celsius(100), Celsius(101), - CubicMeters(5) + CubicMeters(5), ) should be(KilowattHours(5000)) } } diff --git a/src/test/scala/edu/ie3/util/quantities/ThermalConductanceSpec.scala b/src/test/scala/edu/ie3/util/quantities/ThermalConductanceSpec.scala index fd2e290f16..7b71137d69 100644 --- a/src/test/scala/edu/ie3/util/quantities/ThermalConductanceSpec.scala +++ b/src/test/scala/edu/ie3/util/quantities/ThermalConductanceSpec.scala @@ -36,7 +36,7 @@ class ThermalConductanceSpec extends AnyFlatSpec with Matchers { WattsPerKelvin(1000).thermalConductanceToEnergy( Kelvin(10), Kelvin(0), - Hours(5) + Hours(5), ) should be(KilowattHours(50d)) } @@ -44,7 +44,7 @@ class ThermalConductanceSpec extends AnyFlatSpec with Matchers { WattsPerKelvin(1000).thermalConductanceToEnergy( Celsius(10), Celsius(0), - Hours(5) + Hours(5), ) should be(KilowattHours(50d)) } } From b00c1e12b88a3e2c73ec605153dde548f5123659 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 9 Feb 2024 09:40:43 +0100 Subject: [PATCH 218/305] convert to squants --- .../control/TransformerControlGroup.scala | 11 ++++------ .../edu/ie3/simona/model/grid/GridModel.scala | 20 +++++++------------ .../control/TransformerControlGroupSpec.scala | 13 ++++-------- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala index bf9bc582b8..4f04a31951 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -10,10 +10,9 @@ import breeze.math.Complex import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult import edu.ie3.simona.model.control.TransformerControlGroup.RegulationCriterion -import tech.units.indriya.ComparableQuantity import java.util.UUID -import javax.measure.quantity.Dimensionless +import squants.Dimensionless /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, to what extent (here: @@ -28,9 +27,7 @@ import javax.measure.quantity.Dimensionless */ final case class TransformerControlGroup( nodalRegulationCriterion: Map[UUID, RegulationCriterion], - harmonizeRegulationNeeds: Array[ - ComparableQuantity[Dimensionless] - ] => Option[ComparableQuantity[Dimensionless]] + harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless] ) { /** Based on the given successful power flow result, determine the difference @@ -48,7 +45,7 @@ final case class TransformerControlGroup( def determineRegulationNeed( result: SuccessFullPowerFlowResult, uuidToIndex: Map[UUID, Int] - ): Option[ComparableQuantity[Dimensionless]] = { + ): Option[Dimensionless] = { val regulationNeeds = result.nodeData.flatMap { case StateData(resultNodeIndex, _, voltage, _) => /* Find possible matching criterion and evaluate it */ @@ -71,5 +68,5 @@ final case class TransformerControlGroup( object TransformerControlGroup { type RegulationCriterion = - Complex => Option[ComparableQuantity[Dimensionless]] + Complex => Option[Dimensionless] } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 8dbb1a4424..ff85c720c8 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -27,21 +27,19 @@ import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseC } import edu.ie3.simona.util.CollectionUtils -import edu.ie3.util.quantities.PowerSystemUnits import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} -import tech.units.indriya.ComparableQuantity -import tech.units.indriya.quantity.Quantities import edu.ie3.simona.model.control.{ TransformerControlGroup => ControlGroupModel } import java.time.ZonedDateTime import java.util.UUID -import javax.measure.quantity.Dimensionless import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ +import squants.Each +import squants.Dimensionless /** Representation of one physical electrical grid. It holds the references to * nodes, lines, switches and transformers and fundamental properties (like @@ -693,22 +691,18 @@ case object GridModel { val vMag = complexVoltage.abs vMag match { case mag if mag > vMax => - Some(vMax - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + Some(vMax - mag).map(Each(_)) case mag if mag < vMin => - Some(vMin - mag).map(Quantities.getQuantity(_, PowerSystemUnits.PU)) + Some(vMin - mag).map(Each(_)) case _ => None } } }.toMap val harmonizationFunction = - (regulationRequests: Array[ComparableQuantity[Dimensionless]]) => { - val negativeRequests = regulationRequests.filter( - _.isLessThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) - val positiveRequests = regulationRequests.filter( - _.isGreaterThan(Quantities.getQuantity(0d, PowerSystemUnits.PU)) - ) + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { case (true, true) => diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala index 8def596ce6..93725fe473 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala @@ -14,8 +14,7 @@ import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers -import edu.ie3.util.quantities.PowerSystemUnits -import tech.units.indriya.quantity.Quantities +import squants.{Dimensionless, Each} import java.util.UUID @@ -24,7 +23,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { val buildTransformerControlModels = PrivateMethod[TransformerControlGroup]( Symbol("buildTransformerControlModels") ) - + implicit val tolerance: Dimensionless = Each(1e-10) val dut = GridModel invokePrivate buildTransformerControlModels( Set( UUID.fromString( @@ -100,9 +99,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { actual match { case Some(regulationNeed) => - regulationNeed should equalWithTolerance( - Quantities.getQuantity(0.05, PowerSystemUnits.PU) - ) + regulationNeed should approximate(Each(0.05)) case None => fail("Did expect to receive a regulation need.") } } @@ -122,9 +119,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { actual match { case Some(regulationNeed) => - regulationNeed should equalWithTolerance( - Quantities.getQuantity(-0.05, PowerSystemUnits.PU) - ) + regulationNeed should approximate(Each(-0.05)) case None => fail("Did expect to receive a regulation need.") } } From e752b58bd9805441bd74e1d41dc8c5e043bbb971 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 9 Feb 2024 10:40:55 +0100 Subject: [PATCH 219/305] merge ConfigFailFast from #90 --- .../ie3/simona/config/ConfigFailFast.scala | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index b4dfa1414a..d14d9a7c78 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -601,35 +601,46 @@ case object ConfigFailFast extends LazyLogging { * * One important check cannot be performed at this place, as input data is * not available, yet: Do the measurements belong to a region, that can be - * influenced by the transformer? + * influenced by the transformer? This is partly addressed in + * [[edu.ie3.simona.agent.grid.GridAgentFailFast]] * * @param transformerControlGroup * Transformer control group definition */ private def checkTransformerControl( transformerControlGroup: TransformerControlGroup - ): Unit = transformerControlGroup match { - case TransformerControlGroup(measurements, transformers, vMax, vMin) => - if (measurements.isEmpty) - throw new InvalidConfigParameterException( - "A transformer control group cannot have no measurements assigned." - ) - if (transformers.isEmpty) - throw new InvalidConfigParameterException( - "A transformer control group cannot have no transformers assigned." - ) - if (vMin < 0) - throw new InvalidConfigParameterException( - "The minimum permissible voltage magnitude of a transformer control group has to be positive." - ) - if (vMax < 0) - throw new InvalidConfigParameterException( - "The maximum permissible voltage magnitude of a transformer control group has to be positive." - ) - if (vMax < vMin) - throw new InvalidConfigParameterException( - "The minimum permissible voltage magnitude of a transformer control group must be smaller than the maximum permissible voltage magnitude." - ) + ): Unit = { + val lowerBoundary = 0.8 + val upperBoundary = 1.2 + transformerControlGroup match { + case TransformerControlGroup(measurements, transformers, vMax, vMin) => + if (measurements.isEmpty) + throw new InvalidConfigParameterException( + s"A transformer control group (${transformerControlGroup.toString}) cannot have no measurements assigned." + ) + if (transformers.isEmpty) + throw new InvalidConfigParameterException( + s"A transformer control group (${transformerControlGroup.toString}) cannot have no transformers assigned." + ) + if (vMin < 0) + throw new InvalidConfigParameterException( + "The minimum permissible voltage magnitude of a transformer control group has to be positive." + ) + if (vMax < vMin) + throw new InvalidConfigParameterException( + s"The minimum permissible voltage magnitude of a transformer control group (${transformerControlGroup.toString}) must be smaller than the maximum permissible voltage magnitude." + ) + if (vMin < lowerBoundary) + throw new InvalidConfigParameterException( + s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!" + ) + if (vMax > upperBoundary) + throw new InvalidConfigParameterException( + s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " + + s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!" + ) + } } /** Check the default config From eaa4affd7d56419a30231faf0175db198544e71f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 9 Feb 2024 10:53:43 +0100 Subject: [PATCH 220/305] fix imports --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index c24633a320..75bd056b65 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -36,8 +36,7 @@ import java.time.ZonedDateTime import java.util.UUID import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ -import squants.Each -import squants.Dimensionless + /** Representation of one physical electrical grid. It holds the references to * nodes, lines, switches and transformers and fundamental properties (like From dc30f7a6dc4faca2f64b8dce67adc6c9425cd587 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 9 Feb 2024 11:25:23 +0100 Subject: [PATCH 221/305] fmt --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 75bd056b65..3342809985 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -37,7 +37,6 @@ import java.util.UUID import scala.collection.immutable.ListSet import scala.jdk.CollectionConverters._ - /** Representation of one physical electrical grid. It holds the references to * nodes, lines, switches and transformers and fundamental properties (like * nominal voltage etc.). From e3a41d4837610c0f748a0ef05262973627afa9cd Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 13 Feb 2024 09:04:06 +0100 Subject: [PATCH 222/305] fmt --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 2 +- .../simona/agent/grid/GridAgentFailFast.scala | 6 ++-- .../edu/ie3/simona/config/SimonaConfig.scala | 18 +++++----- .../control/TransformerControlGroup.scala | 4 +-- .../edu/ie3/simona/model/grid/GridModel.scala | 18 +++++----- .../simona/config/ConfigFailFastSpec.scala | 12 +++---- .../control/TransformerControlGroupSpec.scala | 22 ++++++------ .../edu/ie3/simona/model/grid/GridSpec.scala | 34 +++++++++---------- .../model/grid/BasicGridWithSwitches.scala | 4 +-- 9 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 22dc8eb5b6..d25f28d1bc 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -187,7 +187,7 @@ class GridAgent( .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime - ) + ), simonaConfig.simona.control, ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala index 27d8d216c8..4e45a97cb7 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala @@ -25,7 +25,7 @@ object GridAgentFailFast { */ def failFast( gridAgentInitData: GridAgentInitData, - simonaConfig: SimonaConfig + simonaConfig: SimonaConfig, ): Unit = { /** Check if there is InitData for superior or inferior GridGates @@ -43,7 +43,7 @@ object GridAgentFailFast { checkControlGroupsForMeasurement( gridAgentInitData.subGridContainer, - simonaConfig.simona.control + simonaConfig.simona.control, ) } @@ -58,7 +58,7 @@ object GridAgentFailFast { */ def checkControlGroupsForMeasurement( subGridContainer: SubGridContainer, - maybeControlConfig: Option[SimonaConfig.Simona.Control] + maybeControlConfig: Option[SimonaConfig.Simona.Control], ): Unit = { val measurementUnits = diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 79ada26af1..f5dd2fdf3b 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -756,13 +756,13 @@ object SimonaConfig { measurements: scala.List[java.lang.String], transformers: scala.List[java.lang.String], vMax: scala.Double, - vMin: scala.Double + vMin: scala.Double, ) object TransformerControlGroup { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.TransformerControlGroup = { SimonaConfig.TransformerControlGroup( measurements = @@ -770,14 +770,14 @@ object SimonaConfig { transformers = $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), - vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator) + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator), ) } private def $_reqDbl( parentPath: java.lang.String, c: com.typesafe.config.Config, path: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.Double = { if (c == null) 0 else @@ -953,20 +953,20 @@ object SimonaConfig { def apply( c: com.typesafe.config.Config, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): SimonaConfig.Simona.Control = { SimonaConfig.Simona.Control( transformer = $_LSimonaConfig_TransformerControlGroup( c.getList("transformer"), parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) } private def $_LSimonaConfig_TransformerControlGroup( cl: com.typesafe.config.ConfigList, parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator + $tsCfgValidator: $TsCfgValidator, ): scala.List[SimonaConfig.TransformerControlGroup] = { import scala.jdk.CollectionConverters._ cl.asScala @@ -974,7 +974,7 @@ object SimonaConfig { SimonaConfig.TransformerControlGroup( cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig, parentPath, - $tsCfgValidator + $tsCfgValidator, ) ) .toList @@ -2666,7 +2666,7 @@ object SimonaConfig { SimonaConfig.Simona.Control( c.getConfig("control"), parentPath + "control.", - $tsCfgValidator + $tsCfgValidator, ) ) else None, diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala index 4f04a31951..3db869c582 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala @@ -27,7 +27,7 @@ import squants.Dimensionless */ final case class TransformerControlGroup( nodalRegulationCriterion: Map[UUID, RegulationCriterion], - harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless] + harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless], ) { /** Based on the given successful power flow result, determine the difference @@ -44,7 +44,7 @@ final case class TransformerControlGroup( */ def determineRegulationNeed( result: SuccessFullPowerFlowResult, - uuidToIndex: Map[UUID, Int] + uuidToIndex: Map[UUID, Int], ): Option[Dimensionless] = { val regulationNeeds = result.nodeData.flatMap { case StateData(resultNodeIndex, _, voltage, _) => diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 0b698d6647..4d20f3316f 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -74,13 +74,13 @@ case object GridModel { refSystem: RefSystem, startDate: ZonedDateTime, endDate: ZonedDateTime, - controlConfig: Option[SimonaConfig.Simona.Control] + controlConfig: Option[SimonaConfig.Simona.Control], ): GridModel = buildAndValidate( subGridContainer, refSystem, startDate, endDate, - controlConfig + controlConfig, ) /** structure that represents all grid components that are needed by a grid @@ -569,7 +569,7 @@ case object GridModel { .map { controlConfig => buildTransformerControlGroups( controlConfig.transformer, - subGridContainer.getRawGrid.getMeasurementUnits + subGridContainer.getRawGrid.getMeasurementUnits, ) } .getOrElse(Set.empty[ControlGroupModel]) @@ -582,7 +582,7 @@ case object GridModel { subGridContainer.getSubnet, refSystem, gridComponents, - gridControls + gridControls, ) // validate @@ -604,14 +604,14 @@ case object GridModel { */ private def buildTransformerControlGroups( config: List[SimonaConfig.TransformerControlGroup], - measurementUnitInput: java.util.Set[MeasurementUnitInput] + measurementUnitInput: java.util.Set[MeasurementUnitInput], ): Set[ControlGroupModel] = config.map { case TransformerControlGroup(measurements, _, vMax, vMin) => buildTransformerControlGroupModel( measurementUnitInput, measurements, vMax, - vMin + vMin, ) }.toSet @@ -635,7 +635,7 @@ case object GridModel { measurementUnitInput: java.util.Set[MeasurementUnitInput], measurementConfigs: List[String], vMax: Double, - vMin: Double + vMin: Double, ): ControlGroupModel = { val nodeUuids = determineNodeUuids(measurementUnitInput, measurementConfigs) @@ -654,7 +654,7 @@ case object GridModel { */ private def determineNodeUuids( measurementUnitInput: java.util.Set[MeasurementUnitInput], - measurementConfigs: List[String] + measurementConfigs: List[String], ): Set[UUID] = Set.from( measurementUnitInput.asScala .filter(input => @@ -679,7 +679,7 @@ case object GridModel { private def buildTransformerControlModels( nodeUuids: Set[UUID], vMax: Double, - vMin: Double + vMin: Double, ): ControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 368e570572..515bba93bc 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -15,7 +15,7 @@ import edu.ie3.simona.config.SimonaConfig.Simona.{Powerflow, Time} import edu.ie3.simona.config.SimonaConfig.{ BaseCsvParams, ResultKafkaParams, - TransformerControlGroup + TransformerControlGroup, } import edu.ie3.simona.exceptions.InvalidConfigParameterException import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec} @@ -964,7 +964,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List.empty[String], List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 1.02, - 0.98 + 0.98, ) intercept[InvalidConfigParameterException] { @@ -977,7 +977,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List("6888c53a-7629-4563-ac8e-840f80b03106"), List.empty[String], 1.02, - 0.98 + 0.98, ) intercept[InvalidConfigParameterException] { @@ -990,7 +990,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 0.98, - 1.02 + 1.02, ) intercept[InvalidConfigParameterException] { @@ -1003,7 +1003,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 1.02, - 0.79 + 0.79, ) intercept[InvalidConfigParameterException] { @@ -1017,7 +1017,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List("6888c53a-7629-4563-ac8e-840f80b03106"), List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 1.21, - 0.98 + 0.98, ) intercept[InvalidConfigParameterException] { diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala index 07d6515338..2d6c6adbf6 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala @@ -35,10 +35,10 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { ), UUID.fromString( "324f49e5-1c35-4c49-afb1-3cf41696bf93" - ) + ), ), 1.1, - 0.9 + 0.9, ) val uuidToIndex = Map( @@ -50,7 +50,7 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { ) -> 1, UUID.fromString( "324f49e5-1c35-4c49-afb1-3cf41696bf93" - ) -> 2 + ) -> 2, ) "return no regulation need, if everything is fine" in { @@ -59,9 +59,9 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { Array( StateData(0, NodeType.SL, Complex.one, Complex.zero), StateData(1, NodeType.PQ, Complex.one, Complex.zero), - StateData(2, NodeType.PQ, Complex.one, Complex.zero) + StateData(2, NodeType.PQ, Complex.one, Complex.zero), ), - DenseMatrix.zeros(1, 1) + DenseMatrix.zeros(1, 1), ) val actual = dut.determineRegulationNeed(result, uuidToIndex) @@ -75,9 +75,9 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { Array( StateData(0, NodeType.SL, Complex.one, Complex.zero), StateData(1, NodeType.PQ, Complex.one * 0.88, Complex.zero), - StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero) + StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero), ), - DenseMatrix.zeros(1, 1) + DenseMatrix.zeros(1, 1), ) val actual = dut.determineRegulationNeed(result, uuidToIndex) @@ -91,9 +91,9 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { Array( StateData(0, NodeType.SL, Complex.one, Complex.zero), StateData(1, NodeType.PQ, Complex.one * 0.85, Complex.zero), - StateData(2, NodeType.PQ, Complex.one * 0.88, Complex.zero) + StateData(2, NodeType.PQ, Complex.one * 0.88, Complex.zero), ), - DenseMatrix.zeros(1, 1) + DenseMatrix.zeros(1, 1), ) val actual = dut.determineRegulationNeed(result, uuidToIndex) @@ -111,9 +111,9 @@ class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { Array( StateData(0, NodeType.SL, Complex.one, Complex.zero), StateData(1, NodeType.PQ, Complex.one * 1.15, Complex.zero), - StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero) + StateData(2, NodeType.PQ, Complex.one * 1.11, Complex.zero), ), - DenseMatrix.zeros(1, 1) + DenseMatrix.zeros(1, 1), ) val actual = dut.determineRegulationNeed(result, uuidToIndex) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 73c36a8470..b13da303ec 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -18,7 +18,7 @@ import edu.ie3.simona.model.control.TransformerControlGroup import edu.ie3.simona.model.grid.GridModel.{ emptyGridControls, GridComponents, - GridControls + GridControls, } import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ @@ -212,7 +212,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches + switches, ), GridControls(Set.empty[TransformerControlGroup]), ) @@ -241,7 +241,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { adaptedLines, Set(transformer2wModel), Set.empty[Transformer3wModel], - Set.empty[SwitchModel] + Set.empty[SwitchModel], ), GridControls(Set.empty[TransformerControlGroup]), ) @@ -287,7 +287,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches + switches, ), emptyGridControls, ) @@ -392,7 +392,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - switches + switches, ), GridControls(Set.empty[TransformerControlGroup]), ) @@ -444,7 +444,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { lines, Set(transformer2wModel), Set.empty[Transformer3wModel], - Set.empty[SwitchModel] + Set.empty[SwitchModel], ), GridControls(Set.empty[TransformerControlGroup]), ) @@ -480,22 +480,22 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { val node0 = TestObjectFactory.buildNodeInput( false, GermanVoltageLevelUtils.MV_10KV, - 1 + 1, ) val node1 = TestObjectFactory.buildNodeInput( false, GermanVoltageLevelUtils.MV_10KV, - 1 + 1, ) val node2 = TestObjectFactory.buildNodeInput( false, GermanVoltageLevelUtils.MV_10KV, - 1 + 1, ) val node3 = TestObjectFactory.buildNodeInput( false, GermanVoltageLevelUtils.MV_10KV, - 1 + 1, ) val measurementUnits = Set( @@ -506,7 +506,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { true, false, false, - false + false, ), new MeasurementUnitInput( UUID.fromString("ab66fbb0-ece1-44b9-9341-86a884233ec4"), @@ -515,7 +515,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { true, false, false, - false + false, ), new MeasurementUnitInput( UUID.fromString("93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d"), @@ -524,7 +524,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { true, false, false, - false + false, ), new MeasurementUnitInput( UUID.fromString("8e84eb8a-2940-4900-b0ce-0eeb6bca8bae"), @@ -533,19 +533,19 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { false, false, false, - false - ) + false, + ), ).asJava val selectedMeasurements = List( "ab66fbb0-ece1-44b9-9341-86a884233ec4", "93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d", - "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae" + "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae", ) val expectedUuids = Set(node1, node2).map(_.getUuid) val actual = GridModel invokePrivate determineNodeUuids( measurementUnits, - selectedMeasurements + selectedMeasurements, ) actual should contain theSameElementsAs expectedUuids } diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index 2660fffab6..5a03235762 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.test.common.model.grid import edu.ie3.simona.model.grid.GridModel.{ emptyGridControls, GridComponents, - GridControls + GridControls, } import edu.ie3.simona.model.grid.{ GridModel, @@ -234,7 +234,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches, ), - emptyGridControls + emptyGridControls, ) } From 82922d7c43491cb620e5717434beabc4ed81af6a Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 10:15:53 +0100 Subject: [PATCH 223/305] Minor things --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 4d20f3316f..5c190e7f74 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -26,7 +26,6 @@ import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseC, } import edu.ie3.simona.util.CollectionUtils - import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} @@ -67,7 +66,7 @@ final case class GridModel( def nodeUuidToIndexMap: Map[UUID, Int] = _nodeUuidToIndexMap } -case object GridModel { +object GridModel { def apply( subGridContainer: SubGridContainer, From c10e0f68f9513d62b1c371b30a8a69c6f9680f4d Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Wed, 14 Feb 2024 14:21:22 +0100 Subject: [PATCH 224/305] Improving implementation. --- .../ie3/simona/actor/SimonaActorNaming.scala | 10 +- .../ie3/simona/agent/EnvironmentRefs.scala | 15 +- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 232 ++++++++++++------ .../edu/ie3/simona/agent/grid/GridAgent.scala | 138 ++++------- .../ie3/simona/agent/grid/GridAgentData.scala | 43 +++- .../simona/agent/grid/GridAgentMessage.scala | 32 +-- .../simona/agent/grid/PowerFlowSupport.scala | 2 +- .../simona/agent/grid/ReceivedValues.scala | 13 +- .../agent/grid/ReceivedValuesStore.scala | 2 +- .../grid}/VoltageMessage.scala | 10 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 10 +- .../sim/setup/SimonaStandaloneSetup.scala | 44 ++-- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 85 ++++--- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 49 ++-- .../grid/DBFSAlgorithmParticipantSpec.scala | 61 +++-- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 33 +-- .../agent/grid/DBFSMockGridAgents.scala | 48 ++-- .../agent/grid/GridAgentSetup2WSpec.scala | 59 +++-- .../agent/grid/GridAgentSetup3WSpec.scala | 63 +++-- .../agent/grid/PowerFlowSupportSpec.scala | 5 +- .../agent/grid/ReceivedValuesStoreSpec.scala | 42 ++-- .../simona/sim/setup/SimonaSetupSpec.scala | 22 +- 22 files changed, 534 insertions(+), 484 deletions(-) rename src/main/scala/edu/ie3/simona/{ontology/messages => agent/grid}/VoltageMessage.scala (88%) diff --git a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala index 04a2dbff60..0b4686d781 100644 --- a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala +++ b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala @@ -7,7 +7,7 @@ package edu.ie3.simona.actor import org.apache.pekko.actor.typed.ActorRef -import org.apache.pekko.actor.{ActorRefFactory, Props, ActorRef => classicRef} +import org.apache.pekko.actor.{ActorRefFactory, Props, ActorRef => ClassicRef} import java.util.UUID @@ -16,10 +16,10 @@ object SimonaActorNaming { implicit class RichActorRefFactory(private val refFactory: ActorRefFactory) extends AnyVal { - def simonaActorOf(props: Props, actorId: String): classicRef = + def simonaActorOf(props: Props, actorId: String): ClassicRef = refFactory.actorOf(props, actorName(props, actorId)) - def simonaActorOf(props: Props): classicRef = + def simonaActorOf(props: Props): ClassicRef = refFactory.actorOf(props, actorName(props, simonaActorUuid)) } @@ -63,13 +63,13 @@ object SimonaActorNaming { def actorName(typeName: String, actorId: String): String = s"${typeName}_${cleanActorIdForPekko(actorId)}" - /** Extracts the actor name from given [[classicRef]]. Cluster singletons are + /** Extracts the actor name from given [[ClassicRef]]. Cluster singletons are * taken care of separately. * * @return * the actor name extract from the ActorRef */ - def actorName(actorRef: classicRef): String = + def actorName(actorRef: ClassicRef): String = actorRef.path.name match { case "singleton" => // singletons end in /${actorName}/singleton diff --git a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala index 2179b90202..c9476136e4 100644 --- a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala +++ b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala @@ -6,7 +6,10 @@ package edu.ie3.simona.agent -import org.apache.pekko.actor.ActorRef +import edu.ie3.simona.event.RuntimeEvent +import edu.ie3.simona.scheduler.TimeAdvancer.Incoming +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.{ActorRef => ClassicRef} /** Container class, that gather together reference to relevant entities, that * represent the environment in the simulation @@ -23,9 +26,9 @@ import org.apache.pekko.actor.ActorRef * Reference to the EV data service, if existing */ final case class EnvironmentRefs( - scheduler: ActorRef, - runtimeEventListener: ActorRef, - primaryServiceProxy: ActorRef, - weather: ActorRef, - evDataService: Option[ActorRef], + scheduler: ClassicRef, + runtimeEventListener: ActorRef[RuntimeEvent], + primaryServiceProxy: ClassicRef, + weather: ClassicRef, + evDataService: Option[ClassicRef], ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index d214a256ad..8e203c7b11 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -17,30 +17,34 @@ import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidN import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, + GridAgentValues, PowerFlowDoneData, } import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.agent.grid.ReceivedValues._ +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.agent.grid.VoltageMessage.{ + ProvideSlackVoltageMessage, + RequestSlackVoltageMessage, +} import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException import edu.ie3.simona.model.grid.{NodeModel, RefSystem} -import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage._ import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage -import edu.ie3.simona.ontology.messages.VoltageMessage.{ - ProvideSlackVoltageMessage, - RequestSlackVoltageMessage, -} +import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.scala.quantities.Megavars import edu.ie3.util.scala.quantities.SquantsUtils.RichElectricPotential import org.apache.pekko.actor.typed.scaladsl.AskPattern._ import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps -import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} +import org.apache.pekko.actor.typed.scaladsl.{ + ActorContext, + Behaviors, + StashBuffer, +} import org.apache.pekko.actor.typed.{ActorRef, Behavior, Scheduler} -import org.apache.pekko.actor.{ActorRef => classicRef} import org.apache.pekko.pattern.ask import org.apache.pekko.util.{Timeout => PekkoTimeout} import org.slf4j.Logger @@ -57,7 +61,51 @@ import scala.util.{Failure, Success} * the standard behaviour of a [[GridAgent]]. */ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { - this: GridAgent => + + /** Method that defines the idle [[Behavior]] of the agent. + * @param gridAgentBaseData + * state data of the actor + * @param values + * immutable [[GridAgent]] values + * @param buffer + * for [[GridAgentMessage]]s + * @return + * a [[Behavior]] + */ + protected def idle( + gridAgentBaseData: GridAgentBaseData + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + case (_, pm: WrappedPowerMessage) => + // needs to be set here to handle if the messages arrive too early + // before a transition to GridAgentBehaviour took place + buffer.stash(pm) + Behaviors.same + + case (_, WrappedActivation(activation: Activation)) => + values.environmentRefs.scheduler ! Completion( + values.activationAdapter, + Some(activation.tick), + ) + buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) + + case (ctx, WrappedResultMessage(StopMessage(_))) => + // shutdown children + gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => + actors.foreach(a => ctx.stop(a)) + } + + // we are done + Behaviors.stopped + + case (_, StopGridAgent) => + Behaviors.stopped + + case _ => + Behaviors.unhandled + } /** Method that defines the [[Behavior]] for simulating the grid. * @param gridAgentData @@ -67,16 +115,19 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * @return * a [[Behavior]] */ - protected def simulateGrid( + private def simulateGrid( gridAgentData: GridAgentData, currentTick: Long, + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { (ctx, message) => (message, gridAgentData) match { // first part of the grid simulation, same for all gridAgents on all levels // we start with a forward-sweep by requesting the data from our child assets and grids (if any) case ( - ActivationAdapter(activation: Activation), + WrappedActivation(activation: Activation), gridAgentBaseData: GridAgentBaseData, ) => ctx.log.debug( @@ -116,7 +167,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // if we receive power values as response on our request, we process them here case ( - ValuesAdapter(receivedValues: ReceivedValues), + receivedValues: ReceivedValues, gridAgentBaseData: GridAgentBaseData, ) => // we just received either all provided slack voltage values or all provided power values @@ -158,24 +209,22 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { updatedGridAgentBaseData, currentTick, simulateGrid, - )(ctx) + )(ctx, values, buffer) } else { goToPowerFlowCalculationOrStay( allValuesReceived, updatedGridAgentBaseData, currentTick, simulateGrid, - )(ctx) + )(ctx, values, buffer) } // if we receive a request for slack voltages from our inferior grids we want to answer it case ( - VMAdapter( - RequestSlackVoltageMessage( - currentSweepNo, - nodeUuids, - sender: ActorRef[GridAgentMessage], - ) + RequestSlackVoltageMessage( + currentSweepNo, + nodeUuids, + sender: ActorRef[GridAgentMessage], ), gridAgentBaseData: GridAgentBaseData, ) => @@ -262,8 +311,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { } } match { case exchangeVoltages => - sender ! VMAdapter( - ProvideSlackVoltageMessage(currentSweepNo, exchangeVoltages) + sender ! ProvideSlackVoltageMessage( + currentSweepNo, + exchangeVoltages, ) Behaviors.same } @@ -272,7 +322,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // before power flow calc for this sweep we either have to stash() the message to answer it later (in current sweep) // or trigger a new run for the next sweepNo case ( - PMAdapter( + WrappedPowerMessage( RequestGridPowerMessage( requestSweepNo, nodeUuids, @@ -288,7 +338,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) buffer.stash( - PMAdapter( + WrappedPowerMessage( RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) ) ) @@ -303,7 +353,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ctx.self ! PrepareNextSweepTrigger(currentTick) buffer.stash( - PMAdapter( + WrappedPowerMessage( RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) ) ) @@ -316,7 +366,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // after power flow calc for this sweepNo case ( - PMAdapter(RequestGridPowerMessage(_, requestedNodeUuids, sender)), + WrappedPowerMessage( + RequestGridPowerMessage(_, requestedNodeUuids, sender) + ), powerFlowDoneData @ PowerFlowDoneData( gridAgentBaseData, powerFlowResult, @@ -408,11 +460,13 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) } - sender ! PMAdapter(ProvideGridPowerMessage(exchangePowers)) + sender ! WrappedPowerMessage( + ProvideGridPowerMessage(exchangePowers) + ) simulateGrid(updatedGridAgentBaseData, currentTick) case _: FailedNewtonRaphsonPFResult => - sender ! PMAdapter(FailedPowerFlow) + sender ! WrappedPowerMessage(FailedPowerFlow) simulateGrid(gridAgentBaseData, currentTick) } case None => @@ -421,7 +475,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { "I got a grid power request from a subgrid I don't know. Can't answer it properly." ) - sender ! PMAdapter(FailedPowerFlow) + sender ! WrappedPowerMessage(FailedPowerFlow) Behaviors.same } @@ -475,8 +529,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) createAndSendPowerFlowResults( gridAgentBaseData, - currentTick.toDateTime(simStartTime), - )(ctx.log) + currentTick.toDateTime(values.simStartTime), + )(ctx.log, values) // do my cleanup stuff ctx.log.debug("Doing my cleanup stuff") @@ -489,9 +543,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) // / inform scheduler that we are done with the whole simulation and request new trigger for next time step - environmentRefs.scheduler ! Completion( - activationAdapter, - Some(currentTick + resolution), + values.environmentRefs.scheduler ! Completion( + values.activationAdapter, + Some(currentTick + values.resolution), ) // return to Idle @@ -519,6 +573,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { private def handlePowerFlowCalculations( gridAgentData: GridAgentData, currentTick: Long, + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { (ctx, message) => (message, gridAgentData) match { @@ -610,7 +667,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // handler for the future provided by `askForAssetPowers` to check if there are any changes in generation/load // of assets based on updated nodal voltages case ( - ValuesAdapter(receivedPowerValues: ReceivedPowerValues), + receivedPowerValues: ReceivedPowerValues, powerFlowDoneData: PowerFlowDoneData, ) => val gridAgentBaseData = powerFlowDoneData.gridAgentBaseData @@ -658,7 +715,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { updatedGridAgentBaseData, currentTick, handlePowerFlowCalculations, - )(ctx) + )(ctx, values, buffer) } else { // no changes from assets, we want to go back to SimulateGrid and report the LF results to our parent grids if any requests @@ -673,7 +730,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // this means we requested an update of the slack voltage values, but for now don't request (and hence don't expect) // updated power values for our power flow calculations case ( - ValuesAdapter(receivedSlackValues: ReceivedSlackVoltageValues), + receivedSlackValues: ReceivedSlackVoltageValues, gridAgentBaseData: GridAgentBaseData, ) => ctx.log.debug( @@ -685,7 +742,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { val previousSweepData = gridAgentBaseData.sweepValueStores.getOrElse( gridAgentBaseData.currentSweepNo - 1, throw new DBFSAlgorithmException( - s"$actorName Unable to get results from previous sweep ${gridAgentBaseData.currentSweepNo - 1}!" + s"${gridAgentBaseData.actorName}: Unable to get results from previous sweep ${gridAgentBaseData.currentSweepNo - 1}!" ), ) @@ -792,28 +849,32 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // (only possible when first simulation triggered and this agent is faster in this state as the request // by a superior grid arrives) case ( - PMAdapter(requestGridPowerMessage: RequestGridPowerMessage), + WrappedPowerMessage( + requestGridPowerMessage: RequestGridPowerMessage + ), _: GridAgentBaseData, ) => ctx.log.debug( "Received Request for Grid Power too early. Stashing away" ) - buffer.stash(PMAdapter(requestGridPowerMessage)) + buffer.stash(WrappedPowerMessage(requestGridPowerMessage)) Behaviors.same // happens only when we received slack data and power values before we received a request to provide grid // (only possible when first simulation triggered and this agent is faster // with its power flow calculation in this state as the request by a superior grid arrives) case ( - PMAdapter(requestGridPowerMessage: RequestGridPowerMessage), + WrappedPowerMessage( + requestGridPowerMessage: RequestGridPowerMessage + ), _: PowerFlowDoneData, ) => ctx.log.debug( "Received Request for Grid Power too early. Stashing away" ) - buffer.stash(PMAdapter(requestGridPowerMessage)) + buffer.stash(WrappedPowerMessage(requestGridPowerMessage)) Behaviors.same case (StopGridAgent, _) => @@ -833,6 +894,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ private def checkPowerDifferences( gridAgentBaseData: GridAgentBaseData + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { case (ctx, CheckPowerDifferencesTrigger(currentTick)) => @@ -973,7 +1037,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { failedResult.cause, ) ctx.self ! FinishGridSimulationTrigger(currentTick) - handlePowerFlowFailure(gridAgentBaseData)(ctx) + handlePowerFlowFailure(gridAgentBaseData)(ctx, values) simulateGrid(gridAgentBaseData, currentTick) } @@ -1007,7 +1071,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData: GridAgentBaseData, currentTick: Long, behavior: (GridAgentData, Long) => Behavior[GridAgentMessage], - )(implicit ctx: ActorContext[GridAgentMessage]): Behavior[GridAgentMessage] = + )(implicit + ctx: ActorContext[GridAgentMessage], + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], + ): Behavior[GridAgentMessage] = if (allReceived) { ctx.log.debug( "All power values of inferior grids, assets + voltage superior grid slack voltages received." @@ -1043,8 +1111,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ctx.log.debug( "Still waiting for asset or grid power values or slack voltage information of inferior grids" ) - - buffer.unstashAll(behavior(gridAgentBaseData, currentTick)) + behavior(gridAgentBaseData, currentTick) } /** Normally only reached by the superior (dummy) agent! @@ -1076,7 +1143,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentTick: Long, behavior: (GridAgentData, Long) => Behavior[GridAgentMessage], )(implicit - ctx: ActorContext[GridAgentMessage] + ctx: ActorContext[GridAgentMessage], + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = { if (allReceived) { ctx.log.debug( @@ -1106,8 +1175,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ctx.log.debug( "Still waiting for asset or grid power values or slack voltage information of inferior grids" ) - - buffer.unstashAll(behavior(gridAgentBaseData, currentTick)) + behavior(gridAgentBaseData, currentTick) } } @@ -1117,8 +1185,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { */ private def handlePowerFlowFailure( gridAgentBaseData: GridAgentBaseData - )(implicit ctx: ActorContext[GridAgentMessage]): Unit = { - environmentRefs.runtimeEventListener ! PowerFlowFailed + )(implicit + ctx: ActorContext[GridAgentMessage], + values: GridAgentValues, + ): Unit = { + values.environmentRefs.runtimeEventListener ! PowerFlowFailed if (gridAgentBaseData.powerFlowParams.stopOnFailure) { ctx.log.error("Stopping because of failed power flow.") @@ -1143,9 +1214,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { private def goToSimulateGridForNextSweepWith( gridAgentBaseData: GridAgentBaseData, currentTick: Long, + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = { - environmentRefs.scheduler ! Completion( - activationAdapter, + values.environmentRefs.scheduler ! Completion( + values.activationAdapter, Some(currentTick), ) @@ -1161,8 +1235,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * the current sweep value store containing the current node voltage for * the assets * @param nodeToAssetAgents - * a map contains a mapping between nodes and the [[classicRef]] s located - * \@ those nodes + * a map contains a mapping between nodes and the [[ActorRef]] s located \@ + * those nodes * @param refSystem * the reference system of the [[edu.ie3.simona.model.grid.GridModel]] of * this [[GridAgent]] @@ -1177,7 +1251,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[ValuesAdapter]] = { + ): Option[Future[GridAgentMessage]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext @@ -1227,7 +1301,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { }) }.toVector ) - .map(res => ValuesAdapter(ReceivedAssetPowerValues(res))) + .map(res => ReceivedAssetPowerValues(res)) pipeToSelf(future, ctx) Some(future) @@ -1252,7 +1326,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[ValuesAdapter]] = { + ): Option[Future[GridAgentMessage]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1281,7 +1355,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .map { case (inferiorGridAgentRef, inferiorGridGateNodes) => inferiorGridAgentRef .ask[GridAgentMessage](ref => - PMAdapter( + WrappedPowerMessage( RequestGridPowerMessage( currentSweepNo, inferiorGridGateNodes.distinct, @@ -1290,17 +1364,17 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) ) .map { - case PMAdapter( + case WrappedPowerMessage( provideGridPowerMessage: ProvideGridPowerMessage ) => (inferiorGridAgentRef, provideGridPowerMessage) - case PMAdapter(FailedPowerFlow) => + case WrappedPowerMessage(FailedPowerFlow) => (inferiorGridAgentRef, FailedPowerFlow) } } .toVector ) - .map(res => ValuesAdapter(ReceivedGridPowerValues(res))) + .map(res => ReceivedGridPowerValues(res)) pipeToSelf(future, ctx) future } @@ -1324,7 +1398,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[ValuesAdapter]] = { + ): Option[Future[GridAgentMessage]] = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1342,24 +1416,19 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .map { case (superiorGridAgent, gridGates) => superiorGridAgent .ask[GridAgentMessage](ref => - VMAdapter( - RequestSlackVoltageMessage( - currentSweepNo, - gridGates.map(_.superiorNode.getUuid), - ref, - ) + RequestSlackVoltageMessage( + currentSweepNo, + gridGates.map(_.superiorNode.getUuid), + ref, ) ) - .map { - case VMAdapter( - providedSlackValues: ProvideSlackVoltageMessage - ) => - (superiorGridAgent, providedSlackValues) + .map { case providedSlackValues: ProvideSlackVoltageMessage => + (superiorGridAgent, providedSlackValues) } } .toVector ) - .map(res => ValuesAdapter(ReceivedSlackVoltageValues(res))) + .map(res => ReceivedSlackVoltageValues(res)) pipeToSelf(future, ctx) future } @@ -1380,10 +1449,13 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { private def createAndSendPowerFlowResults( gridAgentBaseData: GridAgentBaseData, currentTimestamp: ZonedDateTime, - )(implicit log: Logger): Unit = { + )(implicit + log: Logger, + values: GridAgentValues, + ): Unit = { gridAgentBaseData.sweepValueStores.lastOption.foreach { case (_, valueStore) => - notifyListener( + values.notifyListener( this.createResultModels( gridAgentBaseData.gridEnv.gridModel, valueStore, @@ -1402,12 +1474,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * context */ private def pipeToSelf( - future: Future[ValuesAdapter], + future: Future[GridAgentMessage], ctx: ActorContext[GridAgentMessage], ): Unit = { - ctx.pipeToSelf[ValuesAdapter](future) { + ctx.pipeToSelf[GridAgentMessage](future) { case Success(value) => value - case Failure(exception) => ValuesAdapter(ReceivedFailure(exception)) + case Failure(exception) => ReceivedFailure(exception) } } } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 17dfce12be..19de1b9649 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -11,19 +11,19 @@ import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, GridAgentInitData, + GridAgentValues, } import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.ResultEvent -import edu.ie3.simona.event.notifier.Notifier import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.grid.GridModel +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil import org.apache.pekko.actor.typed.scaladsl.adapter.{ @@ -32,25 +32,24 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.{ } import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} import org.apache.pekko.actor.typed.{ActorRef, Behavior} -import org.apache.pekko.actor.{ActorRef => classicRef} +import org.apache.pekko.actor.{ActorRef => ClassicRef} import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID import scala.language.postfixOps -object GridAgent { +object GridAgent extends DBFSAlgorithm { + def apply( environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - listener: Iterable[classicRef], + listener: Iterable[ClassicRef], ): Behavior[GridAgentMessage] = Behaviors.withStash(100) { buffer => Behaviors.setup[GridAgentMessage] { context => - context.messageAdapter(values => ValuesAdapter(values)) - context.messageAdapter(msg => PMAdapter(msg)) - context.messageAdapter(msg => VMAdapter(msg)) + context.messageAdapter(msg => WrappedPowerMessage(msg)) val activationAdapter: ActorRef[Activation] = - context.messageAdapter[Activation](msg => ActivationAdapter(msg)) + context.messageAdapter[Activation](msg => WrappedActivation(msg)) // val initialization val resolution: Long = simonaConfig.simona.powerflow.resolution.get( @@ -60,55 +59,27 @@ object GridAgent { val simStartTime: ZonedDateTime = TimeUtil.withDefaults .toZonedDateTime(simonaConfig.simona.time.startDateTime) - val gridAgentController = - new GridAgentController( - context.toClassic, - environmentRefs, - simStartTime, - TimeUtil.withDefaults - .toZonedDateTime(simonaConfig.simona.time.endDateTime), - simonaConfig.simona.runtime.participant, - simonaConfig.simona.output.participant, - resolution, - listener.map(_.toTyped[ResultEvent]), - context.log, - ) - - val agent = GridAgent( + val agentValues = GridAgentValues( environmentRefs, simonaConfig, listener, resolution, simStartTime, - gridAgentController, - buffer, activationAdapter, - SimonaActorNaming.actorName(context.self), ) - agent.uninitialized + uninitialized(agentValues, buffer) } } -} - -final case class GridAgent( - environmentRefs: EnvironmentRefs, - simonaConfig: SimonaConfig, - override val listener: Iterable[classicRef], - resolution: Long, - simStartTime: ZonedDateTime, - gridAgentController: GridAgentController, - buffer: StashBuffer[GridAgentMessage], - activationAdapter: ActorRef[Activation], - actorName: String, -) extends DBFSAlgorithm - with Notifier { - protected def uninitialized: Behavior[GridAgentMessage] = + private def uninitialized(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], + ): Behavior[GridAgentMessage] = Behaviors.receiveMessage[GridAgentMessage] { case CreateGridAgent(gridAgentInitData, unlockKey) => - environmentRefs.scheduler ! ScheduleActivation( - activationAdapter, + values.environmentRefs.scheduler ! ScheduleActivation( + values.activationAdapter, INIT_SIM_TICK, Some(unlockKey), ) @@ -122,10 +93,13 @@ final case class GridAgent( Behaviors.unhandled } - protected def initializing( + private def initializing( gridAgentInitData: GridAgentInitData + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - case (ctx, ActivationAdapter(Activation(INIT_SIM_TICK))) => + case (ctx, WrappedActivation(Activation(INIT_SIM_TICK))) => // fail fast sanity checks failFast(gridAgentInitData, SimonaActorNaming.actorName(ctx.self)) @@ -156,13 +130,27 @@ final case class GridAgent( subGridContainer, refSystem, TimeUtil.withDefaults.toZonedDateTime( - simonaConfig.simona.time.startDateTime + values.simonaConfig.simona.time.startDateTime ), TimeUtil.withDefaults.toZonedDateTime( - simonaConfig.simona.time.endDateTime + values.simonaConfig.simona.time.endDateTime ), ) + val gridAgentController = + new GridAgentController( + ctx.toClassic, + values.environmentRefs, + values.simStartTime, + TimeUtil.withDefaults + .toZonedDateTime(values.simonaConfig.simona.time.endDateTime), + values.simonaConfig.simona.runtime.participant, + values.simonaConfig.simona.output.participant, + values.resolution, + values.listener.map(_.toTyped[ResultEvent]), + ctx.log, + ) + /* Reassure, that there are also calculation models for the given uuids */ val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef[ParticipantMessage]]] = gridAgentController @@ -187,25 +175,23 @@ final case class GridAgent( gridAgentInitData.superiorGridNodeUuids, gridAgentInitData.inferiorGridGates, PowerFlowParams( - simonaConfig.simona.powerflow.maxSweepPowerDeviation, - simonaConfig.simona.powerflow.newtonraphson.epsilon.toVector.sorted, - simonaConfig.simona.powerflow.newtonraphson.iterations, - simonaConfig.simona.powerflow.sweepTimeout, - simonaConfig.simona.powerflow.stopOnFailure, + values.simonaConfig.simona.powerflow.maxSweepPowerDeviation, + values.simonaConfig.simona.powerflow.newtonraphson.epsilon.toVector.sorted, + values.simonaConfig.simona.powerflow.newtonraphson.iterations, + values.simonaConfig.simona.powerflow.sweepTimeout, + values.simonaConfig.simona.powerflow.stopOnFailure, ), - ctx.log, - ctx.self.toString, + SimonaActorNaming.actorName(ctx.self), ) ctx.log.debug("Je suis initialized") - environmentRefs.scheduler ! Completion( - activationAdapter, - Some(resolution), + values.environmentRefs.scheduler ! Completion( + values.activationAdapter, + Some(values.resolution), ) idle(gridAgentBaseData) - case (_, StopGridAgent) => Behaviors.stopped @@ -213,38 +199,6 @@ final case class GridAgent( Behaviors.unhandled } - protected def idle( - gridAgentBaseData: GridAgentBaseData - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - case (_, pm: PMAdapter) => - // needs to be set here to handle if the messages arrive too early - // before a transition to GridAgentBehaviour took place - buffer.stash(pm) - Behaviors.same - - case (_, ActivationAdapter(activation: Activation)) => - environmentRefs.scheduler ! Completion( - activationAdapter, - Some(activation.tick), - ) - buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) - - case (ctx, ResultMessageAdapter(StopMessage(_))) => - // shutdown children - gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => - actors.foreach(a => ctx.stop(a)) - } - - // we are done - Behaviors.stopped - - case (_, StopGridAgent) => - Behaviors.stopped - - case _ => - Behaviors.unhandled - } - private def failFast( gridAgentInitData: GridAgentInitData, actorName: String, diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala index d4b91858df..d5a726bd0b 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala @@ -10,13 +10,17 @@ import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.powerflow.model.PowerFlowResult import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult +import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.ReceivedValues.{ ReceivedPowerValues, ReceivedSlackVoltageValues, } import edu.ie3.simona.agent.grid.ReceivedValuesStore.NodeToReceivedPower import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.event.notifier.Notifier import edu.ie3.simona.model.grid.{GridModel, RefSystem} +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ FailedPowerFlow, PowerResponseMessage, @@ -24,8 +28,10 @@ import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvidePowerMessage, } import org.apache.pekko.actor.typed.ActorRef -import org.slf4j.Logger +import org.apache.pekko.actor.typed.scaladsl.StashBuffer +import org.apache.pekko.actor.{ActorRef => ClassicRef} +import java.time.ZonedDateTime import java.util.UUID sealed trait GridAgentData @@ -34,6 +40,29 @@ sealed trait GridAgentData */ object GridAgentData { + /** Class holding some [[GridAgent]] values that are immutable. + * @param environmentRefs + * environment actor refs + * @param simonaConfig + * config + * @param listener + * listeners + * @param resolution + * of the simulation + * @param simStartTime + * start time of the simulation + * @param activationAdapter + * adapter for [[Activation]] + */ + final case class GridAgentValues private ( + environmentRefs: EnvironmentRefs, + simonaConfig: SimonaConfig, + override val listener: Iterable[ClassicRef], + resolution: Long, + simStartTime: ZonedDateTime, + activationAdapter: ActorRef[Activation], + ) extends Notifier + /** Data that is send to the [[GridAgent]] directly after startup. It contains * the main information for initialization. This data should include all * [[GridAgent]] individual data, for data that is the same for all @@ -103,7 +132,6 @@ object GridAgentData { superiorGridNodeUuids: Vector[UUID], inferiorGridGates: Vector[SubGridGate], powerFlowParams: PowerFlowParams, - log: Logger, actorName: String, ): GridAgentBaseData = { @@ -126,7 +154,6 @@ object GridAgentData { superiorGridNodeUuids, ), sweepValueStores, - log, actorName, ) } @@ -191,7 +218,6 @@ object GridAgentData { currentSweepNo: Int, receivedValueStore: ReceivedValuesStore, sweepValueStores: Map[Int, SweepValueStore], - log: Logger, actorName: String, ) extends GridAgentData with GridAgentDataHelper { @@ -212,14 +238,7 @@ object GridAgentData { val slackVoltageValuesReady = receivedValueStore.nodeToReceivedSlackVoltage.values .forall(_.isDefined) - log.debug( - "slackMap: {}", - receivedValueStore.nodeToReceivedSlackVoltage, - ) - log.debug( - "powerMap: {}", - receivedValueStore.nodeToReceivedPower, - ) + assetAndGridPowerValuesReady & slackVoltageValuesReady } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala index cb8c43b95d..cc11aa44ac 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala @@ -8,11 +8,7 @@ package edu.ie3.simona.agent.grid import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage -import edu.ie3.simona.ontology.messages.{ - Activation, - PowerMessage, - VoltageMessage, -} +import edu.ie3.simona.ontology.messages.{Activation, PowerMessage} import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import org.apache.pekko.actor.typed.ActorRef @@ -25,6 +21,11 @@ sealed trait GridAgentMessage */ object GridAgentMessage { + /** Necessary because we want to extend [[GridAgentMessage]] in other classes, + * but we do want to keep [[GridAgentMessage]] sealed. + */ + private[grid] trait GAMessage extends GridAgentMessage + /** GridAgent initialization data can only be constructed once all GridAgent * actors are created. Thus, we need an extra initialization message. * @@ -78,33 +79,18 @@ object GridAgentMessage { */ final object StopGridAgent extends GridAgentMessage - /** Wrapper for string messages. NOTICE: Only for internal use. - * @param str - * message - * @param sender - * of the message - */ - private[grid] final case class StringAdapter( - str: String, - sender: ActorRef[GridAgentMessage], - ) extends GridAgentMessage - /** Wrapper for activation values * * @param activation * the tick */ - final case class ActivationAdapter(activation: Activation) + final case class WrappedActivation(activation: Activation) extends GridAgentMessage - final case class PMAdapter(msg: PowerMessage) extends GridAgentMessage - - final case class VMAdapter(msg: VoltageMessage) extends GridAgentMessage - - final case class ValuesAdapter(values: ReceivedValues) + final case class WrappedPowerMessage(msg: PowerMessage) extends GridAgentMessage - final case class ResultMessageAdapter(msg: ResultMessage) + final case class WrappedResultMessage(msg: ResultMessage) extends GridAgentMessage } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala index 8d275188b7..5d34d06bd4 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowSupport.scala @@ -17,7 +17,7 @@ import edu.ie3.simona.agent.grid.ReceivedValues.ReceivedSlackVoltageValues import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException import edu.ie3.simona.model.grid._ import edu.ie3.simona.ontology.messages.PowerMessage.ProvidePowerMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.util.scala.quantities.Kilovars import org.slf4j.Logger import squants.electro.ElectricPotential diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala index dd1c5d5b49..eacda5e019 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala @@ -6,27 +6,26 @@ package edu.ie3.simona.agent.grid -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.ontology.messages.PowerMessage.PowerResponseMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage -import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey +import VoltageMessage.ProvideSlackVoltageMessage +import edu.ie3.simona.agent.grid.GridAgentMessage.GAMessage import org.apache.pekko.actor.typed.ActorRef /** Serves as a wrapper class that allows for matches against received values in * [[DBFSAlgorithm]] */ -sealed trait ReceivedValues +sealed trait ReceivedValues extends GAMessage object ReceivedValues { - type ParticipantPowerRequestResponse = + private type ParticipantPowerRequestResponse = ( ActorRef[_], PowerResponseMessage, ) // necessary, because participants are still classic actors - type GridPowerRequestResponse = + private type GridPowerRequestResponse = (ActorRef[GridAgentMessage], PowerResponseMessage) - type ActorSlackVoltageRequestResponse = + private type ActorSlackVoltageRequestResponse = (ActorRef[GridAgentMessage], ProvideSlackVoltageMessage) sealed trait ReceivedPowerValues extends ReceivedValues { diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala index 6e01f44620..a576045703 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValuesStore.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.ontology.messages.PowerMessage.{ PowerResponseMessage, ProvidePowerMessage, } -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.actor.{ActorRef => classicRef} diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala similarity index 88% rename from src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala rename to src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala index 67229c4436..bcbffdf609 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/VoltageMessage.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala @@ -4,16 +4,16 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.ontology.messages +package edu.ie3.simona.agent.grid -import edu.ie3.simona.agent.grid.GridAgentMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.agent.grid.GridAgentMessage.GAMessage +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import org.apache.pekko.actor.typed.ActorRef +import squants.electro.ElectricPotential import java.util.UUID -import squants.electro.ElectricPotential -sealed trait VoltageMessage +sealed trait VoltageMessage extends GAMessage /** Message that is send between [[edu.ie3.simona.agent.grid.GridAgent]] s to * provide voltage information for nodes diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 930c46907a..a0b33394ed 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -6,7 +6,10 @@ package edu.ie3.simona.sim -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps +import org.apache.pekko.actor.typed.scaladsl.adapter.{ + ClassicActorRefOps, + TypedActorRefOps, +} import org.apache.pekko.actor.SupervisorStrategy.Stop import org.apache.pekko.actor.{ Actor, @@ -24,7 +27,7 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.StopGridAgent import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.StopMessage import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage +import edu.ie3.simona.scheduler.TimeAdvancer.{Incoming, StartSimMessage} import edu.ie3.simona.sim.SimMessage.{ InitSim, SimulationFailure, @@ -37,6 +40,7 @@ import edu.ie3.simona.sim.SimonaSim.{ } import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext import scala.concurrent.duration.DurationInt import scala.language.postfixOps @@ -102,7 +106,7 @@ class SimonaSim(simonaSetup: SimonaSetup) context, EnvironmentRefs( scheduler, - runtimeEventListener.toClassic, + runtimeEventListener, primaryServiceProxy, weatherService, extSimulationData.evDataService, diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index 2235f90327..4ab3199f6c 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -45,8 +45,8 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.{ } import org.apache.pekko.actor.{ ActorSystem, - ActorContext => classicContext, - ActorRef => classicRef, + ActorContext, + ActorRef => ClassicRef, } import java.util.concurrent.LinkedBlockingQueue @@ -67,9 +67,9 @@ class SimonaStandaloneSetup( ) extends SimonaSetup { override def gridAgents( - context: classicContext, + context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[classicRef], + systemParticipantListener: Seq[ClassicRef], ): Iterable[ActorRef[GridAgentMessage]] = { /* get the grid */ @@ -142,9 +142,9 @@ class SimonaStandaloneSetup( } override def primaryServiceProxy( - context: classicContext, - scheduler: classicRef, - ): classicRef = { + context: ActorContext, + scheduler: ClassicRef, + ): ClassicRef = { val simulationStart = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) @@ -164,9 +164,9 @@ class SimonaStandaloneSetup( } override def weatherService( - context: classicContext, - scheduler: classicRef, - ): classicRef = { + context: ActorContext, + scheduler: ClassicRef, + ): ClassicRef = { val weatherService = context.simonaActorOf( WeatherService.props( scheduler, @@ -187,8 +187,8 @@ class SimonaStandaloneSetup( } override def extSimulations( - context: classicContext, - scheduler: classicRef, + context: ActorContext, + scheduler: ClassicRef, ): ExtSimSetupData = { val jars = ExtSimLoader.scanInputFolder() @@ -212,7 +212,7 @@ class SimonaStandaloneSetup( // setup data services that belong to this external simulation val (extData, extDataInit): ( Iterable[ExtData], - Iterable[(Class[_ <: SimonaService[_]], classicRef)], + Iterable[(Class[_ <: SimonaService[_]], ClassicRef)], ) = extLink.getExtDataSimulations.asScala.zipWithIndex.map { case (_: ExtEvSimulation, dIndex) => @@ -250,8 +250,8 @@ class SimonaStandaloneSetup( } override def timeAdvancer( - context: classicContext, - simulation: classicRef, + context: ActorContext, + simulation: ClassicRef, runtimeEventListener: ActorRef[RuntimeEvent], ): ActorRef[TimeAdvancer.Incoming] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( @@ -273,9 +273,9 @@ class SimonaStandaloneSetup( } override def scheduler( - context: classicContext, + context: ActorContext, timeAdvancer: ActorRef[TimeAdvancer.Incoming], - ): classicRef = + ): ClassicRef = context .spawn( Scheduler( @@ -286,7 +286,7 @@ class SimonaStandaloneSetup( .toClassic override def runtimeEventListener( - context: classicContext + context: ActorContext ): ActorRef[RuntimeEvent] = context .spawn( @@ -299,8 +299,8 @@ class SimonaStandaloneSetup( ) override def systemParticipantsListener( - context: classicContext - ): Seq[classicRef] = { + context: ActorContext + ): Seq[ClassicRef] = { // append ResultEventListener as well to write raw output files ArgsParser .parseListenerConfigOption(simonaConfig.simona.event.listener) @@ -323,9 +323,9 @@ class SimonaStandaloneSetup( def buildSubGridToActorRefMap( subGridTopologyGraph: SubGridTopologyGraph, - context: classicContext, + context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[classicRef], + systemParticipantListener: Seq[ClassicRef], ): Map[Int, ActorRef[GridAgentMessage]] = { subGridTopologyGraph .vertexSet() diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index c938ad0054..ea7ca31c72 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -19,8 +19,9 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid @@ -54,7 +55,7 @@ class DBFSAlgorithmCenGridSpec private val scheduler: TestProbe[SchedulerMessage] = TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe("runtimeEvents") + private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -76,7 +77,7 @@ class DBFSAlgorithmCenGridSpec private val environmentRefs = EnvironmentRefs( scheduler = scheduler.ref.toClassic, - runtimeEventListener = runtimeEvents.ref.toClassic, + runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref.toClassic, weather = weatherService.ref.toClassic, evDataService = None, @@ -132,14 +133,14 @@ class DBFSAlgorithmCenGridSpec val msg = scheduler.expectMessageType[ScheduleActivation] msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) - centerGridAgent ! ActivationAdapter(Activation(INIT_SIM_TICK)) + centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) + completionMessage shouldBe Completion(msg.actor, Some(3600)) } s"go to SimulateGrid when it receives an activity start trigger" in { - centerGridAgent ! ActivationAdapter(Activation(3600)) + centerGridAgent ! WrappedActivation(Activation(3600)) val msg = scheduler.expectMessageType[Completion] msg shouldBe Completion(msg.actor, Some(3600)) @@ -150,7 +151,7 @@ class DBFSAlgorithmCenGridSpec val firstSweepNo = 0 // send the start grid simulation trigger - centerGridAgent ! ActivationAdapter(Activation(3600)) + centerGridAgent ! WrappedActivation(Activation(3600)) /* We expect one grid power request message per inferior grid */ @@ -217,7 +218,7 @@ class DBFSAlgorithmCenGridSpec // we now answer the request of our centerGridAgent // with three fake grid power messages and one fake slack voltage message - firstPowerRequestSender11 ! PMAdapter( + firstPowerRequestSender11 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid11.nodeUuids.map(nodeUuid => ExchangePower( @@ -229,7 +230,7 @@ class DBFSAlgorithmCenGridSpec ) ) - firstPowerRequestSender12 ! PMAdapter( + firstPowerRequestSender12 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid12.nodeUuids.map(nodeUuid => ExchangePower( @@ -241,7 +242,7 @@ class DBFSAlgorithmCenGridSpec ) ) - firstPowerRequestSender13 ! PMAdapter( + firstPowerRequestSender13 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid13.nodeUuids.map(nodeUuid => ExchangePower( @@ -253,22 +254,20 @@ class DBFSAlgorithmCenGridSpec ) ) - firstSlackVoltageRequestSender ! VMAdapter( - ProvideSlackVoltageMessage( - firstSweepNo, - Seq( - ExchangeVoltage( - supNodeA.getUuid, - Kilovolts(380d), - Kilovolts(0d), - ), - ExchangeVoltage( - supNodeB.getUuid, - Kilovolts(380d), - Kilovolts(0d), - ), + firstSlackVoltageRequestSender ! ProvideSlackVoltageMessage( + firstSweepNo, + Seq( + ExchangeVoltage( + supNodeA.getUuid, + Kilovolts(380d), + Kilovolts(0d), ), - ) + ExchangeVoltage( + supNodeB.getUuid, + Kilovolts(380d), + Kilovolts(0d), + ), + ), ) // power flow calculation should run now. After it's done, @@ -301,22 +300,20 @@ class DBFSAlgorithmCenGridSpec superiorGridAgent.expectSlackVoltageRequest(secondSweepNo) // the superior grid would answer with updated slack voltage values - secondSlackAskSender ! VMAdapter( - ProvideSlackVoltageMessage( - secondSweepNo, - Seq( - ExchangeVoltage( - supNodeB.getUuid, - Kilovolts(374.22694614463d), // 380 kV @ 10° - Kilovolts(65.9863075134335d), // 380 kV @ 10° - ), - ExchangeVoltage( // this one should currently be ignored anyways - supNodeA.getUuid, - Kilovolts(380d), - Kilovolts(0d), - ), + secondSlackAskSender ! ProvideSlackVoltageMessage( + secondSweepNo, + Seq( + ExchangeVoltage( + supNodeB.getUuid, + Kilovolts(374.22694614463d), // 380 kV @ 10° + Kilovolts(65.9863075134335d), // 380 kV @ 10° ), - ) + ExchangeVoltage( // this one should currently be ignored anyways + supNodeA.getUuid, + Kilovolts(380d), + Kilovolts(0d), + ), + ), ) // After the intermediate power flow calculation, we expect one grid power @@ -385,7 +382,7 @@ class DBFSAlgorithmCenGridSpec // we now answer the requests of our centerGridAgent // with three fake grid power message - secondPowerRequestSender11 ! PMAdapter( + secondPowerRequestSender11 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid11.nodeUuids.map(nodeUuid => ExchangePower( @@ -397,7 +394,7 @@ class DBFSAlgorithmCenGridSpec ) ) - secondPowerRequestSender12 ! PMAdapter( + secondPowerRequestSender12 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid12.nodeUuids.map(nodeUuid => ExchangePower( @@ -409,7 +406,7 @@ class DBFSAlgorithmCenGridSpec ) ) - secondPowerRequestSender13 ! PMAdapter( + secondPowerRequestSender13 ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGrid13.nodeUuids.map(nodeUuid => ExchangePower( diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index 5586c8e5d4..eebcce4a0c 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -21,8 +21,9 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid @@ -49,7 +50,7 @@ class DBFSAlgorithmFailedPowerFlowSpec private val scheduler: TestProbe[SchedulerMessage] = TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe("runtimeEvents") + private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -63,7 +64,7 @@ class DBFSAlgorithmFailedPowerFlowSpec private val environmentRefs = EnvironmentRefs( scheduler = scheduler.ref.toClassic, - runtimeEventListener = runtimeEvents.ref.toClassic, + runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref.toClassic, weather = weatherService.ref.toClassic, evDataService = None, @@ -112,21 +113,17 @@ class DBFSAlgorithmFailedPowerFlowSpec key, ) - val message = scheduler.expectMessageType[ScheduleActivation] - message shouldBe ScheduleActivation( - message.actor, - INIT_SIM_TICK, - Some(key), - ) + val msg = scheduler.expectMessageType[ScheduleActivation] + msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) - centerGridAgent ! ActivationAdapter(Activation(INIT_SIM_TICK)) - scheduler.expectMessage(Completion(message.actor, Some(3600))) + centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) + scheduler.expectMessage(Completion(msg.actor, Some(3600))) } s"go to SimulateGrid when it receives an activation" in { // send init data to agent - centerGridAgent ! ActivationAdapter(Activation(3600)) + centerGridAgent ! WrappedActivation(Activation(3600)) // we expect a completion message val message = scheduler.expectMessageType[Completion] @@ -137,7 +134,7 @@ class DBFSAlgorithmFailedPowerFlowSpec val sweepNo = 0 // send the start grid simulation trigger - centerGridAgent ! ActivationAdapter(Activation(3600)) + centerGridAgent ! WrappedActivation(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo val powerRequestSender = inferiorGridAgent.expectGridPowerRequest() @@ -166,7 +163,7 @@ class DBFSAlgorithmFailedPowerFlowSpec // we now answer the request of our centerGridAgent // with a fake grid power message and one fake slack voltage message - powerRequestSender ! PMAdapter( + powerRequestSender ! WrappedPowerMessage( ProvideGridPowerMessage( inferiorGridAgent.nodeUuids.map(nodeUuid => ExchangePower( @@ -178,17 +175,15 @@ class DBFSAlgorithmFailedPowerFlowSpec ) ) - slackVoltageRequestSender ! VMAdapter( - ProvideSlackVoltageMessage( - sweepNo, - Seq( - ExchangeVoltage( - supNodeA.getUuid, - Kilovolts(380d), - Kilovolts(0d), - ) - ), - ) + slackVoltageRequestSender ! ProvideSlackVoltageMessage( + sweepNo, + Seq( + ExchangeVoltage( + supNodeA.getUuid, + Kilovolts(380d), + Kilovolts(0d), + ) + ), ) // power flow calculation should run now. After it's done, @@ -201,7 +196,7 @@ class DBFSAlgorithmFailedPowerFlowSpec // wait 30 seconds max for power flow to finish superiorGridAgent.gaProbe.expectMessage( 30 seconds, - PMAdapter(FailedPowerFlow), + WrappedPowerMessage(FailedPowerFlow), ) // normally the slack node would send a FinishGridSimulationTrigger to all diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index 0f2fa775b1..034b41cc2b 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -10,10 +10,9 @@ import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage.{ - ActivationAdapter, - VMAdapter, CreateGridAgent, FinishGridSimulationTrigger, + WrappedActivation, } import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem @@ -22,8 +21,9 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.services.ServiceMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationFailedMessage @@ -53,14 +53,14 @@ class DBFSAlgorithmParticipantSpec private val scheduler: TestProbe[SchedulerMessage] = TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe("runtimeEvents") + private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") private val primaryService: TestProbe[ServiceMessage] = TestProbe[ServiceMessage]("primaryService") private val weatherService = TestProbe("weatherService") private val environmentRefs = EnvironmentRefs( scheduler = scheduler.ref.toClassic, - runtimeEventListener = runtimeEvents.ref.toClassic, + runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref.toClassic, weather = weatherService.ref.toClassic, evDataService = None, @@ -109,7 +109,7 @@ class DBFSAlgorithmParticipantSpec msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) // send init data to agent and expect a CompletionMessage - gridAgentWithParticipants ! ActivationAdapter(Activation(INIT_SIM_TICK)) + gridAgentWithParticipants ! WrappedActivation(Activation(INIT_SIM_TICK)) val message = scheduler.expectMessageType[ScheduleActivation] @@ -120,6 +120,9 @@ class DBFSAlgorithmParticipantSpec _, ) => loadAgent + + case other => + fail(s"$other was not expected") } val completionMessage = scheduler.expectMessageType[Completion] @@ -148,7 +151,7 @@ class DBFSAlgorithmParticipantSpec s"go to SimulateGrid when it receives an activity start trigger" in { // send init data to agent - gridAgentWithParticipants ! ActivationAdapter(Activation(3600)) + gridAgentWithParticipants ! WrappedActivation(Activation(3600)) // we expect a completion message val message = scheduler.expectMessageType[Completion] @@ -161,7 +164,7 @@ class DBFSAlgorithmParticipantSpec // send the start grid simulation trigger // the gird agent should send a RequestAssetPowerMessage to the load agent - gridAgentWithParticipants ! ActivationAdapter(Activation(3600)) + gridAgentWithParticipants ! WrappedActivation(Activation(3600)) // we expect a request for voltage values of our slack node // (voltages are requested by our agent under test from the superior grid) @@ -170,17 +173,15 @@ class DBFSAlgorithmParticipantSpec // we now answer the request of our gridAgentsWithParticipants // with a fake slack voltage message - firstSlackVoltageRequestSender ! VMAdapter( - ProvideSlackVoltageMessage( - firstSweepNo, - Seq( - ExchangeVoltage( - supNodeA.getUuid, - Kilovolts(380d), - Kilovolts(0d), - ) - ), - ) + firstSlackVoltageRequestSender ! ProvideSlackVoltageMessage( + firstSweepNo, + Seq( + ExchangeVoltage( + supNodeA.getUuid, + Kilovolts(380d), + Kilovolts(0d), + ) + ), ) // power flow calculation should run now. After it's done, @@ -217,17 +218,15 @@ class DBFSAlgorithmParticipantSpec superiorGridAgent.expectSlackVoltageRequest(secondSweepNo) // the superior grid would answer with updated slack voltage values - secondSlackAskSender ! VMAdapter( - ProvideSlackVoltageMessage( - secondSweepNo, - Seq( - ExchangeVoltage( - supNodeA.getUuid, - Kilovolts(374.2269461446d), - Kilovolts(65.9863075134d), - ) - ), - ) + secondSlackAskSender ! ProvideSlackVoltageMessage( + secondSweepNo, + Seq( + ExchangeVoltage( + supNodeA.getUuid, + Kilovolts(374.2269461446d), + Kilovolts(65.9863075134d), + ) + ), ) // here the gridAgentWithParticipants has received a second AssetPowerUnchangedMessage diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index 5d023f1017..19f68dc84b 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -11,12 +11,13 @@ import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage.{ - ActivationAdapter, CreateGridAgent, FinishGridSimulationTrigger, - PMAdapter, + WrappedActivation, + WrappedPowerMessage, } import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower @@ -61,7 +62,7 @@ class DBFSAlgorithmSupGridSpec private val scheduler: TestProbe[SchedulerMessage] = TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe("runtimeEvents") + private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") private val primaryService: TestProbe[ServiceMessage] = TestProbe[ServiceMessage]("primaryService") private val weatherService = TestProbe("weatherService") @@ -70,7 +71,7 @@ class DBFSAlgorithmSupGridSpec private val environmentRefs = EnvironmentRefs( scheduler = scheduler.ref.toClassic, - runtimeEventListener = runtimeEvents.ref.toClassic, + runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref.toClassic, weather = weatherService.ref.toClassic, evDataService = None, @@ -110,7 +111,7 @@ class DBFSAlgorithmSupGridSpec val am = scheduler.expectMessageType[ScheduleActivation] am shouldBe ScheduleActivation(am.actor, INIT_SIM_TICK, Some(key)) - superiorGridAgentFSM ! ActivationAdapter(Activation(INIT_SIM_TICK)) + superiorGridAgentFSM ! WrappedActivation(Activation(INIT_SIM_TICK)) val cm = scheduler.expectMessageType[Completion] cm shouldBe Completion(cm.actor, Some(3600)) @@ -118,7 +119,7 @@ class DBFSAlgorithmSupGridSpec s"go to SimulateGrid when it receives an activity start trigger" in { // send init data to agent - superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) + superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a completion message val message = scheduler.expectMessageType[Completion] @@ -134,13 +135,15 @@ class DBFSAlgorithmSupGridSpec Vector(UUID.fromString("9fe5fa33-6d3b-4153-a829-a16f4347bc4e")) // send the start grid simulation trigger - superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) + superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo - val message = hvGrid.expectMessageType[PMAdapter] + val message = hvGrid.expectMessageType[WrappedPowerMessage] val lastSender = message match { - case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => + case WrappedPowerMessage( + requestGridPowerMessage: RequestGridPowerMessage + ) => requestGridPowerMessage.currentSweepNo shouldBe sweepNo requestGridPowerMessage.nodeUuids should contain allElementsOf requestedConnectionNodeUuids @@ -154,7 +157,7 @@ class DBFSAlgorithmSupGridSpec // we return with a fake grid power message // / as we are using the ask pattern, we cannot send it to the grid agent directly but have to send it to the // / ask sender - lastSender ! PMAdapter( + lastSender ! WrappedPowerMessage( ProvideGridPowerMessage( requestedConnectionNodeUuids.map { uuid => ExchangePower( @@ -245,7 +248,7 @@ class DBFSAlgorithmSupGridSpec ) // bring agent in simulate grid state - superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) + superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a completion message val message = scheduler.expectMessageType[Completion] @@ -258,13 +261,15 @@ class DBFSAlgorithmSupGridSpec Vector(UUID.fromString("9fe5fa33-6d3b-4153-a829-a16f4347bc4e")) // send the start grid simulation trigger - superiorGridAgentFSM ! ActivationAdapter(Activation(3600)) + superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a request for grid power values here for sweepNo $sweepNo val message = hvGrid.expectMessageType[GridAgentMessage] val lastSender = message match { - case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => + case WrappedPowerMessage( + requestGridPowerMessage: RequestGridPowerMessage + ) => requestGridPowerMessage.currentSweepNo shouldBe sweepNo requestGridPowerMessage.nodeUuids should contain allElementsOf requestedConnectionNodeUuids @@ -278,7 +283,7 @@ class DBFSAlgorithmSupGridSpec // we return with a fake grid power message // / as we are using the ask pattern, we cannot send it to the grid agent directly but have to send it to the // / ask sender - lastSender ! PMAdapter( + lastSender ! WrappedPowerMessage( ProvideGridPowerMessage( requestedConnectionNodeUuids.map { uuid => ExchangePower( diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala index fe35899c69..27c542611c 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSMockGridAgents.scala @@ -6,21 +6,21 @@ package edu.ie3.simona.agent.grid -import edu.ie3.simona.agent.grid.GridAgentMessage.{PMAdapter, VMAdapter} -import org.apache.pekko.actor.typed.ActorRef +import edu.ie3.simona.agent.grid.GridAgentMessage.WrappedPowerMessage +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.agent.grid.VoltageMessage.{ + ProvideSlackVoltageMessage, + RequestSlackVoltageMessage, +} import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvideGridPowerMessage, RequestGridPowerMessage, } -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage -import edu.ie3.simona.ontology.messages.VoltageMessage.{ - ProvideSlackVoltageMessage, - RequestSlackVoltageMessage, -} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.quantities.{Megavars, ReactivePower} import org.apache.pekko.actor.testkit.typed.scaladsl.TestProbe +import org.apache.pekko.actor.typed.ActorRef import squants.Power import squants.electro.Volts import squants.energy.Megawatts @@ -53,10 +53,10 @@ trait DBFSMockGridAgents extends UnitSpec { ) extends GAActorAndModel { def expectGridPowerRequest(): ActorRef[GridAgentMessage] = { - val message = gaProbe.expectMessageType[GridAgentMessage] - - message match { - case PMAdapter(requestGridPowerMessage: RequestGridPowerMessage) => + gaProbe.expectMessageType[GridAgentMessage] match { + case WrappedPowerMessage( + requestGridPowerMessage: RequestGridPowerMessage + ) => requestGridPowerMessage.nodeUuids should contain allElementsOf nodeUuids requestGridPowerMessage.sender @@ -67,10 +67,8 @@ trait DBFSMockGridAgents extends UnitSpec { expectedSweepNo: Int, expectedExchangedVoltages: Seq[ExchangeVoltage], ): Unit = { - val message = gaProbe.expectMessageType[GridAgentMessage] - - message match { - case VMAdapter(msg: ProvideSlackVoltageMessage) => + gaProbe.expectMessageType[GridAgentMessage] match { + case msg: ProvideSlackVoltageMessage => msg.currentSweepNo shouldBe expectedSweepNo msg.nodalSlackVoltages.size shouldBe expectedExchangedVoltages.size @@ -95,9 +93,7 @@ trait DBFSMockGridAgents extends UnitSpec { receiver: ActorRef[GridAgentMessage], sweepNo: Int, ): Unit = - receiver ! VMAdapter( - RequestSlackVoltageMessage(sweepNo, nodeUuids, gaProbe.ref) - ) + receiver ! RequestSlackVoltageMessage(sweepNo, nodeUuids, gaProbe.ref) } final case class SuperiorGA( @@ -108,12 +104,8 @@ trait DBFSMockGridAgents extends UnitSpec { def expectSlackVoltageRequest( expectedSweepNo: Int ): ActorRef[GridAgentMessage] = { - val message = gaProbe.expectMessageType[GridAgentMessage] - - message match { - case VMAdapter( - requestSlackVoltageMessage: RequestSlackVoltageMessage - ) => + gaProbe.expectMessageType[GridAgentMessage] match { + case requestSlackVoltageMessage: RequestSlackVoltageMessage => requestSlackVoltageMessage.currentSweepNo shouldBe expectedSweepNo requestSlackVoltageMessage.nodeUuids should have size nodeUuids.size requestSlackVoltageMessage.nodeUuids should contain allElementsOf nodeUuids @@ -126,10 +118,8 @@ trait DBFSMockGridAgents extends UnitSpec { expectedExchangedPowers: Seq[ExchangePower], maxDuration: FiniteDuration = 30 seconds, ): Unit = { - val message = gaProbe.expectMessageType[GridAgentMessage](maxDuration) - - message match { - case PMAdapter(msg: ProvideGridPowerMessage) => + gaProbe.expectMessageType[GridAgentMessage](maxDuration) match { + case WrappedPowerMessage(msg: ProvideGridPowerMessage) => msg.nodalResidualPower should have size expectedExchangedPowers.size expectedExchangedPowers.foreach { expectedPower => @@ -153,7 +143,7 @@ trait DBFSMockGridAgents extends UnitSpec { receiver: ActorRef[GridAgentMessage], sweepNo: Int, ): Unit = { - receiver ! PMAdapter( + receiver ! WrappedPowerMessage( RequestGridPowerMessage(sweepNo, nodeUuids, gaProbe.ref) ) } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala index 243167c216..19120cbe35 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala @@ -9,14 +9,23 @@ package edu.ie3.simona.agent.grid import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgentMessage.StringAdapter +import edu.ie3.simona.agent.grid.GridAgentMessage.{ + FinishGridSimulationTrigger, + PrepareNextSweepTrigger, +} +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.result.ResultSinkType import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import edu.ie3.simona.test.common.ConfigTestData import edu.ie3.simona.test.common.input.TransformerInputTestData import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig -import org.apache.pekko.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + BehaviorTestKit, + ScalaTestWithActorTestKit, + TestProbe, +} +import org.apache.pekko.actor.typed.{ActorRef, Scheduler} import org.apache.pekko.actor.typed.receptionist.Receptionist.{ Listing, Register, @@ -29,9 +38,12 @@ import org.apache.pekko.actor.typed.scaladsl.adapter.{ TypedActorContextOps, TypedActorRefOps, } -import org.apache.pekko.actor.typed.{ActorRef, Scheduler} -import org.apache.pekko.actor.{ActorRef => classicRef} +import org.apache.pekko.actor.{ + ActorContext => ClassicContext, + ActorRef => ClassicRef, +} import org.apache.pekko.util.Timeout +import org.mockito.Mock import org.scalatest.wordspec.AnyWordSpecLike import java.util.concurrent.TimeUnit @@ -46,6 +58,19 @@ class GridAgentSetup2WSpec with LazyLogging { "The setup of grid agents" must { + + val scheduler = TestProbe("scheduler") + val runtimeEventListener = TestProbe[RuntimeEvent]("listener") + val primaryServiceProxy = TestProbe("primaryServiceProxy") + + val environmentRefs = EnvironmentRefs( + scheduler.ref.toClassic, + runtimeEventListener.ref, + primaryServiceProxy = primaryServiceProxy.ref.toClassic, + weather = ClassicRef.noSender, + evDataService = None, + ) + "provide two grid agents on presence of a two winding transformer" in { implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) @@ -58,19 +83,7 @@ class GridAgentSetup2WSpec ctx.system.receptionist ! Register(serviceKey, ctx.self) Behaviors.receive[GridAgentMessage] { - case (ctx, StringAdapter("ping", sender)) => - // replying to ping signal - sender ! StringAdapter("pong", ctx.self) - Behaviors.same - case (ctx, StringAdapter("setup", _)) => - val environmentRefs = EnvironmentRefs( - scheduler = ctx.self.toClassic, - runtimeEventListener = ctx.self.toClassic, - primaryServiceProxy = ctx.self.toClassic, - weather = classicRef.noSender, - evDataService = None, - ) - + case (ctx, PrepareNextSweepTrigger(tick)) => SimonaStandaloneSetup( typesafeConfig, ResultFileHierarchy( @@ -88,19 +101,23 @@ class GridAgentSetup2WSpec gridContainer.getSubGridTopologyGraph, ctx.toClassic, environmentRefs, - Seq.empty[classicRef], + Seq.empty[ClassicRef], ) - ctx.self ! StringAdapter("done", ctx.self) + + ctx.self ! FinishGridSimulationTrigger(tick) Behaviors.same + + case other => + fail(s"$other was not expected") } }) Await.ready( - actor.ask[GridAgentMessage](ref => StringAdapter("setup", ref)), + actor.ask[GridAgentMessage](_ => PrepareNextSweepTrigger(0)), Duration(10, TimeUnit.SECONDS), ) - testKit.spawn(Behaviors.setup[Listing] { ctx => + BehaviorTestKit(Behaviors.setup[Listing] { ctx => logger.debug("Subscribing to the actors.") ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala index 988e941400..e269e9c0e9 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala @@ -9,13 +9,22 @@ package edu.ie3.simona.agent.grid import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgentMessage.StringAdapter +import edu.ie3.simona.agent.grid.GridAgentMessage.{ + FinishGridSimulationTrigger, + PrepareNextSweepTrigger, +} +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.result.ResultSinkType import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import edu.ie3.simona.test.common.{ConfigTestData, ThreeWindingTestData} import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig -import org.apache.pekko.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + BehaviorTestKit, + ScalaTestWithActorTestKit, + TestProbe, +} +import org.apache.pekko.actor.typed.{ActorRef, Scheduler} import org.apache.pekko.actor.typed.receptionist.Receptionist.{ Listing, Register, @@ -24,12 +33,11 @@ import org.apache.pekko.actor.typed.receptionist.Receptionist.{ import org.apache.pekko.actor.typed.receptionist.ServiceKey import org.apache.pekko.actor.typed.scaladsl.AskPattern.Askable import org.apache.pekko.actor.typed.scaladsl.Behaviors -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - TypedActorContextOps, - TypedActorRefOps, +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps +import org.apache.pekko.actor.{ + ActorContext => ClassicContext, + ActorRef => ClassicRef, } -import org.apache.pekko.actor.typed.{ActorRef, Scheduler} -import org.apache.pekko.actor.{ActorRef => classicRef} import org.apache.pekko.util.Timeout import org.scalatest.wordspec.AnyWordSpecLike @@ -45,6 +53,19 @@ class GridAgentSetup3WSpec with LazyLogging { "The setup of grid agents" must { + + val scheduler = TestProbe("scheduler") + val runtimeEventListener = TestProbe[RuntimeEvent]("listener") + val primaryServiceProxy = TestProbe("primaryServiceProxy") + + val environmentRefs = EnvironmentRefs( + scheduler.ref.toClassic, + runtimeEventListener.ref, + primaryServiceProxy = primaryServiceProxy.ref.toClassic, + weather = ClassicRef.noSender, + evDataService = None, + ) + "provide three grid agents on presence of a three winding transformer" in { implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) implicit val scheduler: Scheduler = system.scheduler @@ -56,20 +77,7 @@ class GridAgentSetup3WSpec ctx.system.receptionist ! Register(serviceKey, ctx.self) Behaviors.receive[GridAgentMessage] { - case (ctx, StringAdapter("ping", sender)) => - // replying to ping signal - sender ! StringAdapter("pong", ctx.self) - Behaviors.same - - case (ctx, StringAdapter("setup", _)) => - val environmentRefs = EnvironmentRefs( - scheduler = ctx.self.toClassic, - runtimeEventListener = ctx.self.toClassic, - primaryServiceProxy = ctx.self.toClassic, - weather = classicRef.noSender, - evDataService = None, - ) - + case (ctx, PrepareNextSweepTrigger(tick)) => SimonaStandaloneSetup( typesafeConfig, ResultFileHierarchy( @@ -85,21 +93,24 @@ class GridAgentSetup3WSpec ), ).buildSubGridToActorRefMap( threeWindingTestGrid.getSubGridTopologyGraph, - ctx.toClassic, + ctx.asInstanceOf[ClassicContext], environmentRefs, - Seq.empty[classicRef], + Seq.empty[ClassicRef], ) - ctx.self ! StringAdapter("done", ctx.self) + ctx.self ! FinishGridSimulationTrigger(tick) Behaviors.same + + case other => + fail(s"$other was not expected") } }) Await.ready( - actor.ask[GridAgentMessage](ref => StringAdapter("setup", ref)), + actor.ask[GridAgentMessage](_ => PrepareNextSweepTrigger(0)), Duration(10, TimeUnit.SECONDS), ) - testKit.spawn(Behaviors.setup[Listing] { ctx => + BehaviorTestKit(Behaviors.setup[Listing] { ctx => logger.debug("Subscribing to the actors.") ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala index 53e17242e7..070e771241 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.grid import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower -import edu.ie3.simona.ontology.messages.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.BasicGridWithSwitches import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble @@ -41,8 +41,7 @@ class PowerFlowSupportSpec with PowerFlowSupport with GridResultsSupport { - implicit val log: Logger = - LoggerFactory.getLogger(PowerFlowSupportSpec.super.getClass) + implicit val log: Logger = LoggerFactory.getLogger(this.getClass) val actorRef: ActorRef[GridAgentMessage] = TestProbe[GridAgentMessage]("noSender").ref diff --git a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala index 3d24cdd038..378c08c1ef 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/ReceivedValuesStoreSpec.scala @@ -24,22 +24,22 @@ class ReceivedValuesStoreSpec with SubGridGateMokka { // test actorRefs - val actorProbe1: TestProbe[ParticipantMessage] = + val participant1: TestProbe[ParticipantMessage] = TestProbe[ParticipantMessage]() - val actorProbe2: TestProbe[ParticipantMessage] = + val participant2: TestProbe[ParticipantMessage] = TestProbe[ParticipantMessage]() - val actorProbe3: TestProbe[ParticipantMessage] = + val participant3: TestProbe[ParticipantMessage] = TestProbe[ParticipantMessage]() - val actorProbe4: TestProbe[GridAgentMessage] = TestProbe[GridAgentMessage]() + val gridAgent: TestProbe[GridAgentMessage] = TestProbe[GridAgentMessage]() // test data used by almost all tests // / node to asset agents mapping val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef[ParticipantMessage]]] = Map( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") -> Set( - actorProbe1.ref + participant1.ref ), UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") -> Set( - actorProbe2.ref + participant2.ref ), ) @@ -51,7 +51,7 @@ class ReceivedValuesStoreSpec 1, UUID.fromString("1676360a-c7c4-43a9-a667-90ddfe8a18e6"), 2, - ) -> actorProbe4.ref + ) -> gridAgent.ref ) // / superior grid nodeUuid vector @@ -93,13 +93,13 @@ class ReceivedValuesStoreSpec receivedValuesStore.nodeToReceivedPower.size shouldBe 3 receivedValuesStore.nodeToReceivedPower( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") - ) shouldBe Map(actorProbe1.ref -> None) + ) shouldBe Map(participant1.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") - ) shouldBe Map(actorProbe2.ref -> None) + ) shouldBe Map(participant2.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8") - ) shouldBe Map(actorProbe4.ref -> None) + ) shouldBe Map(gridAgent.ref -> None) receivedValuesStore.nodeToReceivedSlackVoltage.size shouldBe 1 receivedValuesStore.nodeToReceivedSlackVoltage( @@ -113,11 +113,11 @@ class ReceivedValuesStoreSpec val nodeToAssetAgentsMap = Map( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") -> Set( - actorProbe1.ref + participant1.ref ), UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") -> Set( - actorProbe2.ref, - actorProbe3.ref, + participant2.ref, + participant3.ref, ), ) @@ -137,12 +137,12 @@ class ReceivedValuesStoreSpec receivedValuesStore.nodeToReceivedPower.size shouldBe 2 receivedValuesStore.nodeToReceivedPower( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") - ) shouldBe Map(actorProbe1.ref -> None) + ) shouldBe Map(participant1.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") ) shouldBe Map( - actorProbe2.ref -> None, - actorProbe3.ref -> None, + participant2.ref -> None, + participant3.ref -> None, ) } @@ -163,13 +163,13 @@ class ReceivedValuesStoreSpec receivedValuesStore.nodeToReceivedPower.size shouldBe 3 receivedValuesStore.nodeToReceivedPower( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") - ) shouldBe Map(actorProbe1.ref -> None) + ) shouldBe Map(participant1.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") - ) shouldBe Map(actorProbe2.ref -> None) + ) shouldBe Map(participant2.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("5cd55ab5-a7d2-499f-a25f-6dbc3845c5e8") - ) shouldBe Map(actorProbe4.ref -> None) + ) shouldBe Map(gridAgent.ref -> None) } @@ -222,10 +222,10 @@ class ReceivedValuesStoreSpec receivedValuesStore.nodeToReceivedPower.size shouldBe 2 receivedValuesStore.nodeToReceivedPower( UUID.fromString("dd9a5b54-94bb-4201-9108-2b1b7d689546") - ) shouldBe Map(actorProbe1.ref -> None) + ) shouldBe Map(participant1.ref -> None) receivedValuesStore.nodeToReceivedPower( UUID.fromString("34e807f1-c62b-4968-b0f6-980ce500ff97") - ) shouldBe Map(actorProbe2.ref -> None) + ) shouldBe Map(participant2.ref -> None) } diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index f3811556c3..7ce21d9cdd 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -7,9 +7,9 @@ package edu.ie3.simona.sim.setup import org.apache.pekko.actor.{ - ActorContext, - ActorRef => classicRef, ActorSystem, + ActorContext, + ActorRef => ClassicRef, } import org.apache.pekko.actor.typed.ActorRef import edu.ie3.datamodel.exceptions.NotImplementedException @@ -40,31 +40,31 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def systemParticipantsListener( context: ActorContext - ): Seq[classicRef] = throw new NotImplementedException( + ): Seq[ClassicRef] = throw new NotImplementedException( "This is a dummy setup" ) override def primaryServiceProxy( context: ActorContext, - scheduler: classicRef, - ): classicRef = + scheduler: ClassicRef, + ): ClassicRef = throw new NotImplementedException("This is a dummy setup") override def weatherService( context: ActorContext, - scheduler: classicRef, - ): classicRef = + scheduler: ClassicRef, + ): ClassicRef = throw new NotImplementedException("This is a dummy setup") override def extSimulations( context: ActorContext, - scheduler: classicRef, + scheduler: ClassicRef, ): ExtSimSetupData = throw new NotImplementedException("This is a dummy setup") override def timeAdvancer( context: ActorContext, - simulation: classicRef, + simulation: ClassicRef, runtimeEventListener: ActorRef[RuntimeEvent], ): ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException("This is a dummy setup") @@ -72,12 +72,12 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def scheduler( context: ActorContext, timeAdvancer: ActorRef[TimeAdvancer.Incoming], - ): classicRef = throw new NotImplementedException("This is a dummy setup") + ): ClassicRef = throw new NotImplementedException("This is a dummy setup") override def gridAgents( context: ActorContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[classicRef], + systemParticipantListener: Seq[ClassicRef], ): Iterable[ActorRef[GridAgentMessage]] = throw new NotImplementedException("This is a dummy setup") From a2c31557b435e6e4022e559d645eb8c0e05f89b8 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 17:08:13 +0100 Subject: [PATCH 225/305] Specifying logger name for test kit --- .../simona/event/listener/RuntimeEventListenerSpec.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala index a1bad16bde..1f9ec7f3ae 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala @@ -147,8 +147,12 @@ class RuntimeEventListenerSpec ), ) + val loggingTestKit = LoggingTestKit.empty + // logger name for ActorContext loggers (ctx.log) is the class name + .withLoggerName(RuntimeEventListener.getClass.getName) + events.foreach { case (event, level, msg) => - LoggingTestKit.empty + loggingTestKit .withLogLevel(level) .withMessageContains(msg) .expect { From 7c3df8d0ef68ab0295546288b8511f8e8a04c082 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 17:33:05 +0100 Subject: [PATCH 226/305] Separating test cases --- .../listener/RuntimeEventListenerSpec.scala | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala index 1f9ec7f3ae..f547693e08 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala @@ -47,30 +47,27 @@ class RuntimeEventListenerSpec with PrivateMethodTester { // global variables - val eventQueue = new LinkedBlockingQueue[RuntimeEvent]() val startDateTimeString = "2011-01-01 00:00:00" val endTick = 3600 val duration = 10805000 - val errMsg = - "Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein" + val errMsg = "testing error msg" - // to change for Ready event test cases val currentTick = 0 - // build the listener - private val listenerRef = spawn( - RuntimeEventListener( - SimonaConfig.Simona.Runtime.Listener( - None, - None, - ), - Some(eventQueue), - startDateTimeString, - ) - ) - "A runtime event listener" must { "add a valid runtime event to the blocking queue for further processing" in { + val eventQueue = new LinkedBlockingQueue[RuntimeEvent]() + + val listenerRef = spawn( + RuntimeEventListener( + SimonaConfig.Simona.Runtime.Listener( + None, + None, + ), + Some(eventQueue), + startDateTimeString, + ) + ) // valid runtime events val eventsToQueue: Seq[RuntimeEvent] = List( @@ -97,6 +94,17 @@ class RuntimeEventListenerSpec "return valid log messages for each status event" in { + val listenerRef = spawn( + RuntimeEventListener( + SimonaConfig.Simona.Runtime.Listener( + None, + None, + ), + None, + startDateTimeString, + ) + ) + def calcTime(curTick: Long): String = { TimeUtil.withDefaults.toString( curTick.toDateTime( From a806229639483b96bc96cb4aa839c9792024f73e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 14 Feb 2024 17:55:21 +0100 Subject: [PATCH 227/305] remove wrong entry in changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e36f22096d..ea7a458337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Relevant scientific papers have been added to the documentation [#139](https://github.com/ie3-institute/simona/issues/139) - Add troubleshooting section to Users guide [#160](https://github.com/ie3-institute/simona/issues/160) - Added Kafka sink for results [#24](https://github.com/ie3-institute/simona/issues/24) -- Config possibility for transformer control groups [#90](https://github.com/ie3-institute/simona/issues/90) - Added Kafka sink for runtime events, re-implemented RuntimeEventListener in akka typed [#242](https://github.com/ie3-institute/simona/issues/242) - Added listeners to DBFS tests to check the result output and check the handling of failed power flows [#269](https://github.com/ie3-institute/simona/issues/269) - Added DBFS test with participant load and added testing for FinishGridSimulationTrigger [#281](https://github.com/ie3-institute/simona/issues/281) From a971ed71cd702b0d58ffe5b2f6b0606b1cf41408 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 18:54:51 +0100 Subject: [PATCH 228/305] Actually fixing RuntimeEventListenerKafkaSpec --- .../listener/RuntimeEventListenerKafkaSpec.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala index 47b14f6aee..71a17a5407 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala @@ -128,13 +128,14 @@ class RuntimeEventListenerKafkaSpec forAll(cases) { case (event, expectedMsg) => listenerRef ! event - val records: List[SimonaEndMessage] = - eventually(timeout(20 seconds), interval(1 second)) { + eventually(timeout(20 seconds), interval(1 second)) { + val records = testConsumer.poll((1 second) toJava).asScala.map(_.value()).toList - } - records should have length 1 - records should contain(expectedMsg) + records should have length 1 + records should contain(expectedMsg) + } + } } From 19fbd30eff0b47c1fb4fcafec0d334eacdee4c21 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 18:57:35 +0100 Subject: [PATCH 229/305] A bit more leeway for stochastic test --- .../simona/model/participant/load/LoadModelScalingSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala index 351cb6630d..b8dc25b01a 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/load/LoadModelScalingSpec.scala @@ -340,7 +340,7 @@ class LoadModelScalingSpec extends UnitSpec with TableDrivenPropertyChecks { getRelativeDifference( quantile95, targetMaximumPower, - ) should be < Percent(1d) + ) should be < Percent(2d) } "correctly account for the scaling factor when targeting at maximum power" in { From e9255aa872fab5c446726258496a9503ba772ce5 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 19:01:33 +0100 Subject: [PATCH 230/305] Better test structure --- .../RuntimeEventListenerKafkaSpec.scala | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala index 71a17a5407..03d3545389 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala @@ -128,13 +128,20 @@ class RuntimeEventListenerKafkaSpec forAll(cases) { case (event, expectedMsg) => listenerRef ! event - eventually(timeout(20 seconds), interval(1 second)) { - val records = - testConsumer.poll((1 second) toJava).asScala.map(_.value()).toList + val receivedRecord = + eventually(timeout(20 seconds), interval(1 second)) { + val records = + testConsumer.poll((1 second) toJava).asScala.map(_.value()).toList - records should have length 1 - records should contain(expectedMsg) - } + // run until one record is received. After each second, if no record + // was received, the length check below fails and we retry + records should have length 1 + + // return final record to be checked + records.headOption.value + } + + receivedRecord shouldBe expectedMsg } From 5f919aa6609317002f54b0769cbf7067167ef0f4 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 19:31:05 +0100 Subject: [PATCH 231/305] Better test result checks --- .../integration/RunSimonaStandaloneIT.scala | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala index bbb75ab499..0262ebcf1c 100644 --- a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala +++ b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala @@ -126,28 +126,25 @@ class RunSimonaStandaloneIT private def checkRuntimeEvents( runtimeEvents: Iterable[RuntimeEvent] ): Unit = { - runtimeEvents.toVector.size shouldBe 11 - val groupedRuntimeEvents = runtimeEvents.toVector.groupBy { - case Initializing => Initializing - case InitComplete(_) => InitComplete - case Simulating(_, _) => Simulating - case CheckWindowPassed(_, _) => CheckWindowPassed - case Done(_, _, _) => Done - case other => fail(s"Unexpected runtime event: $other") - } - - groupedRuntimeEvents.size shouldBe 5 - groupedRuntimeEvents.keySet should contain allOf (Simulating, CheckWindowPassed, InitComplete, Initializing, Done) + val groupedRuntimeEvents = runtimeEvents.groupBy(event => event.getClass) + + groupedRuntimeEvents.keySet should contain only ( + classOf[Simulating], + classOf[CheckWindowPassed], + classOf[InitComplete], + classOf[Initializing.type], + classOf[Done] + ) groupedRuntimeEvents - .get(Simulating) + .get(classOf[Simulating]) .foreach(simulatingEvents => { simulatingEvents.size shouldBe 1 simulatingEvents.headOption.foreach(_ shouldBe Simulating(0, 7200)) }) groupedRuntimeEvents - .get(CheckWindowPassed) + .get(classOf[CheckWindowPassed]) .foreach(checkWindowsPassed => { checkWindowsPassed.size shouldBe 7 checkWindowsPassed.foreach { @@ -161,19 +158,19 @@ class RunSimonaStandaloneIT }) groupedRuntimeEvents - .get(InitComplete) + .get(classOf[InitComplete]) .foreach(initComplets => { initComplets.size shouldBe 1 }) groupedRuntimeEvents - .get(Initializing) + .get(classOf[Initializing.type]) .foreach(initializings => { initializings.size shouldBe 1 }) groupedRuntimeEvents - .get(Done) + .get(classOf[Done]) .foreach(dones => { dones.size shouldBe 1 dones.headOption.foreach { From 0ce4edf1a2e05a3b4b902718e4934627755d32db Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 20:05:51 +0100 Subject: [PATCH 232/305] Adding to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 216b8976cb..569f69400f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Logging wrong duration in the first simulation hour [#705](https://github.com/ie3-institute/simona/issues/705) - Fixed some compiler warnings [#657](https://github.com/ie3-institute/simona/issues/657) - Fixing false negative in ref system voltage validation [#706](https://github.com/ie3-institute/simona/issues/706) +- Fixing randomly failing test in `RuntimeEventListenerSpec` etc. [#709](https://github.com/ie3-institute/simona/issues/709) ## [3.0.0] - 2023-08-07 From c26415257bfe506d4accd1d0ab6c5d66a40d81a7 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 20:21:07 +0100 Subject: [PATCH 233/305] Small improvements in ResultEventListener --- CHANGELOG.md | 1 + .../event/listener/RuntimeEventListener.scala | 19 ++++++++++--------- .../io/runtime/RuntimeEventKafkaSink.scala | 10 +++++++--- .../io/runtime/RuntimeEventLogSink.scala | 6 ++++-- .../io/runtime/RuntimeEventQueueSink.scala | 1 - .../simona/io/runtime/RuntimeEventSink.scala | 3 --- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 216b8976cb..8d6861eaa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use `ThermalGrid` to calculate thermal environment of a heat pump [#315](https://github.com/ie3-institute/simona/issues/315) - Enable windows path as config parameters [#549](https://github.com/ie3-institute/simona/issues/549) - Unified consideration of scaling factor when simulating system participants [#81](https://github.com/ie3-institute/simona/issues/81) +- Small improvements in `ResultEventListener` [#738](https://github.com/ie3-institute/simona/issues/738) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index 3b12951688..c3bfd98062 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -19,7 +19,6 @@ import edu.ie3.simona.io.runtime.{ RuntimeEventSink, } import edu.ie3.util.TimeUtil -import org.slf4j.Logger import java.util.concurrent.BlockingQueue @@ -43,24 +42,27 @@ object RuntimeEventListener { listenerConf: SimonaConfig.Simona.Runtime.Listener, queue: Option[BlockingQueue[RuntimeEvent]], startDateTimeString: String, - ): Behavior[RuntimeEvent] = { + ): Behavior[RuntimeEvent] = Behaviors.setup { ctx => val listeners = Iterable( Some( RuntimeEventLogSink( - TimeUtil.withDefaults.toZonedDateTime(startDateTimeString) + TimeUtil.withDefaults.toZonedDateTime(startDateTimeString), + ctx.log, ) ), queue.map(qu => RuntimeEventQueueSink(qu)), - listenerConf.kafka.map(kafkaConf => RuntimeEventKafkaSink(kafkaConf)), + listenerConf.kafka.map(kafkaConf => + RuntimeEventKafkaSink(kafkaConf, ctx.log) + ), ).flatten - RuntimeEventListener( + apply( listeners, listenerConf.eventsToProcess, ) } - def apply( + private def apply( listeners: Iterable[RuntimeEventSink], eventsToProcess: Option[List[String]] = None, runtimeStats: RuntimeStats = RuntimeStats(), @@ -75,7 +77,7 @@ object RuntimeEventListener { val process = eventsToProcess.forall(_.contains(event.id)) if (process) - processEvent(listeners, event, runtimeStats, ctx.log) + processEvent(listeners, event, runtimeStats) else ctx.log.debug( "Skipping event {} as it is not in the list of events to process.", @@ -92,8 +94,7 @@ object RuntimeEventListener { listeners: Iterable[RuntimeEventSink], event: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger, ): Unit = - listeners.foreach(_.handleRuntimeEvent(event, runtimeStats, log)) + listeners.foreach(_.handleRuntimeEvent(event, runtimeStats)) } diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala index b38e3c252d..c13a3ca75b 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala @@ -31,18 +31,20 @@ import scala.jdk.CollectionConverters._ * @param simRunId * the id of this simulation run * @param topic - * the topic to send the events to + * the topic to send the events to ticks + * @param log + * The logger to use */ final case class RuntimeEventKafkaSink( producer: KafkaProducer[String, SimonaEndMessage], simRunId: UUID, topic: String, + log: Logger, ) extends RuntimeEventSink { override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger, ): Unit = { (runtimeEvent match { case Done(_, _, errorInSim) => @@ -74,7 +76,8 @@ final case class RuntimeEventKafkaSink( object RuntimeEventKafkaSink { def apply( - config: RuntimeKafkaParams + config: RuntimeKafkaParams, + log: Logger, ): RuntimeEventKafkaSink = { val simRunId = UUID.fromString(config.runId) @@ -106,6 +109,7 @@ object RuntimeEventKafkaSink { ), simRunId, config.topic, + log, ) } diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala index 6117ebccb9..bda989ba68 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala @@ -18,15 +18,17 @@ import java.time.ZonedDateTime * @param simulationStartDate * the simulation start date time, used for calculating simulation time from * ticks + * @param log + * The logger to use */ final case class RuntimeEventLogSink( - simulationStartDate: ZonedDateTime + simulationStartDate: ZonedDateTime, + log: Logger, ) extends RuntimeEventSink { override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger, ): Unit = runtimeEvent match { case Initializing => diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala index 202f13f0d9..82198970bb 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala @@ -21,7 +21,6 @@ final case class RuntimeEventQueueSink(queue: BlockingQueue[RuntimeEvent]) override def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger, ): Unit = queue.put(runtimeEvent) diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala index 4a526788be..e10ef7c42e 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala @@ -22,13 +22,10 @@ trait RuntimeEventSink { * The runtime event that should be processed * @param runtimeStats * The runtime statistical data - * @param log - * The logger to use */ def handleRuntimeEvent( runtimeEvent: RuntimeEvent, runtimeStats: RuntimeStats, - log: Logger, ): Unit /** Contains all cleanup operations before closing this sink. Should be From 21b263ad8585bf552f5dde5eabf2ef778c004e47 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 14 Feb 2024 20:27:20 +0100 Subject: [PATCH 234/305] Fixing small code issues --- .../edu/ie3/simona/event/listener/RuntimeEventListener.scala | 1 + .../edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala | 4 +++- .../scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala | 2 ++ .../edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala | 2 +- .../scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala | 1 - 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index c3bfd98062..28a0a40077 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -29,6 +29,7 @@ import java.util.concurrent.BlockingQueue object RuntimeEventListener { /** Creates a runtime event listener behavior with given configuration. + * * @param listenerConf * configuration that determines additional sinks and event filters * @param queue diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala index c13a3ca75b..4698d25215 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventKafkaSink.scala @@ -5,6 +5,7 @@ */ package edu.ie3.simona.io.runtime + import com.sksamuel.avro4s.RecordFormat import edu.ie3.simona.config.SimonaConfig.RuntimeKafkaParams import edu.ie3.simona.event.RuntimeEvent @@ -26,12 +27,13 @@ import scala.jdk.CollectionConverters._ /** Runtime event sink that sends events related to the simulation ending to a * kafka topic. + * * @param producer * the kafka producer to use * @param simRunId * the id of this simulation run * @param topic - * the topic to send the events to ticks + * the topic to send the events to * @param log * The logger to use */ diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala index bda989ba68..5f6b74b906 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventLogSink.scala @@ -5,6 +5,7 @@ */ package edu.ie3.simona.io.runtime + import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.RuntimeEvent._ import edu.ie3.simona.io.runtime.RuntimeEventSink.RuntimeStats @@ -15,6 +16,7 @@ import org.slf4j.Logger import java.time.ZonedDateTime /** Runtime event sink that just logs all received events. + * * @param simulationStartDate * the simulation start date time, used for calculating simulation time from * ticks diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala index 82198970bb..b10393a030 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventQueueSink.scala @@ -5,9 +5,9 @@ */ package edu.ie3.simona.io.runtime + import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.runtime.RuntimeEventSink.RuntimeStats -import org.slf4j.Logger import java.util.concurrent.BlockingQueue diff --git a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala index e10ef7c42e..2638e8fe00 100644 --- a/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala +++ b/src/main/scala/edu/ie3/simona/io/runtime/RuntimeEventSink.scala @@ -8,7 +8,6 @@ package edu.ie3.simona.io.runtime import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.runtime.RuntimeEventSink.RuntimeStats -import org.slf4j.Logger /** Runtime event sinks are handling runtime events. More than one sink can * exist in parallel. From 79c2273a103b5df2c4b8b1fba6649faa376063bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 08:14:29 +0000 Subject: [PATCH 235/305] Bump com.sksamuel.avro4s:avro4s-core_2.13 from 4.1.1 to 4.1.2 (#740) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index af9b979865..cf39efdbe2 100644 --- a/build.gradle +++ b/build.gradle @@ -142,7 +142,7 @@ dependencies { /* Kafka */ implementation "org.apache.kafka:kafka-clients:${confluentKafkaVersion}-ccs" implementation "io.confluent:kafka-streams-avro-serde:${confluentKafkaVersion}" - implementation "com.sksamuel.avro4s:avro4s-core_${scalaVersion}:4.1.1" + implementation "com.sksamuel.avro4s:avro4s-core_${scalaVersion}:4.1.2" implementation 'org.apache.commons:commons-math3:3.6.1' // apache commons math3 implementation 'org.apache.poi:poi-ooxml:5.2.5' // used for FilenameUtils From e629b7a92036d3369a6d5855af296531e17b4b8a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 09:34:11 +0100 Subject: [PATCH 236/305] measurementsConfigs as Set --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 5c190e7f74..624f7783aa 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -608,7 +608,7 @@ object GridModel { case TransformerControlGroup(measurements, _, vMax, vMin) => buildTransformerControlGroupModel( measurementUnitInput, - measurements, + measurements.toSet, vMax, vMin, ) @@ -632,7 +632,7 @@ object GridModel { */ private def buildTransformerControlGroupModel( measurementUnitInput: java.util.Set[MeasurementUnitInput], - measurementConfigs: List[String], + measurementConfigs: Set[String], vMax: Double, vMin: Double, ): ControlGroupModel = { @@ -653,7 +653,7 @@ object GridModel { */ private def determineNodeUuids( measurementUnitInput: java.util.Set[MeasurementUnitInput], - measurementConfigs: List[String], + measurementConfigs: Set[String], ): Set[UUID] = Set.from( measurementUnitInput.asScala .filter(input => From 70934be3ae0090f8b0aa23c9c24a8e9a779a5abc Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 09:37:45 +0100 Subject: [PATCH 237/305] renaming config-template --- gradle/scripts/tscfg.gradle | 2 +- ...fig-template.conf => config-template.conf} | 0 .../edu/ie3/simona/config/SimonaConfig.scala | 78 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) rename src/main/resources/config/{simona-config-template.conf => config-template.conf} (100%) diff --git a/gradle/scripts/tscfg.gradle b/gradle/scripts/tscfg.gradle index d9ee8bca7b..0f94fba657 100644 --- a/gradle/scripts/tscfg.gradle +++ b/gradle/scripts/tscfg.gradle @@ -15,7 +15,7 @@ task genConfigClass { args = [ "build/tscfg-${tscfgVersion}.jar", "--spec", - "src/main/resources/config/simona-config-template.conf", + "src/main/resources/config/config-template.conf", "--scala", "--durations", "--pn", diff --git a/src/main/resources/config/simona-config-template.conf b/src/main/resources/config/config-template.conf similarity index 100% rename from src/main/resources/config/simona-config-template.conf rename to src/main/resources/config/config-template.conf diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index f5dd2fdf3b..f122d05d39 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -752,45 +752,6 @@ object SimonaConfig { } - final case class TransformerControlGroup( - measurements: scala.List[java.lang.String], - transformers: scala.List[java.lang.String], - vMax: scala.Double, - vMin: scala.Double, - ) - object TransformerControlGroup { - def apply( - c: com.typesafe.config.Config, - parentPath: java.lang.String, - $tsCfgValidator: $TsCfgValidator, - ): SimonaConfig.TransformerControlGroup = { - SimonaConfig.TransformerControlGroup( - measurements = - $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), - transformers = - $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), - vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), - vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator), - ) - } - private def $_reqDbl( - parentPath: java.lang.String, - c: com.typesafe.config.Config, - path: java.lang.String, - $tsCfgValidator: $TsCfgValidator, - ): scala.Double = { - if (c == null) 0 - else - try c.getDouble(path) - catch { - case e: com.typesafe.config.ConfigException => - $tsCfgValidator.addBadPath(parentPath + path, e) - 0 - } - } - - } - final case class SimpleOutputConfig( override val notifier: java.lang.String, override val simulationResult: scala.Boolean, @@ -841,6 +802,45 @@ object SimonaConfig { } + final case class TransformerControlGroup( + measurements: scala.List[java.lang.String], + transformers: scala.List[java.lang.String], + vMax: scala.Double, + vMin: scala.Double, + ) + object TransformerControlGroup { + def apply( + c: com.typesafe.config.Config, + parentPath: java.lang.String, + $tsCfgValidator: $TsCfgValidator, + ): SimonaConfig.TransformerControlGroup = { + SimonaConfig.TransformerControlGroup( + measurements = + $_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator), + transformers = + $_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator), + vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator), + vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator), + ) + } + private def $_reqDbl( + parentPath: java.lang.String, + c: com.typesafe.config.Config, + path: java.lang.String, + $tsCfgValidator: $TsCfgValidator, + ): scala.Double = { + if (c == null) 0 + else + try c.getDouble(path) + catch { + case e: com.typesafe.config.ConfigException => + $tsCfgValidator.addBadPath(parentPath + path, e) + 0 + } + } + + } + final case class VoltLvlConfig( id: java.lang.String, vNom: java.lang.String, From 628908bcb0baa5057d9234dd4abaabf5320403c5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 09:50:51 +0100 Subject: [PATCH 238/305] renaming TransformerControlGroup to TransformerControlGroupModel --- ...ala => TransformerControlGroupModel.scala} | 6 ++--- .../edu/ie3/simona/model/grid/GridModel.scala | 27 ++++++++++--------- ...=> TransformerControlGroupModelSpec.scala} | 9 ++++--- .../edu/ie3/simona/model/grid/GridSpec.scala | 10 +++---- 4 files changed, 27 insertions(+), 25 deletions(-) rename src/main/scala/edu/ie3/simona/model/control/{TransformerControlGroup.scala => TransformerControlGroupModel.scala} (92%) rename src/test/scala/edu/ie3/simona/model/control/{TransformerControlGroupSpec.scala => TransformerControlGroupModelSpec.scala} (94%) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala similarity index 92% rename from src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala rename to src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index 3db869c582..ada32e4fb0 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroup.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.model.control import breeze.math.Complex import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult -import edu.ie3.simona.model.control.TransformerControlGroup.RegulationCriterion +import edu.ie3.simona.model.control.TransformerControlGroupModel.RegulationCriterion import java.util.UUID import squants.Dimensionless @@ -25,7 +25,7 @@ import squants.Dimensionless * Partial function to harmonize different, possible contradictory regulation * needs */ -final case class TransformerControlGroup( +final case class TransformerControlGroupModel( nodalRegulationCriterion: Map[UUID, RegulationCriterion], harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless], ) { @@ -66,7 +66,7 @@ final case class TransformerControlGroup( } } -object TransformerControlGroup { +object TransformerControlGroupModel { type RegulationCriterion = Complex => Option[Dimensionless] } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 624f7783aa..15c0bda9a7 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -16,9 +16,7 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.control.{ - TransformerControlGroup => ControlGroupModel -} +import edu.ie3.simona.model.control.TransformerControlGroupModel import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, @@ -99,13 +97,13 @@ object GridModel { * Transformer control groups */ final case class GridControls( - transformerControlGroups: Set[ControlGroupModel] + transformerControlGroups: Set[TransformerControlGroupModel] ) - /** Represents an empty Transformer control groups + /** Represents an empty Transformer control group */ val emptyGridControls: GridControls = GridControls( - Set.empty[ControlGroupModel] + Set.empty[TransformerControlGroupModel] ) /** Checks the availability of node calculation models, that are connected by @@ -571,7 +569,7 @@ object GridModel { subGridContainer.getRawGrid.getMeasurementUnits, ) } - .getOrElse(Set.empty[ControlGroupModel]) + .getOrElse(Set.empty[TransformerControlGroupModel]) /* Build grid related control strategies */ val gridControls = GridControls(transformerControlGroups) @@ -604,7 +602,7 @@ object GridModel { private def buildTransformerControlGroups( config: List[SimonaConfig.TransformerControlGroup], measurementUnitInput: java.util.Set[MeasurementUnitInput], - ): Set[ControlGroupModel] = config.map { + ): Set[TransformerControlGroupModel] = config.map { case TransformerControlGroup(measurements, _, vMax, vMin) => buildTransformerControlGroupModel( measurementUnitInput, @@ -628,14 +626,14 @@ object GridModel { * @param vMin * Lower permissible voltage magnitude * @return - * A [[ControlGroupModel]] + * A [[TransformerControlGroupModel]] */ private def buildTransformerControlGroupModel( measurementUnitInput: java.util.Set[MeasurementUnitInput], measurementConfigs: Set[String], vMax: Double, vMin: Double, - ): ControlGroupModel = { + ): TransformerControlGroupModel = { val nodeUuids = determineNodeUuids(measurementUnitInput, measurementConfigs) buildTransformerControlModels(nodeUuids, vMax, vMin) @@ -673,13 +671,13 @@ object GridModel { * @param vMin * Lower permissible voltage magnitude * @return - * A [[ControlGroupModel]] + * A [[TransformerControlGroupModel]] */ private def buildTransformerControlModels( nodeUuids: Set[UUID], vMax: Double, vMin: Double, - ): ControlGroupModel = { + ): TransformerControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => uuid -> { (complexVoltage: Complex) => @@ -715,7 +713,10 @@ object GridModel { } - ControlGroupModel(nodeUuidToRegulationCriterion, harmonizationFunction) + TransformerControlGroupModel( + nodeUuidToRegulationCriterion, + harmonizationFunction, + ) } /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala similarity index 94% rename from src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala rename to src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala index 2d6c6adbf6..2ea7876057 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala @@ -18,12 +18,13 @@ import squants.{Dimensionless, Each} import java.util.UUID -class TransformerControlGroupSpec extends UnitSpec with QuantityMatchers { +class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { implicit val tolerance: Dimensionless = Each(1e-10) "Checking the function of transformer control groups" should { - val buildTransformerControlModels = PrivateMethod[TransformerControlGroup]( - Symbol("buildTransformerControlModels") - ) + val buildTransformerControlModels = + PrivateMethod[TransformerControlGroupModel]( + Symbol("buildTransformerControlModels") + ) implicit val tolerance: Dimensionless = Each(1e-10) val dut = GridModel invokePrivate buildTransformerControlModels( Set( diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index b13da303ec..b0280a2534 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -14,7 +14,7 @@ import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.control.TransformerControlGroup +import edu.ie3.simona.model.control.TransformerControlGroupModel import edu.ie3.simona.model.grid.GridModel.{ emptyGridControls, GridComponents, @@ -214,7 +214,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches, ), - GridControls(Set.empty[TransformerControlGroup]), + GridControls(Set.empty[TransformerControlGroupModel]), ) // get the private method for validation val validateConnectivity: PrivateMethod[Unit] = @@ -243,7 +243,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], Set.empty[SwitchModel], ), - GridControls(Set.empty[TransformerControlGroup]), + GridControls(Set.empty[TransformerControlGroupModel]), ) // get the private method for validation @@ -394,7 +394,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], switches, ), - GridControls(Set.empty[TransformerControlGroup]), + GridControls(Set.empty[TransformerControlGroupModel]), ) // update the uuidToIndexMap @@ -446,7 +446,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { Set.empty[Transformer3wModel], Set.empty[SwitchModel], ), - GridControls(Set.empty[TransformerControlGroup]), + GridControls(Set.empty[TransformerControlGroupModel]), ) // update the uuidToIndexMap From 48966357fc99212f56b5bdc9bbb8adbb93685e88 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 09:54:18 +0100 Subject: [PATCH 239/305] emptyGridControls as def --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 15c0bda9a7..f9c902f8b0 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -102,7 +102,7 @@ object GridModel { /** Represents an empty Transformer control group */ - val emptyGridControls: GridControls = GridControls( + def emptyGridControls: GridControls = GridControls( Set.empty[TransformerControlGroupModel] ) From bc37db363296d0f354c65b2863decc279f9896a5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 10:42:41 +0100 Subject: [PATCH 240/305] fix GridSpec --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index b0280a2534..f1dd5c4460 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -536,7 +536,7 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { false, ), ).asJava - val selectedMeasurements = List( + val selectedMeasurements = Set( "ab66fbb0-ece1-44b9-9341-86a884233ec4", "93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d", "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae", From c4f3c735120cef4780d3f15f406eff90c0201b75 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 17:35:38 +0100 Subject: [PATCH 241/305] refactor GA FailFast and move into GridModel validation --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 6 +- .../simona/agent/grid/GridAgentFailFast.scala | 106 ------------------ .../edu/ie3/simona/model/grid/GridModel.scala | 94 +++++++++++++++- .../edu/ie3/simona/model/grid/GridSpec.scala | 30 ++++- 4 files changed, 120 insertions(+), 116 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index d25f28d1bc..5a7d265835 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -154,9 +154,6 @@ class GridAgent( Activation(INIT_SIM_TICK), gridAgentInitData: GridAgentInitData, ) => - // fail fast sanity checks - GridAgentFailFast.failFast(gridAgentInitData, simonaConfig) - log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", gridAgentInitData.inferiorGridIds, @@ -188,7 +185,8 @@ class GridAgent( TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime ), - simonaConfig.simona.control, + gridAgentInitData, + simonaConfig, ) /* Reassure, that there are also calculation models for the given uuids */ diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala deleted file mode 100644 index 4e45a97cb7..0000000000 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentFailFast.scala +++ /dev/null @@ -1,106 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.agent.grid - -import edu.ie3.datamodel.models.input.container.SubGridContainer -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.exceptions.agent.GridAgentInitializationException - -import java.util.UUID -import scala.jdk.CollectionConverters._ - -object GridAgentFailFast { - - /** FailFast Check of GridAgent at Initialisation - * @param gridAgentInitData - * Data that is send to the [[GridAgent]] directly after startup. It - * contains the main information for initialization. - * @param simonaConfig - * the config that should be checked - */ - def failFast( - gridAgentInitData: GridAgentInitData, - simonaConfig: SimonaConfig, - ): Unit = { - - /** Check if there is InitData for superior or inferior GridGates - */ - if ( - gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty - ) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + - s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" - ) - - /** Check if there exits voltage measurements for transformerControlGroups - */ - - checkControlGroupsForMeasurement( - gridAgentInitData.subGridContainer, - simonaConfig.simona.control, - ) - } - - /** Checks all ControlGroups if a) Transformer of ControlGroup and Measurement - * belongs to the same sub grid. b) Measurements are measure voltage - * magnitude. - * - * @param subGridContainer - * Container of all models for this sub grid - * @param maybeControlConfig - * Config of ControlGroup - */ - def checkControlGroupsForMeasurement( - subGridContainer: SubGridContainer, - maybeControlConfig: Option[SimonaConfig.Simona.Control], - ): Unit = { - - val measurementUnits = - subGridContainer.getRawGrid.getMeasurementUnits.asScala - - val transformerUnits2W = - subGridContainer.getRawGrid.getTransformer2Ws.asScala - - val transformerUnits3W = - subGridContainer.getRawGrid.getTransformer3Ws.asScala - - maybeControlConfig.foreach(control => - control.transformer.foreach(controlGroup => - controlGroup.transformers.map(UUID.fromString).foreach { transformer => - val transformerUnit2W = transformerUnits2W - .find(_.getUuid == transformer) - val transformerUnit3W = transformerUnits3W - .find(_.getUuid == transformer) - - /** In order to check that the measurements are located in the subgrid - * of this GridAgent, it is first checked if the transformer belongs - * to this GridAgent and is therefore part of this subgrid. - */ - if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { - controlGroup.measurements - .map(UUID.fromString) - .foreach { measurement => - val measurementUnit = measurementUnits - .find(_.getUuid == measurement) - .getOrElse( - throw new GridAgentInitializationException( - s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exists in this subnet." - ) - ) - if (!measurementUnit.getVMag) - throw new GridAgentInitializationException( - s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." - ) - } - } - } - ) - ) - } -} diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index f9c902f8b0..0c05990f13 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -12,9 +12,11 @@ import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException +import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.control.TransformerControlGroupModel import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} @@ -71,13 +73,15 @@ object GridModel { refSystem: RefSystem, startDate: ZonedDateTime, endDate: ZonedDateTime, - controlConfig: Option[SimonaConfig.Simona.Control], + gridAgentInitData: GridAgentInitData, + simonaConfig: SimonaConfig, ): GridModel = buildAndValidate( subGridContainer, refSystem, startDate, endDate, - controlConfig, + gridAgentInitData, + simonaConfig, ) /** structure that represents all grid components that are needed by a grid @@ -472,12 +476,79 @@ object GridModel { } + private def checkForGridGates(gridAgentInitData: GridAgentInitData): Unit = { + if ( + gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty + ) + throw new GridAgentInitializationException( + s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" + ) + } + + /** Checks all ControlGroups if a) Transformer of ControlGroup and Measurement + * belongs to the same sub grid. b) Measurements are measure voltage + * magnitude. + * + * @param subGridContainer + * Container of all models for this sub grid + * @param maybeControlConfig + * Config of ControlGroup + */ + private def checkControlGroupsForMeasurement( + subGridContainer: SubGridContainer, + maybeControlConfig: Option[SimonaConfig.Simona.Control], + ): Unit = { + + val measurementUnits = + subGridContainer.getRawGrid.getMeasurementUnits.asScala + .map(measurement => measurement.getUuid -> measurement) + .toMap + + val transformerUnits2W = + subGridContainer.getRawGrid.getTransformer2Ws.asScala + .map(transformer2w => transformer2w.getUuid -> transformer2w) + .toMap + + val transformerUnits3W = + subGridContainer.getRawGrid.getTransformer3Ws.asScala + .map(transformer3w => transformer3w.getUuid -> transformer3w) + .toMap + + maybeControlConfig.foreach(control => + control.transformer.foreach(controlGroup => + controlGroup.transformers.map(UUID.fromString).foreach { transformer => + val transformerUnit2W = transformerUnits2W.get(transformer) + val transformerUnit3W = transformerUnits3W.get(transformer) + + if (transformerUnit2W.isDefined || transformerUnit3W.isDefined) { + controlGroup.measurements + .map(UUID.fromString) + .foreach { measurement => + val measurementUnit = measurementUnits.getOrElse( + measurement, + throw new GridAgentInitializationException( + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exist in this subnet." + ), + ) + if (!measurementUnit.getVMag) + throw new GridAgentInitializationException( + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + ) + } + } + } + ) + ) + } + private def buildAndValidate( subGridContainer: SubGridContainer, refSystem: RefSystem, startDate: ZonedDateTime, endDate: ZonedDateTime, - maybeControlConfig: Option[SimonaConfig.Simona.Control], + gridAgentInitData: GridAgentInitData, + simonaConfig: SimonaConfig, ): GridModel = { // build @@ -562,6 +633,12 @@ object GridModel { ) /* Build transformer control groups */ + val maybeControlConfig: Option[SimonaConfig.Simona.Control] = + simonaConfig.simona.control match { + case Some(control) => simonaConfig.simona.control + case None => None + } + val transformerControlGroups = maybeControlConfig .map { controlConfig => buildTransformerControlGroups( @@ -582,9 +659,20 @@ object GridModel { gridControls, ) + /** Check and validates the grid. Especially the consistency of the grid + * model the connectivity of the grid model if there is InitData for + * superior or inferior GridGates if there exits voltage measurements for + * transformerControlGroups + */ + // validate validateConsistency(gridModel) validateConnectivity(gridModel) + checkForGridGates(gridAgentInitData) + checkControlGroupsForMeasurement( + gridAgentInitData.subGridContainer, + simonaConfig.simona.control, + ) // return gridModel diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index f1dd5c4460..be089f18f1 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -13,6 +13,8 @@ import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.simona.agent.grid.DBFSMockGridAgents +import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.TransformerControlGroupModel import edu.ie3.simona.model.grid.GridModel.{ @@ -28,10 +30,20 @@ import edu.ie3.simona.test.common.model.grid.{ } import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} import testutils.TestObjectFactory - +import edu.ie3.simona.test.common.model.grid.DbfsTestGrid +import org.apache.pekko.testkit.TestProbe +import edu.ie3.simona.test.common.ConfigTestData +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import scala.jdk.CollectionConverters.SetHasAsJava +import edu.ie3.datamodel.models.input.container.ThermalGrid -class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { +class GridSpec + extends UnitSpec + with LineInputTestData + with DefaultTestData + with DbfsTestGrid + with DBFSMockGridAgents + with ConfigTestData { private val _printAdmittanceMatrixOnMismatch : (DenseMatrix[Complex], DenseMatrix[Complex]) => Unit = { @@ -552,12 +564,24 @@ class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData { } "process a valid GridInputModel without an Exception" in new GridInputTestData { + val simonaConfig: SimonaConfig = SimonaConfig(typesafeConfig) + private val superiorGridAgent = SuperiorGA( + TestProbe("superiorGridAgent_1000"), + Seq(supNodeA.getUuid), + ) + GridModel( validTestGridInputModel, gridInputModelTestDataRefSystem, defaultSimulationStart, defaultSimulationEnd, - controlConfig = None, + GridAgentInitData( + hvGridContainer, + Seq.empty[ThermalGrid], + superiorGridAgent.ref, + RefSystem("2000 MVA", "110 kV"), + ), + simonaConfig, ) } } From b8028cf1111a8344136118475d694b4c8d68cd41 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 18:04:14 +0100 Subject: [PATCH 242/305] add transformer control group config parameters to config.md --- docs/readthedocs/config.md | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/readthedocs/config.md b/docs/readthedocs/config.md index 91a6d952a5..52b2caef92 100644 --- a/docs/readthedocs/config.md +++ b/docs/readthedocs/config.md @@ -236,3 +236,42 @@ Secondary convergence criterion for the power flow calculation is the number of Resolution of the power flow calculation: `simona.powerflow.resolution = "3600s"` + +## Transformer Control Group configuration + +It's possible to add a voltage control function to a transformer or group of transformers. This requires measurements within the network to be under voltage control and at least one corresponding transformer. +The voltage control will attempt to adjust the voltage by changing the tap position of the corresponding transformer. If changing the tap position would cause a voltage limit to be exceeded, the initial voltage deviation cannot be reduced by the voltage control system. + +Transformer control groups must contain at least one transformer and one measurement. And can be configured as shown in this example for two transformer control groups: +``` +simona.control.transformer = [ +{ +transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"], +measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"], +vMin = 0.98, +vMax = 1.02 +} +, { +transformers = ["1132dbf4-e8a1-44ae-8415-f42d4497aa1d"], +measurements = ["7686b818-a0ba-465c-8e4e-f7d3c4e171fc"], +vMin = 0.98, +vMax = 1.02 +} +] +``` + +UUID of transformer in control group: + +`transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"]` + +UUID of measurement in control group: + +`measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"]` + +Minimum Voltage Limit in p.u.: + +`vMin = 0.98` + +Maximum Voltage Limit in p.u.: + +`vMin = 1.02` \ No newline at end of file From ff70c4c8b1f4b89873d7206759b809ae76d7b1b7 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 15 Feb 2024 18:06:31 +0100 Subject: [PATCH 243/305] add transformer control group config parameters to config.md --- docs/readthedocs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readthedocs/config.md b/docs/readthedocs/config.md index 52b2caef92..f1db2fc5b6 100644 --- a/docs/readthedocs/config.md +++ b/docs/readthedocs/config.md @@ -274,4 +274,4 @@ Minimum Voltage Limit in p.u.: Maximum Voltage Limit in p.u.: -`vMin = 1.02` \ No newline at end of file +`vMax = 1.02` \ No newline at end of file From 19301f3466a6b046f56a06064feca86d9acb891e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 16 Feb 2024 08:56:01 +0100 Subject: [PATCH 244/305] move measurement_control.md --- docs/readthedocs/models.md | 2 +- docs/readthedocs/{ => models}/measurement_control.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/readthedocs/{ => models}/measurement_control.md (100%) diff --git a/docs/readthedocs/models.md b/docs/readthedocs/models.md index 18b2c330a5..e32ee67098 100644 --- a/docs/readthedocs/models.md +++ b/docs/readthedocs/models.md @@ -39,5 +39,5 @@ models/wec_model --- maxdepth: 1 --- -measurement_control +models/measurement_control ``` diff --git a/docs/readthedocs/measurement_control.md b/docs/readthedocs/models/measurement_control.md similarity index 100% rename from docs/readthedocs/measurement_control.md rename to docs/readthedocs/models/measurement_control.md From 2f7e963ee2e8f9f6f8abc818f1f0a8b5802106be Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Sat, 17 Feb 2024 08:50:20 +0100 Subject: [PATCH 245/305] remove todo in config-template --- src/main/resources/config/config-template.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/config/config-template.conf b/src/main/resources/config/config-template.conf index e46f34d520..b006cafd6b 100644 --- a/src/main/resources/config/config-template.conf +++ b/src/main/resources/config/config-template.conf @@ -130,7 +130,6 @@ GridOutputConfig { TransformerControlGroup { measurements: [string] transformers: [string] - # TODO: Currently, only limit prevention is configurable. Should be an interface, when it is allowed by tscfg vMax: Double vMin: Double } From d353b2ea8d01c65b59b0061e3e7b0a4eb0c1648e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Sat, 17 Feb 2024 08:54:08 +0100 Subject: [PATCH 246/305] rename buildControlGroups --- docs/readthedocs/config.md | 2 +- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/readthedocs/config.md b/docs/readthedocs/config.md index f1db2fc5b6..64a9dfc1b7 100644 --- a/docs/readthedocs/config.md +++ b/docs/readthedocs/config.md @@ -274,4 +274,4 @@ Minimum Voltage Limit in p.u.: Maximum Voltage Limit in p.u.: -`vMax = 1.02` \ No newline at end of file +`vMax = 1.02` diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 0c05990f13..48a51e400c 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -641,7 +641,7 @@ object GridModel { val transformerControlGroups = maybeControlConfig .map { controlConfig => - buildTransformerControlGroups( + buildControlGroups( controlConfig.transformer, subGridContainer.getRawGrid.getMeasurementUnits, ) @@ -678,7 +678,7 @@ object GridModel { gridModel } - /** Build business models for transformer control groups + /** Build business models for control groups * * @param config * List of configs for control groups @@ -687,7 +687,7 @@ object GridModel { * @return * A set of control group business models */ - private def buildTransformerControlGroups( + private def buildControlGroups( config: List[SimonaConfig.TransformerControlGroup], measurementUnitInput: java.util.Set[MeasurementUnitInput], ): Set[TransformerControlGroupModel] = config.map { From b128a634fc341e962b809c178a0b13279691be6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:37:39 +0000 Subject: [PATCH 247/305] Bump testContainerVersion from 0.41.2 to 0.41.3 (#742) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index cf39efdbe2..19ee5267d6 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ ext { tscfgVersion = '1.0.0' scapegoatVersion = '2.1.3' - testContainerVersion = '0.41.2' + testContainerVersion = '0.41.3' scriptsLocation = 'gradle' + File.separator + 'scripts' + File.separator // location of script plugins } From 350e8c4a34853120d2fa4d7a246349f11edfd84e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:50:21 +0000 Subject: [PATCH 248/305] Bump ch.qos.logback:logback-classic from 1.4.14 to 1.5.0 (#741) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 19ee5267d6..84c534b02e 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { /* logging */ implementation "com.typesafe.scala-logging:scala-logging_${scalaVersion}:3.9.5" // pekko scala logging - implementation "ch.qos.logback:logback-classic:1.4.14" + implementation "ch.qos.logback:logback-classic:1.5.0" /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' From adba3b5c0e5631ae4c6e0cd6f8196be40c3cd04d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 15 Feb 2024 21:19:59 +0100 Subject: [PATCH 249/305] Backup --- .../ie3/simona/agent/EnvironmentRefs.scala | 14 +- .../edu/ie3/simona/agent/grid/GridAgent.scala | 10 +- .../agent/grid/GridAgentController.scala | 18 +- .../edu/ie3/simona/api/ExtSimAdapter.scala | 10 +- .../event/listener/ResultEventListener.scala | 7 +- .../scala/edu/ie3/simona/main/RunSimona.scala | 51 +-- .../ie3/simona/main/RunSimonaStandalone.scala | 60 +-- .../ontology/messages/StopMessage.scala | 12 - .../ie3/simona/scheduler/TimeAdvancer.scala | 34 +- .../scala/edu/ie3/simona/sim/SimMessage.scala | 29 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 396 ++++++++---------- .../ie3/simona/sim/setup/SimonaSetup.scala | 60 +-- .../sim/setup/SimonaStandaloneSetup.scala | 118 +++--- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 2 +- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 2 +- .../grid/DBFSAlgorithmParticipantSpec.scala | 2 +- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 2 +- .../agent/grid/GridAgentSetup2WSpec.scala | 23 +- .../agent/grid/GridAgentSetup3WSpec.scala | 23 +- .../ie3/simona/api/ExtSimAdapterSpec.scala | 9 +- .../listener/ResultEventListenerSpec.scala | 13 +- .../integration/RunSimonaStandaloneIT.scala | 4 +- .../simona/scheduler/TimeAdvancerSpec.scala | 135 ++---- .../ie3/simona/sim/SimonaSimFailSpec.scala | 153 ------- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 233 +++++++++++ .../simona/sim/setup/SimonaSetupSpec.scala | 74 ++-- 26 files changed, 709 insertions(+), 785 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/ontology/messages/StopMessage.scala delete mode 100644 src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala diff --git a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala index 2179b90202..2421cdd5c3 100644 --- a/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala +++ b/src/main/scala/edu/ie3/simona/agent/EnvironmentRefs.scala @@ -6,7 +6,9 @@ package edu.ie3.simona.agent -import org.apache.pekko.actor.ActorRef +import edu.ie3.simona.ontology.messages.SchedulerMessage +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.{ActorRef => ClassicRef} /** Container class, that gather together reference to relevant entities, that * represent the environment in the simulation @@ -23,9 +25,9 @@ import org.apache.pekko.actor.ActorRef * Reference to the EV data service, if existing */ final case class EnvironmentRefs( - scheduler: ActorRef, - runtimeEventListener: ActorRef, - primaryServiceProxy: ActorRef, - weather: ActorRef, - evDataService: Option[ActorRef], + scheduler: ActorRef[SchedulerMessage], + runtimeEventListener: ClassicRef, + primaryServiceProxy: ClassicRef, + weather: ClassicRef, + evDataService: Option[ClassicRef], ) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 8ea4b12f5d..2b0ec33a23 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -23,7 +23,7 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.ontology.messages.{Activation, StopMessage} +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil @@ -257,14 +257,6 @@ class GridAgent( goto(SimulateGrid) using gridAgentBaseData - case Event(StopMessage(_), data: GridAgentBaseData) => - // shutdown children - data.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => - actors.foreach(context.stop) - } - - // we are done - stop() } // everything else diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala index 895afb7cc1..a65fd6d9cf 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala @@ -6,9 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorContext, ActorRef} -import org.apache.pekko.event.LoggingAdapter import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.input.container.{SubGridContainer, ThermalGrid} import edu.ie3.datamodel.models.input.system._ @@ -33,6 +30,9 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.util.ConfigUtil import edu.ie3.simona.util.ConfigUtil._ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import org.apache.pekko.actor.typed.scaladsl.adapter.{ClassicActorRefOps, _} +import org.apache.pekko.actor.{ActorContext, ActorRef} +import org.apache.pekko.event.LoggingAdapter import java.time.ZonedDateTime import java.util.UUID @@ -339,7 +339,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( FixedFeedInAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( fixedFeedInInput, modelConfiguration, @@ -390,7 +390,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( LoadAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( loadInput, modelConfiguration, @@ -444,7 +444,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( PvAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( pvInput, modelConfiguration, @@ -498,7 +498,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( EvcsAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( evcsInput, modelConfiguration, @@ -547,7 +547,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( HpAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( hpInput, thermalGrid, @@ -602,7 +602,7 @@ class GridAgentController( ): ActorRef = gridAgentContext.simonaActorOf( WecAgent.props( - environmentRefs.scheduler, + environmentRefs.scheduler.toClassic, ParticipantInitializeStateData( wecInput, modelConfiguration, diff --git a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala index be3d434a8a..e9a4f8ae9f 100644 --- a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala +++ b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala @@ -8,7 +8,11 @@ package edu.ie3.simona.api import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.actor.{Actor, ActorRef, PoisonPill, Props} -import edu.ie3.simona.api.ExtSimAdapter.{Create, ExtSimAdapterStateData} +import edu.ie3.simona.api.ExtSimAdapter.{ + Create, + ExtSimAdapterStateData, + StopMessage, +} import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.api.simulation.ontology.{ @@ -23,7 +27,7 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.ScheduleServiceActivation -import edu.ie3.simona.ontology.messages.{Activation, StopMessage} +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK @@ -45,6 +49,8 @@ object ExtSimAdapter { */ final case class Create(extSimData: ExtSimAdapterData, unlockKey: ScheduleKey) + final case class StopMessage(simulationSuccessful: Boolean) + final case class ExtSimAdapterStateData( extSimData: ExtSimAdapterData, currentTick: Option[Long] = None, diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index fcd820db4c..6fd4a4b0cd 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -23,7 +23,6 @@ import edu.ie3.simona.exceptions.{ ProcessResultEventException, } import edu.ie3.simona.io.result._ -import edu.ie3.simona.ontology.messages.StopMessage import edu.ie3.simona.util.ResultFileHierarchy import org.slf4j.Logger @@ -42,6 +41,8 @@ object ResultEventListener extends Transformer3wResultSupport { private final case class Failed(ex: Exception) extends ResultMessage + final case object FlushAndStop extends ResultMessage + private final case object StopTimeout extends ResultMessage /** [[ResultEventListener]] base data containing all information the listener @@ -319,9 +320,9 @@ object ResultEventListener extends Transformer3wResultSupport { val updatedBaseData = handleResult(flexOptionsResult, baseData, ctx.log) idle(updatedBaseData) - case (ctx, _: StopMessage) => + case (ctx, FlushAndStop) => ctx.log.debug( - s"${getClass.getSimpleName} received Stop message, shutting down when no message has been received in 5 seconds." + s"Received FlushAndStop message, shutting down once no message has been received for 5 seconds." ) ctx.setReceiveTimeout(5.seconds, StopTimeout) Behaviors.same diff --git a/src/main/scala/edu/ie3/simona/main/RunSimona.scala b/src/main/scala/edu/ie3/simona/main/RunSimona.scala index df011e6614..5e4944fb8f 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimona.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimona.scala @@ -6,21 +6,17 @@ package edu.ie3.simona.main -import java.util.Locale - -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.pattern.gracefulStop -import org.apache.pekko.util.Timeout import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.sim.setup.SimonaSetup import edu.ie3.util.scala.quantities.QuantityUtil +import org.apache.pekko.util.Timeout -import scala.concurrent.Future +import java.util.Locale import scala.concurrent.duration.FiniteDuration import scala.util.Random /** Trait to be mixed in all implementations that should be used to run a simona - * simulation. For a sample implemenation see [[RunSimonaStandalone]]. + * simulation. For a sample implementation see [[RunSimonaStandalone]]. * * @version 0.1 * @since 01.07.20 @@ -39,30 +35,26 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging { printOpener() - setup(args).foreach(run) + val simonaSetup = setup(args) + + val successful = run(simonaSetup) printGoodbye() - Thread.sleep( - 1000 - ) // prevents cutting of the log when having a fast simulation - System.exit(0) - } + // prevents cutting of the log when having a fast simulation + Thread.sleep(1000) - def shutdownGracefully( - simonaSim: ActorRef - )(implicit timeout: FiniteDuration): Future[Boolean] = { - gracefulStop(simonaSim, timeout) + System.exit(if (successful) 0 else 1) } // a fancy opener - protected def printOpener(): Unit = { + private def printOpener(): Unit = { logger.info( s"Starting SIMONA with interface '${getClass.getSimpleName.replaceAll("\\$", "")}'.\n" + " _____ ______ _______ _ _____ \n / ___// _/ |/ / __ \\/ | / / |\n \\__ \\ / // /|_/ / / / / |/ / /| |\n ___/ // // / / / /_/ / /| / ___ |\n/____/___/_/ /_/\\____/_/ |_/_/ |_|\n " ) } - def printGoodbye(): Unit = { + private def printGoodbye(): Unit = { val myWords = Array( "\"Vielleicht ist heute ein besonders guter Tag zum Sterben.\" - Worf (in Star Trek: Der erste Kontakt)", "\"Assimiliert das!\" - Worf (in Star Trek: Der erste Kontakt)", @@ -78,21 +70,32 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging { } /** Method to be implemented to setup everything that is necessary for a - * sequence of simulations. This is by creating an instance of - * [[SimonaSetup]] implementation + * simulations. This is by creating an instance of [[SimonaSetup]] + * implementation * * @param args * arguments provided by the command line * @return - * the setup instances + * the setup instance */ - def setup(args: Array[String]): Seq[T] + def setup(args: Array[String]): T /** Actually run the simona simulation using the provided [[SimonaSetup]] * * @param simonaSetup * the setup data that should be used + * @return + * Whether the simualtion was successful or not + */ + def run(simonaSetup: T): Boolean + +} + +object RunSimona { + + /** Reported back from the scheduler if an error occurred during the + * simulation */ - def run(simonaSetup: T): Unit + case class SimonaEnded(successful: Boolean) } diff --git a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala index 1fe37611a5..bd9e1d3766 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala @@ -6,35 +6,27 @@ package edu.ie3.simona.main -import org.apache.pekko.actor.ActorSystem - -import java.util.concurrent.TimeUnit -import org.apache.pekko.pattern.ask -import org.apache.pekko.util.Timeout import edu.ie3.simona.config.{ArgsParser, ConfigFailFast, SimonaConfig} -import edu.ie3.simona.sim.SimMessage.{ - InitSim, - SimulationFailure, - SimulationSuccessful, - StartSimulation, -} +import edu.ie3.simona.main.RunSimona._ +import edu.ie3.simona.sim.SimMessage.StartSimulation import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.sim.setup.SimonaStandaloneSetup +import org.apache.pekko.actor.typed.scaladsl.AskPattern._ +import org.apache.pekko.actor.typed.{ActorSystem, Scheduler} +import org.apache.pekko.util.Timeout import scala.concurrent.Await +import scala.concurrent.duration.DurationInt /** Run a standalone simulation of simona * - * @version 0.1 * @since 01.07.20 */ object RunSimonaStandalone extends RunSimona[SimonaStandaloneSetup] { - override implicit val timeout: Timeout = Timeout(50000, TimeUnit.SECONDS) + override implicit val timeout: Timeout = Timeout(12.hours) - override def setup( - args: Array[String] - ): Seq[SimonaStandaloneSetup] = { + override def setup(args: Array[String]): SimonaStandaloneSetup = { // get the config and prepare it with the provided args val (arguments, parsedConfig) = ArgsParser.prepareConfig(args) @@ -42,36 +34,30 @@ object RunSimonaStandalone extends RunSimona[SimonaStandaloneSetup] { val simonaConfig = SimonaConfig(parsedConfig) ConfigFailFast.check(parsedConfig, simonaConfig) - Seq( - SimonaStandaloneSetup( - parsedConfig, - SimonaStandaloneSetup.buildResultFileHierarchy(parsedConfig), - mainArgs = arguments.mainArgs, - ) + SimonaStandaloneSetup( + parsedConfig, + SimonaStandaloneSetup.buildResultFileHierarchy(parsedConfig), + mainArgs = arguments.mainArgs, ) } - override def run( - simonaSetup: SimonaStandaloneSetup - ): Unit = { - val actorSystem: ActorSystem = simonaSetup.buildActorSystem.apply() - // build the simulation container actor - val simonaSim = actorSystem.actorOf( - SimonaSim.props(simonaSetup) + override def run(simonaSetup: SimonaStandaloneSetup): Boolean = { + val simonaSim = ActorSystem( + SimonaSim(simonaSetup), + name = "Simona", + config = simonaSetup.typeSafeConfig, ) + implicit val scheduler: Scheduler = simonaSim.scheduler + // run the simulation - val terminated = simonaSim ? InitSim + val terminated = simonaSim.ask[SimonaEnded](ref => StartSimulation(ref)) Await.result(terminated, timeout.duration) match { - case SimulationFailure | SimulationSuccessful => - Await.ready(shutdownGracefully(simonaSim), timeout.duration) - Await.ready(actorSystem.terminate(), timeout.duration) + case SimonaEnded(successful) => + simonaSim.terminate() - case unknown => - throw new RuntimeException( - s"Unexpected message from SimonaSim $unknown" - ) + successful } } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/StopMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/StopMessage.scala deleted file mode 100644 index c6e4809a27..0000000000 --- a/src/main/scala/edu/ie3/simona/ontology/messages/StopMessage.scala +++ /dev/null @@ -1,12 +0,0 @@ -/* - * © 2022. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.ontology.messages - -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage - -final case class StopMessage(simulationSuccessful: Boolean) - extends ResultMessage diff --git a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala index 63aac6d223..200b61f1da 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.scheduler -import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} -import org.apache.pekko.actor.typed.{ActorRef, Behavior} import edu.ie3.simona.actor.ActorUtil.stopOnError import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.Activation @@ -15,8 +13,11 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.sim.SimMessage.{SimulationFailure, SimulationSuccessful} +import edu.ie3.simona.sim.SimMessage +import edu.ie3.simona.sim.SimMessage.SimulationEnded import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} +import org.apache.pekko.actor.typed.{ActorRef, Behavior} /** Unit that is in control of time advancement within the simulation. * Represents the root entity of any scheduler hierarchy. @@ -35,14 +36,6 @@ object TimeAdvancer { pauseTick: Option[Long] = None ) extends Incoming - /** Notifies TimeAdvancer that the simulation should stop because of some - * error - * - * @param errorMsg - * The error message - */ - final case class Stop(errorMsg: String) extends Incoming - /** @param simulation * The root actor of the simulation * @param eventListener @@ -53,7 +46,7 @@ object TimeAdvancer { * last tick of the simulation */ def apply( - simulation: org.apache.pekko.actor.ActorRef, + simulation: ActorRef[SimMessage], eventListener: Option[ActorRef[RuntimeEvent]], checkWindow: Option[Int], endTick: Long, @@ -65,9 +58,6 @@ object TimeAdvancer { tick, tick, ) - - case (ctx, Stop(errorMsg: String)) => - endWithFailure(ctx, simulation, None, INIT_SIM_TICK, errorMsg) } /** TimeAdvancer is inactive and waiting for a StartScheduleMessage to start @@ -105,9 +95,6 @@ object TimeAdvancer { nextActiveTick, pauseTick, ) - - case (ctx, Stop(errorMsg: String)) => - endWithFailure(ctx, data.simulation, notifier, startingTick, errorMsg) } /** TimeAdvancer is active and waiting for the current activation of the @@ -130,7 +117,7 @@ object TimeAdvancer { ): Behavior[Incoming] = Behaviors.receivePartial { case (ctx, Completion(_, maybeNewTick)) => checkCompletion(activeTick, maybeNewTick) - .map(endWithFailure(ctx, data.simulation, notifier, activeTick, _)) + .map(endWithFailure(ctx, notifier, activeTick, _)) .getOrElse { (maybeNewTick, pauseTick) match { @@ -188,16 +175,13 @@ object TimeAdvancer { } } - case (ctx, Stop(errorMsg: String)) => - endWithFailure(ctx, data.simulation, notifier, activeTick, errorMsg) - } private def endSuccessfully( data: TimeAdvancerData, notifier: Option[RuntimeNotifier], ): Behavior[Incoming] = { - data.simulation ! SimulationSuccessful + data.simulation ! SimulationEnded notifier.foreach { // we do not want a check window message for the endTick @@ -211,12 +195,10 @@ object TimeAdvancer { private def endWithFailure( ctx: ActorContext[Incoming], - simulation: org.apache.pekko.actor.ActorRef, notifier: Option[RuntimeNotifier], tick: Long, errorMsg: String, ): Behavior[Incoming] = { - simulation ! SimulationFailure notifier.foreach(_.error(tick, errorMsg)) stopOnError(ctx, errorMsg) @@ -241,7 +223,7 @@ object TimeAdvancer { * the last tick of the simulation */ private final case class TimeAdvancerData( - simulation: org.apache.pekko.actor.ActorRef, + simulation: ActorRef[SimMessage], schedulee: ActorRef[Activation], endTick: Long, ) diff --git a/src/main/scala/edu/ie3/simona/sim/SimMessage.scala b/src/main/scala/edu/ie3/simona/sim/SimMessage.scala index 1ca7438421..bd7ba7fd9c 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimMessage.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimMessage.scala @@ -6,30 +6,19 @@ package edu.ie3.simona.sim -trait SimMessage -object SimMessage { +import edu.ie3.simona.main.RunSimona.SimonaEnded +import org.apache.pekko.actor.typed.ActorRef + +sealed trait SimMessage - /** Tell the [[SimonaSim]] to initialize the simulation - */ - case object InitSim extends SimMessage +object SimMessage { - /** Starts simulation by activating the next (or first) tick - * - * @param pauseTick - * Last tick that can be activated or completed before the simulation is - * paused - */ + /** Starts simulation by activating the next (or first) tick */ final case class StartSimulation( - pauseTick: Option[Long] = None + starter: ActorRef[SimonaEnded] ) extends SimMessage - /** Reported back from the scheduler if an error occurred during the - * simulation - */ - case object SimulationFailure extends SimMessage - - /** Reported back from the scheduler if the simulation terminated as expected - */ - case object SimulationSuccessful extends SimMessage + /** Indicate that the simulation has ended successfully */ + case object SimulationEnded extends SimMessage } diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 5200e39371..75a3e6fa6c 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -6,36 +6,20 @@ package edu.ie3.simona.sim -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps -import org.apache.pekko.actor.SupervisorStrategy.Stop -import org.apache.pekko.actor.{ - Actor, - ActorRef, - AllForOneStrategy, - Props, - Stash, - SupervisorStrategy, - Terminated, -} -import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.ontology.messages.StopMessage +import edu.ie3.simona.event.listener.ResultEventListener +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage -import edu.ie3.simona.sim.SimMessage.{ - InitSim, - SimulationFailure, - SimulationSuccessful, - StartSimulation, -} -import edu.ie3.simona.sim.SimonaSim.{ - EmergencyShutdownInitiated, - SimonaSimStateData, -} +import edu.ie3.simona.sim.SimMessage.{SimulationEnded, StartSimulation} import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} +import org.apache.pekko.actor.typed.scaladsl.adapter._ +import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} +import org.apache.pekko.actor.typed.{ActorRef, Behavior, PostStop, Terminated} +import org.apache.pekko.actor.{ActorRef => ClassicRef} -import scala.concurrent.duration.DurationInt import scala.language.postfixOps /** Main entrance point to a simona simulation as top level actor. This actors @@ -51,229 +35,211 @@ import scala.language.postfixOps * @version 0.1 * @since 01.07.20 */ -class SimonaSim(simonaSetup: SimonaSetup) - extends Actor - with LazyLogging - with Stash { - - override val supervisorStrategy: SupervisorStrategy = - AllForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { - case ex: Exception => - self ! EmergencyShutdownInitiated - logger.error( - "The simulation's guardian received an uncaught exception. - {}: \"{}\" - Start emergency shutdown.", - ex.getClass.getSimpleName, - ex.getMessage, - ) - Stop - } - - /* start listener */ - // output listener - val systemParticipantsListener: Seq[ActorRef] = - simonaSetup.systemParticipantsListener(context) - - // runtime event listener - val runtimeEventListener - : org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = - simonaSetup.runtimeEventListener(context) - - /* start scheduler */ - val timeAdvancer - : org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = - simonaSetup.timeAdvancer(context, self, runtimeEventListener) - val scheduler: ActorRef = simonaSetup.scheduler(context, timeAdvancer) - - /* start services */ - // primary service proxy - val primaryServiceProxy: ActorRef = - simonaSetup.primaryServiceProxy(context, scheduler) - - // weather service - val weatherService: ActorRef = - simonaSetup.weatherService(context, scheduler) - - val extSimulationData: ExtSimSetupData = - simonaSetup.extSimulations(context, scheduler) - - /* start grid agents */ - val gridAgents: Iterable[ActorRef] = simonaSetup.gridAgents( - context, - EnvironmentRefs( - scheduler, - runtimeEventListener.toClassic, - primaryServiceProxy, - weatherService, - extSimulationData.evDataService, - ), - systemParticipantsListener, - ) - - /* watch all actors */ - systemParticipantsListener.foreach(context.watch) - context.watch(runtimeEventListener.toClassic) - context.watch(timeAdvancer.toClassic) - context.watch(scheduler) - context.watch(primaryServiceProxy) - context.watch(weatherService) - gridAgents.foreach(context.watch) - - override def receive: Receive = simonaSimReceive(SimonaSimStateData()) +object SimonaSim { - def simonaSimReceive(data: SimonaSim.SimonaSimStateData): Receive = { + def apply(simonaSetup: SimonaSetup): Behavior[SimMessage] = + Behaviors.receivePartial { + case (ctx, startMsg @ StartSimulation(starter)) => + // We redirect to initializing behavior so that starter ref + // is available in case of a sudden termination of this actor + ctx.self ! startMsg + initializing(simonaSetup, starter) + } - case InitSim => - // tell scheduler to process all init messages - timeAdvancer ! StartSimMessage() - context become simonaSimReceive(data.copy(initSimSender = sender())) + /** Initializing behavior that is separated from [[apply]] above only because + * in case of a sudden stop of this actor itself (PostStop signal), the + * [[SimonaEnded]] message is sent to the starter + * + * @param starter + * The starter ref that needs to be notified once simulation has ended + */ + private def initializing( + simonaSetup: SimonaSetup, + starter: ActorRef[SimonaEnded], + ): Behavior[SimMessage] = + Behaviors + .receivePartial[SimMessage] { case (ctx, StartSimulation(_)) => + val resultEventListeners = + simonaSetup.systemParticipantsListener(ctx) + + val runtimeEventListener = simonaSetup.runtimeEventListener(ctx) + + val timeAdvancer = + simonaSetup.timeAdvancer(ctx, ctx.self, runtimeEventListener) + val scheduler = simonaSetup.scheduler(ctx, timeAdvancer) + + /* start services */ + // primary service proxy + val primaryServiceProxy = + simonaSetup.primaryServiceProxy(ctx, scheduler) + + // weather service + val weatherService = + simonaSetup.weatherService(ctx, scheduler) + + val extSimulationData: ExtSimSetupData = + simonaSetup.extSimulations(ctx, scheduler) + + val environmentRefs = EnvironmentRefs( + scheduler, + runtimeEventListener.toClassic, + primaryServiceProxy, + weatherService, + extSimulationData.evDataService, + ) - case StartSimulation(pauseScheduleAtTick) => - timeAdvancer ! StartSimMessage(pauseScheduleAtTick) + /* start grid agents */ + val gridAgents = simonaSetup.gridAgents( + ctx, + environmentRefs, + resultEventListeners, + ) - case msg @ (SimulationSuccessful | SimulationFailure) => - val simulationSuccessful = msg match { - case SimulationSuccessful => - logger.info( - "Simulation terminated successfully. Stopping children ..." + /* watch all actors */ + resultEventListeners.foreach(ctx.watch) + ctx.watch(runtimeEventListener) + ctx.watch(timeAdvancer) + ctx.watch(scheduler) + ctx.watch(primaryServiceProxy.toTyped) + ctx.watch(weatherService.toTyped) + gridAgents.foreach(ref => ctx.watch(ref.toTyped)) + + // Start simulation + timeAdvancer ! TimeAdvancer.StartSimMessage() + + val watchedActors = Iterable( + runtimeEventListener, + timeAdvancer, + scheduler, + primaryServiceProxy.toTyped, + weatherService.toTyped, + ) ++ gridAgents.map(_.toTyped) + + idle( + ActorData( + starter, + runtimeEventListener, + watchedActors, + extSimulationData.extSimAdapters, + resultEventListeners, ) - true - case SimulationFailure => - logger.error( - "An error occurred during the simulation. See stacktrace for details." - ) - false + ) } + .receiveSignal { case (_, PostStop) => + // Something must have gone wrong during initialization above + // (could have been an exception thrown), there's nothing much + // we can do here besides notifying starter + starter ! SimonaEnded(successful = false) - // stop all children - stopAllChildrenGracefully(simulationSuccessful) - - // wait for listeners and send final message to parent - context become waitingForListener( - data.initSimSender, - simulationSuccessful, - systemParticipantsListener, - ) - - case EmergencyShutdownInitiated => - logger.debug( - "Simulation guardian is aware, that emergency shutdown has been initiated. Inform the init sender." - ) - data.initSimSender ! SimulationFailure - context.become(emergencyShutdownReceive) + Behaviors.stopped + } - case Terminated(actorRef) => - logger.error( + private def idle(actorData: ActorData): Behavior[SimMessage] = Behaviors + .receivePartial[SimMessage] { case (ctx, SimulationEnded) => + // stop all children and wait for result listeners + stopActors(ctx, actorData, simulationSuccessful = true) + } + .receiveSignal { case (ctx, Terminated(actor)) => + ctx.log.error( "An actor ({}) unexpectedly terminated. Shut down all children gracefully and report simulation " + "failure. See logs and possible stacktrace for details.", - actorRef, + actor, ) - // stop all children - stopAllChildrenGracefully(simulationSuccessful = false) + // stop all children and end + stopActors(ctx, actorData, simulationSuccessful = false) + } - // wait for listeners and send final message to parent - context become waitingForListener( - data.initSimSender, - successful = false, - systemParticipantsListener, - ) - } + private def stopActors( + ctx: ActorContext[_], + actorData: ActorData, + simulationSuccessful: Boolean, + ): Behavior[SimMessage] = { - def emergencyShutdownReceive: Receive = { - case EmergencyShutdownInitiated => - /* Nothing to do. Already know about emergency shutdown. */ + actorData.watchedActors.foreach { ref => + ctx.unwatch(ref) + ctx.stop(ref) + } - case Terminated(actorRef) => - logger.debug("'{}' successfully terminated.", actorRef) + actorData.extSimAdapters.foreach { ref => + ctx.unwatch(ref) + ref ! ExtSimAdapter.StopMessage(simulationSuccessful) + } - case unsupported => - logger.warn( - "Received the following message. Simulation is in emergency shutdown mode. Will neglect that " + - "message!\n\t{}", - unsupported, + if (simulationSuccessful) { + // if the simulation is successful, we're waiting for the result listeners + // to terminate and thus do not unwatch them here + ctx.log.info( + "Simulation terminated successfully. Stopping children and waiting for results to flush out..." ) - } - def waitingForListener( - initSimSender: ActorRef, - successful: Boolean, - remainingListeners: Seq[ActorRef], - ): Receive = { - case Terminated(actor) if remainingListeners.contains(actor) => - val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) + actorData.resultListener.foreach(_ ! ResultEventListener.FlushAndStop) - logger.debug( - "Listener {} has been terminated. Remaining listeners: {}", - actor, - updatedRemainingListeners, + waitingForListener( + actorData.starter, + remainingListeners = actorData.resultListener.toSeq, + ) + } else { + ctx.log.error( + "An error occurred during the simulation. See stacktrace for details." ) - if (updatedRemainingListeners.isEmpty) { - logger.info( - "The last remaining result listener has been terminated. Exiting." - ) - - val msg = - if (successful) SimulationSuccessful - else SimulationFailure - // inform InitSim Sender - initSimSender ! msg + // if an error happened, we do not care for all results to be flushed out + // and just end everything right away + actorData.resultListener.foreach { ref => + ctx.unwatch(ref) + ctx.stop(ref) } - context become waitingForListener( - initSimSender, - successful, - updatedRemainingListeners, + // also notify RuntimeEventListener that error happened + actorData.runtimeEventListener ! RuntimeEvent.Error( + "Simulation stopped with error." ) - } - def stopAllChildrenGracefully( - simulationSuccessful: Boolean - ): Unit = { - gridAgents.foreach { gridAgentRef => - context.unwatch(gridAgentRef) - gridAgentRef ! StopMessage(simulationSuccessful) - } + actorData.starter ! SimonaEnded(successful = false) - context.unwatch(scheduler) - context.stop(scheduler) + Behaviors.stopped + } + } - context.unwatch(weatherService) - context.stop(weatherService) + private def waitingForListener( + starter: ActorRef[SimonaEnded], + remainingListeners: Seq[ActorRef[_]], + ): Behavior[SimMessage] = Behaviors.receiveSignal[SimMessage] { + case (ctx, Terminated(actor)) if remainingListeners.contains(actor) => + val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) - extSimulationData.extSimAdapters.foreach { ref => - context.unwatch(ref) - ref ! StopMessage(simulationSuccessful) - } - extSimulationData.extDataServices.foreach { case (_, ref) => - context.unwatch(ref) - context.stop(ref) - } + if (updatedRemainingListeners.isEmpty) { + ctx.log.info( + "All result listeners have terminated. Ending simulation successfully." + ) - // do not unwatch the result listeners, as we're waiting for their termination - systemParticipantsListener.foreach( - _ ! StopMessage(simulationSuccessful) - ) + // inform InitSim Sender + starter ! SimonaEnded(successful = true) - context.unwatch(runtimeEventListener.toClassic) - context.stop(runtimeEventListener.toClassic) + Behaviors.stopped + } else { + waitingForListener( + starter, + updatedRemainingListeners, + ) + } - logger.debug("Stopping all listeners requested.") } -} - -object SimonaSim { - /** Object to indicate to the scheduler itself, that an uncaught exception has - * triggered an emergency shutdown of the simulation system + /** TODO scaladoc + * @param starter + * @param runtimeEventListener + * @param watchedActors + * excluding ExtSimAdapters and ResultListeners + * @param extSimAdapters + * @param resultListener */ - case object EmergencyShutdownInitiated - - private[SimonaSim] final case class SimonaSimStateData( - initSimSender: ActorRef = ActorRef.noSender + private final case class ActorData( + starter: ActorRef[SimonaEnded], + runtimeEventListener: ActorRef[RuntimeEvent], + watchedActors: Iterable[ActorRef[_]], + extSimAdapters: Iterable[ClassicRef], + resultListener: Iterable[ActorRef[ResultMessage]], ) - - def props(simonaSetup: SimonaSetup): Props = - Props(new SimonaSim(simonaSetup)) - } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index e94f782e4c..f0504948df 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -6,12 +6,17 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.RuntimeEvent +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} +import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer +import edu.ie3.simona.sim.SimMessage +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext +import org.apache.pekko.actor.{ActorRef => ClassicRef} /** Trait that can be used to setup a customized simona simulation by providing * implementations for all setup information required by a @@ -30,11 +35,6 @@ trait SimonaSetup { */ val args: Array[String] - /** A function, that constructs the [[ActorSystem]], the simulation shall live - * in - */ - val buildActorSystem: () => ActorSystem - /** Creates the runtime event listener * * @param context @@ -43,8 +43,8 @@ trait SimonaSetup { * An actor reference to the runtime event listener */ def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] + context: ActorContext[_] + ): ActorRef[RuntimeEvent] /** Creates a sequence of system participant event listeners * @@ -54,8 +54,8 @@ trait SimonaSetup { * A sequence of actor references to runtime event listeners */ def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] + context: ActorContext[_] + ): Seq[ActorRef[ResultMessage]] /** Creates a primary service proxy. The proxy is the first instance to ask * for primary data. If necessary, it delegates the registration request to @@ -69,9 +69,9 @@ trait SimonaSetup { * An actor reference to the service */ def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef /** Creates a weather service * @@ -84,9 +84,9 @@ trait SimonaSetup { * the service */ def weatherService( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef /** Loads external simulations and provides corresponding actors and init data * @@ -98,8 +98,8 @@ trait SimonaSetup { * External simulations and their init data */ def extSimulations( - context: ActorContext, - scheduler: ActorRef, + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], ): ExtSimSetupData /** Creates the time advancer @@ -114,10 +114,10 @@ trait SimonaSetup { * An actor reference to the time advancer */ def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] + context: ActorContext[_], + simulation: ActorRef[SimMessage], + runtimeEventListener: ActorRef[RuntimeEvent], + ): ActorRef[TimeAdvancer.Incoming] /** Creates a scheduler service * @@ -129,9 +129,9 @@ trait SimonaSetup { * An actor reference to the scheduler */ def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], - ): ActorRef + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Incoming], + ): ActorRef[SchedulerMessage] /** Creates all the needed grid agents * @@ -139,17 +139,17 @@ trait SimonaSetup { * Actor context to use * @param environmentRefs * EnvironmentRefs to use - * @param systemParticipantListener + * @param resultEventListeners * Listeners that await events from system participants * @return * A mapping from actor reference to it's according initialization data to * be used when setting up the agents */ def gridAgents( - context: ActorContext, + context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef], - ): Iterable[ActorRef] + resultEventListeners: Seq[ActorRef[ResultEvent]], + ): Iterable[ClassicRef] /** SIMONA links sub grids connected by a three winding transformer a bit * different. Therefore, the internal node has to be set as superior node. diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index cf9e78689f..1d5d0d5ff2 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -6,12 +6,6 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorContextOps, - ClassicActorRefOps, - TypedActorRefOps, -} -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import com.typesafe.config.Config import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridTopologyGraph @@ -25,10 +19,12 @@ import edu.ie3.simona.api.data.ExtData import edu.ie3.simona.api.data.ev.{ExtEvData, ExtEvSimulation} import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.config.{ArgsParser, RefSystemParser, SimonaConfig} -import edu.ie3.simona.event.RuntimeEvent +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.io.grid.GridProvider +import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.scheduler.{ScheduleLock, Scheduler, TimeAdvancer} import edu.ie3.simona.service.SimonaService @@ -38,10 +34,18 @@ import edu.ie3.simona.service.primary.PrimaryServiceProxy import edu.ie3.simona.service.primary.PrimaryServiceProxy.InitPrimaryServiceProxyStateData import edu.ie3.simona.service.weather.WeatherService import edu.ie3.simona.service.weather.WeatherService.InitWeatherServiceStateData +import edu.ie3.simona.sim.SimMessage import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.simona.util.TickUtil.RichZonedDateTime import edu.ie3.util.TimeUtil +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext +import org.apache.pekko.actor.typed.scaladsl.adapter._ +import org.apache.pekko.actor.{ + ActorRef => ClassicRef, + ActorContext => ClassicContext, +} import java.util.concurrent.LinkedBlockingQueue import scala.jdk.CollectionConverters._ @@ -53,7 +57,7 @@ import scala.jdk.CollectionConverters._ * @since 01.07.20 */ class SimonaStandaloneSetup( - override val buildActorSystem: () => ActorSystem, + val typeSafeConfig: Config, simonaConfig: SimonaConfig, resultFileHierarchy: ResultFileHierarchy, runtimeEventQueue: Option[LinkedBlockingQueue[RuntimeEvent]] = None, @@ -61,10 +65,10 @@ class SimonaStandaloneSetup( ) extends SimonaSetup { override def gridAgents( - context: ActorContext, + context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef], - ): Iterable[ActorRef] = { + resultEventListeners: Seq[ActorRef[ResultEvent]], + ): Iterable[ClassicRef] = { /* get the grid */ val subGridTopologyGraph = GridProvider @@ -84,14 +88,14 @@ class SimonaStandaloneSetup( /* Create all agents and map the sub grid id to their actor references */ val subGridToActorRefMap = buildSubGridToActorRefMap( subGridTopologyGraph, - context, + context.toClassic, environmentRefs, - systemParticipantListener, + resultEventListeners.map(_.toClassic), ) val keys = ScheduleLock.multiKey( context, - environmentRefs.scheduler.toTyped, + environmentRefs.scheduler, INIT_SIM_TICK, subGridTopologyGraph.vertexSet().size, ) @@ -136,15 +140,15 @@ class SimonaStandaloneSetup( } override def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = { + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = { val simulationStart = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) - val primaryServiceProxy = context.simonaActorOf( + val primaryServiceProxy = context.toClassic.simonaActorOf( PrimaryServiceProxy.props( - scheduler, + scheduler.toClassic, InitPrimaryServiceProxyStateData( simonaConfig.simona.input.primary, simulationStart, @@ -158,12 +162,12 @@ class SimonaStandaloneSetup( } override def weatherService( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = { - val weatherService = context.simonaActorOf( + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = { + val weatherService = context.toClassic.simonaActorOf( WeatherService.props( - scheduler, + scheduler.toClassic, TimeUtil.withDefaults .toZonedDateTime(simonaConfig.simona.time.startDateTime), TimeUtil.withDefaults @@ -174,15 +178,15 @@ class SimonaStandaloneSetup( InitWeatherServiceStateData( simonaConfig.simona.input.weather.datasource ), - ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK), + ScheduleLock.singleKey(context, scheduler, INIT_SIM_TICK), ) weatherService } override def extSimulations( - context: ActorContext, - scheduler: ActorRef, + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], ): ExtSimSetupData = { val jars = ExtSimLoader.scanInputFolder() @@ -191,8 +195,8 @@ class SimonaStandaloneSetup( val (extSimAdapters, extDataServices) = extLinks.zipWithIndex.map { case (extLink, index) => // external simulation always needs at least an ExtSimAdapter - val extSimAdapter = context.simonaActorOf( - ExtSimAdapter.props(scheduler), + val extSimAdapter = context.toClassic.simonaActorOf( + ExtSimAdapter.props(scheduler.toClassic), s"$index", ) val extSimAdapterData = new ExtSimAdapterData(extSimAdapter, args) @@ -200,18 +204,18 @@ class SimonaStandaloneSetup( // send init data right away, init activation is scheduled extSimAdapter ! ExtSimAdapter.Create( extSimAdapterData, - ScheduleLock.singleKey(context, scheduler.toTyped, INIT_SIM_TICK), + ScheduleLock.singleKey(context, scheduler, INIT_SIM_TICK), ) // setup data services that belong to this external simulation val (extData, extDataInit): ( Iterable[ExtData], - Iterable[(Class[_ <: SimonaService[_]], ActorRef)], + Iterable[(Class[_ <: SimonaService[_]], ClassicRef)], ) = extLink.getExtDataSimulations.asScala.zipWithIndex.map { case (_: ExtEvSimulation, dIndex) => - val extEvDataService = context.simonaActorOf( - ExtEvDataService.props(scheduler), + val extEvDataService = context.toClassic.simonaActorOf( + ExtEvDataService.props(scheduler.toClassic), s"$index-$dIndex", ) val extEvData = new ExtEvData(extEvDataService, extSimAdapter) @@ -220,7 +224,7 @@ class SimonaStandaloneSetup( InitExtEvData(extEvData), ScheduleLock.singleKey( context, - scheduler.toTyped, + scheduler, INIT_SIM_TICK, ), ) @@ -244,10 +248,10 @@ class SimonaStandaloneSetup( } override def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = { + context: ActorContext[_], + simulation: ActorRef[SimMessage], + runtimeEventListener: ActorRef[RuntimeEvent], + ): ActorRef[TimeAdvancer.Incoming] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) @@ -267,21 +271,18 @@ class SimonaStandaloneSetup( } override def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], - ): ActorRef = + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Incoming], + ): ActorRef[SchedulerMessage] = context .spawn( - Scheduler( - timeAdvancer - ), + Scheduler(timeAdvancer), Scheduler.getClass.getSimpleName, ) - .toClassic override def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = + context: ActorContext[_] + ): ActorRef[RuntimeEvent] = context .spawn( RuntimeEventListener( @@ -293,17 +294,19 @@ class SimonaStandaloneSetup( ) override def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] = { + context: ActorContext[_] + ): Seq[ActorRef[ResultMessage]] = { // append ResultEventListener as well to write raw output files ArgsParser .parseListenerConfigOption(simonaConfig.simona.event.listener) .zipWithIndex .map { case ((listenerCompanion, events), index) => - context.simonaActorOf( - listenerCompanion.props(events), - index.toString, - ) + context.toClassic + .simonaActorOf( + listenerCompanion.props(events), + index.toString, + ) + .toTyped } .toSeq :+ context .spawn( @@ -312,15 +315,14 @@ class SimonaStandaloneSetup( ), ResultEventListener.getClass.getSimpleName, ) - .toClassic } def buildSubGridToActorRefMap( subGridTopologyGraph: SubGridTopologyGraph, - context: ActorContext, + context: ClassicContext, environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef], - ): Map[Int, ActorRef] = { + systemParticipantListener: Seq[ClassicRef], + ): Map[Int, ClassicRef] = { subGridTopologyGraph .vertexSet() .asScala @@ -369,7 +371,7 @@ object SimonaStandaloneSetup extends LazyLogging with SetupHelper { mainArgs: Array[String] = Array.empty[String], ): SimonaStandaloneSetup = new SimonaStandaloneSetup( - () => ActorSystem("simona", typeSafeConfig), + typeSafeConfig, SimonaConfig(typeSafeConfig), resultFileHierarchy, runtimeEventQueue, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index ace38eb295..6573f32bc0 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -86,7 +86,7 @@ class DBFSAlgorithmCenGridSpec ) private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, + scheduler = scheduler.ref.toTyped, runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index bd677049a2..49c601a8c2 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -74,7 +74,7 @@ class DBFSAlgorithmFailedPowerFlowSpec InferiorGA(TestProbe("inferiorGridAgent"), Seq(node1.getUuid)) private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, + scheduler = scheduler.ref.toTyped, runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index c15e254661..362d5ce692 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -66,7 +66,7 @@ class DBFSAlgorithmParticipantSpec private val weatherService = TestProbe("weatherService") private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, + scheduler = scheduler.ref.toTyped, runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index a9dd723f8d..fd5974b755 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -73,7 +73,7 @@ class DBFSAlgorithmSupGridSpec private val hvGrid: TestProbe = TestProbe("hvGrid") private val environmentRefs = EnvironmentRefs( - scheduler = scheduler.ref, + scheduler = scheduler.ref.toTyped, runtimeEventListener = runtimeEvents.ref, primaryServiceProxy = primaryService.ref, weather = weatherService.ref, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala index 3a5490b892..58320c23e8 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala @@ -6,16 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.{ - Actor, - ActorIdentity, - ActorRef, - ActorSystem, - Identify, - Props, -} -import org.apache.pekko.testkit.ImplicitSender -import org.apache.pekko.util.Timeout import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity @@ -26,6 +16,17 @@ import edu.ie3.simona.test.common.input.TransformerInputTestData import edu.ie3.simona.test.common.{ConfigTestData, TestKitWithShutdown} import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.typed.scaladsl.adapter._ +import org.apache.pekko.actor.{ + Actor, + ActorIdentity, + ActorRef, + ActorSystem, + Identify, + Props, +} +import org.apache.pekko.testkit.ImplicitSender +import org.apache.pekko.util.Timeout import org.scalatest.wordspec.AnyWordSpecLike import java.util.concurrent.TimeUnit @@ -60,7 +61,7 @@ class GridAgentSetup2WSpec system.actorOf(Props(new Actor { override def receive: Receive = { case "setup" => val environmentRefs = EnvironmentRefs( - scheduler = self, + scheduler = self.toTyped, runtimeEventListener = self, primaryServiceProxy = self, weather = ActorRef.noSender, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala index e12209b4f2..14d8540ecd 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala @@ -6,16 +6,6 @@ package edu.ie3.simona.agent.grid -import org.apache.pekko.actor.{ - Actor, - ActorIdentity, - ActorRef, - ActorSystem, - Identify, - Props, -} -import org.apache.pekko.testkit.ImplicitSender -import org.apache.pekko.util.Timeout import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity @@ -29,6 +19,17 @@ import edu.ie3.simona.test.common.{ } import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.typed.scaladsl.adapter._ +import org.apache.pekko.actor.{ + Actor, + ActorIdentity, + ActorRef, + ActorSystem, + Identify, + Props, +} +import org.apache.pekko.testkit.ImplicitSender +import org.apache.pekko.util.Timeout import org.scalatest.wordspec.AnyWordSpecLike import java.util.concurrent.TimeUnit @@ -62,7 +63,7 @@ class GridAgentSetup3WSpec system.actorOf(Props(new Actor { override def receive: Receive = { case "setup" => val environmentRefs = EnvironmentRefs( - scheduler = self, + scheduler = self.toTyped, runtimeEventListener = self, primaryServiceProxy = self, weather = ActorRef.noSender, diff --git a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala index da6431493b..49a7353124 100644 --- a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala +++ b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala @@ -6,10 +6,8 @@ package edu.ie3.simona.api -import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps -import org.apache.pekko.actor.{ActorSystem, Terminated} -import org.apache.pekko.testkit.{TestActorRef, TestProbe} import com.typesafe.config.ConfigFactory +import edu.ie3.simona.api.ExtSimAdapter.StopMessage import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.api.simulation.ontology.{ @@ -18,15 +16,18 @@ import edu.ie3.simona.api.simulation.ontology.{ TerminationMessage, CompletionMessage => ExtCompletionMessage, } +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.ScheduleServiceActivation -import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.test.common.{TestKitWithShutdown, TestSpawnerClassic} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.{ActorSystem, Terminated} +import org.apache.pekko.testkit.{TestActorRef, TestProbe} import org.scalatest.wordspec.AnyWordSpecLike import java.util.UUID diff --git a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala index 067162f30b..5788bd9f76 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala @@ -20,8 +20,8 @@ import edu.ie3.simona.event.ResultEvent.{ ParticipantResultEvent, PowerFlowResultEvent, } +import edu.ie3.simona.event.listener.ResultEventListener.FlushAndStop import edu.ie3.simona.io.result.{ResultEntitySink, ResultSinkType} -import edu.ie3.simona.ontology.messages.StopMessage import edu.ie3.simona.test.common.result.PowerFlowResultData import edu.ie3.simona.test.common.{IOTestCommons, UnitSpec} import edu.ie3.simona.util.ResultFileHierarchy @@ -32,7 +32,6 @@ import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, } import org.apache.pekko.testkit.TestKit.awaitCond -import org.apache.pekko.testkit.TestProbe import java.io.{File, FileInputStream} import java.util.UUID @@ -140,7 +139,7 @@ class ResultEventListenerSpec ) ) - listener ! StopMessage(true) + listener ! FlushAndStop deathWatch expectTerminated (listener, 10 seconds) } } @@ -174,7 +173,7 @@ class ResultEventListenerSpec ) // stop listener so that result is flushed out - listenerRef ! StopMessage(true) + listenerRef ! FlushAndStop // wait until all lines have been written out: awaitCond( @@ -256,7 +255,7 @@ class ResultEventListenerSpec ) // stop listener so that result is flushed out - listenerRef ! StopMessage(true) + listenerRef ! FlushAndStop // wait until all lines have been written out: awaitCond( @@ -340,7 +339,7 @@ class ResultEventListenerSpec listener ! powerflow3wResult(resultB) // stop listener so that result is flushed out - listener ! StopMessage(true) + listener ! FlushAndStop /* Await that the result is written */ awaitCond( @@ -403,7 +402,7 @@ class ResultEventListenerSpec // otherwise it might happen, that the shutdown is triggered even before the just send ParticipantResultEvent // reached the listener // this also triggers the compression of result files - listenerRef ! StopMessage(true) + listenerRef ! FlushAndStop // shutdown the actor system system.terminate() diff --git a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala index 0262ebcf1c..4ecafebdbf 100644 --- a/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala +++ b/src/test/scala/edu/ie3/simona/integration/RunSimonaStandaloneIT.scala @@ -82,10 +82,12 @@ class RunSimonaStandaloneIT ) /* run simulation */ - RunSimonaStandalone.run( + val successful = RunSimonaStandalone.run( simonaStandaloneSetup ) + successful shouldBe true + /* check the results */ // check configs val configOutputDir = new File(resultFileHierarchy.configOutputDir) diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index 3ad6cda04a..4d48501d7a 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -6,11 +6,6 @@ package edu.ie3.simona.scheduler -import org.apache.pekko.actor.testkit.typed.scaladsl.{ - ScalaTestWithActorTestKit, - TestProbe, -} -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.RuntimeEvent._ import edu.ie3.simona.ontology.messages.Activation @@ -18,10 +13,13 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.scheduler.TimeAdvancer.{StartSimMessage, Stop} +import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage import edu.ie3.simona.sim.SimMessage -import edu.ie3.simona.sim.SimMessage.{SimulationFailure, SimulationSuccessful} import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe, +} import org.scalatest.matchers.should import org.scalatest.wordspec.AnyWordSpecLike @@ -46,7 +44,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 7200, @@ -134,7 +132,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "started without checkWindow and pauseTick" in { @@ -143,7 +141,7 @@ class TimeAdvancerSpec val listener = TestProbe[RuntimeEvent]("listener") val timeAdvancer = spawn( - TimeAdvancer(simulation.ref.toClassic, Some(listener.ref), None, 3600) + TimeAdvancer(simulation.ref, Some(listener.ref), None, 3600) ) timeAdvancer ! ScheduleActivation(scheduler.ref, INIT_SIM_TICK) @@ -186,7 +184,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "paused and started after initialization" in { @@ -196,7 +194,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 3600, @@ -260,7 +258,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "paused and started and there is a gap between StartSchedule tick and next activation tick" in { @@ -270,7 +268,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 5400, @@ -348,7 +346,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "paused and endTick - pauseScheduleAtTick == 1" in { @@ -358,7 +356,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 3600, @@ -426,7 +424,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "activation has been scheduled after endTick" in { @@ -436,7 +434,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(1800), 3600, @@ -476,7 +474,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "no next trigger has been supplied" in { @@ -486,7 +484,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 3600, @@ -536,7 +534,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "endTick < pauseScheduleAtTick" in { @@ -546,7 +544,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(1800), 3600, @@ -586,7 +584,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } "endTick == pauseScheduleAtTick" in { @@ -596,7 +594,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 1800, @@ -636,7 +634,7 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimulationSuccessful) + simulation.expectMessage(SimMessage.SimulationEnded) } } @@ -649,7 +647,7 @@ class TimeAdvancerSpec val timeAdvancer = spawn( TimeAdvancer( - simulation.ref.toClassic, + simulation.ref, Some(listener.ref), Some(900), 1800, @@ -682,89 +680,8 @@ class TimeAdvancerSpec scheduler.expectTerminated(timeAdvancer) - simulation.expectMessage(SimulationFailure) - } - - "receiving error message while uninitialized" in { - val simulation = TestProbe[SimMessage]("simulation") - val scheduler = TestProbe[Activation]("scheduler") - val listener = TestProbe[RuntimeEvent]("listener") - - val timeAdvancer = spawn( - TimeAdvancer(simulation.ref.toClassic, Some(listener.ref), None, 1800) - ) - - // Send stop message - timeAdvancer ! Stop("Test message") - - // we cannot check the console, thus just check if time advancer died - scheduler.expectTerminated(timeAdvancer) - - simulation.expectMessage(SimulationFailure) - } - - "receiving error message while inactive" in { - val simulation = TestProbe[SimMessage]("simulation") - val scheduler = TestProbe[Activation]("scheduler") - val listener = TestProbe[RuntimeEvent]("listener") - - val timeAdvancer = spawn( - TimeAdvancer(simulation.ref.toClassic, Some(listener.ref), None, 1800) - ) - timeAdvancer ! ScheduleActivation(scheduler.ref, 1) - - // Send stop message - timeAdvancer ! Stop("Test message") - - listener.expectMessageType[Error].errMsg should include("Test message") - listener.expectMessageType[Done] match { - case Done(tick, duration, errorInSim) => - tick shouldBe 1 - duration should (be >= 0L and be < maxEventDuration) - errorInSim shouldBe true - } - - scheduler.expectTerminated(timeAdvancer) - - simulation.expectMessage(SimulationFailure) - } - - "receiving error message while active" in { - val simulation = TestProbe[SimMessage]("simulation") - val scheduler = TestProbe[Activation]("scheduler") - val listener = TestProbe[RuntimeEvent]("listener") - - val timeAdvancer = spawn( - TimeAdvancer( - simulation.ref.toClassic, - Some(listener.ref), - Some(900), - 1800, - ) - ) - timeAdvancer ! ScheduleActivation(scheduler.ref, 0) - - // start simulation - timeAdvancer ! StartSimMessage() - - // tick 0 is activated - scheduler.expectMessage(Activation(0)) - listener.expectMessage(Simulating(0, 1800)) - - // Send stop message - timeAdvancer ! Stop("Test message") - - listener.expectMessageType[Error].errMsg should include("Test message") - listener.expectMessageType[Done] match { - case Done(tick, duration, errorInSim) => - tick shouldBe 0 - duration should (be >= 0L and be < maxEventDuration) - errorInSim shouldBe true - } - - scheduler.expectTerminated(timeAdvancer) - - simulation.expectMessage(SimulationFailure) + // No SimulationEnded message + simulation.expectNoMessage() } } diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala deleted file mode 100644 index e9ad87efff..0000000000 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala +++ /dev/null @@ -1,153 +0,0 @@ -/* - * © 2021. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.sim - -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorRefOps, - ClassicActorSystemOps, -} -import org.apache.pekko.actor.{ - Actor, - ActorContext, - ActorRef, - ActorSystem, - Props, -} -import org.apache.pekko.testkit.{TestActorRef, TestProbe} -import com.typesafe.config.ConfigFactory -import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage -import edu.ie3.simona.sim.SimMessage.{InitSim, SimulationFailure} -import edu.ie3.simona.sim.SimonaSimFailSpec.FailSim -import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} -import edu.ie3.simona.test.common.AgentSpec - -class SimonaSimFailSpec - extends AgentSpec( - ActorSystem( - "SimonaSimFailSpec", - ConfigFactory - .parseString(""" - |pekko.loggers = ["org.apache.pekko.testkit.TestEventListener"] - |pekko.loglevel="OFF" - """.stripMargin), - ) - ) { - "A SimonaSim" should { - "properly fail on uncaught exception" in { - val timeAdvancer = TestProbe("timeAdvancer") - - val failSim = TestActorRef.create[FailSim]( - system, - Props( - new FailSim( - system, - timeAdvancer.ref.toTyped, - ) - ), - ) - - /* Init the simulation */ - failSim ! InitSim - - /* The sim asks the scheduler to start it's schedule */ - timeAdvancer.expectMsg(StartSimMessage()) - - /* Trigger the child to fail */ - failSim.underlyingActor.getChild ! "fail" - - expectMsg(SimulationFailure) - } - } -} - -object SimonaSimFailSpec { - class FailSim( - actorSystem: ActorSystem, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], - ) extends SimonaSim( - new DummySetup( - actorSystem, - timeAdvancer, - ) - ) { - val child: ActorRef = context.actorOf(Props(new Loser)) - context.watch(child) - - def getChild: ActorRef = child - } - - class Loser extends Actor { - override def receive: Receive = { case _ => - throw new RuntimeException("Nah, I'm not gonna do that!") - } - } - - class DummySetup( - actorSystem: ActorSystem, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[ - TimeAdvancer.Incoming - ], - override val args: Array[String] = Array.empty[String], - ) extends SimonaSetup { - - override val buildActorSystem: () => ActorSystem = () => actorSystem - - override def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = - org.apache.pekko.actor.testkit.typed.scaladsl - .TestProbe[RuntimeEvent]()(actorSystem.toTyped) - .ref - - override def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] = Seq.empty[ActorRef] - - override def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = - TestProbe("primaryService")(actorSystem).ref - - override def weatherService( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = - TestProbe("weatherService")(actorSystem).ref - - override def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[ - RuntimeEvent - ], - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = - timeAdvancer - - override def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[ - TimeAdvancer.Incoming - ], - ): ActorRef = TestProbe("scheduler")(actorSystem).ref - - override def gridAgents( - context: ActorContext, - environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef], - ): Iterable[ActorRef] = Iterable.empty - - override def extSimulations( - context: ActorContext, - scheduler: ActorRef, - ): ExtSimSetupData = - ExtSimSetupData(Iterable.empty, Map.empty) - } -} diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala new file mode 100644 index 0000000000..6882767300 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -0,0 +1,233 @@ +/* + * © 2021. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.sim + +import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} +import edu.ie3.simona.main.RunSimona.SimonaEnded +import edu.ie3.simona.ontology.messages.SchedulerMessage +import edu.ie3.simona.scheduler.TimeAdvancer +import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage +import edu.ie3.simona.sim.SimMessage.StartSimulation +import edu.ie3.simona.sim.SimonaSimSpec.{ + MockSetup, + stopOnMessage, + throwOnMessage, +} +import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} +import edu.ie3.simona.test.common.UnitSpec +import org.apache.pekko.actor.testkit.typed.scaladsl.{ + ScalaTestWithActorTestKit, + TestProbe, +} +import org.apache.pekko.actor.typed.scaladsl.adapter._ +import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} +import org.apache.pekko.actor.typed.{ActorRef, Behavior} +import org.apache.pekko.actor.{ActorRef => ClassicRef} + +class SimonaSimSpec extends ScalaTestWithActorTestKit with UnitSpec { + + "SimonaSim" should { + "stop and indicate failure to starter" when { + + "child stops due to thrown exception" in { + val starter = TestProbe[SimonaEnded]("starter") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + + val receiveThrowingActor = + TestProbe[ActorRef[RuntimeEvent]]("receiveThrowingActor") + + val simonaSim = spawn( + SimonaSim( + new MockSetup(timeAdvancer.ref) { + override def runtimeEventListener( + context: ActorContext[_] + ): ActorRef[RuntimeEvent] = { + // has to be created by correct context + val throwingActor = + context.spawn[RuntimeEvent](throwOnMessage, "throwingActor") + // send ref to the outside + receiveThrowingActor.ref ! throwingActor + throwingActor + } + } + ), + "simonaSim", + ) + + simonaSim ! StartSimulation(starter.ref) + + // Initialization has started, mock actors are being created + val failActor = + receiveThrowingActor.expectMessageType[ActorRef[RuntimeEvent]] + timeAdvancer.expectMessage(StartSimMessage()) + + // Simulation should still "run" at this point + starter.expectNoMessage() + + // We cause an actor to fail. + // (The actor reacts to any message with an exception, + // we just pick the first best fit) + failActor ! RuntimeEvent.Initializing + + // SimonaSim should run its failure routine and tell us that a failure happened + starter.expectMessage(SimonaEnded(successful = false)) + } + + "child stops by changing behavior" in { + val starter = TestProbe[SimonaEnded]("starter") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + + val receiveStoppingActor = + TestProbe[ActorRef[RuntimeEvent]]("receiveStoppingActor") + + val simonaSim = spawn( + SimonaSim( + new MockSetup(timeAdvancer.ref) { + override def runtimeEventListener( + context: ActorContext[_] + ): ActorRef[RuntimeEvent] = { + // has to be created by correct context + val stoppingActor = + context.spawn[RuntimeEvent](stopOnMessage, "stoppingActor") + // send ref to the outside + receiveStoppingActor.ref ! stoppingActor + stoppingActor + } + } + ), + "simonaSim", + ) + + simonaSim ! StartSimulation(starter.ref) + + // Initialization has started, mock actors are being created + val stoppingActor = + receiveStoppingActor.expectMessageType[ActorRef[RuntimeEvent]] + timeAdvancer.expectMessage(StartSimMessage()) + + // Simulation should still "run" at this point + starter.expectNoMessage() + + // We cause an actor to fail. + // (The actor reacts to any message by stopping itself, + // we just pick the first best fit) + stoppingActor ! RuntimeEvent.Initializing + + // SimonaSim should run its failure routine and tell us that a failure happened + starter.expectMessage(SimonaEnded(successful = false)) + } + } + + "exception is thrown while initializing" in { + val starter = TestProbe[SimonaEnded]("starter") + + val simonaSim = spawn( + SimonaSim( + new MockSetup(TestProbe().ref) { + override def timeAdvancer( + context: ActorContext[_], + simulation: ActorRef[SimMessage], + runtimeEventListener: ActorRef[RuntimeEvent], + ): ActorRef[TimeAdvancer.Incoming] = { + throw new RuntimeException("Test exception") + } + } + ), + "simonaSim", + ) + + // Initialization should not have started yet + starter.expectNoMessage() + + simonaSim ! StartSimulation(starter.ref) + + // SimonaSim should run its failure routine and tell us that a failure happened + starter.expectMessage(SimonaEnded(successful = false)) + } + } + + // TODO: + // SimulationEnded(successful = true) + // -> also test that all actors that were started also are stopped + // SimulationEnded(successful = false) + // REL fails in edge cases + + // generally: test that Error is sent to RuntimeEventListener +} + +object SimonaSimSpec { + + def empty[T]: Behavior[T] = Behaviors.receiveMessage { _ => + Behaviors.same + } + + def forwardMessage[T](recipient: ActorRef[T]): Behavior[T] = + Behaviors.receiveMessage { msg => + recipient ! msg + Behaviors.same + } + + def throwOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => + throw new RuntimeException("Nah, I'm not gonna do that!") + } + + def stopOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => + Behaviors.stopped + } + + class MockSetup(timeAdvancer: ActorRef[TimeAdvancer.Incoming]) + extends SimonaSetup { + + override val args: Array[String] = Array.empty[String] + + override def runtimeEventListener( + context: ActorContext[_] + ): ActorRef[RuntimeEvent] = context.spawn(empty, "runtimeEvent") + + override def systemParticipantsListener( + context: ActorContext[_] + ): Seq[ActorRef[ResultMessage]] = Seq.empty + + override def primaryServiceProxy( + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = + context.spawn(empty, "primaryService").toClassic + + override def weatherService( + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = + context.spawn(empty, "weatherService").toClassic + + override def timeAdvancer( + context: ActorContext[_], + simulation: ActorRef[SimMessage], + runtimeEventListener: ActorRef[RuntimeEvent], + ): ActorRef[TimeAdvancer.Incoming] = + context.spawn(forwardMessage(timeAdvancer), "timeAdvancerForwarder") + + override def scheduler( + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Incoming], + ): ActorRef[SchedulerMessage] = context.spawn(empty, "scheduler") + + override def gridAgents( + context: ActorContext[_], + environmentRefs: EnvironmentRefs, + systemParticipantListener: Seq[ActorRef[ResultEvent]], + ): Iterable[ClassicRef] = Iterable.empty + + override def extSimulations( + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ExtSimSetupData = + ExtSimSetupData(Iterable.empty, Map.empty) + } +} diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 671ebad4e9..2ae9938ffd 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -6,17 +6,21 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ActorContext, ActorRef, ActorSystem} import edu.ie3.datamodel.exceptions.NotImplementedException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, Transformer3WInput, } import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.RuntimeEvent +import edu.ie3.simona.event.listener.ResultEventListener +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} +import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer +import edu.ie3.simona.sim.SimMessage import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.SubGridGateMokka +import org.apache.pekko.actor.typed.scaladsl +import org.apache.pekko.actor.{ActorRef, typed} import java.util.UUID @@ -24,54 +28,56 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override val args: Array[String] = Array.empty[String] - override val buildActorSystem: () => ActorSystem = () => - throw new NotImplementedException("This is a dummy setup") - override def runtimeEventListener( - context: ActorContext - ): org.apache.pekko.actor.typed.ActorRef[RuntimeEvent] = - throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_] + ): typed.ActorRef[RuntimeEvent] = throw new NotImplementedException( + "This is a dummy setup" + ) override def systemParticipantsListener( - context: ActorContext - ): Seq[ActorRef] = throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_] + ): Seq[typed.ActorRef[ResultEventListener.ResultMessage]] = + throw new NotImplementedException("This is a dummy setup") override def primaryServiceProxy( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = - throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_], + scheduler: typed.ActorRef[SchedulerMessage], + ): ActorRef = throw new NotImplementedException("This is a dummy setup") override def weatherService( - context: ActorContext, - scheduler: ActorRef, - ): ActorRef = - throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_], + scheduler: typed.ActorRef[SchedulerMessage], + ): ActorRef = throw new NotImplementedException("This is a dummy setup") override def extSimulations( - context: ActorContext, - scheduler: ActorRef, - ): ExtSimSetupData = - throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_], + scheduler: typed.ActorRef[SchedulerMessage], + ): ExtSimSetupData = throw new NotImplementedException( + "This is a dummy setup" + ) override def timeAdvancer( - context: ActorContext, - simulation: ActorRef, - runtimeEventListener: org.apache.pekko.actor.typed.ActorRef[RuntimeEvent], - ): org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming] = - throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_], + simulation: typed.ActorRef[SimMessage], + runtimeEventListener: typed.ActorRef[RuntimeEvent], + ): typed.ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException( + "This is a dummy setup" + ) override def scheduler( - context: ActorContext, - timeAdvancer: org.apache.pekko.actor.typed.ActorRef[TimeAdvancer.Incoming], - ): ActorRef = throw new NotImplementedException("This is a dummy setup") + context: scaladsl.ActorContext[_], + timeAdvancer: typed.ActorRef[TimeAdvancer.Incoming], + ): typed.ActorRef[SchedulerMessage] = throw new NotImplementedException( + "This is a dummy setup" + ) override def gridAgents( - context: ActorContext, + context: scaladsl.ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef], - ): Iterable[ActorRef] = - throw new NotImplementedException("This is a dummy setup") + resultEventListeners: Seq[typed.ActorRef[ResultEvent]], + ): Iterable[ActorRef] = throw new NotImplementedException( + "This is a dummy setup" + ) "Attempting to modify a sub grid gate" should { val nodeAUuid = UUID.randomUUID() From 3403333dc0b48748b8bf8507fd65909327bfb17e Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 20 Feb 2024 01:29:56 +0100 Subject: [PATCH 250/305] Test log output only on failure --- src/test/resources/logback-test.xml | 36 ++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index b2c5260199..79b160e703 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -1,27 +1,25 @@ - + %highlight%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - OFF - + test/logs/simona/simona_tests.log - test/logs/simona/archive/simona_tests-%d{yyyyMMdd'T'HHmmss}-${bySecond}.log - + test/logs/simona/archive/simona_tests-%d{yyyyMMdd'T'HHmmss}.log + 10 3GB @@ -32,8 +30,30 @@ DEBUG - + + + + + + + + + + + + \ No newline at end of file From 508522d89bee6619ce0feae5a8d5e1aa7be4af8f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 20 Feb 2024 10:04:58 +0100 Subject: [PATCH 251/305] fmt --- docs/readthedocs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readthedocs/config.md b/docs/readthedocs/config.md index f1db2fc5b6..64a9dfc1b7 100644 --- a/docs/readthedocs/config.md +++ b/docs/readthedocs/config.md @@ -274,4 +274,4 @@ Minimum Voltage Limit in p.u.: Maximum Voltage Limit in p.u.: -`vMax = 1.02` \ No newline at end of file +`vMax = 1.02` From 163a3b046c95fe5e1eecf9d9b916d600756ee6c4 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 20 Feb 2024 10:54:20 +0100 Subject: [PATCH 252/305] Refactorings and fixes --- .../edu/ie3/simona/api/ExtSimAdapter.scala | 10 +- .../edu/ie3/simona/event/ResultEvent.scala | 4 +- .../edu/ie3/simona/event/RuntimeEvent.scala | 4 +- .../event/listener/ResultEventListener.scala | 50 +++-- .../event/listener/RuntimeEventListener.scala | 21 +- .../ie3/simona/main/RunSimonaStandalone.scala | 3 +- .../ie3/simona/scheduler/TimeAdvancer.scala | 13 +- .../scala/edu/ie3/simona/sim/SimMessage.scala | 24 --- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 112 ++++++---- .../ie3/simona/sim/setup/SimonaSetup.scala | 12 +- .../sim/setup/SimonaStandaloneSetup.scala | 13 +- .../ie3/simona/api/ExtSimAdapterSpec.scala | 4 +- .../simona/scheduler/TimeAdvancerSpec.scala | 68 +++--- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 203 +++++++++++------- .../simona/sim/setup/SimonaSetupSpec.scala | 16 +- 15 files changed, 308 insertions(+), 249 deletions(-) delete mode 100644 src/main/scala/edu/ie3/simona/sim/SimMessage.scala diff --git a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala index e9a4f8ae9f..b71adf4a30 100644 --- a/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala +++ b/src/main/scala/edu/ie3/simona/api/ExtSimAdapter.scala @@ -8,11 +8,7 @@ package edu.ie3.simona.api import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps import org.apache.pekko.actor.{Actor, ActorRef, PoisonPill, Props} -import edu.ie3.simona.api.ExtSimAdapter.{ - Create, - ExtSimAdapterStateData, - StopMessage, -} +import edu.ie3.simona.api.ExtSimAdapter.{Create, ExtSimAdapterStateData, Stop} import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.api.simulation.ontology.{ @@ -49,7 +45,7 @@ object ExtSimAdapter { */ final case class Create(extSimData: ExtSimAdapterData, unlockKey: ScheduleKey) - final case class StopMessage(simulationSuccessful: Boolean) + final case class Stop(simulationSuccessful: Boolean) final case class ExtSimAdapterStateData( extSimData: ExtSimAdapterData, @@ -113,7 +109,7 @@ final case class ExtSimAdapter(scheduler: ActorRef) key, ) - case StopMessage(simulationSuccessful) => + case Stop(simulationSuccessful) => // let external sim know that we have terminated stateData.extSimData.queueExtMsg( new TerminationMessage(simulationSuccessful) diff --git a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala index 6c3b55b8af..785bfc8510 100644 --- a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala @@ -18,9 +18,9 @@ import edu.ie3.datamodel.models.result.system.{ } import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.ResultEventListener -sealed trait ResultEvent extends ResultMessage +sealed trait ResultEvent extends Event with ResultEventListener.Incoming /** Calculation result events */ diff --git a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala index c7e793a9a2..9ecea2aef8 100644 --- a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala @@ -6,8 +6,10 @@ package edu.ie3.simona.event +import edu.ie3.simona.event.listener.RuntimeEventListener.Incoming + /** Event type for simulation control */ -sealed trait RuntimeEvent extends Event +sealed trait RuntimeEvent extends Event with Incoming object RuntimeEvent { diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index 6fd4a4b0cd..148d2acf35 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -11,7 +11,6 @@ import org.apache.pekko.actor.typed.{Behavior, PostStop} import edu.ie3.datamodel.io.processor.result.ResultEntityProcessor import edu.ie3.datamodel.models.result.{NodeResult, ResultEntity} import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult -import edu.ie3.simona.event.Event import edu.ie3.simona.event.ResultEvent.{ FlexOptionsResultEvent, ParticipantResultEvent, @@ -33,17 +32,17 @@ import scala.util.{Failure, Success, Try} object ResultEventListener extends Transformer3wResultSupport { - trait ResultMessage extends Event + trait Incoming private final case class SinkResponse( response: Map[Class[_], ResultEntitySink] - ) extends ResultMessage + ) extends Incoming - private final case class Failed(ex: Exception) extends ResultMessage + private final case class InitFailed(ex: Exception) extends Incoming - final case object FlushAndStop extends ResultMessage + final case object FlushAndStop extends Incoming - private final case object StopTimeout extends ResultMessage + private final case object StopTimeout extends Incoming /** [[ResultEventListener]] base data containing all information the listener * needs @@ -235,7 +234,7 @@ object ResultEventListener extends Transformer3wResultSupport { def apply( resultFileHierarchy: ResultFileHierarchy - ): Behavior[ResultMessage] = Behaviors.setup[ResultMessage] { ctx => + ): Behavior[Incoming] = Behaviors.setup[Incoming] { ctx => ctx.log.debug("Starting initialization!") resultFileHierarchy.resultSinkType match { case _: ResultSinkType.Kafka => @@ -254,33 +253,32 @@ object ResultEventListener extends Transformer3wResultSupport { ResultEventListener.initializeSinks(resultFileHierarchy) ) ) { - case Failure(exception: Exception) => Failed(exception) + case Failure(exception: Exception) => InitFailed(exception) case Success(result) => SinkResponse(result.toMap) } init() } - private def init(): Behavior[ResultMessage] = Behaviors.withStash(200) { - buffer => - Behaviors.receive[ResultMessage] { - case (ctx, SinkResponse(response)) => - ctx.log.debug("Initialization complete!") - buffer.unstashAll(idle(BaseData(response))) - - case (ctx, Failed(ex)) => - ctx.log.error("Unable to setup ResultEventListener.", ex) - Behaviors.stopped - - case (_, msg) => - // stash all messages - buffer.stash(msg) - Behaviors.same - } + private def init(): Behavior[Incoming] = Behaviors.withStash(200) { buffer => + Behaviors.receive[Incoming] { + case (ctx, SinkResponse(response)) => + ctx.log.debug("Initialization complete!") + buffer.unstashAll(idle(BaseData(response))) + + case (ctx, InitFailed(ex)) => + ctx.log.error("Unable to setup ResultEventListener.", ex) + Behaviors.stopped + + case (_, msg) => + // stash all messages + buffer.stash(msg) + Behaviors.same + } } - private def idle(baseData: BaseData): Behavior[ResultMessage] = Behaviors - .receive[ResultMessage] { + private def idle(baseData: BaseData): Behavior[Incoming] = Behaviors + .receive[Incoming] { case (ctx, ParticipantResultEvent(participantResult)) => val updatedBaseData = handleResult(participantResult, baseData, ctx.log) idle(updatedBaseData) diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index 28a0a40077..53fd8f8a04 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -28,6 +28,15 @@ import java.util.concurrent.BlockingQueue */ object RuntimeEventListener { + trait Incoming + + /** Message indicating that [[RuntimeEventListener]] should stop. Instead of + * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop()]], this + * way of stopping allows all messages that have been queued before to be + * processed. + */ + case object Stop extends Incoming + /** Creates a runtime event listener behavior with given configuration. * * @param listenerConf @@ -43,7 +52,7 @@ object RuntimeEventListener { listenerConf: SimonaConfig.Simona.Runtime.Listener, queue: Option[BlockingQueue[RuntimeEvent]], startDateTimeString: String, - ): Behavior[RuntimeEvent] = Behaviors.setup { ctx => + ): Behavior[Incoming] = Behaviors.setup { ctx => val listeners = Iterable( Some( RuntimeEventLogSink( @@ -67,14 +76,14 @@ object RuntimeEventListener { listeners: Iterable[RuntimeEventSink], eventsToProcess: Option[List[String]] = None, runtimeStats: RuntimeStats = RuntimeStats(), - ): Behavior[RuntimeEvent] = Behaviors - .receive[RuntimeEvent] { + ): Behavior[Incoming] = Behaviors + .receive[Incoming] { case (_, PowerFlowFailed) => val updatedRuntimeData = runtimeStats .copy(failedPowerFlows = runtimeStats.failedPowerFlows + 1) RuntimeEventListener(listeners, eventsToProcess, updatedRuntimeData) - case (ctx, event) => + case (ctx, event: RuntimeEvent) => val process = eventsToProcess.forall(_.contains(event.id)) if (process) @@ -85,6 +94,10 @@ object RuntimeEventListener { event.id, ) Behaviors.same + + case (ctx, Stop) => + ctx.log.debug("") + Behaviors.stopped } .receiveSignal { case (_, PostStop) => listeners.foreach(_.close()) diff --git a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala index bd9e1d3766..d0a50802b8 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimonaStandalone.scala @@ -8,7 +8,6 @@ package edu.ie3.simona.main import edu.ie3.simona.config.{ArgsParser, ConfigFailFast, SimonaConfig} import edu.ie3.simona.main.RunSimona._ -import edu.ie3.simona.sim.SimMessage.StartSimulation import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import org.apache.pekko.actor.typed.scaladsl.AskPattern._ @@ -51,7 +50,7 @@ object RunSimonaStandalone extends RunSimona[SimonaStandaloneSetup] { implicit val scheduler: Scheduler = simonaSim.scheduler // run the simulation - val terminated = simonaSim.ask[SimonaEnded](ref => StartSimulation(ref)) + val terminated = simonaSim.ask[SimonaEnded](ref => SimonaSim.Start(ref)) Await.result(terminated, timeout.duration) match { case SimonaEnded(successful) => diff --git a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala index 200b61f1da..a12cbecfd1 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala @@ -13,8 +13,7 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.sim.SimMessage -import edu.ie3.simona.sim.SimMessage.SimulationEnded +import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior} @@ -32,7 +31,7 @@ object TimeAdvancer { * Last tick that can be activated or completed before the simulation is * paused */ - final case class StartSimMessage( + final case class Start( pauseTick: Option[Long] = None ) extends Incoming @@ -46,7 +45,7 @@ object TimeAdvancer { * last tick of the simulation */ def apply( - simulation: ActorRef[SimMessage], + simulation: ActorRef[SimonaSim.SimulationEnded.type], eventListener: Option[ActorRef[RuntimeEvent]], checkWindow: Option[Int], endTick: Long, @@ -78,7 +77,7 @@ object TimeAdvancer { startingTick: Long, nextActiveTick: Long, ): Behavior[Incoming] = Behaviors.receivePartial { - case (_, StartSimMessage(pauseTick)) => + case (_, Start(pauseTick)) => val updatedNotifier = notifier.map { _.starting( startingTick, @@ -181,7 +180,7 @@ object TimeAdvancer { data: TimeAdvancerData, notifier: Option[RuntimeNotifier], ): Behavior[Incoming] = { - data.simulation ! SimulationEnded + data.simulation ! SimonaSim.SimulationEnded notifier.foreach { // we do not want a check window message for the endTick @@ -223,7 +222,7 @@ object TimeAdvancer { * the last tick of the simulation */ private final case class TimeAdvancerData( - simulation: ActorRef[SimMessage], + simulation: ActorRef[SimonaSim.SimulationEnded.type], schedulee: ActorRef[Activation], endTick: Long, ) diff --git a/src/main/scala/edu/ie3/simona/sim/SimMessage.scala b/src/main/scala/edu/ie3/simona/sim/SimMessage.scala deleted file mode 100644 index bd7ba7fd9c..0000000000 --- a/src/main/scala/edu/ie3/simona/sim/SimMessage.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* - * © 2023. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.sim - -import edu.ie3.simona.main.RunSimona.SimonaEnded -import org.apache.pekko.actor.typed.ActorRef - -sealed trait SimMessage - -object SimMessage { - - /** Starts simulation by activating the next (or first) tick */ - final case class StartSimulation( - starter: ActorRef[SimonaEnded] - ) extends SimMessage - - /** Indicate that the simulation has ended successfully */ - case object SimulationEnded extends SimMessage - -} diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 75a3e6fa6c..410b9c1a9f 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -9,11 +9,9 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.event.listener.ResultEventListener -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.sim.SimMessage.{SimulationEnded, StartSimulation} import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import org.apache.pekko.actor.typed.scaladsl.adapter._ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} @@ -37,13 +35,22 @@ import scala.language.postfixOps */ object SimonaSim { - def apply(simonaSetup: SimonaSetup): Behavior[SimMessage] = - Behaviors.receivePartial { - case (ctx, startMsg @ StartSimulation(starter)) => - // We redirect to initializing behavior so that starter ref - // is available in case of a sudden termination of this actor - ctx.self ! startMsg - initializing(simonaSetup, starter) + sealed trait Incoming + + /** Starts simulation by activating the next (or first) tick */ + final case class Start( + starter: ActorRef[SimonaEnded] + ) extends Incoming + + /** Indicate that the simulation has ended successfully */ + case object SimulationEnded extends Incoming + + def apply(simonaSetup: SimonaSetup): Behavior[Incoming] = + Behaviors.receivePartial { case (ctx, startMsg @ Start(starter)) => + // We redirect to initializing behavior so that starter ref + // is available in case of a sudden termination of this actor + ctx.self ! startMsg + initializing(simonaSetup, starter) } /** Initializing behavior that is separated from [[apply]] above only because @@ -56,11 +63,11 @@ object SimonaSim { private def initializing( simonaSetup: SimonaSetup, starter: ActorRef[SimonaEnded], - ): Behavior[SimMessage] = + ): Behavior[Incoming] = Behaviors - .receivePartial[SimMessage] { case (ctx, StartSimulation(_)) => + .receivePartial[Incoming] { case (ctx, Start(_)) => val resultEventListeners = - simonaSetup.systemParticipantsListener(ctx) + simonaSetup.resultEventListener(ctx) val runtimeEventListener = simonaSetup.runtimeEventListener(ctx) @@ -105,10 +112,9 @@ object SimonaSim { gridAgents.foreach(ref => ctx.watch(ref.toTyped)) // Start simulation - timeAdvancer ! TimeAdvancer.StartSimMessage() + timeAdvancer ! TimeAdvancer.Start() val watchedActors = Iterable( - runtimeEventListener, timeAdvancer, scheduler, primaryServiceProxy.toTyped, @@ -118,9 +124,9 @@ object SimonaSim { idle( ActorData( starter, - runtimeEventListener, watchedActors, extSimulationData.extSimAdapters, + runtimeEventListener, resultEventListeners, ) ) @@ -134,10 +140,10 @@ object SimonaSim { Behaviors.stopped } - private def idle(actorData: ActorData): Behavior[SimMessage] = Behaviors - .receivePartial[SimMessage] { case (ctx, SimulationEnded) => + private def idle(actorData: ActorData): Behavior[Incoming] = Behaviors + .receivePartial[Incoming] { case (ctx, SimulationEnded) => // stop all children and wait for result listeners - stopActors(ctx, actorData, simulationSuccessful = true) + stop(ctx, actorData, simulationSuccessful = true) } .receiveSignal { case (ctx, Terminated(actor)) => ctx.log.error( @@ -147,25 +153,14 @@ object SimonaSim { ) // stop all children and end - stopActors(ctx, actorData, simulationSuccessful = false) + stop(ctx, actorData, simulationSuccessful = false) } - private def stopActors( + private def stop( ctx: ActorContext[_], actorData: ActorData, simulationSuccessful: Boolean, - ): Behavior[SimMessage] = { - - actorData.watchedActors.foreach { ref => - ctx.unwatch(ref) - ctx.stop(ref) - } - - actorData.extSimAdapters.foreach { ref => - ctx.unwatch(ref) - ref ! ExtSimAdapter.StopMessage(simulationSuccessful) - } - + ): Behavior[Incoming] = if (simulationSuccessful) { // if the simulation is successful, we're waiting for the result listeners // to terminate and thus do not unwatch them here @@ -175,6 +170,8 @@ object SimonaSim { actorData.resultListener.foreach(_ ! ResultEventListener.FlushAndStop) + stopChildren(ctx, actorData, simulationSuccessful) + waitingForListener( actorData.starter, remainingListeners = actorData.resultListener.toSeq, @@ -184,13 +181,6 @@ object SimonaSim { "An error occurred during the simulation. See stacktrace for details." ) - // if an error happened, we do not care for all results to be flushed out - // and just end everything right away - actorData.resultListener.foreach { ref => - ctx.unwatch(ref) - ctx.stop(ref) - } - // also notify RuntimeEventListener that error happened actorData.runtimeEventListener ! RuntimeEvent.Error( "Simulation stopped with error." @@ -198,14 +188,45 @@ object SimonaSim { actorData.starter ! SimonaEnded(successful = false) + stopChildren(ctx, actorData, simulationSuccessful) + Behaviors.stopped } + + private def stopChildren( + ctx: ActorContext[_], + actorData: ActorData, + simulationSuccessful: Boolean, + ): Unit = { + actorData.watchedActors.foreach { ref => + ctx.unwatch(ref) + ctx.stop(ref) + } + + actorData.extSimAdapters.foreach { ref => + ctx.unwatch(ref) + ref ! ExtSimAdapter.Stop(simulationSuccessful) + } + + if (!simulationSuccessful) + // if an error happened, we do not care for all results to be flushed out + // and just end ResultEventListeners right away + actorData.resultListener.foreach { ref => + ctx.unwatch(ref) + ctx.stop(ref) + } + + ctx.unwatch(actorData.runtimeEventListener) + // we stop RuntimeEventListener by message so that RuntimeEvents + // (Error in particular) in queue can still be processed before + actorData.runtimeEventListener ! RuntimeEventListener.Stop + } private def waitingForListener( starter: ActorRef[SimonaEnded], remainingListeners: Seq[ActorRef[_]], - ): Behavior[SimMessage] = Behaviors.receiveSignal[SimMessage] { + ): Behavior[Incoming] = Behaviors.receiveSignal[Incoming] { case (ctx, Terminated(actor)) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) @@ -214,7 +235,6 @@ object SimonaSim { "All result listeners have terminated. Ending simulation successfully." ) - // inform InitSim Sender starter ! SimonaEnded(successful = true) Behaviors.stopped @@ -229,17 +249,17 @@ object SimonaSim { /** TODO scaladoc * @param starter - * @param runtimeEventListener * @param watchedActors - * excluding ExtSimAdapters and ResultListeners + * excluding ExtSimAdapters, ResultListeners, RuntimeEventListener * @param extSimAdapters + * @param runtimeEventListener * @param resultListener */ private final case class ActorData( starter: ActorRef[SimonaEnded], - runtimeEventListener: ActorRef[RuntimeEvent], watchedActors: Iterable[ActorRef[_]], extSimAdapters: Iterable[ClassicRef], - resultListener: Iterable[ActorRef[ResultMessage]], + runtimeEventListener: ActorRef[RuntimeEventListener.Incoming], + resultListener: Iterable[ActorRef[ResultEventListener.Incoming]], ) } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index f0504948df..fcb6f2510d 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -9,11 +9,11 @@ package edu.ie3.simona.sim.setup import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.sim.SimMessage +import edu.ie3.simona.sim.SimonaSim import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.typed.scaladsl.ActorContext import org.apache.pekko.actor.{ActorRef => ClassicRef} @@ -44,7 +44,7 @@ trait SimonaSetup { */ def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEvent] + ): ActorRef[RuntimeEventListener.Incoming] /** Creates a sequence of system participant event listeners * @@ -53,9 +53,9 @@ trait SimonaSetup { * @return * A sequence of actor references to runtime event listeners */ - def systemParticipantsListener( + def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultMessage]] + ): Seq[ActorRef[ResultEventListener.Incoming]] /** Creates a primary service proxy. The proxy is the first instance to ask * for primary data. If necessary, it delegates the registration request to @@ -115,7 +115,7 @@ trait SimonaSetup { */ def timeAdvancer( context: ActorContext[_], - simulation: ActorRef[SimMessage], + simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], ): ActorRef[TimeAdvancer.Incoming] diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index 1d5d0d5ff2..b1c9e45e9f 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -19,7 +19,6 @@ import edu.ie3.simona.api.data.ExtData import edu.ie3.simona.api.data.ev.{ExtEvData, ExtEvSimulation} import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.config.{ArgsParser, RefSystemParser, SimonaConfig} -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.exceptions.agent.GridAgentInitializationException @@ -34,7 +33,7 @@ import edu.ie3.simona.service.primary.PrimaryServiceProxy import edu.ie3.simona.service.primary.PrimaryServiceProxy.InitPrimaryServiceProxyStateData import edu.ie3.simona.service.weather.WeatherService import edu.ie3.simona.service.weather.WeatherService.InitWeatherServiceStateData -import edu.ie3.simona.sim.SimMessage +import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.simona.util.TickUtil.RichZonedDateTime @@ -43,8 +42,8 @@ import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.typed.scaladsl.ActorContext import org.apache.pekko.actor.typed.scaladsl.adapter._ import org.apache.pekko.actor.{ - ActorRef => ClassicRef, ActorContext => ClassicContext, + ActorRef => ClassicRef, } import java.util.concurrent.LinkedBlockingQueue @@ -249,7 +248,7 @@ class SimonaStandaloneSetup( override def timeAdvancer( context: ActorContext[_], - simulation: ActorRef[SimMessage], + simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], ): ActorRef[TimeAdvancer.Incoming] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( @@ -282,7 +281,7 @@ class SimonaStandaloneSetup( override def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEvent] = + ): ActorRef[RuntimeEventListener.Incoming] = context .spawn( RuntimeEventListener( @@ -293,9 +292,9 @@ class SimonaStandaloneSetup( RuntimeEventListener.getClass.getSimpleName, ) - override def systemParticipantsListener( + override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultMessage]] = { + ): Seq[ActorRef[ResultEventListener.Incoming]] = { // append ResultEventListener as well to write raw output files ArgsParser .parseListenerConfigOption(simonaConfig.simona.event.listener) diff --git a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala index 49a7353124..0a4dab2d51 100644 --- a/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala +++ b/src/test/scala/edu/ie3/simona/api/ExtSimAdapterSpec.scala @@ -7,7 +7,7 @@ package edu.ie3.simona.api import com.typesafe.config.ConfigFactory -import edu.ie3.simona.api.ExtSimAdapter.StopMessage +import edu.ie3.simona.api.ExtSimAdapter.Stop import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.api.simulation.ontology.{ @@ -165,7 +165,7 @@ class ExtSimAdapterSpec val stopWatcher = TestProbe() stopWatcher.watch(extSimAdapter) - extSimAdapter ! StopMessage(simSuccessful) + extSimAdapter ! Stop(simSuccessful) awaitCond( !extData.receiveMessageQueue.isEmpty, diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index 4d48501d7a..638cc54731 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -13,8 +13,8 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage -import edu.ie3.simona.sim.SimMessage +import edu.ie3.simona.scheduler.TimeAdvancer.Start +import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import org.apache.pekko.actor.testkit.typed.scaladsl.{ ScalaTestWithActorTestKit, @@ -38,7 +38,7 @@ class TimeAdvancerSpec "The TimeAdvancer should work correctly" when { "started checkWindow but without pauseTick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -57,7 +57,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick -1 is activated scheduler.expectMessage(Activation(INIT_SIM_TICK)) @@ -132,11 +132,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "started without checkWindow and pauseTick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -150,7 +150,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick -1 is activated scheduler.expectMessage(Activation(INIT_SIM_TICK)) @@ -184,11 +184,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "paused and started after initialization" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -207,7 +207,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage(Some(INIT_SIM_TICK)) + timeAdvancer ! Start(Some(INIT_SIM_TICK)) // tick -1 is activated scheduler.expectMessage(Activation(INIT_SIM_TICK)) @@ -226,7 +226,7 @@ class TimeAdvancerSpec listener.expectNoMessage() // start again - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick 3600 is activated scheduler.expectMessage(Activation(3600)) @@ -258,11 +258,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "paused and started and there is a gap between StartSchedule tick and next activation tick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -280,7 +280,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage(Some(3600)) + timeAdvancer ! Start(Some(3600)) // tick -1 is activated scheduler.expectMessage(Activation(INIT_SIM_TICK)) @@ -326,7 +326,7 @@ class TimeAdvancerSpec listener.expectNoMessage() // start again - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick 5400 is activated scheduler.expectMessage(Activation(5400)) @@ -346,11 +346,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "paused and endTick - pauseScheduleAtTick == 1" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -368,7 +368,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage(Some(3599)) + timeAdvancer ! Start(Some(3599)) // tick -1 is activated scheduler.expectMessage(Activation(INIT_SIM_TICK)) @@ -409,7 +409,7 @@ class TimeAdvancerSpec listener.expectNoMessage() // start again - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick 3600 is activated scheduler.expectMessage(Activation(3600)) @@ -424,11 +424,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "activation has been scheduled after endTick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -446,7 +446,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick 0 is activated scheduler.expectMessage(Activation(0)) @@ -474,11 +474,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "no next trigger has been supplied" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -496,7 +496,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage() + timeAdvancer ! Start() // tick 0 is activated scheduler.expectMessage(Activation(0)) @@ -534,11 +534,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "endTick < pauseScheduleAtTick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -556,7 +556,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage(Some(7200)) + timeAdvancer ! Start(Some(7200)) // tick 0 is activated scheduler.expectMessage(Activation(0)) @@ -584,11 +584,11 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } "endTick == pauseScheduleAtTick" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -606,7 +606,7 @@ class TimeAdvancerSpec scheduler.expectNoMessage() // start simulation - timeAdvancer ! StartSimMessage(Some(1800)) + timeAdvancer ! Start(Some(1800)) // tick 0 is activated scheduler.expectMessage(Activation(0)) @@ -634,14 +634,14 @@ class TimeAdvancerSpec errorInSim shouldBe false } - simulation.expectMessage(SimMessage.SimulationEnded) + simulation.expectMessage(SimonaSim.SimulationEnded) } } "The TimeAdvancer should fail and stop" when { "wrong next tick has been supplied" in { - val simulation = TestProbe[SimMessage]("simulation") + val simulation = TestProbe[SimonaSim.Incoming]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -656,7 +656,7 @@ class TimeAdvancerSpec timeAdvancer ! ScheduleActivation(scheduler.ref, 0) // start simulation - timeAdvancer ! StartSimMessage(Some(1800)) + timeAdvancer ! Start(Some(1800)) // tick 0 is activated scheduler.expectMessage(Activation(0)) diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index 6882767300..0da41463b5 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -7,21 +7,17 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.ontology.messages.SchedulerMessage +import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.scheduler.TimeAdvancer.StartSimMessage -import edu.ie3.simona.sim.SimMessage.StartSimulation -import edu.ie3.simona.sim.SimonaSimSpec.{ - MockSetup, - stopOnMessage, - throwOnMessage, -} +import edu.ie3.simona.sim.SimonaSimSpec._ import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import edu.ie3.simona.test.common.UnitSpec import org.apache.pekko.actor.testkit.typed.scaladsl.{ + LogCapturing, ScalaTestWithActorTestKit, TestProbe, } @@ -30,42 +26,65 @@ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior} import org.apache.pekko.actor.{ActorRef => ClassicRef} -class SimonaSimSpec extends ScalaTestWithActorTestKit with UnitSpec { +import java.util.UUID + +class SimonaSimSpec + extends ScalaTestWithActorTestKit + with UnitSpec + with LogCapturing { "SimonaSim" should { + + "stop and indicate success to starter" when { + + "receiving SimulationEnded(successful = true) from TimeAdvancer" in {} + + } + "stop and indicate failure to starter" when { + "receiving SimulationEnded(successful = false) from TimeAdvancer" in {} + "child stops due to thrown exception" in { val starter = TestProbe[SimonaEnded]("starter") val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + val runtimeListener = + TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") val receiveThrowingActor = - TestProbe[ActorRef[RuntimeEvent]]("receiveThrowingActor") + TestProbe[ActorRef[SchedulerMessage]]("receiveThrowingActor") val simonaSim = spawn( SimonaSim( - new MockSetup(timeAdvancer.ref) { - override def runtimeEventListener( - context: ActorContext[_] - ): ActorRef[RuntimeEvent] = { - // has to be created by correct context - val throwingActor = - context.spawn[RuntimeEvent](throwOnMessage, "throwingActor") + new MockSetup(Some(runtimeListener.ref), Some(timeAdvancer.ref)) { + + override def scheduler( + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Incoming], + ): ActorRef[SchedulerMessage] = { + // we cannot return a testprobe ref here, + // needs to be a proper actor created by context + val throwingActor = context + .spawn[SchedulerMessage]( + throwOnMessage, + uniqueName("throwingActor"), + ) // send ref to the outside receiveThrowingActor.ref ! throwingActor throwingActor } + } ), - "simonaSim", + uniqueName("simonaSim"), ) - simonaSim ! StartSimulation(starter.ref) + simonaSim ! SimonaSim.Start(starter.ref) // Initialization has started, mock actors are being created - val failActor = - receiveThrowingActor.expectMessageType[ActorRef[RuntimeEvent]] - timeAdvancer.expectMessage(StartSimMessage()) + val throwingActor = + receiveThrowingActor.expectMessageType[ActorRef[SchedulerMessage]] + timeAdvancer.expectMessage(TimeAdvancer.Start()) // Simulation should still "run" at this point starter.expectNoMessage() @@ -73,43 +92,58 @@ class SimonaSimSpec extends ScalaTestWithActorTestKit with UnitSpec { // We cause an actor to fail. // (The actor reacts to any message with an exception, // we just pick the first best fit) - failActor ! RuntimeEvent.Initializing + throwingActor ! Completion(TestProbe().ref) + + runtimeListener.expectMessage( + RuntimeEvent.Error("Simulation stopped with error.") + ) + runtimeListener.expectMessage(RuntimeEventListener.Stop) // SimonaSim should run its failure routine and tell us that a failure happened starter.expectMessage(SimonaEnded(successful = false)) + starter.expectTerminated(simonaSim) } "child stops by changing behavior" in { val starter = TestProbe[SimonaEnded]("starter") val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + val runtimeListener = + TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") val receiveStoppingActor = - TestProbe[ActorRef[RuntimeEvent]]("receiveStoppingActor") + TestProbe[ActorRef[SchedulerMessage]]("receiveStoppingActor") val simonaSim = spawn( SimonaSim( - new MockSetup(timeAdvancer.ref) { - override def runtimeEventListener( - context: ActorContext[_] - ): ActorRef[RuntimeEvent] = { - // has to be created by correct context + new MockSetup(Some(runtimeListener.ref), Some(timeAdvancer.ref)) { + + override def scheduler( + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Incoming], + ): ActorRef[SchedulerMessage] = { + // we cannot return a testprobe ref here, + // needs to be a proper actor created by context val stoppingActor = - context.spawn[RuntimeEvent](stopOnMessage, "stoppingActor") + context.spawn[SchedulerMessage]( + stopOnMessage, + uniqueName("stoppingActor"), + ) // send ref to the outside receiveStoppingActor.ref ! stoppingActor stoppingActor } + } ), - "simonaSim", + uniqueName("simonaSim"), ) - simonaSim ! StartSimulation(starter.ref) + simonaSim ! SimonaSim.Start(starter.ref) // Initialization has started, mock actors are being created val stoppingActor = - receiveStoppingActor.expectMessageType[ActorRef[RuntimeEvent]] - timeAdvancer.expectMessage(StartSimMessage()) + receiveStoppingActor.expectMessageType[ActorRef[SchedulerMessage]] + timeAdvancer.expectMessage(TimeAdvancer.Start()) // Simulation should still "run" at this point starter.expectNoMessage() @@ -117,48 +151,50 @@ class SimonaSimSpec extends ScalaTestWithActorTestKit with UnitSpec { // We cause an actor to fail. // (The actor reacts to any message by stopping itself, // we just pick the first best fit) - stoppingActor ! RuntimeEvent.Initializing + stoppingActor ! Completion(TestProbe().ref) + + runtimeListener.expectMessage( + RuntimeEvent.Error("Simulation stopped with error.") + ) + runtimeListener.expectMessage(RuntimeEventListener.Stop) // SimonaSim should run its failure routine and tell us that a failure happened starter.expectMessage(SimonaEnded(successful = false)) + starter.expectTerminated(simonaSim) } - } - "exception is thrown while initializing" in { - val starter = TestProbe[SimonaEnded]("starter") - - val simonaSim = spawn( - SimonaSim( - new MockSetup(TestProbe().ref) { - override def timeAdvancer( - context: ActorContext[_], - simulation: ActorRef[SimMessage], - runtimeEventListener: ActorRef[RuntimeEvent], - ): ActorRef[TimeAdvancer.Incoming] = { - throw new RuntimeException("Test exception") + "exception is thrown while initializing" in { + val starter = TestProbe[SimonaEnded]("starter") + + val simonaSim = spawn( + SimonaSim( + new MockSetup() { + + override def resultEventListener( + context: ActorContext[_] + ): Seq[ActorRef[ResultEventListener.Incoming]] = + throwTestException() } - } - ), - "simonaSim", - ) + ), + uniqueName("simonaSim"), + ) - // Initialization should not have started yet - starter.expectNoMessage() + // Initialization should not have started yet + starter.expectNoMessage() - simonaSim ! StartSimulation(starter.ref) + simonaSim ! SimonaSim.Start(starter.ref) - // SimonaSim should run its failure routine and tell us that a failure happened - starter.expectMessage(SimonaEnded(successful = false)) + // SimonaSim should run its failure routine and tell us that a failure happened + starter.expectMessage(SimonaEnded(successful = false)) + starter.expectTerminated(simonaSim) + } } + } // TODO: - // SimulationEnded(successful = true) - // -> also test that all actors that were started also are stopped - // SimulationEnded(successful = false) // REL fails in edge cases - // generally: test that Error is sent to RuntimeEventListener } object SimonaSimSpec { @@ -167,56 +203,75 @@ object SimonaSimSpec { Behaviors.same } - def forwardMessage[T](recipient: ActorRef[T]): Behavior[T] = + def forwardMessage[T](recipient: Option[ActorRef[T]]): Behavior[T] = Behaviors.receiveMessage { msg => - recipient ! msg + recipient.foreach(_ ! msg) Behaviors.same } def throwOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => - throw new RuntimeException("Nah, I'm not gonna do that!") + throwTestException() } def stopOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => Behaviors.stopped } - class MockSetup(timeAdvancer: ActorRef[TimeAdvancer.Incoming]) - extends SimonaSetup { + def throwTestException[T](): T = throw new RuntimeException( + "This is an exception for test purposes. It is expected to be thrown." + ) + + /** @param name + * @return + */ + def uniqueName(name: String): String = + s"${name}_${UUID.randomUUID()}" + + class MockSetup( + runtimeEventProbe: Option[ActorRef[RuntimeEventListener.Incoming]] = None, + timeAdvancerProbe: Option[ActorRef[TimeAdvancer.Incoming]] = None, + ) extends SimonaSetup { override val args: Array[String] = Array.empty[String] override def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEvent] = context.spawn(empty, "runtimeEvent") + ): ActorRef[RuntimeEventListener.Incoming] = context.spawn( + forwardMessage(runtimeEventProbe), + uniqueName("runtimeEventForwarder"), + ) - override def systemParticipantsListener( + override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultMessage]] = Seq.empty + ): Seq[ActorRef[ResultEventListener.Incoming]] = Seq.empty override def primaryServiceProxy( context: ActorContext[_], scheduler: ActorRef[SchedulerMessage], ): ClassicRef = - context.spawn(empty, "primaryService").toClassic + context.spawn(empty, uniqueName("primaryService")).toClassic override def weatherService( context: ActorContext[_], scheduler: ActorRef[SchedulerMessage], ): ClassicRef = - context.spawn(empty, "weatherService").toClassic + context.spawn(empty, uniqueName("weatherService")).toClassic override def timeAdvancer( context: ActorContext[_], - simulation: ActorRef[SimMessage], + simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], ): ActorRef[TimeAdvancer.Incoming] = - context.spawn(forwardMessage(timeAdvancer), "timeAdvancerForwarder") + context.spawn( + forwardMessage(timeAdvancerProbe), + uniqueName("timeAdvancerForwarder"), + ) override def scheduler( context: ActorContext[_], timeAdvancer: ActorRef[TimeAdvancer.Incoming], - ): ActorRef[SchedulerMessage] = context.spawn(empty, "scheduler") + ): ActorRef[SchedulerMessage] = + context.spawn(empty, uniqueName("scheduler")) override def gridAgents( context: ActorContext[_], diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 2ae9938ffd..bcfaad931f 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -13,10 +13,11 @@ import edu.ie3.datamodel.models.input.connector.{ } import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.event.listener.ResultEventListener +import edu.ie3.simona.event.listener.RuntimeEventListener import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.sim.SimMessage +import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.SubGridGateMokka import org.apache.pekko.actor.typed.scaladsl @@ -30,13 +31,14 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def runtimeEventListener( context: scaladsl.ActorContext[_] - ): typed.ActorRef[RuntimeEvent] = throw new NotImplementedException( - "This is a dummy setup" - ) + ): typed.ActorRef[RuntimeEventListener.Incoming] = // todo typed + throw new NotImplementedException( + "This is a dummy setup" + ) - override def systemParticipantsListener( + override def resultEventListener( context: scaladsl.ActorContext[_] - ): Seq[typed.ActorRef[ResultEventListener.ResultMessage]] = + ): Seq[typed.ActorRef[ResultEventListener.Incoming]] = throw new NotImplementedException("This is a dummy setup") override def primaryServiceProxy( @@ -58,7 +60,7 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def timeAdvancer( context: scaladsl.ActorContext[_], - simulation: typed.ActorRef[SimMessage], + simulation: typed.ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: typed.ActorRef[RuntimeEvent], ): typed.ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException( "This is a dummy setup" From 26073bd6545b08bc088f575c0859781693af90cc Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 20 Feb 2024 16:45:55 +0100 Subject: [PATCH 253/305] reintroduce nietzsche quote --- CHANGELOG.md | 1 + src/main/scala/edu/ie3/simona/main/RunSimona.scala | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6861eaa6..fbc38c17d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Energy Management capabilities: - Added capability of SystemParticipants to handle flexibility [#308](https://github.com/ie3-institute/simona/issues/308) - Added smart charging logic [#31](https://github.com/ie3-institute/simona/issues/31) and flex calculation in `EvcsAgent` [#332](https://github.com/ie3-institute/simona/issues/332) +- Enhance output quotes of `RunSimona` [#743](https://github.com/ie3-institute/simona/issues/743) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) diff --git a/src/main/scala/edu/ie3/simona/main/RunSimona.scala b/src/main/scala/edu/ie3/simona/main/RunSimona.scala index df011e6614..cca03dcb31 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimona.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimona.scala @@ -6,15 +6,14 @@ package edu.ie3.simona.main -import java.util.Locale - -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.pattern.gracefulStop -import org.apache.pekko.util.Timeout import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.sim.setup.SimonaSetup import edu.ie3.util.scala.quantities.QuantityUtil +import org.apache.pekko.actor.ActorRef +import org.apache.pekko.pattern.gracefulStop +import org.apache.pekko.util.Timeout +import java.util.Locale import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.util.Random @@ -69,6 +68,7 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging { "\"Lebe lang und erfolgreich.\" - Gruppe von Vulkanier (in Star Trek: Der erste Kontakt)", "\"Ich bin der Anfang, das Ende, die Eine, die Viele ist. Ich bin die Borg.\" - Borg-Königin (in Star Trek: Der erste Kontakt)", "\"A horse! A horse! My kingdom for a horse!\" - King Richard III (in Shakespeare's Richard III, 1594)", + "\"Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein\" - F. Nietzsche", ) val rand = new Random From ecef9c4f60577c137d8082b45d0236efcb91f63b Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 09:01:06 +0100 Subject: [PATCH 254/305] move GridControls in own method --- .../simona/model/control/GridControls.scala | 25 +++++++++++++++++++ .../edu/ie3/simona/model/grid/GridModel.scala | 16 +----------- 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/model/control/GridControls.scala diff --git a/src/main/scala/edu/ie3/simona/model/control/GridControls.scala b/src/main/scala/edu/ie3/simona/model/control/GridControls.scala new file mode 100644 index 0000000000..2afa0f283d --- /dev/null +++ b/src/main/scala/edu/ie3/simona/model/control/GridControls.scala @@ -0,0 +1,25 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.model.control + +/** Collection of grid-related control strategies + * + * @param transformerControlGroups + * Transformer control groups + */ +final case class GridControls( + transformerControlGroups: Set[TransformerControlGroupModel] +) + +object GridControls { + + /** Represents an empty GridControls group + */ + def emptyGridControls: GridControls = GridControls( + Set.empty[TransformerControlGroupModel] + ) +} diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 48a51e400c..531060b842 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -20,6 +20,7 @@ import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.control.TransformerControlGroupModel import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} +import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, @@ -95,21 +96,6 @@ object GridModel { switches: Set[SwitchModel], ) - /** Collection of grid-related control strategies - * - * @param transformerControlGroups - * Transformer control groups - */ - final case class GridControls( - transformerControlGroups: Set[TransformerControlGroupModel] - ) - - /** Represents an empty Transformer control group - */ - def emptyGridControls: GridControls = GridControls( - Set.empty[TransformerControlGroupModel] - ) - /** Checks the availability of node calculation models, that are connected by * the given [[ConnectorInput]]. If not both models can be found, * [[InvalidGridException]] s are thrown From 9b0259c4f0db988ddf48143c196df036e9c3c3ed Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 09:02:19 +0100 Subject: [PATCH 255/305] move transformer control groups into model method --- .../edu/ie3/simona/model/grid/GridModel.scala | 137 +----------------- 1 file changed, 2 insertions(+), 135 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 531060b842..69739a005c 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -9,18 +9,15 @@ package edu.ie3.simona.model.grid import breeze.linalg.DenseMatrix import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.model.SystemComponent -import edu.ie3.simona.model.control.TransformerControlGroupModel -import edu.ie3.simona.model.grid.GridModel.{GridComponents, GridControls} import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} +import edu.ie3.simona.model.grid.GridModel.GridComponents import edu.ie3.simona.model.grid.Transformer3wPowerFlowCase.{ PowerFlowCaseA, PowerFlowCaseB, @@ -30,7 +27,6 @@ import edu.ie3.simona.util.CollectionUtils import org.jgrapht.Graph import org.jgrapht.alg.connectivity.ConnectivityInspector import org.jgrapht.graph.{DefaultEdge, SimpleGraph} -import squants.{Dimensionless, Each} import java.time.ZonedDateTime import java.util.UUID @@ -627,7 +623,7 @@ object GridModel { val transformerControlGroups = maybeControlConfig .map { controlConfig => - buildControlGroups( + TransformerControlGroupModel.buildControlGroups( controlConfig.transformer, subGridContainer.getRawGrid.getMeasurementUnits, ) @@ -664,135 +660,6 @@ object GridModel { gridModel } - /** Build business models for control groups - * - * @param config - * List of configs for control groups - * @param measurementUnitInput - * Set of [[MeasurementUnitInput]] s - * @return - * A set of control group business models - */ - private def buildControlGroups( - config: List[SimonaConfig.TransformerControlGroup], - measurementUnitInput: java.util.Set[MeasurementUnitInput], - ): Set[TransformerControlGroupModel] = config.map { - case TransformerControlGroup(measurements, _, vMax, vMin) => - buildTransformerControlGroupModel( - measurementUnitInput, - measurements.toSet, - vMax, - vMin, - ) - }.toSet - - /** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param measurementUnitInput - * Collection of all known [[MeasurementUnitInput]] s - * @param measurementConfigs - * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] - * s does belong to this control group - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ - private def buildTransformerControlGroupModel( - measurementUnitInput: java.util.Set[MeasurementUnitInput], - measurementConfigs: Set[String], - vMax: Double, - vMin: Double, - ): TransformerControlGroupModel = { - val nodeUuids = - determineNodeUuids(measurementUnitInput, measurementConfigs) - buildTransformerControlModels(nodeUuids, vMax, vMin) - } - - /** Determine the uuids of the nodes to control - * - * @param measurementUnitInput - * Collection of all known [[MeasurementUnitInput]] s - * @param measurementConfigs - * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] - * s does belong to this control group - * @return - * A set of relevant nodal uuids - */ - private def determineNodeUuids( - measurementUnitInput: java.util.Set[MeasurementUnitInput], - measurementConfigs: Set[String], - ): Set[UUID] = Set.from( - measurementUnitInput.asScala - .filter(input => - measurementConfigs.contains(input.getUuid.toString) && input.getVMag - ) - .map(_.getNode.getUuid) - ) - - /** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param nodeUuids - * Collection of all relevant node uuids - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ - private def buildTransformerControlModels( - nodeUuids: Set[UUID], - vMax: Double, - vMin: Double, - ): TransformerControlGroupModel = { - /* Determine the voltage regulation criterion for each of the available nodes */ - val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { (complexVoltage: Complex) => - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => - Some(vMax - mag).map(Each(_)) - case mag if mag < vMin => - Some(vMin - mag).map(Each(_)) - case _ => None - } - } - }.toMap - - val harmonizationFunction = - (regulationRequests: Array[Dimensionless]) => { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) - val positiveRequests = regulationRequests.filter(_ > Each(0d)) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } - - } - - TransformerControlGroupModel( - nodeUuidToRegulationCriterion, - harmonizationFunction, - ) - } - /** Updates the internal state of the [[GridModel.nodeUuidToIndexMap]] to * account for changes on switches (open / close) It is highly recommended (= * mandatory) to call this method every time a node admittance matrix is From 0ecf22da799d38690d412de29b0857f4f8c51c0c Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 09:02:55 +0100 Subject: [PATCH 256/305] move transformer control groups into model method --- .../TransformerControlGroupModel.scala | 136 +++++++++++++++++- .../edu/ie3/simona/model/grid/GridSpec.scala | 13 +- 2 files changed, 140 insertions(+), 9 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index ada32e4fb0..dc37243d3c 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -7,12 +7,16 @@ package edu.ie3.simona.model.control import breeze.math.Complex +import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult +import edu.ie3.simona.config.SimonaConfig +import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.model.control.TransformerControlGroupModel.RegulationCriterion +import squants.{Dimensionless, Each} import java.util.UUID -import squants.Dimensionless +import scala.jdk.CollectionConverters._ /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, to what extent (here: @@ -69,4 +73,134 @@ final case class TransformerControlGroupModel( object TransformerControlGroupModel { type RegulationCriterion = Complex => Option[Dimensionless] + + /** Build business models for control groups + * + * @param config + * List of configs for control groups + * @param measurementUnitInput + * Set of [[MeasurementUnitInput]] s + * @return + * A set of control group business models + */ + def buildControlGroups( + config: List[SimonaConfig.TransformerControlGroup], + measurementUnitInput: java.util.Set[MeasurementUnitInput], + ): Set[TransformerControlGroupModel] = config.map { + case TransformerControlGroup(measurements, _, vMax, vMin) => + buildTransformerControlGroupModel( + measurementUnitInput, + measurements.toSet, + vMax, + vMin, + ) + }.toSet + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[TransformerControlGroupModel]] + */ + private def buildTransformerControlGroupModel( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: Set[String], + vMax: Double, + vMin: Double, + ): TransformerControlGroupModel = { + val nodeUuids = + determineNodeUuids(measurementUnitInput, measurementConfigs) + buildTransformerControlModels(nodeUuids, vMax, vMin) + } + + /** Determine the uuids of the nodes to control + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @return + * A set of relevant nodal uuids + */ + private def determineNodeUuids( + measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementConfigs: Set[String], + ): Set[UUID] = Set.from( + measurementUnitInput.asScala + .filter(input => + measurementConfigs.contains(input.getUuid.toString) && input.getVMag + ) + .map(_.getNode.getUuid) + ) + + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param nodeUuids + * Collection of all relevant node uuids + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[TransformerControlGroupModel]] + */ + private def buildTransformerControlModels( + nodeUuids: Set[UUID], + vMax: Double, + vMin: Double, + ): TransformerControlGroupModel = { + /* Determine the voltage regulation criterion for each of the available nodes */ + + val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => + uuid -> { (complexVoltage: Complex) => + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Each(_)) + case mag if mag < vMin => + Some(vMin - mag).map(Each(_)) + case _ => None + } + } + }.toMap + + val harmonizationFunction = + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) + + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None + } + + } + + TransformerControlGroupModel( + nodeUuidToRegulationCriterion, + harmonizationFunction, + ) + } } diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index be089f18f1..c874a19d00 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -16,12 +16,7 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.agent.grid.DBFSMockGridAgents import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.control.TransformerControlGroupModel -import edu.ie3.simona.model.grid.GridModel.{ - emptyGridControls, - GridComponents, - GridControls, -} +import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, @@ -33,9 +28,11 @@ import testutils.TestObjectFactory import edu.ie3.simona.test.common.model.grid.DbfsTestGrid import org.apache.pekko.testkit.TestProbe import edu.ie3.simona.test.common.ConfigTestData -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData + import scala.jdk.CollectionConverters.SetHasAsJava import edu.ie3.datamodel.models.input.container.ThermalGrid +import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData +import edu.ie3.simona.model.grid.GridModel.GridComponents class GridSpec extends UnitSpec @@ -301,7 +298,7 @@ class GridSpec Set.empty[Transformer3wModel], switches, ), - emptyGridControls, + GridControls.emptyGridControls, ) // get the private method for validation From c2dbd939b2b58eb3e08ebdab0a9e3fc4edea6150 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 09:03:05 +0100 Subject: [PATCH 257/305] fmt --- src/main/scala/edu/ie3/simona/main/RunSimona.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/main/RunSimona.scala b/src/main/scala/edu/ie3/simona/main/RunSimona.scala index df011e6614..fda5a23031 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimona.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimona.scala @@ -6,15 +6,14 @@ package edu.ie3.simona.main -import java.util.Locale - -import org.apache.pekko.actor.{ActorRef, ActorSystem} -import org.apache.pekko.pattern.gracefulStop -import org.apache.pekko.util.Timeout import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.sim.setup.SimonaSetup import edu.ie3.util.scala.quantities.QuantityUtil +import org.apache.pekko.actor.ActorRef +import org.apache.pekko.pattern.gracefulStop +import org.apache.pekko.util.Timeout +import java.util.Locale import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.util.Random From 465d2ef49d6ecf3351fa62c1710aa21c68796708 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 09:14:17 +0100 Subject: [PATCH 258/305] fix BasicGridWithSwitches --- .../model/grid/BasicGridWithSwitches.scala | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index 5a03235762..7d0f70f3f1 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -6,18 +6,9 @@ package edu.ie3.simona.test.common.model.grid -import edu.ie3.simona.model.grid.GridModel.{ - emptyGridControls, - GridComponents, - GridControls, -} -import edu.ie3.simona.model.grid.{ - GridModel, - LineModel, - NodeModel, - SwitchModel, - Transformer3wModel, -} +import edu.ie3.simona.model.control.GridControls +import edu.ie3.simona.model.grid.GridModel.GridComponents +import edu.ie3.simona.model.grid.{GridModel, LineModel, NodeModel, SwitchModel, Transformer3wModel} import edu.ie3.util.quantities.PowerSystemUnits._ import tech.units.indriya.quantity.Quantities @@ -234,7 +225,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches, ), - emptyGridControls, + GridControls.emptyGridControls, ) } From b165f20ee9de810e7a23678cc6d74e0d9fdc0672 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 10:12:11 +0100 Subject: [PATCH 259/305] refactor regulationFunction and harmonizationFunction --- .../TransformerControlGroupModel.scala | 68 ++++++++++--------- .../model/grid/BasicGridWithSwitches.scala | 8 ++- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index dc37243d3c..0a1363ef13 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -144,6 +144,41 @@ object TransformerControlGroupModel { .map(_.getNode.getUuid) ) + private def regulationFunction(complexVoltage: Complex, vMax:Double, vMin: Double): Option[Dimensionless] = { + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Each(_)) + case mag if mag < vMin => + Some(vMin - mag).map(Each(_)) + case _ => None + } + } + } + + + private def harmonizationFunction: Array[Dimensionless] => Option[Dimensionless] = + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) + + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None + } + + } + + /** Build a single control group model. Currently, only limit violation * prevention logic is captured: The nodal regulation need is equal to the * voltage change needed to comply with the given thresholds @@ -163,40 +198,11 @@ object TransformerControlGroupModel { vMin: Double, ): TransformerControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ - + val voltage = Each(1.0) val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> { (complexVoltage: Complex) => - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => - Some(vMax - mag).map(Each(_)) - case mag if mag < vMin => - Some(vMin - mag).map(Each(_)) - case _ => None - } - } + uuid -> regulationFunction(voltage, vMax, vMin) }.toMap - val harmonizationFunction = - (regulationRequests: Array[Dimensionless]) => { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) - val positiveRequests = regulationRequests.filter(_ > Each(0d)) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } - - } TransformerControlGroupModel( nodeUuidToRegulationCriterion, diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index 7d0f70f3f1..d57d902bc1 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -8,7 +8,13 @@ package edu.ie3.simona.test.common.model.grid import edu.ie3.simona.model.control.GridControls import edu.ie3.simona.model.grid.GridModel.GridComponents -import edu.ie3.simona.model.grid.{GridModel, LineModel, NodeModel, SwitchModel, Transformer3wModel} +import edu.ie3.simona.model.grid.{ + GridModel, + LineModel, + NodeModel, + SwitchModel, + Transformer3wModel, +} import edu.ie3.util.quantities.PowerSystemUnits._ import tech.units.indriya.quantity.Quantities From b70dae490fa589db7af05014da5808459bb53487 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 10:13:09 +0100 Subject: [PATCH 260/305] fmt --- .../TransformerControlGroupModel.scala | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index 0a1363ef13..d45888ec0c 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -144,69 +144,70 @@ object TransformerControlGroupModel { .map(_.getNode.getUuid) ) - private def regulationFunction(complexVoltage: Complex, vMax:Double, vMin: Double): Option[Dimensionless] = { - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => - Some(vMax - mag).map(Each(_)) - case mag if mag < vMin => - Some(vMin - mag).map(Each(_)) - case _ => None - } + private def regulationFunction( + complexVoltage: Complex, + vMax: Double, + vMin: Double, + ): Option[Dimensionless] = { + val vMag = complexVoltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Each(_)) + case mag if mag < vMin => + Some(vMin - mag).map(Each(_)) + case _ => None } } +} - - private def harmonizationFunction: Array[Dimensionless] => Option[Dimensionless] = - (regulationRequests: Array[Dimensionless]) => { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) - val positiveRequests = regulationRequests.filter(_ > Each(0d)) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } - +private def harmonizationFunction + : Array[Dimensionless] => Option[Dimensionless] = + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) + + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None } - - /** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param nodeUuids - * Collection of all relevant node uuids - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ - private def buildTransformerControlModels( - nodeUuids: Set[UUID], - vMax: Double, - vMin: Double, - ): TransformerControlGroupModel = { - /* Determine the voltage regulation criterion for each of the available nodes */ - val voltage = Each(1.0) - val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> regulationFunction(voltage, vMax, vMin) - }.toMap - - - TransformerControlGroupModel( - nodeUuidToRegulationCriterion, - harmonizationFunction, - ) } + +/** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param nodeUuids + * Collection of all relevant node uuids + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[TransformerControlGroupModel]] + */ +private def buildTransformerControlModels( + nodeUuids: Set[UUID], + vMax: Double, + vMin: Double, +): TransformerControlGroupModel = { + /* Determine the voltage regulation criterion for each of the available nodes */ + val voltage = Each(1.0) + val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => + uuid -> regulationFunction(voltage, vMax, vMin) + }.toMap + + TransformerControlGroupModel( + nodeUuidToRegulationCriterion, + harmonizationFunction, + ) } From 1e443bf952a4b859cae734e81eda24797652fda7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:28:40 +0000 Subject: [PATCH 261/305] Bump sphinxcontrib-plantuml from 0.27 to 0.28 in /docs/readthedocs (#745) --- docs/readthedocs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readthedocs/requirements.txt b/docs/readthedocs/requirements.txt index 47ba1d25e9..e34adcdafc 100644 --- a/docs/readthedocs/requirements.txt +++ b/docs/readthedocs/requirements.txt @@ -1,6 +1,6 @@ Sphinx==7.2.6 sphinx-rtd-theme==2.0.0 -sphinxcontrib-plantuml==0.27 +sphinxcontrib-plantuml==0.28 myst-parser==2.0.0 markdown-it-py==3.0.0 sphinx-hoverxref==1.3.0 From e5b177223c508facb3f6dbe29a73028594e5968b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 12:12:23 +0100 Subject: [PATCH 262/305] Delayed stopping of RuntimeEventListener --- .../event/listener/DelayedStopHelper.scala | 47 +++++ .../event/listener/ResultEventListener.scala | 19 +- .../event/listener/RuntimeEventListener.scala | 16 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 111 +++++------ .../listener/ResultEventListenerSpec.scala | 11 +- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 173 ++++++++++++++++-- 6 files changed, 261 insertions(+), 116 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala diff --git a/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala new file mode 100644 index 0000000000..b8b502156b --- /dev/null +++ b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala @@ -0,0 +1,47 @@ +/* + * © 2024. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.event.listener + +import org.apache.pekko.actor.typed.Behavior +import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} + +import scala.concurrent.duration.DurationInt + +/** todo + */ +object DelayedStopHelper { + + sealed trait StoppingMsg + extends ResultEventListener.Incoming + with RuntimeEventListener.Incoming + + /** Message indicating that [[RuntimeEventListener]] should stop. Instead of + * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop()]], this + * way of stopping allows all messages that have been queued before to be + * processed. todo + */ + case object FlushAndStop extends StoppingMsg + + private case object StopTimeout extends StoppingMsg + + def handleMsg[T >: StoppingMsg] + : PartialFunction[(ActorContext[T], StoppingMsg), Behavior[T]] = { + + case (ctx, FlushAndStop) => + ctx.log.debug( + s"Received FlushAndStop message, shutting down once no message has been received for 5 seconds." + ) + ctx.setReceiveTimeout(5.seconds, StopTimeout) + Behaviors.same + + case (ctx, StopTimeout) => + // there have been no messages for 5 seconds, let's end this + ctx.log.debug(s"${getClass.getSimpleName} is now stopped.") + Behaviors.stopped + } + +} diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index 148d2acf35..89ef94f38f 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -40,10 +40,6 @@ object ResultEventListener extends Transformer3wResultSupport { private final case class InitFailed(ex: Exception) extends Incoming - final case object FlushAndStop extends Incoming - - private final case object StopTimeout extends Incoming - /** [[ResultEventListener]] base data containing all information the listener * needs * @@ -278,7 +274,7 @@ object ResultEventListener extends Transformer3wResultSupport { } private def idle(baseData: BaseData): Behavior[Incoming] = Behaviors - .receive[Incoming] { + .receivePartial[Incoming] { case (ctx, ParticipantResultEvent(participantResult)) => val updatedBaseData = handleResult(participantResult, baseData, ctx.log) idle(updatedBaseData) @@ -318,17 +314,8 @@ object ResultEventListener extends Transformer3wResultSupport { val updatedBaseData = handleResult(flexOptionsResult, baseData, ctx.log) idle(updatedBaseData) - case (ctx, FlushAndStop) => - ctx.log.debug( - s"Received FlushAndStop message, shutting down once no message has been received for 5 seconds." - ) - ctx.setReceiveTimeout(5.seconds, StopTimeout) - Behaviors.same - - case (ctx, StopTimeout) => - // there have been no messages for 5 seconds, let's end this - ctx.log.debug(s"${getClass.getSimpleName} is now stopped.") - Behaviors.stopped + case (ctx, msg: DelayedStopHelper.StoppingMsg) => + DelayedStopHelper.handleMsg((ctx, msg)) } .receiveSignal { case (ctx, PostStop) => diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index 53fd8f8a04..50c38217eb 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -6,8 +6,6 @@ package edu.ie3.simona.event.listener -import org.apache.pekko.actor.typed.{Behavior, PostStop} -import org.apache.pekko.actor.typed.scaladsl.Behaviors import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed @@ -19,6 +17,8 @@ import edu.ie3.simona.io.runtime.{ RuntimeEventSink, } import edu.ie3.util.TimeUtil +import org.apache.pekko.actor.typed.scaladsl.Behaviors +import org.apache.pekko.actor.typed.{Behavior, PostStop} import java.util.concurrent.BlockingQueue @@ -30,13 +30,6 @@ object RuntimeEventListener { trait Incoming - /** Message indicating that [[RuntimeEventListener]] should stop. Instead of - * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop()]], this - * way of stopping allows all messages that have been queued before to be - * processed. - */ - case object Stop extends Incoming - /** Creates a runtime event listener behavior with given configuration. * * @param listenerConf @@ -95,9 +88,8 @@ object RuntimeEventListener { ) Behaviors.same - case (ctx, Stop) => - ctx.log.debug("") - Behaviors.stopped + case (ctx, msg: DelayedStopHelper.StoppingMsg) => + DelayedStopHelper.handleMsg((ctx, msg)) } .receiveSignal { case (_, PostStop) => listeners.foreach(_.close()) diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 410b9c1a9f..5387124ae1 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -9,17 +9,16 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.listener.{DelayedStopHelper, RuntimeEventListener} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} +import edu.ie3.util.scala.Scope import org.apache.pekko.actor.typed.scaladsl.adapter._ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior, PostStop, Terminated} import org.apache.pekko.actor.{ActorRef => ClassicRef} -import scala.language.postfixOps - /** Main entrance point to a simona simulation as top level actor. This actors * allows to control the simulation in the sense that messages for * initialization and time steps can be send to this actor and will be handled @@ -127,7 +126,7 @@ object SimonaSim { watchedActors, extSimulationData.extSimAdapters, runtimeEventListener, - resultEventListeners, + resultEventListeners.appended(runtimeEventListener), ) ) } @@ -142,62 +141,49 @@ object SimonaSim { private def idle(actorData: ActorData): Behavior[Incoming] = Behaviors .receivePartial[Incoming] { case (ctx, SimulationEnded) => - // stop all children and wait for result listeners - stop(ctx, actorData, simulationSuccessful = true) - } - .receiveSignal { case (ctx, Terminated(actor)) => - ctx.log.error( - "An actor ({}) unexpectedly terminated. Shut down all children gracefully and report simulation " + - "failure. See logs and possible stacktrace for details.", - actor, - ) - - // stop all children and end - stop(ctx, actorData, simulationSuccessful = false) - } - - private def stop( - ctx: ActorContext[_], - actorData: ActorData, - simulationSuccessful: Boolean, - ): Behavior[Incoming] = - if (simulationSuccessful) { - // if the simulation is successful, we're waiting for the result listeners - // to terminate and thus do not unwatch them here + // if the simulation is successful, we're waiting for the event + // listeners to terminate and thus do not unwatch them here ctx.log.info( "Simulation terminated successfully. Stopping children and waiting for results to flush out..." ) - actorData.resultListener.foreach(_ ! ResultEventListener.FlushAndStop) - - stopChildren(ctx, actorData, simulationSuccessful) - - waitingForListener( - actorData.starter, - remainingListeners = actorData.resultListener.toSeq, - ) - } else { - ctx.log.error( - "An error occurred during the simulation. See stacktrace for details." - ) - - // also notify RuntimeEventListener that error happened - actorData.runtimeEventListener ! RuntimeEvent.Error( - "Simulation stopped with error." - ) - - actorData.starter ! SimonaEnded(successful = false) + stopChildren(ctx, actorData, simulationSuccessful = true) + } + .receiveSignal { case (ctx, Terminated(actor)) => + Scope(actorData) + .map(data => + data.copy( + delayedStoppingActors = + data.delayedStoppingActors.toSeq.filterNot(_ == actor) + ) + ) + .map { data => + ctx.log.error( + "An actor ({}) unexpectedly terminated. Shut down all children gracefully and report simulation " + + "failure. See logs and possible stacktrace for details.", + actor, + ) - stopChildren(ctx, actorData, simulationSuccessful) + // also notify RuntimeEventListener that error happened + data.runtimeEventListener ! RuntimeEvent.Error( + "Simulation stopped with error." + ) - Behaviors.stopped + stopChildren(ctx, data, simulationSuccessful = false) + } + .get } + /** @param ctx + * @param actorData + * @param simulationSuccessful + * @return + */ private def stopChildren( ctx: ActorContext[_], actorData: ActorData, simulationSuccessful: Boolean, - ): Unit = { + ): Behavior[Incoming] = { actorData.watchedActors.foreach { ref => ctx.unwatch(ref) ctx.stop(ref) @@ -208,24 +194,21 @@ object SimonaSim { ref ! ExtSimAdapter.Stop(simulationSuccessful) } - if (!simulationSuccessful) - // if an error happened, we do not care for all results to be flushed out - // and just end ResultEventListeners right away - actorData.resultListener.foreach { ref => - ctx.unwatch(ref) - ctx.stop(ref) - } - - ctx.unwatch(actorData.runtimeEventListener) - // we stop RuntimeEventListener by message so that RuntimeEvents - // (Error in particular) in queue can still be processed before - actorData.runtimeEventListener ! RuntimeEventListener.Stop + actorData.delayedStoppingActors.foreach( + _ ! DelayedStopHelper.FlushAndStop + ) + waitingForListener( + actorData.starter, + actorData.delayedStoppingActors, + simulationSuccessful, + ) } private def waitingForListener( starter: ActorRef[SimonaEnded], remainingListeners: Seq[ActorRef[_]], + simulationSuccessful: Boolean, ): Behavior[Incoming] = Behaviors.receiveSignal[Incoming] { case (ctx, Terminated(actor)) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) @@ -235,16 +218,16 @@ object SimonaSim { "All result listeners have terminated. Ending simulation successfully." ) - starter ! SimonaEnded(successful = true) + starter ! SimonaEnded(simulationSuccessful) Behaviors.stopped } else { waitingForListener( starter, updatedRemainingListeners, + simulationSuccessful, ) } - } /** TODO scaladoc @@ -253,13 +236,13 @@ object SimonaSim { * excluding ExtSimAdapters, ResultListeners, RuntimeEventListener * @param extSimAdapters * @param runtimeEventListener - * @param resultListener + * @param delayedStoppingActors */ private final case class ActorData( starter: ActorRef[SimonaEnded], watchedActors: Iterable[ActorRef[_]], extSimAdapters: Iterable[ClassicRef], runtimeEventListener: ActorRef[RuntimeEventListener.Incoming], - resultListener: Iterable[ActorRef[ResultEventListener.Incoming]], + delayedStoppingActors: Seq[ActorRef[DelayedStopHelper.StoppingMsg]], ) } diff --git a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala index 5788bd9f76..db8c7df6e1 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/ResultEventListenerSpec.scala @@ -20,7 +20,6 @@ import edu.ie3.simona.event.ResultEvent.{ ParticipantResultEvent, PowerFlowResultEvent, } -import edu.ie3.simona.event.listener.ResultEventListener.FlushAndStop import edu.ie3.simona.io.result.{ResultEntitySink, ResultSinkType} import edu.ie3.simona.test.common.result.PowerFlowResultData import edu.ie3.simona.test.common.{IOTestCommons, UnitSpec} @@ -139,7 +138,7 @@ class ResultEventListenerSpec ) ) - listener ! FlushAndStop + listener ! DelayedStopHelper.FlushAndStop deathWatch expectTerminated (listener, 10 seconds) } } @@ -173,7 +172,7 @@ class ResultEventListenerSpec ) // stop listener so that result is flushed out - listenerRef ! FlushAndStop + listenerRef ! DelayedStopHelper.FlushAndStop // wait until all lines have been written out: awaitCond( @@ -255,7 +254,7 @@ class ResultEventListenerSpec ) // stop listener so that result is flushed out - listenerRef ! FlushAndStop + listenerRef ! DelayedStopHelper.FlushAndStop // wait until all lines have been written out: awaitCond( @@ -339,7 +338,7 @@ class ResultEventListenerSpec listener ! powerflow3wResult(resultB) // stop listener so that result is flushed out - listener ! FlushAndStop + listener ! DelayedStopHelper.FlushAndStop /* Await that the result is written */ awaitCond( @@ -402,7 +401,7 @@ class ResultEventListenerSpec // otherwise it might happen, that the shutdown is triggered even before the just send ParticipantResultEvent // reached the listener // this also triggers the compression of result files - listenerRef ! FlushAndStop + listenerRef ! DelayedStopHelper.FlushAndStop // shutdown the actor system system.terminate() diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index 0da41463b5..6598058d1d 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -7,12 +7,17 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.listener.{ + DelayedStopHelper, + ResultEventListener, + RuntimeEventListener, +} import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion import edu.ie3.simona.scheduler.TimeAdvancer +import edu.ie3.simona.sim.SimonaSim.SimulationEnded import edu.ie3.simona.sim.SimonaSimSpec._ import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import edu.ie3.simona.test.common.UnitSpec @@ -35,28 +40,69 @@ class SimonaSimSpec "SimonaSim" should { - "stop and indicate success to starter" when { + "indicate success to the starter and stop" when { - "receiving SimulationEnded(successful = true) from TimeAdvancer" in {} + "receiving SimulationEnded from TimeAdvancer" in { + val starter = TestProbe[SimonaEnded]("starter") + val runtimeListener = + TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + val resultListener = + TestProbe[ResultEventListener.Incoming]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") - } + val simonaSim = spawn( + SimonaSim( + new MockSetup( + Some(runtimeListener.ref), + Some(resultListener.ref), + Some(timeAdvancer.ref), + ) + ), + uniqueName("simonaSim"), + ) + + simonaSim ! SimonaSim.Start(starter.ref) + + // Initialization has started, mock actors are being created + timeAdvancer.expectMessage(TimeAdvancer.Start()) - "stop and indicate failure to starter" when { + // Simulation should still "run" at this point + starter.expectNoMessage() - "receiving SimulationEnded(successful = false) from TimeAdvancer" in {} + // TimeAdvancer reached its last tick, ending + simonaSim ! SimulationEnded + + // runtime/result event listeners receive stop message + runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) + resultListener.expectMessage(DelayedStopHelper.FlushAndStop) + + // both runtime and result listener actors have stopped, thus we can end + starter.expectMessage(SimonaEnded(successful = true)) + starter.expectTerminated(simonaSim) + } + + } + + "indicate failure to starter and stop" when { "child stops due to thrown exception" in { val starter = TestProbe[SimonaEnded]("starter") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") val runtimeListener = TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + val resultListener = + TestProbe[ResultEventListener.Incoming]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") val receiveThrowingActor = TestProbe[ActorRef[SchedulerMessage]]("receiveThrowingActor") val simonaSim = spawn( SimonaSim( - new MockSetup(Some(runtimeListener.ref), Some(timeAdvancer.ref)) { + new MockSetup( + Some(runtimeListener.ref), + Some(resultListener.ref), + Some(timeAdvancer.ref), + ) { override def scheduler( context: ActorContext[_], @@ -90,32 +136,40 @@ class SimonaSimSpec starter.expectNoMessage() // We cause an actor to fail. - // (The actor reacts to any message with an exception, + // (The mock actor reacts to any message with an exception, // we just pick the first best fit) throwingActor ! Completion(TestProbe().ref) + // runtime/result event listeners receive stop message runtimeListener.expectMessage( RuntimeEvent.Error("Simulation stopped with error.") ) - runtimeListener.expectMessage(RuntimeEventListener.Stop) + runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) + resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // SimonaSim should run its failure routine and tell us that a failure happened + // both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = false)) starter.expectTerminated(simonaSim) } "child stops by changing behavior" in { val starter = TestProbe[SimonaEnded]("starter") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") val runtimeListener = TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + val resultListener = + TestProbe[ResultEventListener.Incoming]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") val receiveStoppingActor = TestProbe[ActorRef[SchedulerMessage]]("receiveStoppingActor") val simonaSim = spawn( SimonaSim( - new MockSetup(Some(runtimeListener.ref), Some(timeAdvancer.ref)) { + new MockSetup( + Some(runtimeListener.ref), + Some(resultListener.ref), + Some(timeAdvancer.ref), + ) { override def scheduler( context: ActorContext[_], @@ -149,16 +203,81 @@ class SimonaSimSpec starter.expectNoMessage() // We cause an actor to fail. - // (The actor reacts to any message by stopping itself, + // (The mock actor reacts to any message by stopping itself, // we just pick the first best fit) stoppingActor ! Completion(TestProbe().ref) + // runtime/result event listeners receive stop message runtimeListener.expectMessage( RuntimeEvent.Error("Simulation stopped with error.") ) - runtimeListener.expectMessage(RuntimeEventListener.Stop) + runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) + resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // SimonaSim should run its failure routine and tell us that a failure happened + // both runtime and result listener actors have stopped, thus we can end + starter.expectMessage(SimonaEnded(successful = false)) + starter.expectTerminated(simonaSim) + } + + "RuntimeEventListener stops unexpectedly" in { + val starter = TestProbe[SimonaEnded]("starter") + val resultListener = + TestProbe[ResultEventListener.Incoming]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + + val receiveThrowingActor = + TestProbe[ActorRef[RuntimeEventListener.Incoming]]( + "receiveThrowingActor" + ) + + val simonaSim = spawn( + SimonaSim( + new MockSetup( + None, + Some(resultListener.ref), + Some(timeAdvancer.ref), + ) { + + override def runtimeEventListener( + context: ActorContext[_] + ): ActorRef[RuntimeEventListener.Incoming] = { + // we cannot return a testprobe ref here, + // needs to be a proper actor created by context + val throwingActor = context + .spawn[RuntimeEventListener.Incoming]( + throwOnMessage, + uniqueName("throwingActor"), + ) + // send ref to the outside + receiveThrowingActor.ref ! throwingActor + throwingActor + } + + } + ), + uniqueName("simonaSim"), + ) + + simonaSim ! SimonaSim.Start(starter.ref) + + // Initialization has started, mock actors are being created + val throwingActor = + receiveThrowingActor + .expectMessageType[ActorRef[RuntimeEventListener.Incoming]] + timeAdvancer.expectMessage(TimeAdvancer.Start()) + + // Simulation should still "run" at this point + starter.expectNoMessage() + + // We cause the RuntimeEventListener to fail. + // (The mock actor reacts to any message with an exception, + // we just pick the first best fit) + throwingActor ! RuntimeEvent.Initializing + + // Result event listener receives stop message + resultListener.expectMessage(DelayedStopHelper.FlushAndStop) + + // both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = false)) starter.expectTerminated(simonaSim) } @@ -203,6 +322,18 @@ object SimonaSimSpec { Behaviors.same } + def stoppableForwardMessage[T >: DelayedStopHelper.StoppingMsg]( + recipient: Option[ActorRef[T]] + ): Behavior[T] = + Behaviors.receiveMessage { + case msg @ DelayedStopHelper.FlushAndStop => + recipient.foreach(_ ! msg) + Behaviors.stopped + case msg => + recipient.foreach(_ ! msg) + Behaviors.same + } + def forwardMessage[T](recipient: Option[ActorRef[T]]): Behavior[T] = Behaviors.receiveMessage { msg => recipient.foreach(_ ! msg) @@ -229,6 +360,7 @@ object SimonaSimSpec { class MockSetup( runtimeEventProbe: Option[ActorRef[RuntimeEventListener.Incoming]] = None, + resultEventProbe: Option[ActorRef[ResultEventListener.Incoming]] = None, timeAdvancerProbe: Option[ActorRef[TimeAdvancer.Incoming]] = None, ) extends SimonaSetup { @@ -237,13 +369,18 @@ object SimonaSimSpec { override def runtimeEventListener( context: ActorContext[_] ): ActorRef[RuntimeEventListener.Incoming] = context.spawn( - forwardMessage(runtimeEventProbe), + stoppableForwardMessage(runtimeEventProbe), uniqueName("runtimeEventForwarder"), ) override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultEventListener.Incoming]] = Seq.empty + ): Seq[ActorRef[ResultEventListener.Incoming]] = Seq( + context.spawn( + stoppableForwardMessage(resultEventProbe), + uniqueName("resultEventForwarder"), + ) + ) override def primaryServiceProxy( context: ActorContext[_], From d38ed3ae20ef935dbdf20d7a5174fbe6bfd1891f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 12:36:07 +0100 Subject: [PATCH 263/305] Cleanup --- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index 6598058d1d..a4009115a9 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -72,11 +72,11 @@ class SimonaSimSpec // TimeAdvancer reached its last tick, ending simonaSim ! SimulationEnded - // runtime/result event listeners receive stop message + // Runtime/result event listeners receive stop message runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // both runtime and result listener actors have stopped, thus we can end + // Both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = true)) starter.expectTerminated(simonaSim) } @@ -108,14 +108,14 @@ class SimonaSimSpec context: ActorContext[_], timeAdvancer: ActorRef[TimeAdvancer.Incoming], ): ActorRef[SchedulerMessage] = { - // we cannot return a testprobe ref here, + // We cannot return a TestProbe ref here, // needs to be a proper actor created by context val throwingActor = context .spawn[SchedulerMessage]( throwOnMessage, uniqueName("throwingActor"), ) - // send ref to the outside + // Send ref to the outside to make it accessible receiveThrowingActor.ref ! throwingActor throwingActor } @@ -136,18 +136,18 @@ class SimonaSimSpec starter.expectNoMessage() // We cause an actor to fail. - // (The mock actor reacts to any message with an exception, - // we just pick the first best fit) + // (The mock actor reacts to any message with an + // exception, we just pick the first best fit) throwingActor ! Completion(TestProbe().ref) - // runtime/result event listeners receive stop message + // Runtime/result event listeners receive stop message runtimeListener.expectMessage( RuntimeEvent.Error("Simulation stopped with error.") ) runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // both runtime and result listener actors have stopped, thus we can end + // Both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = false)) starter.expectTerminated(simonaSim) } @@ -175,18 +175,17 @@ class SimonaSimSpec context: ActorContext[_], timeAdvancer: ActorRef[TimeAdvancer.Incoming], ): ActorRef[SchedulerMessage] = { - // we cannot return a testprobe ref here, + // We cannot return a TestProbe ref here, // needs to be a proper actor created by context val stoppingActor = context.spawn[SchedulerMessage]( stopOnMessage, uniqueName("stoppingActor"), ) - // send ref to the outside + // Send ref to the outside to make it accessible receiveStoppingActor.ref ! stoppingActor stoppingActor } - } ), uniqueName("simonaSim"), @@ -203,18 +202,18 @@ class SimonaSimSpec starter.expectNoMessage() // We cause an actor to fail. - // (The mock actor reacts to any message by stopping itself, - // we just pick the first best fit) + // (The mock actor reacts to any message by stopping + // itself, we just pick the first best fit) stoppingActor ! Completion(TestProbe().ref) - // runtime/result event listeners receive stop message + // Runtime/result event listeners receive stop message runtimeListener.expectMessage( RuntimeEvent.Error("Simulation stopped with error.") ) runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // both runtime and result listener actors have stopped, thus we can end + // Both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = false)) starter.expectTerminated(simonaSim) } @@ -241,14 +240,14 @@ class SimonaSimSpec override def runtimeEventListener( context: ActorContext[_] ): ActorRef[RuntimeEventListener.Incoming] = { - // we cannot return a testprobe ref here, + // We cannot return a TestProbe ref here, // needs to be a proper actor created by context val throwingActor = context .spawn[RuntimeEventListener.Incoming]( throwOnMessage, uniqueName("throwingActor"), ) - // send ref to the outside + // Send ref to the outside receiveThrowingActor.ref ! throwingActor throwingActor } @@ -270,14 +269,14 @@ class SimonaSimSpec starter.expectNoMessage() // We cause the RuntimeEventListener to fail. - // (The mock actor reacts to any message with an exception, - // we just pick the first best fit) + // (The mock actor reacts to any message with an + // exception, we just pick the first best fit) throwingActor ! RuntimeEvent.Initializing // Result event listener receives stop message resultListener.expectMessage(DelayedStopHelper.FlushAndStop) - // both runtime and result listener actors have stopped, thus we can end + // Both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = false)) starter.expectTerminated(simonaSim) } @@ -311,9 +310,6 @@ class SimonaSimSpec } - // TODO: - // REL fails in edge cases - } object SimonaSimSpec { @@ -322,6 +318,12 @@ object SimonaSimSpec { Behaviors.same } + def forwardMessage[T](recipient: Option[ActorRef[T]]): Behavior[T] = + Behaviors.receiveMessage { msg => + recipient.foreach(_ ! msg) + Behaviors.same + } + def stoppableForwardMessage[T >: DelayedStopHelper.StoppingMsg]( recipient: Option[ActorRef[T]] ): Behavior[T] = @@ -334,12 +336,6 @@ object SimonaSimSpec { Behaviors.same } - def forwardMessage[T](recipient: Option[ActorRef[T]]): Behavior[T] = - Behaviors.receiveMessage { msg => - recipient.foreach(_ ! msg) - Behaviors.same - } - def throwOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => throwTestException() } @@ -352,9 +348,7 @@ object SimonaSimSpec { "This is an exception for test purposes. It is expected to be thrown." ) - /** @param name - * @return - */ + /** Makes the given actor name unique by appending a random UUID */ def uniqueName(name: String): String = s"${name}_${UUID.randomUUID()}" From e490eb9d3c9d517ba163278140401ca347ceddcb Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 13:02:21 +0100 Subject: [PATCH 264/305] Testing stopping of ExtSimAdapter as well --- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 8 ++- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 53 ++++++++++++++++--- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 5387124ae1..9dcb820b6e 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -108,6 +108,10 @@ object SimonaSim { ctx.watch(scheduler) ctx.watch(primaryServiceProxy.toTyped) ctx.watch(weatherService.toTyped) + extSimulationData.extSimAdapters.map(_.toTyped).foreach(ctx.watch) + extSimulationData.extDataServices.values + .map(_.toTyped) + .foreach(ctx.watch) gridAgents.foreach(ref => ctx.watch(ref.toTyped)) // Start simulation @@ -118,7 +122,9 @@ object SimonaSim { scheduler, primaryServiceProxy.toTyped, weatherService.toTyped, - ) ++ gridAgents.map(_.toTyped) + ) ++ + gridAgents.map(_.toTyped) ++ + extSimulationData.extDataServices.values.map(_.toTyped) idle( ActorData( diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index a4009115a9..bddcb62eaa 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -7,6 +7,7 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.event.listener.{ DelayedStopHelper, ResultEventListener, @@ -49,6 +50,7 @@ class SimonaSimSpec val resultListener = TestProbe[ResultEventListener.Incoming]("resultEventListener") val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + val extSimAdapter = TestProbe[ExtSimAdapter.Stop]("extSimAdapter") val simonaSim = spawn( SimonaSim( @@ -56,7 +58,20 @@ class SimonaSimSpec Some(runtimeListener.ref), Some(resultListener.ref), Some(timeAdvancer.ref), - ) + ) { + override def extSimulations( + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ExtSimSetupData = { + // We cannot return a TestProbe ref here, + // needs to be a proper actor created by context + val extSim = context.spawn( + forwardMessage(Some(extSimAdapter.ref)), + uniqueName("extSimAdapterForwarder"), + ) + ExtSimSetupData(Iterable(extSim.toClassic), Map.empty) + } + } ), uniqueName("simonaSim"), ) @@ -72,9 +87,12 @@ class SimonaSimSpec // TimeAdvancer reached its last tick, ending simonaSim ! SimulationEnded - // Runtime/result event listeners receive stop message + // Actors receive stop message runtimeListener.expectMessage(DelayedStopHelper.FlushAndStop) resultListener.expectMessage(DelayedStopHelper.FlushAndStop) + extSimAdapter.expectMessage( + ExtSimAdapter.Stop(simulationSuccessful = true) + ) // Both runtime and result listener actors have stopped, thus we can end starter.expectMessage(SimonaEnded(successful = true)) @@ -108,8 +126,6 @@ class SimonaSimSpec context: ActorContext[_], timeAdvancer: ActorRef[TimeAdvancer.Incoming], ): ActorRef[SchedulerMessage] = { - // We cannot return a TestProbe ref here, - // needs to be a proper actor created by context val throwingActor = context .spawn[SchedulerMessage]( throwOnMessage, @@ -175,8 +191,6 @@ class SimonaSimSpec context: ActorContext[_], timeAdvancer: ActorRef[TimeAdvancer.Incoming], ): ActorRef[SchedulerMessage] = { - // We cannot return a TestProbe ref here, - // needs to be a proper actor created by context val stoppingActor = context.spawn[SchedulerMessage]( stopOnMessage, @@ -240,8 +254,6 @@ class SimonaSimSpec override def runtimeEventListener( context: ActorContext[_] ): ActorRef[RuntimeEventListener.Incoming] = { - // We cannot return a TestProbe ref here, - // needs to be a proper actor created by context val throwingActor = context .spawn[RuntimeEventListener.Incoming]( throwOnMessage, @@ -314,16 +326,25 @@ class SimonaSimSpec object SimonaSimSpec { + /** Behavior that does nothing on receiving message */ def empty[T]: Behavior[T] = Behaviors.receiveMessage { _ => Behaviors.same } + /** Behavior that forwards all messages to given actor. This is required + * because unless actors are created by the ActorContext inside SimonaSim, + * they cannot be stopped by SimonaSim. + */ def forwardMessage[T](recipient: Option[ActorRef[T]]): Behavior[T] = Behaviors.receiveMessage { msg => recipient.foreach(_ ! msg) Behaviors.same } + /** Similarly to [[forwardMessage]], this behavior stops on receiving + * [[DelayedStopHelper.FlushAndStop]] and forwards all other messages to + * given actor. + */ def stoppableForwardMessage[T >: DelayedStopHelper.StoppingMsg]( recipient: Option[ActorRef[T]] ): Behavior[T] = @@ -336,10 +357,14 @@ object SimonaSimSpec { Behaviors.same } + /** Behavior that throws a RuntimeException on receiving any message, which + * should cause the actor to stop + */ def throwOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => throwTestException() } + /** Behavior that stops itself on the first received message */ def stopOnMessage[T]: Behavior[T] = Behaviors.receiveMessage { _ => Behaviors.stopped } @@ -352,6 +377,18 @@ object SimonaSimSpec { def uniqueName(name: String): String = s"${name}_${UUID.randomUUID()}" + /** Mock implementation of [[SimonaSetup]] + * + * @param runtimeEventProbe + * Optional ActorRef that messages received by RuntimeEventListener are + * forwarded to + * @param resultEventProbe + * Optional ActorRef that messages received by ResultEventListener are + * forwarded to + * @param timeAdvancerProbe + * Optional ActorRef that messages received by TimeAdvancer are forwarded + * to + */ class MockSetup( runtimeEventProbe: Option[ActorRef[RuntimeEventListener.Incoming]] = None, resultEventProbe: Option[ActorRef[ResultEventListener.Incoming]] = None, From f575f68402a3436acda7d109aa98655b66cfb875 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 13:14:36 +0100 Subject: [PATCH 265/305] Renaming Incoming -> Request --- .../edu/ie3/simona/event/ResultEvent.scala | 2 +- .../edu/ie3/simona/event/RuntimeEvent.scala | 4 +- .../event/listener/DelayedStopHelper.scala | 4 +- .../event/listener/ResultEventListener.scala | 16 +++--- .../event/listener/RuntimeEventListener.scala | 8 +-- .../scala/edu/ie3/simona/main/RunSimona.scala | 2 +- .../ontology/messages/SchedulerMessage.scala | 2 +- .../edu/ie3/simona/scheduler/Scheduler.scala | 10 ++-- .../ie3/simona/scheduler/TimeAdvancer.scala | 16 +++--- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 22 ++++---- .../ie3/simona/sim/setup/SimonaSetup.scala | 8 +-- .../sim/setup/SimonaStandaloneSetup.scala | 8 +-- .../simona/scheduler/TimeAdvancerSpec.scala | 20 ++++---- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 50 +++++++++---------- .../simona/sim/setup/SimonaSetupSpec.scala | 11 ++-- 15 files changed, 91 insertions(+), 92 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala index 785bfc8510..d81242c608 100644 --- a/src/main/scala/edu/ie3/simona/event/ResultEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/ResultEvent.scala @@ -20,7 +20,7 @@ import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult import edu.ie3.simona.agent.grid.GridResultsSupport.PartialTransformer3wResult import edu.ie3.simona.event.listener.ResultEventListener -sealed trait ResultEvent extends Event with ResultEventListener.Incoming +sealed trait ResultEvent extends Event with ResultEventListener.Request /** Calculation result events */ diff --git a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala index 9ecea2aef8..da02b9c258 100644 --- a/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala +++ b/src/main/scala/edu/ie3/simona/event/RuntimeEvent.scala @@ -6,10 +6,10 @@ package edu.ie3.simona.event -import edu.ie3.simona.event.listener.RuntimeEventListener.Incoming +import edu.ie3.simona.event.listener.RuntimeEventListener.Request /** Event type for simulation control */ -sealed trait RuntimeEvent extends Event with Incoming +sealed trait RuntimeEvent extends Event with Request object RuntimeEvent { diff --git a/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala index b8b502156b..b4da2e06ec 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala @@ -16,8 +16,8 @@ import scala.concurrent.duration.DurationInt object DelayedStopHelper { sealed trait StoppingMsg - extends ResultEventListener.Incoming - with RuntimeEventListener.Incoming + extends ResultEventListener.Request + with RuntimeEventListener.Request /** Message indicating that [[RuntimeEventListener]] should stop. Instead of * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop()]], this diff --git a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala index 89ef94f38f..d5acf17912 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/ResultEventListener.scala @@ -32,13 +32,13 @@ import scala.util.{Failure, Success, Try} object ResultEventListener extends Transformer3wResultSupport { - trait Incoming + trait Request private final case class SinkResponse( response: Map[Class[_], ResultEntitySink] - ) extends Incoming + ) extends Request - private final case class InitFailed(ex: Exception) extends Incoming + private final case class InitFailed(ex: Exception) extends Request /** [[ResultEventListener]] base data containing all information the listener * needs @@ -230,7 +230,7 @@ object ResultEventListener extends Transformer3wResultSupport { def apply( resultFileHierarchy: ResultFileHierarchy - ): Behavior[Incoming] = Behaviors.setup[Incoming] { ctx => + ): Behavior[Request] = Behaviors.setup[Request] { ctx => ctx.log.debug("Starting initialization!") resultFileHierarchy.resultSinkType match { case _: ResultSinkType.Kafka => @@ -256,8 +256,8 @@ object ResultEventListener extends Transformer3wResultSupport { init() } - private def init(): Behavior[Incoming] = Behaviors.withStash(200) { buffer => - Behaviors.receive[Incoming] { + private def init(): Behavior[Request] = Behaviors.withStash(200) { buffer => + Behaviors.receive[Request] { case (ctx, SinkResponse(response)) => ctx.log.debug("Initialization complete!") buffer.unstashAll(idle(BaseData(response))) @@ -273,8 +273,8 @@ object ResultEventListener extends Transformer3wResultSupport { } } - private def idle(baseData: BaseData): Behavior[Incoming] = Behaviors - .receivePartial[Incoming] { + private def idle(baseData: BaseData): Behavior[Request] = Behaviors + .receivePartial[Request] { case (ctx, ParticipantResultEvent(participantResult)) => val updatedBaseData = handleResult(participantResult, baseData, ctx.log) idle(updatedBaseData) diff --git a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala index 50c38217eb..bb97242e13 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/RuntimeEventListener.scala @@ -28,7 +28,7 @@ import java.util.concurrent.BlockingQueue */ object RuntimeEventListener { - trait Incoming + trait Request /** Creates a runtime event listener behavior with given configuration. * @@ -45,7 +45,7 @@ object RuntimeEventListener { listenerConf: SimonaConfig.Simona.Runtime.Listener, queue: Option[BlockingQueue[RuntimeEvent]], startDateTimeString: String, - ): Behavior[Incoming] = Behaviors.setup { ctx => + ): Behavior[Request] = Behaviors.setup { ctx => val listeners = Iterable( Some( RuntimeEventLogSink( @@ -69,8 +69,8 @@ object RuntimeEventListener { listeners: Iterable[RuntimeEventSink], eventsToProcess: Option[List[String]] = None, runtimeStats: RuntimeStats = RuntimeStats(), - ): Behavior[Incoming] = Behaviors - .receive[Incoming] { + ): Behavior[Request] = Behaviors + .receive[Request] { case (_, PowerFlowFailed) => val updatedRuntimeData = runtimeStats .copy(failedPowerFlows = runtimeStats.failedPowerFlows + 1) diff --git a/src/main/scala/edu/ie3/simona/main/RunSimona.scala b/src/main/scala/edu/ie3/simona/main/RunSimona.scala index 9e70abf3e3..707da41338 100644 --- a/src/main/scala/edu/ie3/simona/main/RunSimona.scala +++ b/src/main/scala/edu/ie3/simona/main/RunSimona.scala @@ -97,6 +97,6 @@ object RunSimona { /** Reported back from the scheduler if an error occurred during the * simulation */ - case class SimonaEnded(successful: Boolean) + final case class SimonaEnded(successful: Boolean) } diff --git a/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala b/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala index 02c1918fc1..443971ef18 100644 --- a/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala +++ b/src/main/scala/edu/ie3/simona/ontology/messages/SchedulerMessage.scala @@ -10,7 +10,7 @@ import org.apache.pekko.actor.typed.ActorRef import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.scheduler.{Scheduler, TimeAdvancer} -trait SchedulerMessage extends Scheduler.Incoming with TimeAdvancer.Incoming +trait SchedulerMessage extends Scheduler.Request with TimeAdvancer.Request object SchedulerMessage { final case class Completion( diff --git a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala index 63489d1b20..7339fbbe61 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/Scheduler.scala @@ -28,10 +28,10 @@ import org.apache.pekko.actor.typed.{ActorRef, Behavior} */ object Scheduler { - trait Incoming + trait Request private final case class WrappedActivation(activation: Activation) - extends Incoming + extends Request /** Creates a new scheduler with given parent and core. The scheduler starts * in the inactive state. @@ -44,7 +44,7 @@ object Scheduler { def apply( parent: ActorRef[SchedulerMessage], coreFactory: CoreFactory = RegularSchedulerCore, - ): Behavior[Incoming] = Behaviors.setup { ctx => + ): Behavior[Request] = Behaviors.setup { ctx => val adapter = ctx.messageAdapter[Activation](WrappedActivation) @@ -57,7 +57,7 @@ object Scheduler { private def inactive( data: SchedulerData, core: InactiveCore, - ): Behavior[Incoming] = + ): Behavior[Request] = Behaviors.receive { case (_, WrappedActivation(Activation(tick))) => val (toActivate, activeCore) = core @@ -102,7 +102,7 @@ object Scheduler { private def active( data: SchedulerData, core: ActiveCore, - ): Behavior[Incoming] = Behaviors.receive { + ): Behavior[Request] = Behaviors.receive { case ( _, diff --git a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala index a12cbecfd1..ee6ae7f1a7 100644 --- a/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala +++ b/src/main/scala/edu/ie3/simona/scheduler/TimeAdvancer.scala @@ -23,7 +23,7 @@ import org.apache.pekko.actor.typed.{ActorRef, Behavior} */ object TimeAdvancer { - trait Incoming + trait Request /** Starts simulation by activating the next (or first) tick * @@ -33,7 +33,7 @@ object TimeAdvancer { */ final case class Start( pauseTick: Option[Long] = None - ) extends Incoming + ) extends Request /** @param simulation * The root actor of the simulation @@ -49,7 +49,7 @@ object TimeAdvancer { eventListener: Option[ActorRef[RuntimeEvent]], checkWindow: Option[Int], endTick: Long, - ): Behavior[Incoming] = Behaviors.receivePartial { + ): Behavior[Request] = Behaviors.receivePartial { case (_, ScheduleActivation(actor, tick, _)) => inactive( TimeAdvancerData(simulation, actor, endTick), @@ -76,7 +76,7 @@ object TimeAdvancer { notifier: Option[RuntimeNotifier], startingTick: Long, nextActiveTick: Long, - ): Behavior[Incoming] = Behaviors.receivePartial { + ): Behavior[Request] = Behaviors.receivePartial { case (_, Start(pauseTick)) => val updatedNotifier = notifier.map { _.starting( @@ -113,7 +113,7 @@ object TimeAdvancer { notifier: Option[RuntimeNotifier], activeTick: Long, pauseTick: Option[Long], - ): Behavior[Incoming] = Behaviors.receivePartial { + ): Behavior[Request] = Behaviors.receivePartial { case (ctx, Completion(_, maybeNewTick)) => checkCompletion(activeTick, maybeNewTick) .map(endWithFailure(ctx, notifier, activeTick, _)) @@ -179,7 +179,7 @@ object TimeAdvancer { private def endSuccessfully( data: TimeAdvancerData, notifier: Option[RuntimeNotifier], - ): Behavior[Incoming] = { + ): Behavior[Request] = { data.simulation ! SimonaSim.SimulationEnded notifier.foreach { @@ -193,11 +193,11 @@ object TimeAdvancer { } private def endWithFailure( - ctx: ActorContext[Incoming], + ctx: ActorContext[Request], notifier: Option[RuntimeNotifier], tick: Long, errorMsg: String, - ): Behavior[Incoming] = { + ): Behavior[Request] = { notifier.foreach(_.error(tick, errorMsg)) stopOnError(ctx, errorMsg) diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 9dcb820b6e..a18bff6a5e 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -34,17 +34,17 @@ import org.apache.pekko.actor.{ActorRef => ClassicRef} */ object SimonaSim { - sealed trait Incoming + sealed trait Request /** Starts simulation by activating the next (or first) tick */ final case class Start( starter: ActorRef[SimonaEnded] - ) extends Incoming + ) extends Request /** Indicate that the simulation has ended successfully */ - case object SimulationEnded extends Incoming + case object SimulationEnded extends Request - def apply(simonaSetup: SimonaSetup): Behavior[Incoming] = + def apply(simonaSetup: SimonaSetup): Behavior[Request] = Behaviors.receivePartial { case (ctx, startMsg @ Start(starter)) => // We redirect to initializing behavior so that starter ref // is available in case of a sudden termination of this actor @@ -62,9 +62,9 @@ object SimonaSim { private def initializing( simonaSetup: SimonaSetup, starter: ActorRef[SimonaEnded], - ): Behavior[Incoming] = + ): Behavior[Request] = Behaviors - .receivePartial[Incoming] { case (ctx, Start(_)) => + .receivePartial[Request] { case (ctx, Start(_)) => val resultEventListeners = simonaSetup.resultEventListener(ctx) @@ -145,8 +145,8 @@ object SimonaSim { Behaviors.stopped } - private def idle(actorData: ActorData): Behavior[Incoming] = Behaviors - .receivePartial[Incoming] { case (ctx, SimulationEnded) => + private def idle(actorData: ActorData): Behavior[Request] = Behaviors + .receivePartial[Request] { case (ctx, SimulationEnded) => // if the simulation is successful, we're waiting for the event // listeners to terminate and thus do not unwatch them here ctx.log.info( @@ -189,7 +189,7 @@ object SimonaSim { ctx: ActorContext[_], actorData: ActorData, simulationSuccessful: Boolean, - ): Behavior[Incoming] = { + ): Behavior[Request] = { actorData.watchedActors.foreach { ref => ctx.unwatch(ref) ctx.stop(ref) @@ -215,7 +215,7 @@ object SimonaSim { starter: ActorRef[SimonaEnded], remainingListeners: Seq[ActorRef[_]], simulationSuccessful: Boolean, - ): Behavior[Incoming] = Behaviors.receiveSignal[Incoming] { + ): Behavior[Request] = Behaviors.receiveSignal[Request] { case (ctx, Terminated(actor)) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) @@ -248,7 +248,7 @@ object SimonaSim { starter: ActorRef[SimonaEnded], watchedActors: Iterable[ActorRef[_]], extSimAdapters: Iterable[ClassicRef], - runtimeEventListener: ActorRef[RuntimeEventListener.Incoming], + runtimeEventListener: ActorRef[RuntimeEventListener.Request], delayedStoppingActors: Seq[ActorRef[DelayedStopHelper.StoppingMsg]], ) } diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index fcb6f2510d..71b4dbf720 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -44,7 +44,7 @@ trait SimonaSetup { */ def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEventListener.Incoming] + ): ActorRef[RuntimeEventListener.Request] /** Creates a sequence of system participant event listeners * @@ -55,7 +55,7 @@ trait SimonaSetup { */ def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultEventListener.Incoming]] + ): Seq[ActorRef[ResultEventListener.Request]] /** Creates a primary service proxy. The proxy is the first instance to ask * for primary data. If necessary, it delegates the registration request to @@ -117,7 +117,7 @@ trait SimonaSetup { context: ActorContext[_], simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], - ): ActorRef[TimeAdvancer.Incoming] + ): ActorRef[TimeAdvancer.Request] /** Creates a scheduler service * @@ -130,7 +130,7 @@ trait SimonaSetup { */ def scheduler( context: ActorContext[_], - timeAdvancer: ActorRef[TimeAdvancer.Incoming], + timeAdvancer: ActorRef[TimeAdvancer.Request], ): ActorRef[SchedulerMessage] /** Creates all the needed grid agents diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index b1c9e45e9f..449391259a 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -250,7 +250,7 @@ class SimonaStandaloneSetup( context: ActorContext[_], simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], - ): ActorRef[TimeAdvancer.Incoming] = { + ): ActorRef[TimeAdvancer.Request] = { val startDateTime = TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.startDateTime ) @@ -271,7 +271,7 @@ class SimonaStandaloneSetup( override def scheduler( context: ActorContext[_], - timeAdvancer: ActorRef[TimeAdvancer.Incoming], + timeAdvancer: ActorRef[TimeAdvancer.Request], ): ActorRef[SchedulerMessage] = context .spawn( @@ -281,7 +281,7 @@ class SimonaStandaloneSetup( override def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEventListener.Incoming] = + ): ActorRef[RuntimeEventListener.Request] = context .spawn( RuntimeEventListener( @@ -294,7 +294,7 @@ class SimonaStandaloneSetup( override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultEventListener.Incoming]] = { + ): Seq[ActorRef[ResultEventListener.Request]] = { // append ResultEventListener as well to write raw output files ArgsParser .parseListenerConfigOption(simonaConfig.simona.event.listener) diff --git a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala index 638cc54731..eaa77ef996 100644 --- a/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala +++ b/src/test/scala/edu/ie3/simona/scheduler/TimeAdvancerSpec.scala @@ -38,7 +38,7 @@ class TimeAdvancerSpec "The TimeAdvancer should work correctly" when { "started checkWindow but without pauseTick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -136,7 +136,7 @@ class TimeAdvancerSpec } "started without checkWindow and pauseTick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -188,7 +188,7 @@ class TimeAdvancerSpec } "paused and started after initialization" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -262,7 +262,7 @@ class TimeAdvancerSpec } "paused and started and there is a gap between StartSchedule tick and next activation tick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -350,7 +350,7 @@ class TimeAdvancerSpec } "paused and endTick - pauseScheduleAtTick == 1" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -428,7 +428,7 @@ class TimeAdvancerSpec } "activation has been scheduled after endTick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -478,7 +478,7 @@ class TimeAdvancerSpec } "no next trigger has been supplied" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -538,7 +538,7 @@ class TimeAdvancerSpec } "endTick < pauseScheduleAtTick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -588,7 +588,7 @@ class TimeAdvancerSpec } "endTick == pauseScheduleAtTick" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") @@ -641,7 +641,7 @@ class TimeAdvancerSpec "The TimeAdvancer should fail and stop" when { "wrong next tick has been supplied" in { - val simulation = TestProbe[SimonaSim.Incoming]("simulation") + val simulation = TestProbe[SimonaSim.Request]("simulation") val scheduler = TestProbe[Activation]("scheduler") val listener = TestProbe[RuntimeEvent]("listener") diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index bddcb62eaa..66c8854acb 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -46,10 +46,10 @@ class SimonaSimSpec "receiving SimulationEnded from TimeAdvancer" in { val starter = TestProbe[SimonaEnded]("starter") val runtimeListener = - TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + TestProbe[RuntimeEventListener.Request]("runtimeEventListener") val resultListener = - TestProbe[ResultEventListener.Incoming]("resultEventListener") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + TestProbe[ResultEventListener.Request]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Request]("timeAdvancer") val extSimAdapter = TestProbe[ExtSimAdapter.Stop]("extSimAdapter") val simonaSim = spawn( @@ -106,10 +106,10 @@ class SimonaSimSpec "child stops due to thrown exception" in { val starter = TestProbe[SimonaEnded]("starter") val runtimeListener = - TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + TestProbe[RuntimeEventListener.Request]("runtimeEventListener") val resultListener = - TestProbe[ResultEventListener.Incoming]("resultEventListener") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + TestProbe[ResultEventListener.Request]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Request]("timeAdvancer") val receiveThrowingActor = TestProbe[ActorRef[SchedulerMessage]]("receiveThrowingActor") @@ -124,7 +124,7 @@ class SimonaSimSpec override def scheduler( context: ActorContext[_], - timeAdvancer: ActorRef[TimeAdvancer.Incoming], + timeAdvancer: ActorRef[TimeAdvancer.Request], ): ActorRef[SchedulerMessage] = { val throwingActor = context .spawn[SchedulerMessage]( @@ -171,10 +171,10 @@ class SimonaSimSpec "child stops by changing behavior" in { val starter = TestProbe[SimonaEnded]("starter") val runtimeListener = - TestProbe[RuntimeEventListener.Incoming]("runtimeEventListener") + TestProbe[RuntimeEventListener.Request]("runtimeEventListener") val resultListener = - TestProbe[ResultEventListener.Incoming]("resultEventListener") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + TestProbe[ResultEventListener.Request]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Request]("timeAdvancer") val receiveStoppingActor = TestProbe[ActorRef[SchedulerMessage]]("receiveStoppingActor") @@ -189,7 +189,7 @@ class SimonaSimSpec override def scheduler( context: ActorContext[_], - timeAdvancer: ActorRef[TimeAdvancer.Incoming], + timeAdvancer: ActorRef[TimeAdvancer.Request], ): ActorRef[SchedulerMessage] = { val stoppingActor = context.spawn[SchedulerMessage]( @@ -235,11 +235,11 @@ class SimonaSimSpec "RuntimeEventListener stops unexpectedly" in { val starter = TestProbe[SimonaEnded]("starter") val resultListener = - TestProbe[ResultEventListener.Incoming]("resultEventListener") - val timeAdvancer = TestProbe[TimeAdvancer.Incoming]("timeAdvancer") + TestProbe[ResultEventListener.Request]("resultEventListener") + val timeAdvancer = TestProbe[TimeAdvancer.Request]("timeAdvancer") val receiveThrowingActor = - TestProbe[ActorRef[RuntimeEventListener.Incoming]]( + TestProbe[ActorRef[RuntimeEventListener.Request]]( "receiveThrowingActor" ) @@ -253,9 +253,9 @@ class SimonaSimSpec override def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEventListener.Incoming] = { + ): ActorRef[RuntimeEventListener.Request] = { val throwingActor = context - .spawn[RuntimeEventListener.Incoming]( + .spawn[RuntimeEventListener.Request]( throwOnMessage, uniqueName("throwingActor"), ) @@ -274,7 +274,7 @@ class SimonaSimSpec // Initialization has started, mock actors are being created val throwingActor = receiveThrowingActor - .expectMessageType[ActorRef[RuntimeEventListener.Incoming]] + .expectMessageType[ActorRef[RuntimeEventListener.Request]] timeAdvancer.expectMessage(TimeAdvancer.Start()) // Simulation should still "run" at this point @@ -302,7 +302,7 @@ class SimonaSimSpec override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultEventListener.Incoming]] = + ): Seq[ActorRef[ResultEventListener.Request]] = throwTestException() } ), @@ -390,23 +390,23 @@ object SimonaSimSpec { * to */ class MockSetup( - runtimeEventProbe: Option[ActorRef[RuntimeEventListener.Incoming]] = None, - resultEventProbe: Option[ActorRef[ResultEventListener.Incoming]] = None, - timeAdvancerProbe: Option[ActorRef[TimeAdvancer.Incoming]] = None, + runtimeEventProbe: Option[ActorRef[RuntimeEventListener.Request]] = None, + resultEventProbe: Option[ActorRef[ResultEventListener.Request]] = None, + timeAdvancerProbe: Option[ActorRef[TimeAdvancer.Request]] = None, ) extends SimonaSetup { override val args: Array[String] = Array.empty[String] override def runtimeEventListener( context: ActorContext[_] - ): ActorRef[RuntimeEventListener.Incoming] = context.spawn( + ): ActorRef[RuntimeEventListener.Request] = context.spawn( stoppableForwardMessage(runtimeEventProbe), uniqueName("runtimeEventForwarder"), ) override def resultEventListener( context: ActorContext[_] - ): Seq[ActorRef[ResultEventListener.Incoming]] = Seq( + ): Seq[ActorRef[ResultEventListener.Request]] = Seq( context.spawn( stoppableForwardMessage(resultEventProbe), uniqueName("resultEventForwarder"), @@ -429,7 +429,7 @@ object SimonaSimSpec { context: ActorContext[_], simulation: ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: ActorRef[RuntimeEvent], - ): ActorRef[TimeAdvancer.Incoming] = + ): ActorRef[TimeAdvancer.Request] = context.spawn( forwardMessage(timeAdvancerProbe), uniqueName("timeAdvancerForwarder"), @@ -437,7 +437,7 @@ object SimonaSimSpec { override def scheduler( context: ActorContext[_], - timeAdvancer: ActorRef[TimeAdvancer.Incoming], + timeAdvancer: ActorRef[TimeAdvancer.Request], ): ActorRef[SchedulerMessage] = context.spawn(empty, uniqueName("scheduler")) diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index bcfaad931f..7ce97f9ee1 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -12,8 +12,7 @@ import edu.ie3.datamodel.models.input.connector.{ Transformer3WInput, } import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.event.listener.ResultEventListener -import edu.ie3.simona.event.listener.RuntimeEventListener +import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer @@ -31,14 +30,14 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def runtimeEventListener( context: scaladsl.ActorContext[_] - ): typed.ActorRef[RuntimeEventListener.Incoming] = // todo typed + ): typed.ActorRef[RuntimeEventListener.Request] = // todo typed throw new NotImplementedException( "This is a dummy setup" ) override def resultEventListener( context: scaladsl.ActorContext[_] - ): Seq[typed.ActorRef[ResultEventListener.Incoming]] = + ): Seq[typed.ActorRef[ResultEventListener.Request]] = throw new NotImplementedException("This is a dummy setup") override def primaryServiceProxy( @@ -62,13 +61,13 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { context: scaladsl.ActorContext[_], simulation: typed.ActorRef[SimonaSim.SimulationEnded.type], runtimeEventListener: typed.ActorRef[RuntimeEvent], - ): typed.ActorRef[TimeAdvancer.Incoming] = throw new NotImplementedException( + ): typed.ActorRef[TimeAdvancer.Request] = throw new NotImplementedException( "This is a dummy setup" ) override def scheduler( context: scaladsl.ActorContext[_], - timeAdvancer: typed.ActorRef[TimeAdvancer.Incoming], + timeAdvancer: typed.ActorRef[TimeAdvancer.Request], ): typed.ActorRef[SchedulerMessage] = throw new NotImplementedException( "This is a dummy setup" ) From 22ffbfd86a6575aab47ad70ce59404b2b72b611b Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 15:47:43 +0100 Subject: [PATCH 266/305] Providing ScalaDoc --- .../event/listener/DelayedStopHelper.scala | 13 ++- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 107 +++++++++++------- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala index b4da2e06ec..c6d8cea4d5 100644 --- a/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala +++ b/src/main/scala/edu/ie3/simona/event/listener/DelayedStopHelper.scala @@ -11,18 +11,23 @@ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import scala.concurrent.duration.DurationInt -/** todo +/** Helper that provides functionality for delayed stopping of actors, i.e. upon + * receiving [[FlushAndStop]], the actor is stopped after a fixed amount of + * time after the last message has been received */ object DelayedStopHelper { + /** Note: Needs to extend be message traits for actors that want to use this + * functionality + */ sealed trait StoppingMsg extends ResultEventListener.Request with RuntimeEventListener.Request /** Message indicating that [[RuntimeEventListener]] should stop. Instead of - * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop()]], this - * way of stopping allows all messages that have been queued before to be - * processed. todo + * using [[org.apache.pekko.actor.typed.scaladsl.ActorContext.stop]], this + * way of stopping allows the current mailbox to be processed, plus more + * messages that are pending to be received. */ case object FlushAndStop extends StoppingMsg diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index a18bff6a5e..47bc4bf860 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -19,31 +19,34 @@ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior, PostStop, Terminated} import org.apache.pekko.actor.{ActorRef => ClassicRef} -/** Main entrance point to a simona simulation as top level actor. This actors - * allows to control the simulation in the sense that messages for - * initialization and time steps can be send to this actor and will be handled - * accordingly. This actor does NOT report back any simulation status except of - * if the overall simulation has been successful or not. For specific status +/** Main entrance point to a simona simulation as the guardian actor. This actor + * starts the initialization of all actors and waits for the simulation to end. + * This actor does NOT report back any simulation status except of if the + * overall simulation has been successful or not. For specific status * information, the user needs to pass in and subscribe to the corresponding * listener e.g. [[edu.ie3.simona.event.listener.RuntimeEventListener]] for * simulation status or [[edu.ie3.simona.event.listener.ResultEventListener]] * for result events * - * @version 0.1 * @since 01.07.20 */ object SimonaSim { sealed trait Request - /** Starts simulation by activating the next (or first) tick */ + /** Starts the initialization and then the simulation itself */ final case class Start( starter: ActorRef[SimonaEnded] ) extends Request - /** Indicate that the simulation has ended successfully */ + /** Indicates that the simulation has ended successfully */ case object SimulationEnded extends Request + /** Creates a new [[SimonaSim]] behavior + * + * @param simonaSetup + * The setup instructions + */ def apply(simonaSetup: SimonaSetup): Behavior[Request] = Behaviors.receivePartial { case (ctx, startMsg @ Start(starter)) => // We redirect to initializing behavior so that starter ref @@ -54,7 +57,8 @@ object SimonaSim { /** Initializing behavior that is separated from [[apply]] above only because * in case of a sudden stop of this actor itself (PostStop signal), the - * [[SimonaEnded]] message is sent to the starter + * ActorRef of the starter also needs to be available for sending + * [[SimonaEnded]] * * @param starter * The starter ref that needs to be notified once simulation has ended @@ -117,7 +121,7 @@ object SimonaSim { // Start simulation timeAdvancer ! TimeAdvancer.Start() - val watchedActors = Iterable( + val otherActors = Iterable( timeAdvancer, scheduler, primaryServiceProxy.toTyped, @@ -129,26 +133,26 @@ object SimonaSim { idle( ActorData( starter, - watchedActors, extSimulationData.extSimAdapters, runtimeEventListener, resultEventListeners.appended(runtimeEventListener), + otherActors, ) ) } .receiveSignal { case (_, PostStop) => // Something must have gone wrong during initialization above - // (could have been an exception thrown), there's nothing much - // we can do here besides notifying starter + // (probably an unexpected exception thrown), there's nothing + // much we can do here besides notifying starter starter ! SimonaEnded(successful = false) Behaviors.stopped } + /** Behavior that is active while the simulation is running + */ private def idle(actorData: ActorData): Behavior[Request] = Behaviors .receivePartial[Request] { case (ctx, SimulationEnded) => - // if the simulation is successful, we're waiting for the event - // listeners to terminate and thus do not unwatch them here ctx.log.info( "Simulation terminated successfully. Stopping children and waiting for results to flush out..." ) @@ -165,8 +169,9 @@ object SimonaSim { ) .map { data => ctx.log.error( - "An actor ({}) unexpectedly terminated. Shut down all children gracefully and report simulation " + - "failure. See logs and possible stacktrace for details.", + "An actor ({}) unexpectedly terminated. " + + "Stopping all children and reporting simulation failure. " + + "See logs and possibly stacktrace for details.", actor, ) @@ -180,17 +185,15 @@ object SimonaSim { .get } - /** @param ctx - * @param actorData - * @param simulationSuccessful - * @return + /** Stops all children that can be stopped right away, and requests children + * with delayed stops to stop */ private def stopChildren( ctx: ActorContext[_], actorData: ActorData, simulationSuccessful: Boolean, ): Behavior[Request] = { - actorData.watchedActors.foreach { ref => + actorData.otherActors.foreach { ref => ctx.unwatch(ref) ctx.stop(ref) } @@ -200,17 +203,22 @@ object SimonaSim { ref ! ExtSimAdapter.Stop(simulationSuccessful) } + // if the simulation is successful, we're waiting for the delayed + // stopping listeners to terminate and thus do not unwatch them here actorData.delayedStoppingActors.foreach( _ ! DelayedStopHelper.FlushAndStop ) - waitingForListener( + maybeStop( + ctx, actorData.starter, actorData.delayedStoppingActors, simulationSuccessful, ) } + /** Behavior that waits for all remaining actors with delayed stops to stop + */ private def waitingForListener( starter: ActorRef[SimonaEnded], remainingListeners: Seq[ActorRef[_]], @@ -219,36 +227,55 @@ object SimonaSim { case (ctx, Terminated(actor)) if remainingListeners.contains(actor) => val updatedRemainingListeners = remainingListeners.filterNot(_ == actor) - if (updatedRemainingListeners.isEmpty) { - ctx.log.info( - "All result listeners have terminated. Ending simulation successfully." - ) + maybeStop(ctx, starter, updatedRemainingListeners, simulationSuccessful) + } + + /** Stopping this actor and notifying starter if all actors with delayed stops + * have stopped + */ + private def maybeStop( + ctx: ActorContext[_], + starter: ActorRef[SimonaEnded], + remainingListeners: Seq[ActorRef[_]], + simulationSuccessful: Boolean, + ): Behavior[Request] = { + if (remainingListeners.isEmpty) { + ctx.log.debug( + "All actors with delayed stops have terminated. Ending simulation." + ) - starter ! SimonaEnded(simulationSuccessful) + starter ! SimonaEnded(simulationSuccessful) - Behaviors.stopped - } else { - waitingForListener( - starter, - updatedRemainingListeners, - simulationSuccessful, - ) - } + Behaviors.stopped + } else { + waitingForListener( + starter, + remainingListeners, + simulationSuccessful, + ) + } } - /** TODO scaladoc + /** Data object that mostly holds information about children of this actor + * * @param starter - * @param watchedActors - * excluding ExtSimAdapters, ResultListeners, RuntimeEventListener + * The ActorRef that started the simulation and should be notified about + * its end * @param extSimAdapters + * [[ExtSimAdapter]]s need to receive a [[ExtSimAdapter.Stop]] message * @param runtimeEventListener + * The [[RuntimeEventListener]] that possibly receives an error event * @param delayedStoppingActors + * The actors that are stopped with delay + * @param otherActors + * All remaining children (excluding ExtSimAdapters, ResultListeners and + * RuntimeEventListener) */ private final case class ActorData( starter: ActorRef[SimonaEnded], - watchedActors: Iterable[ActorRef[_]], extSimAdapters: Iterable[ClassicRef], runtimeEventListener: ActorRef[RuntimeEventListener.Request], delayedStoppingActors: Seq[ActorRef[DelayedStopHelper.StoppingMsg]], + otherActors: Iterable[ActorRef[_]], ) } From dbf2b8ed429982fa601ba48b3e848d875aa86c6f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 15:52:27 +0100 Subject: [PATCH 267/305] Only print logs to console when test fails --- src/test/resources/logback-test.xml | 36 ++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index b2c5260199..79b160e703 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -1,27 +1,25 @@ - + %highlight%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - OFF - + test/logs/simona/simona_tests.log - test/logs/simona/archive/simona_tests-%d{yyyyMMdd'T'HHmmss}-${bySecond}.log - + test/logs/simona/archive/simona_tests-%d{yyyyMMdd'T'HHmmss}.log + 10 3GB @@ -32,8 +30,30 @@ DEBUG - + + + + + + + + + + + + \ No newline at end of file From b0ffaeeca60f79e4ec18f16762c683423e25f039 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 15:53:51 +0100 Subject: [PATCH 268/305] Enabling test logs for all UnitSpecs --- src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala index a61f4b7879..bc6f2811b5 100644 --- a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala @@ -6,15 +6,17 @@ package edu.ie3.simona.test.common -import java.util.Locale import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.test.matchers.{QuantityMatchers, SquantsMatchers} import edu.ie3.util.scala.quantities.{QuantityUtil => PSQuantityUtil} +import org.apache.pekko.actor.testkit.typed.scaladsl.LogCapturing import org.scalatest._ import org.scalatest.matchers.should import org.scalatest.prop.TableDrivenPropertyChecks import org.scalatest.wordspec.AnyWordSpecLike +import java.util.Locale + /** Base class to be used with all scala unit tests. All data that should be * commonly available to all unit tests should be placed here instead of mixing * a lot of traits together. See @@ -25,6 +27,7 @@ import org.scalatest.wordspec.AnyWordSpecLike */ trait UnitSpec extends should.Matchers + with LogCapturing with QuantityMatchers with SquantsMatchers with AnyWordSpecLike From 6bbde67388076f7716b6631ee681f18e23f31e06 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 15:54:32 +0100 Subject: [PATCH 269/305] Adding changelog line --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2513a80be2..bfd2eddf99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added capability of SystemParticipants to handle flexibility [#308](https://github.com/ie3-institute/simona/issues/308) - Added smart charging logic [#31](https://github.com/ie3-institute/simona/issues/31) and flex calculation in `EvcsAgent` [#332](https://github.com/ie3-institute/simona/issues/332) - Enhance output quotes of `RunSimona` [#743](https://github.com/ie3-institute/simona/issues/743) +- Printing logs of failed tests [#747](https://github.com/ie3-institute/simona/issues/747) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) From 1964ee03d82822b352bef60faea37f9095839dd6 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 15:56:34 +0100 Subject: [PATCH 270/305] move failFast of superiorGridGates back to GridAgent --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 20 +++++++++-- .../edu/ie3/simona/model/grid/GridModel.scala | 16 +-------- .../edu/ie3/simona/model/grid/GridSpec.scala | 34 ++++--------------- 3 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 5a7d265835..fd4f7934bc 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -12,11 +12,13 @@ import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentInitData, GridAgentUninitializedData, } +import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.{Initializing, SimulateGrid} import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.model.grid.GridModel +import edu.ie3.simona.exceptions.agent.GridAgentInitializationException + import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, @@ -93,6 +95,7 @@ object GridAgent { */ final case class FinishGridSimulationTrigger(tick: Long) } + class GridAgent( val environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, @@ -154,6 +157,9 @@ class GridAgent( Activation(INIT_SIM_TICK), gridAgentInitData: GridAgentInitData, ) => + // fail fast sanity checks + failFast(gridAgentInitData) + log.debug( s"Inferior Subnets: {}; Inferior Subnet Nodes: {}", gridAgentInitData.inferiorGridIds, @@ -185,8 +191,7 @@ class GridAgent( TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime ), - gridAgentInitData, - simonaConfig, + simonaConfig ) /* Reassure, that there are also calculation models for the given uuids */ @@ -267,4 +272,13 @@ class GridAgent( // everything else whenUnhandled(myUnhandled()) + private def failFast(gridAgentInitData: GridAgentInitData): Unit = { + if ( + gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty + ) + throw new GridAgentInitializationException( + s"$actorName has neither superior nor inferior grids! This can either " + + s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" + ) + } } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 69739a005c..94ad793968 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -70,14 +70,12 @@ object GridModel { refSystem: RefSystem, startDate: ZonedDateTime, endDate: ZonedDateTime, - gridAgentInitData: GridAgentInitData, simonaConfig: SimonaConfig, ): GridModel = buildAndValidate( subGridContainer, refSystem, startDate, endDate, - gridAgentInitData, simonaConfig, ) @@ -458,15 +456,6 @@ object GridModel { } - private def checkForGridGates(gridAgentInitData: GridAgentInitData): Unit = { - if ( - gridAgentInitData.superiorGridGates.isEmpty && gridAgentInitData.inferiorGridGates.isEmpty - ) - throw new GridAgentInitializationException( - s"${gridAgentInitData.subGridContainer.getGridName} has neither superior nor inferior grids! This can either " + - s"be cause by wrong subnetGate information or invalid parametrization of the simulation!" - ) - } /** Checks all ControlGroups if a) Transformer of ControlGroup and Measurement * belongs to the same sub grid. b) Measurements are measure voltage @@ -529,7 +518,6 @@ object GridModel { refSystem: RefSystem, startDate: ZonedDateTime, endDate: ZonedDateTime, - gridAgentInitData: GridAgentInitData, simonaConfig: SimonaConfig, ): GridModel = { @@ -650,9 +638,7 @@ object GridModel { // validate validateConsistency(gridModel) validateConnectivity(gridModel) - checkForGridGates(gridAgentInitData) - checkControlGroupsForMeasurement( - gridAgentInitData.subGridContainer, + checkControlGroupsForMeasurement(subGridContainer, simonaConfig.simona.control, ) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index c874a19d00..862a7175fc 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -10,36 +10,28 @@ import java.util.UUID import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs + import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils -import edu.ie3.simona.agent.grid.DBFSMockGridAgents -import edu.ie3.simona.config.SimonaConfig + import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} -import edu.ie3.simona.test.common.model.grid.{ - BasicGrid, - BasicGridWithSwitches, - FiveLinesWithNodes, -} -import edu.ie3.simona.test.common.{DefaultTestData, UnitSpec} +import edu.ie3.simona.test.common.model.grid.{BasicGrid, BasicGridWithSwitches, FiveLinesWithNodes} +import edu.ie3.simona.test.common.{ConfigTestData, DefaultTestData, , UnitSpec} import testutils.TestObjectFactory -import edu.ie3.simona.test.common.model.grid.DbfsTestGrid -import org.apache.pekko.testkit.TestProbe -import edu.ie3.simona.test.common.ConfigTestData + import scala.jdk.CollectionConverters.SetHasAsJava -import edu.ie3.datamodel.models.input.container.ThermalGrid -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData + import edu.ie3.simona.model.grid.GridModel.GridComponents + class GridSpec extends UnitSpec with LineInputTestData with DefaultTestData - with DbfsTestGrid - with DBFSMockGridAgents with ConfigTestData { private val _printAdmittanceMatrixOnMismatch @@ -561,23 +553,11 @@ class GridSpec } "process a valid GridInputModel without an Exception" in new GridInputTestData { - val simonaConfig: SimonaConfig = SimonaConfig(typesafeConfig) - private val superiorGridAgent = SuperiorGA( - TestProbe("superiorGridAgent_1000"), - Seq(supNodeA.getUuid), - ) - GridModel( validTestGridInputModel, gridInputModelTestDataRefSystem, defaultSimulationStart, defaultSimulationEnd, - GridAgentInitData( - hvGridContainer, - Seq.empty[ThermalGrid], - superiorGridAgent.ref, - RefSystem("2000 MVA", "110 kV"), - ), simonaConfig, ) } From a4edc1d1849b30a130ea8a943a9c8a829147b7ba Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 15:57:57 +0100 Subject: [PATCH 271/305] fmt --- .../scala/edu/ie3/simona/agent/grid/GridAgent.scala | 2 +- .../scala/edu/ie3/simona/model/grid/GridModel.scala | 4 ++-- .../scala/edu/ie3/simona/model/grid/GridSpec.scala | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index fd4f7934bc..e4dcca569f 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -191,7 +191,7 @@ class GridAgent( TimeUtil.withDefaults.toZonedDateTime( simonaConfig.simona.time.endDateTime ), - simonaConfig + simonaConfig, ) /* Reassure, that there are also calculation models for the given uuids */ diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 94ad793968..da108c62e9 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -456,7 +456,6 @@ object GridModel { } - /** Checks all ControlGroups if a) Transformer of ControlGroup and Measurement * belongs to the same sub grid. b) Measurements are measure voltage * magnitude. @@ -638,7 +637,8 @@ object GridModel { // validate validateConsistency(gridModel) validateConnectivity(gridModel) - checkControlGroupsForMeasurement(subGridContainer, + checkControlGroupsForMeasurement( + subGridContainer, simonaConfig.simona.control, ) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 862a7175fc..49ada4cf9e 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -18,16 +18,18 @@ import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} -import edu.ie3.simona.test.common.model.grid.{BasicGrid, BasicGridWithSwitches, FiveLinesWithNodes} -import edu.ie3.simona.test.common.{ConfigTestData, DefaultTestData, , UnitSpec} +import edu.ie3.simona.test.common.model.grid.{ + BasicGrid, + BasicGridWithSwitches, + FiveLinesWithNodes, +} +import edu.ie3.simona.test.common.{ConfigTestData, DefaultTestData, UnitSpec} import testutils.TestObjectFactory - import scala.jdk.CollectionConverters.SetHasAsJava import edu.ie3.simona.model.grid.GridModel.GridComponents - class GridSpec extends UnitSpec with LineInputTestData From 11bdb7f2a3c1de9ba0281062c372eaaddd97f89e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 21 Feb 2024 15:58:15 +0100 Subject: [PATCH 272/305] fmt --- .../TransformerControlGroupModel.scala | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index d45888ec0c..737ea0217f 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -158,56 +158,56 @@ object TransformerControlGroupModel { case _ => None } } -} -private def harmonizationFunction - : Array[Dimensionless] => Option[Dimensionless] = - (regulationRequests: Array[Dimensionless]) => { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) - val positiveRequests = regulationRequests.filter(_ > Each(0d)) + private def harmonizationFunction + : Array[Dimensionless] => Option[Dimensionless] = + (regulationRequests: Array[Dimensionless]) => { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None + } - } + } -/** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param nodeUuids - * Collection of all relevant node uuids - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ -private def buildTransformerControlModels( - nodeUuids: Set[UUID], - vMax: Double, - vMin: Double, -): TransformerControlGroupModel = { - /* Determine the voltage regulation criterion for each of the available nodes */ - val voltage = Each(1.0) - val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> regulationFunction(voltage, vMax, vMin) - }.toMap + /** Build a single control group model. Currently, only limit violation + * prevention logic is captured: The nodal regulation need is equal to the + * voltage change needed to comply with the given thresholds + * + * @param nodeUuids + * Collection of all relevant node uuids + * @param vMax + * Upper permissible voltage magnitude + * @param vMin + * Lower permissible voltage magnitude + * @return + * A [[TransformerControlGroupModel]] + */ + private def buildTransformerControlModels( + nodeUuids: Set[UUID], + vMax: Double, + vMin: Double, + ): TransformerControlGroupModel = { + /* Determine the voltage regulation criterion for each of the available nodes */ + val voltage = Complex(1.0, 0.0) + val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => + uuid -> regulationFunction(voltage, vMax, vMin) + }.toMap - TransformerControlGroupModel( - nodeUuidToRegulationCriterion, - harmonizationFunction, - ) + TransformerControlGroupModel( + nodeUuidToRegulationCriterion, + harmonizationFunction, + ) + } } From d9e8053857e0d7e2963f2e9dc707052306470735 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 16:05:32 +0100 Subject: [PATCH 273/305] Fixes --- src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala | 3 +-- .../event/listener/RuntimeEventListenerKafkaSpec.scala | 2 +- .../simona/event/listener/RuntimeEventListenerSpec.scala | 8 ++------ src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala b/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala index ede6b3043b..58f545e21d 100644 --- a/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/ValueStoreSpec.scala @@ -7,11 +7,10 @@ package edu.ie3.simona.agent import edu.ie3.simona.test.common.UnitSpec -import org.scalatest.PrivateMethodTester import scala.collection.SortedMap -class ValueStoreSpec extends UnitSpec with PrivateMethodTester { +class ValueStoreSpec extends UnitSpec { "An empty value store" should { val emptyValueStore: ValueStore[String] = ValueStore[String](Long.MaxValue) diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala index 03d3545389..b2f8393ace 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerKafkaSpec.scala @@ -31,8 +31,8 @@ import scala.language.postfixOps class RuntimeEventListenerKafkaSpec extends ScalaTestWithActorTestKit - with KafkaSpecLike with UnitSpec + with KafkaSpecLike with GivenWhenThen with TableDrivenPropertyChecks { private var testConsumer: KafkaConsumer[Bytes, SimonaEndMessage] = _ diff --git a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala index f547693e08..92186149bc 100644 --- a/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/event/listener/RuntimeEventListenerSpec.scala @@ -24,11 +24,9 @@ import edu.ie3.simona.event.RuntimeEvent.{ Ready, Simulating, } +import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.util.TickUtil._ import edu.ie3.util.TimeUtil -import org.scalatest.PrivateMethodTester -import org.scalatest.matchers.should -import org.scalatest.wordspec.AnyWordSpecLike import org.slf4j.event.Level import java.util.concurrent.{LinkedBlockingQueue, TimeUnit} @@ -42,9 +40,7 @@ class RuntimeEventListenerSpec ConfigValueFactory.fromAnyRef("30s"), ) ) - with AnyWordSpecLike - with should.Matchers - with PrivateMethodTester { + with UnitSpec { // global variables val startDateTimeString = "2011-01-01 00:00:00" diff --git a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala index bc6f2811b5..5cbf725051 100644 --- a/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala +++ b/src/test/scala/edu/ie3/simona/test/common/UnitSpec.scala @@ -27,10 +27,10 @@ import java.util.Locale */ trait UnitSpec extends should.Matchers - with LogCapturing with QuantityMatchers with SquantsMatchers with AnyWordSpecLike + with LogCapturing with OptionValues with Inside with Inspectors From f4d6abcc89c9d75118fe0fd4071f472b96231731 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 21 Feb 2024 18:01:28 +0100 Subject: [PATCH 274/305] Added line to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfd2eddf99..2f64e9f668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enable windows path as config parameters [#549](https://github.com/ie3-institute/simona/issues/549) - Unified consideration of scaling factor when simulating system participants [#81](https://github.com/ie3-institute/simona/issues/81) - Small improvements in `ResultEventListener` [#738](https://github.com/ie3-institute/simona/issues/738) +- Converting `SimonaSim` to pekko typed/terminating SimonSim when initialization fails [#210](https://github.com/ie3-institute/simona/issues/210) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) From cf4fd39261267ae1a228a9e5e960359fc922d32e Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 22 Feb 2024 11:22:42 +0100 Subject: [PATCH 275/305] Reverting unnecessary changes --- gradle/scripts/tscfg.gradle | 2 +- src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gradle/scripts/tscfg.gradle b/gradle/scripts/tscfg.gradle index 0f94fba657..e81ad99320 100644 --- a/gradle/scripts/tscfg.gradle +++ b/gradle/scripts/tscfg.gradle @@ -47,7 +47,7 @@ task genConfigSample { args = [ "build/tscfg-${tscfgVersion}.jar", "--spec", - "src/main/resources/config/simona-config-template.conf", + "src/main/resources/config/config-template.conf", "--tpl", "input/samples/configSample.conf" ] diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index e4dcca569f..78a30ea294 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -12,13 +12,12 @@ import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentInitData, GridAgentUninitializedData, } -import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.agent.state.AgentState.{Idle, Uninitialized} import edu.ie3.simona.agent.state.GridAgentState.{Initializing, SimulateGrid} import edu.ie3.simona.agent.{EnvironmentRefs, SimonaAgent} import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.agent.GridAgentInitializationException - +import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.ontology.messages.PowerMessage.RequestGridPowerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, @@ -28,8 +27,8 @@ import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil -import org.apache.pekko.actor.{ActorRef, Props, Stash} import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps +import org.apache.pekko.actor.{ActorRef, Props, Stash} import java.time.ZonedDateTime import java.time.temporal.ChronoUnit From a34064a12a719e1615833e461dc91290e91c8c79 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Thu, 22 Feb 2024 12:21:09 +0100 Subject: [PATCH 276/305] Some minor internal changes to the `GridAgent`. --- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 48 +------------------ .../edu/ie3/simona/agent/grid/GridAgent.scala | 43 +++++++++++++++++ .../simona/agent/grid/GridAgentMessage.scala | 7 +-- .../simona/agent/grid/ReceivedValues.scala | 4 +- .../simona/agent/grid/VoltageMessage.scala | 4 +- 5 files changed, 50 insertions(+), 56 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index 8e203c7b11..10987efa0d 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -15,6 +15,7 @@ import edu.ie3.powerflow.model.PowerFlowResult import edu.ie3.powerflow.model.PowerFlowResult.FailedPowerFlowResult.FailedNewtonRaphsonPFResult import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.powerflow.model.enums.NodeType +import edu.ie3.simona.agent.grid.GridAgent.idle import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, GridAgentValues, @@ -62,51 +63,6 @@ import scala.util.{Failure, Success} */ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { - /** Method that defines the idle [[Behavior]] of the agent. - * @param gridAgentBaseData - * state data of the actor - * @param values - * immutable [[GridAgent]] values - * @param buffer - * for [[GridAgentMessage]]s - * @return - * a [[Behavior]] - */ - protected def idle( - gridAgentBaseData: GridAgentBaseData - )(implicit - values: GridAgentValues, - buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - case (_, pm: WrappedPowerMessage) => - // needs to be set here to handle if the messages arrive too early - // before a transition to GridAgentBehaviour took place - buffer.stash(pm) - Behaviors.same - - case (_, WrappedActivation(activation: Activation)) => - values.environmentRefs.scheduler ! Completion( - values.activationAdapter, - Some(activation.tick), - ) - buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) - - case (ctx, WrappedResultMessage(StopMessage(_))) => - // shutdown children - gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => - actors.foreach(a => ctx.stop(a)) - } - - // we are done - Behaviors.stopped - - case (_, StopGridAgent) => - Behaviors.stopped - - case _ => - Behaviors.unhandled - } - /** Method that defines the [[Behavior]] for simulating the grid. * @param gridAgentData * state data of the actor @@ -115,7 +71,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * @return * a [[Behavior]] */ - private def simulateGrid( + private[grid] def simulateGrid( gridAgentData: GridAgentData, currentTick: Long, )(implicit diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 19de1b9649..4c6670fbf3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -199,6 +199,49 @@ object GridAgent extends DBFSAlgorithm { Behaviors.unhandled } + /** Method that defines the idle [[Behavior]] of the agent. + * + * @param gridAgentBaseData + * state data of the actor + * @param values + * immutable [[GridAgent]] values + * @param buffer + * for [[GridAgentMessage]]s + * @return + * a [[Behavior]] + */ + private[grid] def idle( + gridAgentBaseData: GridAgentBaseData + )(implicit + values: GridAgentValues, + buffer: StashBuffer[GridAgentMessage], + ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + case (_, pm: WrappedPowerMessage) => + // needs to be set here to handle if the messages arrive too early + // before a transition to GridAgentBehaviour took place + buffer.stash(pm) + Behaviors.same + + case (_, WrappedActivation(activation: Activation)) => + values.environmentRefs.scheduler ! Completion( + values.activationAdapter, + Some(activation.tick), + ) + buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) + + case (ctx, StopGridAgent) => + // shutdown children + gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => + actors.foreach(a => ctx.stop(a)) + } + + // we are done + Behaviors.stopped + + case _ => + Behaviors.unhandled + } + private def failFast( gridAgentInitData: GridAgentInitData, actorName: String, diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala index cc11aa44ac..4a2b4dbe1c 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala @@ -7,10 +7,8 @@ package edu.ie3.simona.agent.grid import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage import edu.ie3.simona.ontology.messages.{Activation, PowerMessage} import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey -import org.apache.pekko.actor.typed.ActorRef /** Trait for [[GridAgent]] messages. */ @@ -24,7 +22,7 @@ object GridAgentMessage { /** Necessary because we want to extend [[GridAgentMessage]] in other classes, * but we do want to keep [[GridAgentMessage]] sealed. */ - private[grid] trait GAMessage extends GridAgentMessage + private[grid] trait InternalMessage extends GridAgentMessage /** GridAgent initialization data can only be constructed once all GridAgent * actors are created. Thus, we need an extra initialization message. @@ -90,7 +88,4 @@ object GridAgentMessage { final case class WrappedPowerMessage(msg: PowerMessage) extends GridAgentMessage - final case class WrappedResultMessage(msg: ResultMessage) - extends GridAgentMessage - } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala index eacda5e019..c1accbb471 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/ReceivedValues.scala @@ -8,13 +8,13 @@ package edu.ie3.simona.agent.grid import edu.ie3.simona.ontology.messages.PowerMessage.PowerResponseMessage import VoltageMessage.ProvideSlackVoltageMessage -import edu.ie3.simona.agent.grid.GridAgentMessage.GAMessage +import edu.ie3.simona.agent.grid.GridAgentMessage.InternalMessage import org.apache.pekko.actor.typed.ActorRef /** Serves as a wrapper class that allows for matches against received values in * [[DBFSAlgorithm]] */ -sealed trait ReceivedValues extends GAMessage +sealed trait ReceivedValues extends InternalMessage object ReceivedValues { diff --git a/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala index bcbffdf609..41c311f61d 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/VoltageMessage.scala @@ -6,14 +6,14 @@ package edu.ie3.simona.agent.grid -import edu.ie3.simona.agent.grid.GridAgentMessage.GAMessage +import edu.ie3.simona.agent.grid.GridAgentMessage.InternalMessage import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import org.apache.pekko.actor.typed.ActorRef import squants.electro.ElectricPotential import java.util.UUID -sealed trait VoltageMessage extends GAMessage +sealed trait VoltageMessage extends InternalMessage /** Message that is send between [[edu.ie3.simona.agent.grid.GridAgent]] s to * provide voltage information for nodes From 932cb1f32c453ce96e49c45e20d0bcfd1ef7a350 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Thu, 22 Feb 2024 14:15:21 +0100 Subject: [PATCH 277/305] Fixing ScalaDoc --- src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index 71b4dbf720..1405141150 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -46,12 +46,12 @@ trait SimonaSetup { context: ActorContext[_] ): ActorRef[RuntimeEventListener.Request] - /** Creates a sequence of system participant event listeners + /** Creates a sequence of result event listeners * * @param context * Actor context to use * @return - * A sequence of actor references to runtime event listeners + * A sequence of actor references to result event listeners */ def resultEventListener( context: ActorContext[_] From 3b51ed3d12f823add6a303c27cce48095271eaab Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Fri, 23 Feb 2024 14:48:01 +0100 Subject: [PATCH 278/305] Adapting to recent changes in `dev` branch. --- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 2 +- .../scala/edu/ie3/simona/sim/SimonaSim.scala | 34 +---- .../ie3/simona/sim/setup/SimonaSetup.scala | 10 +- .../sim/setup/SimonaStandaloneSetup.scala | 24 +--- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 7 +- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 5 +- .../grid/DBFSAlgorithmParticipantSpec.scala | 6 +- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 9 +- .../agent/grid/GridAgentSetup2WSpec.scala | 129 ++++++------------ .../agent/grid/GridAgentSetup3WSpec.scala | 121 ++++++---------- .../ie3/simona/sim/SimonaSimFailSpec.scala | 0 .../edu/ie3/simona/sim/SimonaSimSpec.scala | 8 +- .../simona/sim/setup/SimonaSetupSpec.scala | 54 ++++---- 13 files changed, 132 insertions(+), 277 deletions(-) delete mode 100644 src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index 10987efa0d..c9bb5ddc71 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -32,9 +32,9 @@ import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException import edu.ie3.simona.model.grid.{NodeModel, RefSystem} +import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage._ import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion -import edu.ie3.simona.ontology.messages.{Activation, StopMessage} import edu.ie3.simona.util.TickUtil.TickLong import edu.ie3.util.scala.quantities.Megavars import edu.ie3.util.scala.quantities.SquantsUtils.RichElectricPotential diff --git a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala index 4887f96516..f62dc5e45a 100644 --- a/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala +++ b/src/main/scala/edu/ie3/simona/sim/SimonaSim.scala @@ -6,48 +6,18 @@ package edu.ie3.simona.sim -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorRefOps, - TypedActorRefOps, -} -import org.apache.pekko.actor.SupervisorStrategy.Stop -import org.apache.pekko.actor.{ - Actor, - AllForOneStrategy, - Props, - Stash, - SupervisorStrategy, - Terminated, - ActorRef => classicRef, -} -import com.typesafe.scalalogging.LazyLogging import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgentMessage -import edu.ie3.simona.agent.grid.GridAgentMessage.StopGridAgent import edu.ie3.simona.api.ExtSimAdapter import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{DelayedStopHelper, RuntimeEventListener} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.scheduler.TimeAdvancer -import edu.ie3.simona.scheduler.TimeAdvancer.{Incoming, StartSimMessage} -import edu.ie3.simona.sim.SimMessage.{ - InitSim, - SimulationFailure, - SimulationSuccessful, - StartSimulation, -} -import edu.ie3.simona.sim.SimonaSim.{ - EmergencyShutdownInitiated, - SimonaSimStateData, -} import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import edu.ie3.util.scala.Scope import org.apache.pekko.actor.typed.scaladsl.adapter._ import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors} import org.apache.pekko.actor.typed.{ActorRef, Behavior, PostStop, Terminated} import org.apache.pekko.actor.{ActorRef => ClassicRef} -import org.apache.pekko.actor.typed.ActorRef -import org.apache.pekko.actor.typed.scaladsl.ActorContext /** Main entrance point to a simona simulation as the guardian actor. This actor * starts the initialization of all actors and waits for the simulation to end. @@ -146,7 +116,7 @@ object SimonaSim { extSimulationData.extDataServices.values .map(_.toTyped) .foreach(ctx.watch) - gridAgents.foreach(ref => ctx.watch(ref.toTyped)) + gridAgents.foreach(ref => ctx.watch(ref)) // Start simulation timeAdvancer ! TimeAdvancer.Start() @@ -157,7 +127,7 @@ object SimonaSim { primaryServiceProxy.toTyped, weatherService.toTyped, ) ++ - gridAgents.map(_.toTyped) ++ + gridAgents ++ extSimulationData.extDataServices.values.map(_.toTyped) idle( diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index 98e39cca49..ee850a092d 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -6,22 +6,14 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ - ActorSystem, - ActorContext => classicContext, - ActorRef => classicRef, -} import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} -import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer -import org.apache.pekko.actor.typed.ActorRef -import org.apache.pekko.actor.typed.scaladsl.ActorContext import edu.ie3.simona.sim.SimonaSim import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.typed.scaladsl.ActorContext @@ -157,7 +149,7 @@ trait SimonaSetup { def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[classicRef], + resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], ): Iterable[ActorRef[GridAgentMessage]] /** SIMONA links sub grids connected by a three winding transformer a bit diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index 4c48b75495..d43c2ec4ba 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -11,7 +11,7 @@ import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.graph.SubGridTopologyGraph import edu.ie3.datamodel.models.input.container.{GridContainer, ThermalGrid} import edu.ie3.datamodel.models.input.thermal.ThermalBusInput -import edu.ie3.simona.actor.SimonaActorNaming._ +import edu.ie3.simona.actor.SimonaActorNaming.RichActorRefFactory import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage.CreateGridAgent import edu.ie3.simona.agent.grid.{GridAgent, GridAgentMessage} @@ -20,8 +20,8 @@ import edu.ie3.simona.api.data.ExtData import edu.ie3.simona.api.data.ev.{ExtEvData, ExtEvSimulation} import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.config.{ArgsParser, RefSystemParser, SimonaConfig} +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} -import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.io.grid.GridProvider import edu.ie3.simona.ontology.messages.SchedulerMessage @@ -40,23 +40,13 @@ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.simona.util.TickUtil.RichZonedDateTime import edu.ie3.util.TimeUtil import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorContextOps, ClassicActorRefOps, + TypedActorContextOps, TypedActorRefOps, } -import org.apache.pekko.actor.{ - ActorSystem, - ActorContext, - ActorRef => ClassicRef, -} -import org.apache.pekko.actor.typed.ActorRef -import org.apache.pekko.actor.typed.scaladsl.ActorContext -import org.apache.pekko.actor.typed.scaladsl.adapter._ -import org.apache.pekko.actor.{ - ActorContext => ClassicContext, - ActorRef => ClassicRef, -} +import org.apache.pekko.actor.{ActorRef => ClassicRef} import java.util.concurrent.LinkedBlockingQueue import scala.jdk.CollectionConverters._ @@ -78,7 +68,7 @@ class SimonaStandaloneSetup( override def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - resultEventListeners: Seq[ActorRef[ResultEvent]], + resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], ): Iterable[ActorRef[GridAgentMessage]] = { /* get the grid */ @@ -330,7 +320,7 @@ class SimonaStandaloneSetup( def buildSubGridToActorRefMap( subGridTopologyGraph: SubGridTopologyGraph, - context: ActorContext, + context: ActorContext[_], environmentRefs: EnvironmentRefs, systemParticipantListener: Seq[ClassicRef], ): Map[Int, ActorRef[GridAgentMessage]] = { diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index 9af89c60f1..56af76d286 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -11,7 +11,7 @@ import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.ResultEventListener.Request import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower @@ -83,8 +83,7 @@ class DBFSAlgorithmCenGridSpec evDataService = None, ) - val resultListener: TestProbe[ResultMessage] = - TestProbe[ResultMessage]("resultListener") + val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") "A GridAgent actor in center position with async test" should { @@ -451,7 +450,7 @@ class DBFSAlgorithmCenGridSpec val cm = scheduler.expectMessageType[Completion] cm shouldBe Completion(cm.actor, Some(7200)) - val resultMessage = resultListener.expectMessageType[ResultMessage] + val resultMessage = resultListener.expectMessageType[Request] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => // we expect results for 4 nodes, 5 lines and 2 transformer2ws diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index 75fa5fe7f8..672e5342c3 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -10,7 +10,7 @@ import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage._ -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.ResultEventListener.Request import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -70,8 +70,7 @@ class DBFSAlgorithmFailedPowerFlowSpec evDataService = None, ) - val resultListener: TestProbe[ResultMessage] = - TestProbe[ResultMessage]("resultListener") + val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") "A GridAgent actor in center position with async test" should { diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index 16cdebb266..eb4946d119 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -14,7 +14,7 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ FinishGridSimulationTrigger, WrappedActivation, } -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.ResultEventListener.Request import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ @@ -66,8 +66,8 @@ class DBFSAlgorithmParticipantSpec evDataService = None, ) - protected val resultListener: TestProbe[ResultMessage] = - TestProbe[ResultMessage]("resultListener") + protected val resultListener: TestProbe[Request] = + TestProbe[Request]("resultListener") private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index 69d062491c..f4f43b5757 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -18,7 +18,7 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ } import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.event.listener.ResultEventListener.ResultMessage +import edu.ie3.simona.event.listener.ResultEventListener.Request import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -77,8 +77,7 @@ class DBFSAlgorithmSupGridSpec evDataService = None, ) - val resultListener: TestProbe[ResultMessage] = - TestProbe[ResultMessage]("resultListener") + val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") "A GridAgent actor in superior position with async test" should { val superiorGridAgentFSM: ActorRef[GridAgentMessage] = testKit.spawn( @@ -181,7 +180,7 @@ class DBFSAlgorithmSupGridSpec case Completion(_, Some(7200)) => // agent should be in Idle again and listener should contain power flow result data val resultMessage = - resultListener.expectMessageType[ResultMessage] + resultListener.expectMessageType[Request] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => @@ -310,7 +309,7 @@ class DBFSAlgorithmSupGridSpec case Completion(_, Some(7200)) => // after doing cleanup stuff, our agent should go back to idle again and listener should contain power flow result data val resultMessage = - resultListener.expectMessageType[ResultMessage] + resultListener.expectMessageType[Request] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala index 2a1cc430b7..da08685dba 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.grid -import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs @@ -16,41 +15,23 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ } import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.result.ResultSinkType +import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import edu.ie3.simona.test.common.ConfigTestData import edu.ie3.simona.test.common.input.TransformerInputTestData import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.testkit.typed.Effect.Spawned import org.apache.pekko.actor.testkit.typed.scaladsl.{ BehaviorTestKit, ScalaTestWithActorTestKit, TestProbe, } -import org.apache.pekko.actor.typed.{ActorRef, Scheduler} -import org.apache.pekko.actor.typed.receptionist.Receptionist.{ - Listing, - Register, - Subscribe, -} -import org.apache.pekko.actor.typed.receptionist.ServiceKey -import org.apache.pekko.actor.typed.scaladsl.AskPattern.Askable import org.apache.pekko.actor.typed.scaladsl.Behaviors -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - TypedActorContextOps, - TypedActorRefOps, -} -import org.apache.pekko.actor.{ - ActorContext => ClassicContext, - ActorRef => ClassicRef, -} -import org.apache.pekko.util.Timeout -import org.mockito.Mock +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps +import org.apache.pekko.actor.{ActorRef => ClassicRef} import org.scalatest.wordspec.AnyWordSpecLike -import java.util.concurrent.TimeUnit -import scala.concurrent.Await -import scala.concurrent.duration.Duration - class GridAgentSetup2WSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike @@ -60,12 +41,13 @@ class GridAgentSetup2WSpec "The setup of grid agents" must { - val scheduler = TestProbe("scheduler") + val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") val runtimeEventListener = TestProbe[RuntimeEvent]("listener") val primaryServiceProxy = TestProbe("primaryServiceProxy") val environmentRefs = EnvironmentRefs( - scheduler.ref.toClassic, + scheduler.ref, runtimeEventListener.ref, primaryServiceProxy = primaryServiceProxy.ref.toClassic, weather = ClassicRef.noSender, @@ -73,76 +55,45 @@ class GridAgentSetup2WSpec ) "provide two grid agents on presence of a two winding transformer" in { - - implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) - implicit val scheduler: Scheduler = system.scheduler - - // in order to get an actor system we need a tmp actor that calls the corresponding method - val serviceKey = ServiceKey[GridAgentMessage]("gridAgent") - - val actor = testKit.spawn(Behaviors.setup[GridAgentMessage] { ctx => - ctx.system.receptionist ! Register(serviceKey, ctx.self) - - Behaviors.receive[GridAgentMessage] { - case (ctx, PrepareNextSweepTrigger(tick)) => - SimonaStandaloneSetup( - typesafeConfig, - ResultFileHierarchy( - "test/tmp", - "GridAgentSetup2WSpec", - ResultEntityPathConfig( - Set.empty[Class[_ <: ResultEntity]], - ResultSinkType( - simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName, - ), + val testKit = BehaviorTestKit(Behaviors.receive[GridAgentMessage] { + case (ctx, PrepareNextSweepTrigger(tick)) => + SimonaStandaloneSetup( + typesafeConfig, + ResultFileHierarchy( + "test/tmp", + "GridAgentSetup2WSpec", + ResultEntityPathConfig( + Set.empty[Class[_ <: ResultEntity]], + ResultSinkType( + simonaConfig.simona.output.sink, + simonaConfig.simona.simulationName, ), ), - ).buildSubGridToActorRefMap( - gridContainer.getSubGridTopologyGraph, - ctx.toClassic, - environmentRefs, - Seq.empty[ClassicRef], - ) - - ctx.self ! FinishGridSimulationTrigger(tick) - Behaviors.same - - case other => - fail(s"$other was not expected") - } + ), + ).buildSubGridToActorRefMap( + gridContainer.getSubGridTopologyGraph, + ctx, + environmentRefs, + Seq.empty[ClassicRef], + ) + + ctx.self ! FinishGridSimulationTrigger(tick) + Behaviors.same + + case other => + fail(s"$other was not expected") }) - Await.ready( - actor.ask[GridAgentMessage](_ => PrepareNextSweepTrigger(0)), - Duration(10, TimeUnit.SECONDS), - ) - - BehaviorTestKit(Behaviors.setup[Listing] { ctx => - logger.debug("Subscribing to the actors.") - ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) - - Behaviors.receiveMessagePartial[Listing] { - case serviceKey.Listing(listings) => - logger.debug("All responses received. Evaluating...") + testKit.run(PrepareNextSweepTrigger(0)) - listings.size should be(2) + // two actor should be spawned + testKit.expectEffectPF { case Spawned(_, str, _) => + str shouldBe "1" + } - val regex = """GridAgent_\d*""".r - val expectedSenders = Vector("GridAgent_1", "GridAgent_2") - val actualSenders = listings - .collect { case actorId: ActorRef[GridAgentMessage] => - val actorRefString = actorId.toString - regex.findFirstIn(actorRefString) - } - .flatten - .toVector - - actualSenders should be(expectedSenders) - - Behaviors.same - } - }) + testKit.expectEffectPF { case Spawned(_, str, _) => + str shouldBe "2" + } } } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala index 3ea296387e..6e19a2185c 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala @@ -6,7 +6,6 @@ package edu.ie3.simona.agent.grid -import com.typesafe.config.ConfigFactory import com.typesafe.scalalogging.LazyLogging import edu.ie3.datamodel.models.result.ResultEntity import edu.ie3.simona.agent.EnvironmentRefs @@ -16,36 +15,22 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ } import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.io.result.ResultSinkType +import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.sim.setup.SimonaStandaloneSetup import edu.ie3.simona.test.common.{ConfigTestData, ThreeWindingTestData} import edu.ie3.simona.util.ResultFileHierarchy import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig +import org.apache.pekko.actor.testkit.typed.Effect.Spawned import org.apache.pekko.actor.testkit.typed.scaladsl.{ BehaviorTestKit, ScalaTestWithActorTestKit, TestProbe, } -import org.apache.pekko.actor.typed.{ActorRef, Scheduler} -import org.apache.pekko.actor.typed.receptionist.Receptionist.{ - Listing, - Register, - Subscribe, -} -import org.apache.pekko.actor.typed.receptionist.ServiceKey -import org.apache.pekko.actor.typed.scaladsl.AskPattern.Askable import org.apache.pekko.actor.typed.scaladsl.Behaviors import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps -import org.apache.pekko.actor.{ - ActorContext => ClassicContext, - ActorRef => ClassicRef, -} -import org.apache.pekko.util.Timeout +import org.apache.pekko.actor.{ActorRef => ClassicRef} import org.scalatest.wordspec.AnyWordSpecLike -import java.util.concurrent.TimeUnit -import scala.concurrent.Await -import scala.concurrent.duration.Duration - class GridAgentSetup3WSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike @@ -55,12 +40,13 @@ class GridAgentSetup3WSpec "The setup of grid agents" must { - val scheduler = TestProbe("scheduler") + val scheduler: TestProbe[SchedulerMessage] = + TestProbe[SchedulerMessage]("scheduler") val runtimeEventListener = TestProbe[RuntimeEvent]("listener") val primaryServiceProxy = TestProbe("primaryServiceProxy") val environmentRefs = EnvironmentRefs( - scheduler.ref.toClassic, + scheduler.ref, runtimeEventListener.ref, primaryServiceProxy = primaryServiceProxy.ref.toClassic, weather = ClassicRef.noSender, @@ -68,74 +54,49 @@ class GridAgentSetup3WSpec ) "provide three grid agents on presence of a three winding transformer" in { - implicit val timeout: Timeout = Timeout(1, TimeUnit.SECONDS) - implicit val scheduler: Scheduler = system.scheduler - - // in order to get an actor system we need a tmp actor that calls the corresponding method - val serviceKey = ServiceKey[GridAgentMessage]("gridAgent") - - val actor = testKit.spawn(Behaviors.setup[GridAgentMessage] { ctx => - ctx.system.receptionist ! Register(serviceKey, ctx.self) - Behaviors.receive[GridAgentMessage] { - case (ctx, PrepareNextSweepTrigger(tick)) => - SimonaStandaloneSetup( - typesafeConfig, - ResultFileHierarchy( - "test/tmp", - "GridAgentSetup3WSpec", - ResultEntityPathConfig( - Set.empty[Class[_ <: ResultEntity]], - ResultSinkType( - simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName, - ), + val testKit = BehaviorTestKit(Behaviors.receive[GridAgentMessage] { + case (ctx, PrepareNextSweepTrigger(tick)) => + SimonaStandaloneSetup( + typesafeConfig, + ResultFileHierarchy( + "test/tmp", + "GridAgentSetup3WSpec", + ResultEntityPathConfig( + Set.empty[Class[_ <: ResultEntity]], + ResultSinkType( + simonaConfig.simona.output.sink, + simonaConfig.simona.simulationName, ), ), - ).buildSubGridToActorRefMap( - threeWindingTestGrid.getSubGridTopologyGraph, - ctx.asInstanceOf[ClassicContext], - environmentRefs, - Seq.empty[ClassicRef], - ) - ctx.self ! FinishGridSimulationTrigger(tick) - Behaviors.same - - case other => - fail(s"$other was not expected") - } + ), + ).buildSubGridToActorRefMap( + threeWindingTestGrid.getSubGridTopologyGraph, + ctx, + environmentRefs, + Seq.empty[ClassicRef], + ) + ctx.self ! FinishGridSimulationTrigger(tick) + Behaviors.same + + case other => + fail(s"$other was not expected") }) - Await.ready( - actor.ask[GridAgentMessage](_ => PrepareNextSweepTrigger(0)), - Duration(10, TimeUnit.SECONDS), - ) - - BehaviorTestKit(Behaviors.setup[Listing] { ctx => - logger.debug("Subscribing to the actors.") - ctx.system.receptionist ! Subscribe(serviceKey, ctx.self) + testKit.run(PrepareNextSweepTrigger(0)) - Behaviors.receiveMessagePartial[Listing] { - case serviceKey.Listing(listings) => - logger.debug("All responses received. Evaluating...") + // three actor should be spawned + testKit.expectEffectPF { case Spawned(_, str, _) => + str shouldBe "1" + } - listings.size should be(3) - val regex = """GridAgent_\d*""".r - val expectedSenders = - Vector("GridAgent_1", "GridAgent_2", "GridAgent_3") - val actualSenders = listings - .collect { case actorId: ActorRef[GridAgentMessage] => - val actorRefString = actorId.toString - regex.findFirstIn(actorRefString) - } - .flatten - .toVector + testKit.expectEffectPF { case Spawned(_, str, _) => + str shouldBe "2" + } - actualSenders should be(expectedSenders) - - Behaviors.same - } - }) + testKit.expectEffectPF { case Spawned(_, str, _) => + str shouldBe "3" + } } } diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimFailSpec.scala deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index fc2308c9f0..b179ffe60c 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -7,13 +7,14 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.api.ExtSimAdapter +import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ DelayedStopHelper, ResultEventListener, RuntimeEventListener, } -import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.main.RunSimona.SimonaEnded import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion @@ -23,7 +24,6 @@ import edu.ie3.simona.sim.SimonaSimSpec._ import edu.ie3.simona.sim.setup.{ExtSimSetupData, SimonaSetup} import edu.ie3.simona.test.common.UnitSpec import org.apache.pekko.actor.testkit.typed.scaladsl.{ - LogCapturing, ScalaTestWithActorTestKit, TestProbe, } @@ -441,8 +441,8 @@ object SimonaSimSpec { override def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ActorRef[ResultEvent]], - ): Iterable[ClassicRef] = Iterable.empty + resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], + ): Iterable[ActorRef[GridAgentMessage]] = Iterable.empty override def extSimulations( context: ActorContext[_], diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 4bf91a8168..190501f8d3 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -6,12 +6,6 @@ package edu.ie3.simona.sim.setup -import org.apache.pekko.actor.{ - ActorSystem, - ActorContext, - ActorRef => ClassicRef, -} -import org.apache.pekko.actor.typed.ActorRef import edu.ie3.datamodel.exceptions.NotImplementedException import edu.ie3.datamodel.models.input.connector.{ ConnectorPort, @@ -21,14 +15,14 @@ import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} -import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.sim.SimonaSim import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.model.grid.SubGridGateMokka -import org.apache.pekko.actor.typed.scaladsl -import org.apache.pekko.actor.{ActorRef, typed} +import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext +import org.apache.pekko.actor.{ActorRef => ClassicRef} import java.util.UUID @@ -37,53 +31,53 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override val args: Array[String] = Array.empty[String] override def runtimeEventListener( - context: scaladsl.ActorContext[_] - ): typed.ActorRef[RuntimeEventListener.Request] = // todo typed + context: ActorContext[_] + ): ActorRef[RuntimeEventListener.Request] = throw new NotImplementedException( "This is a dummy setup" ) override def resultEventListener( - context: scaladsl.ActorContext[_] - ): Seq[typed.ActorRef[ResultEventListener.Request]] = + context: ActorContext[_] + ): Seq[ActorRef[ResultEventListener.Request]] = throw new NotImplementedException("This is a dummy setup") override def primaryServiceProxy( - context: scaladsl.ActorContext[_], - scheduler: typed.ActorRef[SchedulerMessage], - ): ActorRef = throw new NotImplementedException("This is a dummy setup") + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = throw new NotImplementedException("This is a dummy setup") override def weatherService( - context: scaladsl.ActorContext[_], - scheduler: typed.ActorRef[SchedulerMessage], - ): ActorRef = throw new NotImplementedException("This is a dummy setup") + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], + ): ClassicRef = throw new NotImplementedException("This is a dummy setup") override def extSimulations( - context: scaladsl.ActorContext[_], - scheduler: typed.ActorRef[SchedulerMessage], + context: ActorContext[_], + scheduler: ActorRef[SchedulerMessage], ): ExtSimSetupData = throw new NotImplementedException( "This is a dummy setup" ) override def timeAdvancer( - context: scaladsl.ActorContext[_], - simulation: typed.ActorRef[SimonaSim.SimulationEnded.type], - runtimeEventListener: typed.ActorRef[RuntimeEvent], - ): typed.ActorRef[TimeAdvancer.Request] = throw new NotImplementedException( + context: ActorContext[_], + simulation: ActorRef[SimonaSim.SimulationEnded.type], + runtimeEventListener: ActorRef[RuntimeEvent], + ): ActorRef[TimeAdvancer.Request] = throw new NotImplementedException( "This is a dummy setup" ) override def scheduler( - context: scaladsl.ActorContext[_], - timeAdvancer: typed.ActorRef[TimeAdvancer.Request], - ): typed.ActorRef[SchedulerMessage] = throw new NotImplementedException( + context: ActorContext[_], + timeAdvancer: ActorRef[TimeAdvancer.Request], + ): ActorRef[SchedulerMessage] = throw new NotImplementedException( "This is a dummy setup" ) override def gridAgents( - context: scaladsl.ActorContext[_], + context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ClassicRef], + resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], ): Iterable[ActorRef[GridAgentMessage]] = throw new NotImplementedException("This is a dummy setup") From 46cdb8841052a2b3bff55f7a677b23f4916b3fad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:43:57 +0000 Subject: [PATCH 279/305] Bump com.sksamuel.scapegoat:scalac-scapegoat-plugin_2.13.12 (#752) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 84c534b02e..8b36a3241e 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ ext { jtsVersion = '1.19.0' confluentKafkaVersion = '7.4.0' tscfgVersion = '1.0.0' - scapegoatVersion = '2.1.3' + scapegoatVersion = '2.1.4' testContainerVersion = '0.41.3' From 73af727da83cc911638d69d6b7c7bd4c6a68fe8a Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Mon, 26 Feb 2024 12:28:22 +0100 Subject: [PATCH 280/305] Simplifying and unifying GridAgent setup tests --- .../agent/grid/GridAgentSetup2WSpec.scala | 99 ----------------- .../agent/grid/GridAgentSetup3WSpec.scala | 103 ------------------ .../agent/grid/GridAgentSetupSpec.scala | 88 +++++++++++++++ 3 files changed, 88 insertions(+), 202 deletions(-) delete mode 100644 src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala delete mode 100644 src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala create mode 100644 src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetupSpec.scala diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala deleted file mode 100644 index da08685dba..0000000000 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup2WSpec.scala +++ /dev/null @@ -1,99 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.agent.grid - -import com.typesafe.scalalogging.LazyLogging -import edu.ie3.datamodel.models.result.ResultEntity -import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgentMessage.{ - FinishGridSimulationTrigger, - PrepareNextSweepTrigger, -} -import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.io.result.ResultSinkType -import edu.ie3.simona.ontology.messages.SchedulerMessage -import edu.ie3.simona.sim.setup.SimonaStandaloneSetup -import edu.ie3.simona.test.common.ConfigTestData -import edu.ie3.simona.test.common.input.TransformerInputTestData -import edu.ie3.simona.util.ResultFileHierarchy -import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig -import org.apache.pekko.actor.testkit.typed.Effect.Spawned -import org.apache.pekko.actor.testkit.typed.scaladsl.{ - BehaviorTestKit, - ScalaTestWithActorTestKit, - TestProbe, -} -import org.apache.pekko.actor.typed.scaladsl.Behaviors -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps -import org.apache.pekko.actor.{ActorRef => ClassicRef} -import org.scalatest.wordspec.AnyWordSpecLike - -class GridAgentSetup2WSpec - extends ScalaTestWithActorTestKit - with AnyWordSpecLike - with TransformerInputTestData - with ConfigTestData - with LazyLogging { - - "The setup of grid agents" must { - - val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - val runtimeEventListener = TestProbe[RuntimeEvent]("listener") - val primaryServiceProxy = TestProbe("primaryServiceProxy") - - val environmentRefs = EnvironmentRefs( - scheduler.ref, - runtimeEventListener.ref, - primaryServiceProxy = primaryServiceProxy.ref.toClassic, - weather = ClassicRef.noSender, - evDataService = None, - ) - - "provide two grid agents on presence of a two winding transformer" in { - val testKit = BehaviorTestKit(Behaviors.receive[GridAgentMessage] { - case (ctx, PrepareNextSweepTrigger(tick)) => - SimonaStandaloneSetup( - typesafeConfig, - ResultFileHierarchy( - "test/tmp", - "GridAgentSetup2WSpec", - ResultEntityPathConfig( - Set.empty[Class[_ <: ResultEntity]], - ResultSinkType( - simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName, - ), - ), - ), - ).buildSubGridToActorRefMap( - gridContainer.getSubGridTopologyGraph, - ctx, - environmentRefs, - Seq.empty[ClassicRef], - ) - - ctx.self ! FinishGridSimulationTrigger(tick) - Behaviors.same - - case other => - fail(s"$other was not expected") - }) - - testKit.run(PrepareNextSweepTrigger(0)) - - // two actor should be spawned - testKit.expectEffectPF { case Spawned(_, str, _) => - str shouldBe "1" - } - - testKit.expectEffectPF { case Spawned(_, str, _) => - str shouldBe "2" - } - } - } -} diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala deleted file mode 100644 index 6e19a2185c..0000000000 --- a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetup3WSpec.scala +++ /dev/null @@ -1,103 +0,0 @@ -/* - * © 2020. TU Dortmund University, - * Institute of Energy Systems, Energy Efficiency and Energy Economics, - * Research group Distribution grid planning and operation - */ - -package edu.ie3.simona.agent.grid - -import com.typesafe.scalalogging.LazyLogging -import edu.ie3.datamodel.models.result.ResultEntity -import edu.ie3.simona.agent.EnvironmentRefs -import edu.ie3.simona.agent.grid.GridAgentMessage.{ - FinishGridSimulationTrigger, - PrepareNextSweepTrigger, -} -import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.io.result.ResultSinkType -import edu.ie3.simona.ontology.messages.SchedulerMessage -import edu.ie3.simona.sim.setup.SimonaStandaloneSetup -import edu.ie3.simona.test.common.{ConfigTestData, ThreeWindingTestData} -import edu.ie3.simona.util.ResultFileHierarchy -import edu.ie3.simona.util.ResultFileHierarchy.ResultEntityPathConfig -import org.apache.pekko.actor.testkit.typed.Effect.Spawned -import org.apache.pekko.actor.testkit.typed.scaladsl.{ - BehaviorTestKit, - ScalaTestWithActorTestKit, - TestProbe, -} -import org.apache.pekko.actor.typed.scaladsl.Behaviors -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps -import org.apache.pekko.actor.{ActorRef => ClassicRef} -import org.scalatest.wordspec.AnyWordSpecLike - -class GridAgentSetup3WSpec - extends ScalaTestWithActorTestKit - with AnyWordSpecLike - with ThreeWindingTestData - with ConfigTestData - with LazyLogging { - - "The setup of grid agents" must { - - val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - val runtimeEventListener = TestProbe[RuntimeEvent]("listener") - val primaryServiceProxy = TestProbe("primaryServiceProxy") - - val environmentRefs = EnvironmentRefs( - scheduler.ref, - runtimeEventListener.ref, - primaryServiceProxy = primaryServiceProxy.ref.toClassic, - weather = ClassicRef.noSender, - evDataService = None, - ) - - "provide three grid agents on presence of a three winding transformer" in { - - val testKit = BehaviorTestKit(Behaviors.receive[GridAgentMessage] { - case (ctx, PrepareNextSweepTrigger(tick)) => - SimonaStandaloneSetup( - typesafeConfig, - ResultFileHierarchy( - "test/tmp", - "GridAgentSetup3WSpec", - ResultEntityPathConfig( - Set.empty[Class[_ <: ResultEntity]], - ResultSinkType( - simonaConfig.simona.output.sink, - simonaConfig.simona.simulationName, - ), - ), - ), - ).buildSubGridToActorRefMap( - threeWindingTestGrid.getSubGridTopologyGraph, - ctx, - environmentRefs, - Seq.empty[ClassicRef], - ) - ctx.self ! FinishGridSimulationTrigger(tick) - Behaviors.same - - case other => - fail(s"$other was not expected") - }) - - testKit.run(PrepareNextSweepTrigger(0)) - - // three actor should be spawned - testKit.expectEffectPF { case Spawned(_, str, _) => - str shouldBe "1" - } - - testKit.expectEffectPF { case Spawned(_, str, _) => - str shouldBe "2" - } - - testKit.expectEffectPF { case Spawned(_, str, _) => - str shouldBe "3" - } - } - } - -} diff --git a/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetupSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetupSpec.scala new file mode 100644 index 0000000000..5d7eea87c5 --- /dev/null +++ b/src/test/scala/edu/ie3/simona/agent/grid/GridAgentSetupSpec.scala @@ -0,0 +1,88 @@ +/* + * © 2020. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.agent.grid + +import edu.ie3.simona.agent.EnvironmentRefs +import edu.ie3.simona.sim.setup.SimonaStandaloneSetup +import edu.ie3.simona.test.common.input.TransformerInputTestData +import edu.ie3.simona.test.common.{ + ConfigTestData, + ThreeWindingTestData, + UnitSpec, +} +import edu.ie3.simona.util.ResultFileHierarchy +import org.apache.pekko.actor.testkit.typed.Effect.Spawned +import org.apache.pekko.actor.testkit.typed.scaladsl.BehaviorTestKit +import org.apache.pekko.actor.typed.scaladsl.Behaviors +import org.scalatestplus.mockito.MockitoSugar + +class GridAgentSetupSpec + extends UnitSpec + with MockitoSugar + with TransformerInputTestData + with ConfigTestData + with ThreeWindingTestData { + + "The setup of grid agents" must { + + "provide two grid agents on presence of a two winding transformer" in { + + val testKit = BehaviorTestKit(Behaviors.setup[AnyRef] { ctx => + SimonaStandaloneSetup( + typesafeConfig, + mock[ResultFileHierarchy], + ).buildSubGridToActorRefMap( + gridContainer.getSubGridTopologyGraph, + ctx, + mock[EnvironmentRefs], + Seq.empty, + ) + + Behaviors.stopped + }) + + // two actor should be spawned + testKit.expectEffectPF { case Spawned(_, actorName, _) => + actorName shouldBe "1" + } + + testKit.expectEffectPF { case Spawned(_, actorName, _) => + actorName shouldBe "2" + } + } + + "provide three grid agents on presence of a three winding transformer" in { + + val testKit = BehaviorTestKit(Behaviors.setup[AnyRef] { ctx => + SimonaStandaloneSetup( + typesafeConfig, + mock[ResultFileHierarchy], + ).buildSubGridToActorRefMap( + threeWindingTestGrid.getSubGridTopologyGraph, + ctx, + mock[EnvironmentRefs], + Seq.empty, + ) + + Behaviors.stopped + }) + + // three actor should be spawned + testKit.expectEffectPF { case Spawned(_, actorName, _) => + actorName shouldBe "1" + } + + testKit.expectEffectPF { case Spawned(_, actorName, _) => + actorName shouldBe "2" + } + + testKit.expectEffectPF { case Spawned(_, actorName, _) => + actorName shouldBe "3" + } + } + } +} From d7d2c14f9dc85a3bce42e7810ba9ce8178662bbe Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Mon, 26 Feb 2024 20:24:06 +0100 Subject: [PATCH 281/305] Implementing requested changes. --- .../ie3/simona/actor/SimonaActorNaming.scala | 10 +- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 235 +++++++++--------- .../edu/ie3/simona/agent/grid/GridAgent.scala | 46 ++-- .../agent/grid/GridAgentController.scala | 24 +- .../ie3/simona/agent/grid/GridAgentData.scala | 14 +- .../simona/agent/grid/GridAgentMessage.scala | 4 - .../agent/participant/ParticipantAgent.scala | 13 +- .../ie3/simona/sim/setup/SimonaSetup.scala | 4 +- .../sim/setup/SimonaStandaloneSetup.scala | 10 +- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 33 +-- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 30 ++- .../grid/DBFSAlgorithmParticipantSpec.scala | 13 +- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 13 +- .../agent/grid/PowerFlowSupportSpec.scala | 2 +- .../ParticipantAgent2ListenerSpec.scala | 6 +- .../edu/ie3/simona/sim/SimonaSimSpec.scala | 4 +- .../simona/sim/setup/SetupHelperSpec.scala | 2 +- .../simona/sim/setup/SimonaSetupSpec.scala | 4 +- 18 files changed, 222 insertions(+), 245 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala index 0b4686d781..6aeeaf093c 100644 --- a/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala +++ b/src/main/scala/edu/ie3/simona/actor/SimonaActorNaming.scala @@ -7,6 +7,7 @@ package edu.ie3.simona.actor import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorRefOps import org.apache.pekko.actor.{ActorRefFactory, Props, ActorRef => ClassicRef} import java.util.UUID @@ -84,14 +85,7 @@ object SimonaActorNaming { * @return * the actor name extract from the ActorRef */ - def actorName(actorRef: ActorRef[_]): String = - actorRef.path.name match { - case "singleton" => - // singletons end in /${actorName}/singleton - actorRef.path.parent.name - case other => - other - } + def actorName(actorRef: ActorRef[_]): String = actorName(actorRef.toClassic) /** Constructs the type name from given props. * diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index c9bb5ddc71..cae5528653 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -18,7 +18,7 @@ import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.simona.agent.grid.GridAgent.idle import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, - GridAgentValues, + GridAgentConstantData, PowerFlowDoneData, } import edu.ie3.simona.agent.grid.GridAgentMessage._ @@ -28,7 +28,10 @@ import edu.ie3.simona.agent.grid.VoltageMessage.{ ProvideSlackVoltageMessage, RequestSlackVoltageMessage, } -import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage +import edu.ie3.simona.agent.participant.ParticipantAgent.{ + FinishParticipantSimulation, + ParticipantMessage, +} import edu.ie3.simona.event.RuntimeEvent.PowerFlowFailed import edu.ie3.simona.exceptions.agent.DBFSAlgorithmException import edu.ie3.simona.model.grid.{NodeModel, RefSystem} @@ -75,10 +78,10 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentData: GridAgentData, currentTick: Long, )(implicit - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - (ctx, message) => + ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + case (ctx, message) => (message, gridAgentData) match { // first part of the grid simulation, same for all gridAgents on all levels // we start with a forward-sweep by requesting the data from our child assets and grids (if any) @@ -165,14 +168,14 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { updatedGridAgentBaseData, currentTick, simulateGrid, - )(ctx, values, buffer) + )(ctx, constantData, buffer) } else { goToPowerFlowCalculationOrStay( allValuesReceived, updatedGridAgentBaseData, currentTick, simulateGrid, - )(ctx, values, buffer) + )(ctx, constantData, buffer) } // if we receive a request for slack voltages from our inferior grids we want to answer it @@ -180,7 +183,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { RequestSlackVoltageMessage( currentSweepNo, nodeUuids, - sender: ActorRef[GridAgentMessage], + sender, ), gridAgentBaseData: GridAgentBaseData, ) => @@ -278,11 +281,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // before power flow calc for this sweep we either have to stash() the message to answer it later (in current sweep) // or trigger a new run for the next sweepNo case ( - WrappedPowerMessage( + msg @ WrappedPowerMessage( RequestGridPowerMessage( requestSweepNo, - nodeUuids, - sender: ActorRef[GridAgentMessage], + _, + _, ) ), gridAgentBaseData: GridAgentBaseData, @@ -293,11 +296,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { requestSweepNo, ) - buffer.stash( - WrappedPowerMessage( - RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) - ) - ) + buffer.stash(msg) Behaviors.same } else { @@ -308,11 +307,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) ctx.self ! PrepareNextSweepTrigger(currentTick) - buffer.stash( - WrappedPowerMessage( - RequestGridPowerMessage(requestSweepNo, nodeUuids, sender) - ) - ) + buffer.stash(msg) simulateGrid( gridAgentBaseData.copy(currentSweepNo = requestSweepNo), @@ -475,7 +470,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData.gridEnv.nodeToAssetAgents.foreach { case (_, actors) => actors.foreach { actor => - actor.toClassic ! FinishGridSimulationTrigger(currentTick) + actor ! FinishParticipantSimulation(currentTick) } } @@ -485,8 +480,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) createAndSendPowerFlowResults( gridAgentBaseData, - currentTick.toDateTime(values.simStartTime), - )(ctx.log, values) + currentTick.toDateTime(constantData.simStartTime), + )(ctx.log, constantData) // do my cleanup stuff ctx.log.debug("Doing my cleanup stuff") @@ -499,18 +494,16 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) // / inform scheduler that we are done with the whole simulation and request new trigger for next time step - values.environmentRefs.scheduler ! Completion( - values.activationAdapter, - Some(currentTick + values.resolution), + constantData.environmentRefs.scheduler ! Completion( + constantData.activationAdapter, + Some(currentTick + constantData.resolution), ) // return to Idle idle(cleanedGridAgentBaseData) - case (StopGridAgent, _) => - Behaviors.stopped - - case (_, _) => + case _ => + // preventing "match may not be exhaustive" Behaviors.unhandled } } @@ -530,12 +523,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentData: GridAgentData, currentTick: Long, )(implicit - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - (ctx, message) => + ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + case (ctx, message) => (message, gridAgentData) match { - // main method for power flow calculations case ( DoPowerFlowTrigger(currentTick, _), @@ -583,28 +575,29 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridModel.nodeUuidToIndexMap, ) ) - askForAssetPowers( - currentTick, - sweepValueStoreOpt, - gridAgentBaseData.gridEnv.nodeToAssetAgents, - gridModel.mainRefSystem, - gridAgentBaseData.powerFlowParams.sweepTimeout, - )(ctx) match { - case None => - // when we don't have assets we can skip another request for different asset behaviour due to changed - // voltage values and go back to SimulateGrid directly - ctx.log.debug( - s"No generation or load assets in the grid. Going back to SimulateGrid." - ) - // we can answer the stashed grid power requests now - buffer.unstashAll( - simulateGrid(powerFlowDoneData, currentTick) - ) + if ( + askForAssetPowers( + currentTick, + sweepValueStoreOpt, + gridAgentBaseData.gridEnv.nodeToAssetAgents, + gridModel.mainRefSystem, + gridAgentBaseData.powerFlowParams.sweepTimeout, + )(ctx) + ) { + // will return a future based on the `ask-pattern` which will be processed below + handlePowerFlowCalculations(powerFlowDoneData, currentTick) + } else { + // when we don't have assets we can skip another request for different asset behaviour due to changed + // voltage values and go back to SimulateGrid directly + ctx.log.debug( + s"No generation or load assets in the grid. Going back to SimulateGrid." + ) - case Some(_) => - // will return a future based on the `ask-pattern` which will be processed below - handlePowerFlowCalculations(powerFlowDoneData, currentTick) + // we can answer the stashed grid power requests now + buffer.unstashAll( + simulateGrid(powerFlowDoneData, currentTick) + ) } case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => @@ -671,7 +664,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { updatedGridAgentBaseData, currentTick, handlePowerFlowCalculations, - )(ctx, values, buffer) + )(ctx, constantData, buffer) } else { // no changes from assets, we want to go back to SimulateGrid and report the LF results to our parent grids if any requests @@ -759,33 +752,31 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // when we don't have inferior grids and no assets both methods return None and we can skip doing another power // flow calculation otherwise we go back to simulate grid and wait for the answers - (askForAssetPowersOpt, askForInferiorGridPowersOpt) match { - case (None, None) => - ctx.log.debug( - "I don't have assets or child grids. " + - "Going back to SimulateGrid and provide the power flow result if there is any request left." - ) - - val powerFlowDoneData = - PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) + if (!askForAssetPowersOpt && !askForInferiorGridPowersOpt) { + ctx.log.debug( + "I don't have assets or child grids. " + + "Going back to SimulateGrid and provide the power flow result if there is any request left." + ) - // we can answer the stashed grid power requests now - buffer.unstashAll( - simulateGrid(powerFlowDoneData, currentTick) - ) + val powerFlowDoneData = + PowerFlowDoneData(gridAgentBaseData, validPowerFlowResult) - case _ => - ctx.log.debug( - "Going back to SimulateGrid and wait for my assets or inferior grids to return." - ) + // we can answer the stashed grid power requests now + buffer.unstashAll( + simulateGrid(powerFlowDoneData, currentTick) + ) + } else { + ctx.log.debug( + "Going back to SimulateGrid and wait for my assets or inferior grids to return." + ) - // go back to simulate grid - simulateGrid( - gridAgentBaseData - .updateWithReceivedSlackVoltages(receivedSlackValues) - .copy(sweepValueStores = updatedSweepValueStore), - currentTick, - ) + // go back to simulate grid + simulateGrid( + gridAgentBaseData + .updateWithReceivedSlackVoltages(receivedSlackValues) + .copy(sweepValueStores = updatedSweepValueStore), + currentTick, + ) } case failedNewtonRaphsonPFResult: FailedNewtonRaphsonPFResult => @@ -805,8 +796,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // (only possible when first simulation triggered and this agent is faster in this state as the request // by a superior grid arrives) case ( - WrappedPowerMessage( - requestGridPowerMessage: RequestGridPowerMessage + msg @ WrappedPowerMessage( + _: RequestGridPowerMessage ), _: GridAgentBaseData, ) => @@ -814,15 +805,15 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { "Received Request for Grid Power too early. Stashing away" ) - buffer.stash(WrappedPowerMessage(requestGridPowerMessage)) + buffer.stash(msg) Behaviors.same // happens only when we received slack data and power values before we received a request to provide grid // (only possible when first simulation triggered and this agent is faster // with its power flow calculation in this state as the request by a superior grid arrives) case ( - WrappedPowerMessage( - requestGridPowerMessage: RequestGridPowerMessage + msg @ WrappedPowerMessage( + _: RequestGridPowerMessage ), _: PowerFlowDoneData, ) => @@ -830,13 +821,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { "Received Request for Grid Power too early. Stashing away" ) - buffer.stash(WrappedPowerMessage(requestGridPowerMessage)) + buffer.stash(msg) Behaviors.same - case (StopGridAgent, _) => - Behaviors.stopped - - case (_, _) => + case _ => + // preventing "match may not be exhaustive" Behaviors.unhandled } } @@ -851,9 +840,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { private def checkPowerDifferences( gridAgentBaseData: GridAgentBaseData )(implicit - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { case (ctx, CheckPowerDifferencesTrigger(currentTick)) => ctx.log.debug("Starting the power differences check ...") @@ -993,15 +982,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { failedResult.cause, ) ctx.self ! FinishGridSimulationTrigger(currentTick) - handlePowerFlowFailure(gridAgentBaseData)(ctx, values) + handlePowerFlowFailure(gridAgentBaseData)(ctx, constantData) simulateGrid(gridAgentBaseData, currentTick) } - - case (_, StopGridAgent) => - Behaviors.stopped - - case (_, _) => - Behaviors.unhandled } /** Checks if all data has been received and if yes checks if the there are @@ -1029,7 +1012,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { behavior: (GridAgentData, Long) => Behavior[GridAgentMessage], )(implicit ctx: ActorContext[GridAgentMessage], - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = if (allReceived) { @@ -1100,7 +1083,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { behavior: (GridAgentData, Long) => Behavior[GridAgentMessage], )(implicit ctx: ActorContext[GridAgentMessage], - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = { if (allReceived) { @@ -1143,13 +1126,12 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData: GridAgentBaseData )(implicit ctx: ActorContext[GridAgentMessage], - values: GridAgentValues, + constantData: GridAgentConstantData, ): Unit = { - values.environmentRefs.runtimeEventListener ! PowerFlowFailed + constantData.environmentRefs.runtimeEventListener ! PowerFlowFailed if (gridAgentBaseData.powerFlowParams.stopOnFailure) { ctx.log.error("Stopping because of failed power flow.") - Behaviors.stopped } } @@ -1171,11 +1153,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { gridAgentBaseData: GridAgentBaseData, currentTick: Long, )(implicit - values: GridAgentValues, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = { - values.environmentRefs.scheduler ! Completion( - values.activationAdapter, + constantData.environmentRefs.scheduler ! Completion( + constantData.activationAdapter, Some(currentTick), ) @@ -1198,6 +1180,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * this [[GridAgent]] * @param askTimeout * a timeout for the request + * @return + * true if this grids contains assets or false if no request has been send + * due to non-existence of assets */ private def askForAssetPowers( currentTick: Long, @@ -1207,7 +1192,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[GridAgentMessage]] = { + ): Boolean = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext @@ -1260,8 +1245,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { .map(res => ReceivedAssetPowerValues(res)) pipeToSelf(future, ctx) - Some(future) - } else None + true + } else false } /** Triggers an execution of the pekko `ask` pattern for all power values @ @@ -1274,6 +1259,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * [[ActorRef]] s of [[GridAgent]] s @ these nodes * @param askTimeout * a timeout for the request + * @return + * true if this grids has connected inferior grids or false if this no + * inferior grids */ private def askInferiorGridsForPowers( currentSweepNo: Int, @@ -1282,7 +1270,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[GridAgentMessage]] = { + ): Boolean = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1292,7 +1280,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { inferiorGridGates, ) - Option.when(inferiorGridGates.nonEmpty) { + if (inferiorGridGates.nonEmpty) { val future = Future .sequence( inferiorGridGates @@ -1332,8 +1320,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) .map(res => ReceivedGridPowerValues(res)) pipeToSelf(future, ctx) - future - } + true + } else false } /** Triggers an execution of the pekko `ask` pattern for all slack voltages of @@ -1346,6 +1334,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * [[ActorRef]] s of [[GridAgent]] s @ these nodes * @param askTimeout * a timeout for the request + * @return + * true if this grids has connected superior grids or false if this no + * superior grids */ private def askSuperiorGridsForSlackVoltages( currentSweepNo: Int, @@ -1354,7 +1345,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { askTimeout: Duration, )(implicit ctx: ActorContext[GridAgentMessage] - ): Option[Future[GridAgentMessage]] = { + ): Boolean = { implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1364,7 +1355,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { superiorGridGates, ) - Option.when(superiorGridGates.nonEmpty) { + if (superiorGridGates.nonEmpty) { val future = Future .sequence( superiorGridGates @@ -1386,8 +1377,8 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ) .map(res => ReceivedSlackVoltageValues(res)) pipeToSelf(future, ctx) - future - } + true + } else false } /** Create an instance of @@ -1407,11 +1398,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentTimestamp: ZonedDateTime, )(implicit log: Logger, - values: GridAgentValues, + constantData: GridAgentConstantData, ): Unit = { gridAgentBaseData.sweepValueStores.lastOption.foreach { case (_, valueStore) => - values.notifyListener( + constantData.notifyListeners( this.createResultModels( gridAgentBaseData.gridEnv.gridModel, valueStore, @@ -1423,7 +1414,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { } } - /** Simple method to pipe a future to itself. + /** This method uses [[ActorContext.pipeToSelf()]] to send a future message to + * itself. If the future is a [[Success]] the message is send, else a + * [[ReceivedFailure]] with the thrown error is send. * @param future * value * @param ctx diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index c773c2ffe1..6d2cfaaf3b 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -10,8 +10,8 @@ import edu.ie3.simona.actor.SimonaActorNaming import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.{ GridAgentBaseData, + GridAgentConstantData, GridAgentInitData, - GridAgentValues, } import edu.ie3.simona.agent.grid.GridAgentMessage._ import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage @@ -26,13 +26,9 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil -import org.apache.pekko.actor.typed.scaladsl.adapter.{ - ClassicActorRefOps, - TypedActorContextOps, -} +import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorContextOps import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} import org.apache.pekko.actor.typed.{ActorRef, Behavior} -import org.apache.pekko.actor.{ActorRef => ClassicRef} import java.time.ZonedDateTime import java.time.temporal.ChronoUnit @@ -44,7 +40,7 @@ object GridAgent extends DBFSAlgorithm { def apply( environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - listener: Iterable[ClassicRef], + listener: Iterable[ActorRef[ResultEvent]], ): Behavior[GridAgentMessage] = Behaviors.withStash(100) { buffer => Behaviors.setup[GridAgentMessage] { context => context.messageAdapter(msg => WrappedPowerMessage(msg)) @@ -59,7 +55,7 @@ object GridAgent extends DBFSAlgorithm { val simStartTime: ZonedDateTime = TimeUtil.withDefaults .toZonedDateTime(simonaConfig.simona.time.startDateTime) - val agentValues = GridAgentValues( + val agentValues = GridAgentConstantData( environmentRefs, simonaConfig, listener, @@ -73,10 +69,10 @@ object GridAgent extends DBFSAlgorithm { } private def uninitialized(implicit - values: GridAgentValues, + values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = - Behaviors.receiveMessage[GridAgentMessage] { + Behaviors.receiveMessagePartial[GridAgentMessage] { case CreateGridAgent(gridAgentInitData, unlockKey) => values.environmentRefs.scheduler ! ScheduleActivation( values.activationAdapter, @@ -85,20 +81,14 @@ object GridAgent extends DBFSAlgorithm { ) initializing(gridAgentInitData) - - case GridAgentMessage.StopGridAgent => - Behaviors.stopped - - case _ => - Behaviors.unhandled } private def initializing( gridAgentInitData: GridAgentInitData )(implicit - values: GridAgentValues, + values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { case (ctx, WrappedActivation(Activation(INIT_SIM_TICK))) => // fail fast sanity checks failFast(gridAgentInitData, SimonaActorNaming.actorName(ctx.self)) @@ -139,7 +129,7 @@ object GridAgent extends DBFSAlgorithm { val gridAgentController = new GridAgentController( - ctx.toClassic, + ctx, values.environmentRefs, values.simStartTime, TimeUtil.withDefaults @@ -147,7 +137,7 @@ object GridAgent extends DBFSAlgorithm { values.simonaConfig.simona.runtime.participant, values.simonaConfig.simona.output.participant, values.resolution, - values.listener.map(_.toTyped[ResultEvent]), + values.listener, ctx.log, ) @@ -192,11 +182,6 @@ object GridAgent extends DBFSAlgorithm { ) idle(gridAgentBaseData) - case (_, StopGridAgent) => - Behaviors.stopped - - case (_, _) => - Behaviors.unhandled } /** Method that defines the idle [[Behavior]] of the agent. @@ -213,13 +198,13 @@ object GridAgent extends DBFSAlgorithm { private[grid] def idle( gridAgentBaseData: GridAgentBaseData )(implicit - values: GridAgentValues, + values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receive[GridAgentMessage] { - case (_, pm: WrappedPowerMessage) => + ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + case (_, msg @ WrappedPowerMessage(_)) => // needs to be set here to handle if the messages arrive too early // before a transition to GridAgentBehaviour took place - buffer.stash(pm) + buffer.stash(msg) Behaviors.same case (_, WrappedActivation(activation: Activation)) => @@ -228,9 +213,6 @@ object GridAgent extends DBFSAlgorithm { Some(activation.tick), ) buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) - - case _ => - Behaviors.unhandled } private def failFast( diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala index b97e6e5fc3..a8904c9ef9 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala @@ -33,11 +33,13 @@ import edu.ie3.simona.util.ConfigUtil import edu.ie3.simona.util.ConfigUtil._ import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import org.apache.pekko.actor.typed.ActorRef +import org.apache.pekko.actor.typed.scaladsl.ActorContext import org.apache.pekko.actor.typed.scaladsl.adapter.{ ClassicActorRefOps, + TypedActorContextOps, TypedActorRefOps, } -import org.apache.pekko.actor.{ActorContext, ActorRef => ClassicRef} +import org.apache.pekko.actor.{ActorRef => ClassicRef} import org.slf4j.Logger import java.time.ZonedDateTime @@ -68,7 +70,7 @@ import scala.jdk.CollectionConverters._ * @since 2019-07-18 */ class GridAgentController( - gridAgentContext: ActorContext, + gridAgentContext: ActorContext[_], environmentRefs: EnvironmentRefs, simulationStartDate: ZonedDateTime, simulationEndDate: ZonedDateTime, @@ -196,7 +198,7 @@ class GridAgentController( thermalIslandGridsByBusId, environmentRefs, ) - introduceAgentToEnvironment(actorRef.toClassic) + introduceAgentToEnvironment(actorRef) // return uuid to actorRef node.getUuid -> actorRef }) @@ -343,7 +345,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( FixedFeedInAgent.props( environmentRefs.scheduler.toClassic, @@ -396,7 +398,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( LoadAgent.props( environmentRefs.scheduler.toClassic, @@ -452,7 +454,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( PvAgent.props( environmentRefs.scheduler.toClassic, @@ -508,7 +510,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( EvcsAgent.props( environmentRefs.scheduler.toClassic, @@ -559,7 +561,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( HpAgent.props( environmentRefs.scheduler.toClassic, @@ -616,7 +618,7 @@ class GridAgentController( requestVoltageDeviationThreshold: Double, outputConfig: NotifierConfig, ): ActorRef[ParticipantMessage] = - gridAgentContext + gridAgentContext.toClassic .simonaActorOf( WecAgent.props( environmentRefs.scheduler.toClassic, @@ -643,11 +645,11 @@ class GridAgentController( * Reference to the actor to add to the environment */ private def introduceAgentToEnvironment( - actorRef: ClassicRef + actorRef: ActorRef[ParticipantMessage] ): Unit = { gridAgentContext.watch(actorRef) environmentRefs.scheduler ! ScheduleActivation( - actorRef.toTyped, + actorRef.toClassic.toTyped, INIT_SIM_TICK, ) } diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala index d5a726bd0b..8f014f40e2 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentData.scala @@ -18,7 +18,7 @@ import edu.ie3.simona.agent.grid.ReceivedValues.{ import edu.ie3.simona.agent.grid.ReceivedValuesStore.NodeToReceivedPower import edu.ie3.simona.agent.participant.ParticipantAgent.ParticipantMessage import edu.ie3.simona.config.SimonaConfig -import edu.ie3.simona.event.notifier.Notifier +import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.model.grid.{GridModel, RefSystem} import edu.ie3.simona.ontology.messages.Activation import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -28,8 +28,6 @@ import edu.ie3.simona.ontology.messages.PowerMessage.{ ProvidePowerMessage, } import org.apache.pekko.actor.typed.ActorRef -import org.apache.pekko.actor.typed.scaladsl.StashBuffer -import org.apache.pekko.actor.{ActorRef => ClassicRef} import java.time.ZonedDateTime import java.util.UUID @@ -54,14 +52,18 @@ object GridAgentData { * @param activationAdapter * adapter for [[Activation]] */ - final case class GridAgentValues private ( + final case class GridAgentConstantData private ( environmentRefs: EnvironmentRefs, simonaConfig: SimonaConfig, - override val listener: Iterable[ClassicRef], + listener: Iterable[ActorRef[ResultEvent]], resolution: Long, simStartTime: ZonedDateTime, activationAdapter: ActorRef[Activation], - ) extends Notifier + ) { + def notifyListeners(event: ResultEvent): Unit = { + listener.foreach(listener => listener ! event) + } + } /** Data that is send to the [[GridAgent]] directly after startup. It contains * the main information for initialization. This data should include all diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala index 4a2b4dbe1c..a40d5bb9e8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgentMessage.scala @@ -73,10 +73,6 @@ object GridAgentMessage { final case class FinishGridSimulationTrigger(tick: Long) extends GridAgentMessage - /** Message that should be send by the - */ - final object StopGridAgent extends GridAgentMessage - /** Wrapper for activation values * * @param activation diff --git a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala index 01673099c1..a01c5677a1 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/ParticipantAgent.scala @@ -7,9 +7,8 @@ package edu.ie3.simona.agent.participant import edu.ie3.datamodel.models.input.system.SystemParticipantInput -import edu.ie3.simona.agent.{SimonaAgent, ValueStore} -import edu.ie3.simona.agent.grid.GridAgentMessage.FinishGridSimulationTrigger import edu.ie3.simona.agent.participant.ParticipantAgent.{ + FinishParticipantSimulation, StartCalculationTrigger, getAndCheckNodalVoltage, } @@ -33,6 +32,7 @@ import edu.ie3.simona.agent.state.ParticipantAgentState.{ Calculate, HandleInformation, } +import edu.ie3.simona.agent.{SimonaAgent, ValueStore} import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.agent.InconsistentStateException @@ -44,13 +44,13 @@ import edu.ie3.simona.model.participant.{ SystemParticipant, } import edu.ie3.simona.ontology.messages.Activation +import edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage +import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ FlexResponse, IssueFlexControl, RequestFlexOptions, } -import edu.ie3.simona.ontology.messages.PowerMessage.RequestAssetPowerMessage -import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationSuccessfulMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.{ PrimaryServiceRegistrationMessage, @@ -215,7 +215,7 @@ abstract class ParticipantAgent[ ) case Event( - FinishGridSimulationTrigger(tick), + FinishParticipantSimulation(tick), baseStateData: BaseStateData[PD], ) => // clean up agent result value store @@ -872,6 +872,9 @@ object ParticipantAgent { trait ParticipantMessage + final case class FinishParticipantSimulation(tick: Long) + extends ParticipantMessage + final case class StartCalculationTrigger(tick: Long) /** Verifies that a nodal voltage value has been provided in the model diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala index ee850a092d..16809499b0 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala @@ -10,8 +10,8 @@ import edu.ie3.datamodel.graph.SubGridGate import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.sim.SimonaSim @@ -149,7 +149,7 @@ trait SimonaSetup { def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], + resultEventListeners: Seq[ActorRef[ResultEvent]], ): Iterable[ActorRef[GridAgentMessage]] /** SIMONA links sub grids connected by a three winding transformer a bit diff --git a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala index d43c2ec4ba..322d02bc93 100644 --- a/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala +++ b/src/main/scala/edu/ie3/simona/sim/setup/SimonaStandaloneSetup.scala @@ -20,8 +20,8 @@ import edu.ie3.simona.api.data.ExtData import edu.ie3.simona.api.data.ev.{ExtEvData, ExtEvSimulation} import edu.ie3.simona.api.simulation.ExtSimAdapterData import edu.ie3.simona.config.{ArgsParser, RefSystemParser, SimonaConfig} -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.exceptions.agent.GridAgentInitializationException import edu.ie3.simona.io.grid.GridProvider import edu.ie3.simona.ontology.messages.SchedulerMessage @@ -68,7 +68,7 @@ class SimonaStandaloneSetup( override def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], + resultEventListeners: Seq[ActorRef[ResultEvent]], ): Iterable[ActorRef[GridAgentMessage]] = { /* get the grid */ @@ -91,7 +91,7 @@ class SimonaStandaloneSetup( subGridTopologyGraph, context, environmentRefs, - resultEventListeners.map(_.toClassic), + resultEventListeners, ) val keys = ScheduleLock.multiKey( @@ -322,7 +322,7 @@ class SimonaStandaloneSetup( subGridTopologyGraph: SubGridTopologyGraph, context: ActorContext[_], environmentRefs: EnvironmentRefs, - systemParticipantListener: Seq[ClassicRef], + resultEventListeners: Seq[ActorRef[ResultEvent]], ): Map[Int, ActorRef[GridAgentMessage]] = { subGridTopologyGraph .vertexSet() @@ -333,7 +333,7 @@ class SimonaStandaloneSetup( GridAgent( environmentRefs, simonaConfig, - systemParticipantListener, + resultEventListeners, ), subGridContainer.getSubnet.toString, ) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index 56af76d286..6a715fb7dc 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -10,8 +10,10 @@ import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage._ +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent -import edu.ie3.simona.event.listener.ResultEventListener.Request +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower @@ -19,9 +21,6 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import VoltageMessage.ProvideSlackVoltageMessage -import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid @@ -83,7 +82,8 @@ class DBFSAlgorithmCenGridSpec evDataService = None, ) - val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") + val resultListener: TestProbe[ResultEvent] = + TestProbe[ResultEvent]("resultListener") "A GridAgent actor in center position with async test" should { @@ -92,7 +92,7 @@ class DBFSAlgorithmCenGridSpec GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref.toClassic), + listener = Iterable(resultListener.ref), ) ) @@ -129,20 +129,23 @@ class DBFSAlgorithmCenGridSpec key, ) - val msg = scheduler.expectMessageType[ScheduleActivation] - msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) + val gridAgentActivation = scheduler.expectMessageType[ScheduleActivation] + gridAgentActivation shouldBe ScheduleActivation( + gridAgentActivation.actor, + INIT_SIM_TICK, + Some(key), + ) centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(msg.actor, Some(3600)) + scheduler.expectMessage(Completion(gridAgentActivation.actor, Some(3600))) } s"go to SimulateGrid when it receives an activity start trigger" in { centerGridAgent ! WrappedActivation(Activation(3600)) - val msg = scheduler.expectMessageType[Completion] - msg shouldBe Completion(msg.actor, Some(3600)) + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) } s"start the simulation when activation is sent" in { @@ -447,10 +450,10 @@ class DBFSAlgorithmCenGridSpec inferiorGrid13.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - val cm = scheduler.expectMessageType[Completion] - cm shouldBe Completion(cm.actor, Some(7200)) + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(7200)) - val resultMessage = resultListener.expectMessageType[Request] + val resultMessage = resultListener.expectMessageType[ResultEvent] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => // we expect results for 4 nodes, 5 lines and 2 transformer2ws diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index 672e5342c3..b198914136 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -10,7 +10,9 @@ import edu.ie3.datamodel.models.input.container.ThermalGrid import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.agent.grid.GridAgentMessage._ -import edu.ie3.simona.event.listener.ResultEventListener.Request +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -21,9 +23,6 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import VoltageMessage.ProvideSlackVoltageMessage -import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.scheduler.ScheduleLock import edu.ie3.simona.test.common.model.grid.DbfsTestGrid @@ -70,7 +69,8 @@ class DBFSAlgorithmFailedPowerFlowSpec evDataService = None, ) - val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") + val resultListener: TestProbe[ResultEvent] = + TestProbe[ResultEvent]("resultListener") "A GridAgent actor in center position with async test" should { @@ -79,7 +79,7 @@ class DBFSAlgorithmFailedPowerFlowSpec GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref.toClassic), + listener = Iterable(resultListener.ref), ) ) @@ -112,11 +112,15 @@ class DBFSAlgorithmFailedPowerFlowSpec key, ) - val msg = scheduler.expectMessageType[ScheduleActivation] - msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) + val gridAgentActivation = scheduler.expectMessageType[ScheduleActivation] + gridAgentActivation shouldBe ScheduleActivation( + gridAgentActivation.actor, + INIT_SIM_TICK, + Some(key), + ) centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) - scheduler.expectMessage(Completion(msg.actor, Some(3600))) + scheduler.expectMessage(Completion(gridAgentActivation.actor, Some(3600))) } s"go to SimulateGrid when it receives an activation" in { @@ -125,8 +129,8 @@ class DBFSAlgorithmFailedPowerFlowSpec centerGridAgent ! WrappedActivation(Activation(3600)) // we expect a completion message - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(3600)) + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) } s"start the simulation when an activation is sent is sent, handle failed power flow if it occurs" in { @@ -208,8 +212,8 @@ class DBFSAlgorithmFailedPowerFlowSpec inferiorGridAgent.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(7200)) + val completionMessage = scheduler.expectMessageType[Completion] + completionMessage shouldBe Completion(completionMessage.actor, Some(7200)) resultListener.expectNoMessage() diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index eb4946d119..0d8afa972e 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -14,16 +14,15 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ FinishGridSimulationTrigger, WrappedActivation, } -import edu.ie3.simona.event.listener.ResultEventListener.Request +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage +import edu.ie3.simona.agent.grid.VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, } -import VoltageMessage.ProvideSlackVoltageMessage -import VoltageMessage.ProvideSlackVoltageMessage.ExchangeVoltage -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.ontology.messages.services.ServiceMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.PrimaryServiceRegistrationMessage import edu.ie3.simona.ontology.messages.services.ServiceMessage.RegistrationResponseMessage.RegistrationFailedMessage @@ -66,8 +65,8 @@ class DBFSAlgorithmParticipantSpec evDataService = None, ) - protected val resultListener: TestProbe[Request] = - TestProbe[Request]("resultListener") + protected val resultListener: TestProbe[ResultEvent] = + TestProbe[ResultEvent]("resultListener") private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), @@ -79,7 +78,7 @@ class DBFSAlgorithmParticipantSpec GridAgent( environmentRefs, simonaConfig, - Iterable(resultListener.ref.toClassic), + Iterable(resultListener.ref), ) ) diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index f4f43b5757..57e6c1f507 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -17,8 +17,7 @@ import edu.ie3.simona.agent.grid.GridAgentMessage.{ WrappedPowerMessage, } import edu.ie3.simona.event.ResultEvent.PowerFlowResultEvent -import edu.ie3.simona.event.RuntimeEvent -import edu.ie3.simona.event.listener.ResultEventListener.Request +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.model.grid.RefSystem import edu.ie3.simona.ontology.messages.PowerMessage.ProvideGridPowerMessage.ExchangePower import edu.ie3.simona.ontology.messages.PowerMessage.{ @@ -77,14 +76,15 @@ class DBFSAlgorithmSupGridSpec evDataService = None, ) - val resultListener: TestProbe[Request] = TestProbe[Request]("resultListener") + val resultListener: TestProbe[ResultEvent] = + TestProbe[ResultEvent]("resultListener") "A GridAgent actor in superior position with async test" should { val superiorGridAgentFSM: ActorRef[GridAgentMessage] = testKit.spawn( GridAgent( environmentRefs, simonaConfig, - listener = Iterable(resultListener.ref.toClassic), + listener = Iterable(resultListener.ref), ) ) @@ -179,8 +179,7 @@ class DBFSAlgorithmSupGridSpec // we expect another completion message when the agent is in SimulateGrid again case Completion(_, Some(7200)) => // agent should be in Idle again and listener should contain power flow result data - val resultMessage = - resultListener.expectMessageType[Request] + val resultMessage = resultListener.expectMessageType[ResultEvent] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => @@ -309,7 +308,7 @@ class DBFSAlgorithmSupGridSpec case Completion(_, Some(7200)) => // after doing cleanup stuff, our agent should go back to idle again and listener should contain power flow result data val resultMessage = - resultListener.expectMessageType[Request] + resultListener.expectMessageType[ResultEvent] resultMessage match { case powerFlowResultEvent: PowerFlowResultEvent => diff --git a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala index 070e771241..719930b288 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -43,7 +43,7 @@ class PowerFlowSupportSpec implicit val log: Logger = LoggerFactory.getLogger(this.getClass) val actorRef: ActorRef[GridAgentMessage] = - TestProbe[GridAgentMessage]("noSender").ref + TestProbe[GridAgentMessage]("mock_grid_agent").ref /** Setting voltage at slack node to 110 kV and introducing a load of 1 MW at * node 1 diff --git a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala index 9155f8e480..2db9a91fc0 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.agent.participant import com.typesafe.config.ConfigFactory import edu.ie3.datamodel.models.input.system.SystemParticipantInput import edu.ie3.datamodel.models.result.system.SystemParticipantResult -import edu.ie3.simona.agent.grid.GridAgentMessage.FinishGridSimulationTrigger +import edu.ie3.simona.agent.participant.ParticipantAgent.FinishParticipantSimulation import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData import edu.ie3.simona.config.SimonaConfig @@ -241,7 +241,7 @@ class ParticipantAgent2ListenerSpec case unknownMsg => fail(s"Received unexpected message: $unknownMsg") } - scheduler.send(mockAgent, FinishGridSimulationTrigger(3000L)) + scheduler.send(mockAgent, FinishParticipantSimulation(3000L)) /* Wait for the result event (this is the event listener) */ logger.warn( @@ -303,7 +303,7 @@ class ParticipantAgent2ListenerSpec case unknownMsg => fail(s"Received unexpected message: $unknownMsg") } - scheduler.send(mockAgent, FinishGridSimulationTrigger(3000L)) + scheduler.send(mockAgent, FinishParticipantSimulation(3000L)) /* Make sure nothing else is sent */ expectNoMessage(noReceiveTimeOut.duration) diff --git a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala index b179ffe60c..07522bfe44 100644 --- a/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/SimonaSimSpec.scala @@ -9,7 +9,7 @@ package edu.ie3.simona.sim import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage import edu.ie3.simona.api.ExtSimAdapter -import edu.ie3.simona.event.RuntimeEvent +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.event.listener.{ DelayedStopHelper, ResultEventListener, @@ -441,7 +441,7 @@ object SimonaSimSpec { override def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], + resultEventListeners: Seq[ActorRef[ResultEvent]], ): Iterable[ActorRef[GridAgentMessage]] = Iterable.empty override def extSimulations( diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala index 383c33d0b9..1a933a3bd9 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SetupHelperSpec.scala @@ -37,7 +37,7 @@ class SetupHelperSpec "A setup helper" should { val actorRef: ActorRef[GridAgentMessage] = - TestProbe[GridAgentMessage]("noSender").ref + TestProbe[GridAgentMessage]("mock_grid_agent").ref "reduce multiple SubGridGates between the same superior and inferior nodes to one unique SubGridGate" in { diff --git a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala index 190501f8d3..de7cc0e38d 100644 --- a/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala +++ b/src/test/scala/edu/ie3/simona/sim/setup/SimonaSetupSpec.scala @@ -13,8 +13,8 @@ import edu.ie3.datamodel.models.input.connector.{ } import edu.ie3.simona.agent.EnvironmentRefs import edu.ie3.simona.agent.grid.GridAgentMessage -import edu.ie3.simona.event.RuntimeEvent import edu.ie3.simona.event.listener.{ResultEventListener, RuntimeEventListener} +import edu.ie3.simona.event.{ResultEvent, RuntimeEvent} import edu.ie3.simona.ontology.messages.SchedulerMessage import edu.ie3.simona.scheduler.TimeAdvancer import edu.ie3.simona.sim.SimonaSim @@ -77,7 +77,7 @@ class SimonaSetupSpec extends UnitSpec with SimonaSetup with SubGridGateMokka { override def gridAgents( context: ActorContext[_], environmentRefs: EnvironmentRefs, - resultEventListeners: Seq[ActorRef[ResultEventListener.Request]], + resultEventListeners: Seq[ActorRef[ResultEvent]], ): Iterable[ActorRef[GridAgentMessage]] = throw new NotImplementedException("This is a dummy setup") From 8ab90e329134b18e3e534f53719d6d22bf8b03ce Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 27 Feb 2024 15:52:03 +0100 Subject: [PATCH 282/305] Minor code adaptations --- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 14 ++---- .../edu/ie3/simona/agent/grid/GridAgent.scala | 6 +-- .../agent/grid/DBFSAlgorithmCenGridSpec.scala | 37 +++++++-------- .../DBFSAlgorithmFailedPowerFlowSpec.scala | 33 ++++++------- .../grid/DBFSAlgorithmParticipantSpec.scala | 46 ++++++++----------- .../agent/grid/DBFSAlgorithmSupGridSpec.scala | 45 ++++++++---------- 6 files changed, 75 insertions(+), 106 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index cae5528653..18329de0d8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -80,7 +80,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { )(implicit constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (ctx, message) => (message, gridAgentData) match { // first part of the grid simulation, same for all gridAgents on all levels @@ -525,7 +525,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { )(implicit constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (ctx, message) => (message, gridAgentData) match { // main method for power flow calculations @@ -796,9 +796,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // (only possible when first simulation triggered and this agent is faster in this state as the request // by a superior grid arrives) case ( - msg @ WrappedPowerMessage( - _: RequestGridPowerMessage - ), + msg: WrappedPowerMessage, _: GridAgentBaseData, ) => ctx.log.debug( @@ -812,9 +810,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { // (only possible when first simulation triggered and this agent is faster // with its power flow calculation in this state as the request by a superior grid arrives) case ( - msg @ WrappedPowerMessage( - _: RequestGridPowerMessage - ), + msg: WrappedPowerMessage, _: PowerFlowDoneData, ) => ctx.log.debug( @@ -842,7 +838,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { )(implicit constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (ctx, CheckPowerDifferencesTrigger(currentTick)) => ctx.log.debug("Starting the power differences check ...") diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 6d2cfaaf3b..e1ede433e3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -72,7 +72,7 @@ object GridAgent extends DBFSAlgorithm { values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = - Behaviors.receiveMessagePartial[GridAgentMessage] { + Behaviors.receiveMessagePartial { case CreateGridAgent(gridAgentInitData, unlockKey) => values.environmentRefs.scheduler ! ScheduleActivation( values.activationAdapter, @@ -88,7 +88,7 @@ object GridAgent extends DBFSAlgorithm { )(implicit values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (ctx, WrappedActivation(Activation(INIT_SIM_TICK))) => // fail fast sanity checks failFast(gridAgentInitData, SimonaActorNaming.actorName(ctx.self)) @@ -200,7 +200,7 @@ object GridAgent extends DBFSAlgorithm { )(implicit values: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], - ): Behavior[GridAgentMessage] = Behaviors.receivePartial[GridAgentMessage] { + ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (_, msg @ WrappedPowerMessage(_)) => // needs to be set here to handle if the messages arrive too early // before a transition to GridAgentBehaviour took place diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala index 6a715fb7dc..d1715cb356 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmCenGridSpec.scala @@ -52,9 +52,9 @@ class DBFSAlgorithmCenGridSpec with DbfsTestGrid with TestSpawnerTyped { - private val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") + private val scheduler: TestProbe[SchedulerMessage] = TestProbe("scheduler") + private val runtimeEvents: TestProbe[RuntimeEvent] = + TestProbe("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -82,8 +82,7 @@ class DBFSAlgorithmCenGridSpec evDataService = None, ) - val resultListener: TestProbe[ResultEvent] = - TestProbe[ResultEvent]("resultListener") + val resultListener: TestProbe[ResultEvent] = TestProbe("resultListener") "A GridAgent actor in center position with async test" should { @@ -119,33 +118,30 @@ class DBFSAlgorithmCenGridSpec RefSystem("2000 MVA", "110 kV"), ) - val key = - ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) - scheduler - .expectMessageType[ScheduleActivation] // lock activation scheduled + val key = ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) + // lock activation scheduled + scheduler.expectMessageType[ScheduleActivation] centerGridAgent ! CreateGridAgent( gridAgentInitData, key, ) - val gridAgentActivation = scheduler.expectMessageType[ScheduleActivation] - gridAgentActivation shouldBe ScheduleActivation( - gridAgentActivation.actor, - INIT_SIM_TICK, - Some(key), - ) + val scheduleActivationMsg = + scheduler.expectMessageType[ScheduleActivation] + scheduleActivationMsg.tick shouldBe INIT_SIM_TICK + scheduleActivationMsg.unlockKey shouldBe Some(key) + val gridAgentActivation = scheduleActivationMsg.actor centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) - scheduler.expectMessage(Completion(gridAgentActivation.actor, Some(3600))) + scheduler.expectMessage(Completion(gridAgentActivation, Some(3600))) } s"go to SimulateGrid when it receives an activity start trigger" in { centerGridAgent ! WrappedActivation(Activation(3600)) - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(3600) } s"start the simulation when activation is sent" in { @@ -449,9 +445,8 @@ class DBFSAlgorithmCenGridSpec inferiorGrid13.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) - // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(7200)) + // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a Completion + scheduler.expectMessageType[Completion].newTick shouldBe Some(7200) val resultMessage = resultListener.expectMessageType[ResultEvent] resultMessage match { diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala index b198914136..5e24639625 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmFailedPowerFlowSpec.scala @@ -47,9 +47,9 @@ class DBFSAlgorithmFailedPowerFlowSpec with DbfsTestGrid with TestSpawnerTyped { - private val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") + private val scheduler: TestProbe[SchedulerMessage] = TestProbe("scheduler") + private val runtimeEvents: TestProbe[RuntimeEvent] = + TestProbe("runtimeEvents") private val primaryService = TestProbe("primaryService") private val weatherService = TestProbe("weatherService") @@ -69,8 +69,7 @@ class DBFSAlgorithmFailedPowerFlowSpec evDataService = None, ) - val resultListener: TestProbe[ResultEvent] = - TestProbe[ResultEvent]("resultListener") + val resultListener: TestProbe[ResultEvent] = TestProbe("resultListener") "A GridAgent actor in center position with async test" should { @@ -105,22 +104,22 @@ class DBFSAlgorithmFailedPowerFlowSpec val key = ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) - scheduler.expectMessageType[SchedulerMessage] // lock activation scheduled + // lock activation scheduled + scheduler.expectMessageType[ScheduleActivation] centerGridAgent ! CreateGridAgent( gridAgentInitData, key, ) - val gridAgentActivation = scheduler.expectMessageType[ScheduleActivation] - gridAgentActivation shouldBe ScheduleActivation( - gridAgentActivation.actor, - INIT_SIM_TICK, - Some(key), - ) + val scheduleActivationMsg = + scheduler.expectMessageType[ScheduleActivation] + scheduleActivationMsg.tick shouldBe INIT_SIM_TICK + scheduleActivationMsg.unlockKey shouldBe Some(key) + val gridAgentActivation = scheduleActivationMsg.actor centerGridAgent ! WrappedActivation(Activation(INIT_SIM_TICK)) - scheduler.expectMessage(Completion(gridAgentActivation.actor, Some(3600))) + scheduler.expectMessage(Completion(gridAgentActivation, Some(3600))) } s"go to SimulateGrid when it receives an activation" in { @@ -129,8 +128,7 @@ class DBFSAlgorithmFailedPowerFlowSpec centerGridAgent ! WrappedActivation(Activation(3600)) // we expect a completion message - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(3600) } s"start the simulation when an activation is sent is sent, handle failed power flow if it occurs" in { @@ -211,9 +209,8 @@ class DBFSAlgorithmFailedPowerFlowSpec // should receive a FinishGridSimulationTrigger inferiorGridAgent.gaProbe.expectMessage(FinishGridSimulationTrigger(3600)) - // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a CompletionMessage - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(7200)) + // after all grids have received a FinishGridSimulationTrigger, the scheduler should receive a Completion + scheduler.expectMessageType[Completion].newTick shouldBe Some(7200) resultListener.expectNoMessage() diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala index 0d8afa972e..4bcbe85b42 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmParticipantSpec.scala @@ -50,11 +50,11 @@ class DBFSAlgorithmParticipantSpec with DbfsTestGridWithParticipants with TestSpawnerTyped { - private val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") + private val scheduler: TestProbe[SchedulerMessage] = TestProbe("scheduler") + private val runtimeEvents: TestProbe[RuntimeEvent] = + TestProbe("runtimeEvents") private val primaryService: TestProbe[ServiceMessage] = - TestProbe[ServiceMessage]("primaryService") + TestProbe("primaryService") private val weatherService = TestProbe("weatherService") private val environmentRefs = EnvironmentRefs( @@ -66,7 +66,7 @@ class DBFSAlgorithmParticipantSpec ) protected val resultListener: TestProbe[ResultEvent] = - TestProbe[ResultEvent]("resultListener") + TestProbe("resultListener") private val superiorGridAgent = SuperiorGA( TestProbe("superiorGridAgent_1000"), @@ -104,28 +104,20 @@ class DBFSAlgorithmParticipantSpec gridAgentWithParticipants ! CreateGridAgent(gridAgentInitData, key) - val msg = scheduler.expectMessageType[ScheduleActivation] - msg shouldBe ScheduleActivation(msg.actor, INIT_SIM_TICK, Some(key)) + val scheduleActivationMsg = + scheduler.expectMessageType[ScheduleActivation] + scheduleActivationMsg.tick shouldBe INIT_SIM_TICK + scheduleActivationMsg.unlockKey shouldBe Some(key) + val gridAgentActivation = scheduleActivationMsg.actor - // send init data to agent and expect a CompletionMessage + // send init data to agent and expect a Completion gridAgentWithParticipants ! WrappedActivation(Activation(INIT_SIM_TICK)) - val message = scheduler.expectMessageType[ScheduleActivation] + val scheduleLoadAgentMsg = scheduler.expectMessageType[ScheduleActivation] + scheduleLoadAgentMsg.tick shouldBe INIT_SIM_TICK + val loadAgent = scheduleLoadAgentMsg.actor - val loadAgent: ActorRef[Activation] = message match { - case ScheduleActivation( - loadAgent, - INIT_SIM_TICK, - _, - ) => - loadAgent - - case other => - fail(s"$other was not expected") - } - - val completionMessage = scheduler.expectMessageType[Completion] - completionMessage shouldBe Completion(completionMessage.actor, Some(3600)) + scheduler.expectMessage(Completion(gridAgentActivation, Some(3600))) loadAgent ! Activation(INIT_SIM_TICK) @@ -142,7 +134,7 @@ class DBFSAlgorithmParticipantSpec // triggering the loadAgent's calculation loadAgent ! Activation(0) - // the load agent should send a CompletionMessage + // the load agent should send a Completion scheduler.expectMessage(Completion(loadAgent, None)) } @@ -153,8 +145,7 @@ class DBFSAlgorithmParticipantSpec gridAgentWithParticipants ! WrappedActivation(Activation(3600)) // we expect a completion message - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(3600)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(3600) } s"check the request asset power message indirectly" in { @@ -244,8 +235,7 @@ class DBFSAlgorithmParticipantSpec // (here we do it by hand) gridAgentWithParticipants ! FinishGridSimulationTrigger(3600L) - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(7200)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(7200) } } } diff --git a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala index 57e6c1f507..1c2907a411 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/DBFSAlgorithmSupGridSpec.scala @@ -59,14 +59,13 @@ class DBFSAlgorithmSupGridSpec with DbfsTestGrid with TestSpawnerTyped { - private val scheduler: TestProbe[SchedulerMessage] = - TestProbe[SchedulerMessage]("scheduler") - private val runtimeEvents = TestProbe[RuntimeEvent]("runtimeEvents") + private val scheduler: TestProbe[SchedulerMessage] = TestProbe("scheduler") + private val runtimeEvents: TestProbe[RuntimeEvent] = + TestProbe("runtimeEvents") private val primaryService: TestProbe[ServiceMessage] = - TestProbe[ServiceMessage]("primaryService") + TestProbe("primaryService") private val weatherService = TestProbe("weatherService") - private val hvGrid: TestProbe[GridAgentMessage] = - TestProbe[GridAgentMessage]("hvGrid") + private val hvGrid: TestProbe[GridAgentMessage] = TestProbe("hvGrid") private val environmentRefs = EnvironmentRefs( scheduler = scheduler.ref, @@ -76,8 +75,7 @@ class DBFSAlgorithmSupGridSpec evDataService = None, ) - val resultListener: TestProbe[ResultEvent] = - TestProbe[ResultEvent]("resultListener") + val resultListener: TestProbe[ResultEvent] = TestProbe("resultListener") "A GridAgent actor in superior position with async test" should { val superiorGridAgentFSM: ActorRef[GridAgentMessage] = testKit.spawn( @@ -102,18 +100,19 @@ class DBFSAlgorithmSupGridSpec val key = ScheduleLock.singleKey(TSpawner, scheduler.ref, INIT_SIM_TICK) - scheduler - .expectMessageType[ScheduleActivation] // lock activation scheduled + // lock activation scheduled + scheduler.expectMessageType[ScheduleActivation] superiorGridAgentFSM ! CreateGridAgent(gridAgentInitData, key) - val am = scheduler.expectMessageType[ScheduleActivation] - am shouldBe ScheduleActivation(am.actor, INIT_SIM_TICK, Some(key)) + val scheduleActivationMsg = + scheduler.expectMessageType[ScheduleActivation] + scheduleActivationMsg.tick shouldBe INIT_SIM_TICK + scheduleActivationMsg.unlockKey shouldBe Some(key) + val gridAgentActivation = scheduleActivationMsg.actor superiorGridAgentFSM ! WrappedActivation(Activation(INIT_SIM_TICK)) - - val cm = scheduler.expectMessageType[Completion] - cm shouldBe Completion(cm.actor, Some(3600)) + scheduler.expectMessage(Completion(gridAgentActivation, Some(3600))) } s"go to SimulateGrid when it receives an activity start trigger" in { @@ -121,8 +120,7 @@ class DBFSAlgorithmSupGridSpec superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a completion message - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(3600)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(3600) } s"start the simulation, do 2 sweeps and should end afterwards when no deviation on nodal " + @@ -171,10 +169,7 @@ class DBFSAlgorithmSupGridSpec // we expect a completion message here and that the agent goes back to simulate grid // and waits until the newly scheduled StartGridSimulationTrigger is send // wait 30 seconds max for power flow to finish - val completionMessage = - scheduler.expectMessageType[Completion](130 seconds) - - completionMessage match { + scheduler.expectMessageType[Completion](130 seconds) match { case Completion(_, Some(3600)) => // we expect another completion message when the agent is in SimulateGrid again case Completion(_, Some(7200)) => @@ -249,8 +244,7 @@ class DBFSAlgorithmSupGridSpec superiorGridAgentFSM ! WrappedActivation(Activation(3600)) // we expect a completion message - val message = scheduler.expectMessageType[Completion] - message shouldBe Completion(message.actor, Some(3600)) + scheduler.expectMessageType[Completion].newTick shouldBe Some(3600) // go on with testing the sweep behaviour for (sweepNo <- 0 to maxNumberOfTestSweeps) { @@ -298,10 +292,7 @@ class DBFSAlgorithmSupGridSpec // Simulate Grid // wait 30 seconds max for power flow to finish - val completionMessage = - scheduler.expectMessageType[Completion](30 seconds) - - completionMessage match { + scheduler.expectMessageType[Completion](30 seconds) match { case Completion(_, Some(3600)) => // when we received a FinishGridSimulationTrigger (as inferior grid agent) // we expect another completion message then as well (scheduler view) From 6cd336a5fa8c451e6e54a237618535d14979a859 Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Tue, 27 Feb 2024 17:28:40 +0100 Subject: [PATCH 283/305] Implementing requested changes. --- .../ie3/simona/agent/grid/DBFSAlgorithm.scala | 23 ++++---- .../edu/ie3/simona/agent/grid/GridAgent.scala | 53 +++++++++---------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala index 18329de0d8..f47f3ef8b8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -978,8 +978,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { failedResult.cause, ) ctx.self ! FinishGridSimulationTrigger(currentTick) - handlePowerFlowFailure(gridAgentBaseData)(ctx, constantData) - simulateGrid(gridAgentBaseData, currentTick) + handlePowerFlowFailure(gridAgentBaseData, currentTick, ctx) } } @@ -1100,8 +1099,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ctx.log.warn("Power flow failed! This incident will be reported!") ctx.self ! FinishGridSimulationTrigger(currentTick) - handlePowerFlowFailure(gridAgentBaseData) - simulateGrid(gridAgentBaseData, currentTick) + handlePowerFlowFailure(gridAgentBaseData, currentTick, ctx) } else { ctx.self ! CheckPowerDifferencesTrigger(currentTick) checkPowerDifferences(gridAgentBaseData) @@ -1117,18 +1115,25 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { /** Method for handling failed power flows. * @param gridAgentBaseData * state data of the actor + * @param currentTick + * of the simulation */ private def handlePowerFlowFailure( - gridAgentBaseData: GridAgentBaseData - )(implicit + gridAgentBaseData: GridAgentBaseData, + currentTick: Long, ctx: ActorContext[GridAgentMessage], + )(implicit constantData: GridAgentConstantData, - ): Unit = { + buffer: StashBuffer[GridAgentMessage], + ): Behavior[GridAgentMessage] = { constantData.environmentRefs.runtimeEventListener ! PowerFlowFailed if (gridAgentBaseData.powerFlowParams.stopOnFailure) { ctx.log.error("Stopping because of failed power flow.") + Behaviors.stopped } + + simulateGrid(gridAgentBaseData, currentTick) } /** Normally only reached by the superior (dummy) agent! @@ -1414,9 +1419,9 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { * itself. If the future is a [[Success]] the message is send, else a * [[ReceivedFailure]] with the thrown error is send. * @param future - * value + * future message that should be send to the agent after it was processed * @param ctx - * context + * [[ActorContext]] of the receiving actor */ private def pipeToSelf( future: Future[GridAgentMessage], diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index e1ede433e3..3b8fce03d3 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -26,7 +26,6 @@ import edu.ie3.simona.ontology.messages.SchedulerMessage.{ } import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK import edu.ie3.util.TimeUtil -import org.apache.pekko.actor.typed.scaladsl.adapter.TypedActorContextOps import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} import org.apache.pekko.actor.typed.{ActorRef, Behavior} @@ -69,13 +68,13 @@ object GridAgent extends DBFSAlgorithm { } private def uninitialized(implicit - values: GridAgentConstantData, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receiveMessagePartial { case CreateGridAgent(gridAgentInitData, unlockKey) => - values.environmentRefs.scheduler ! ScheduleActivation( - values.activationAdapter, + constantData.environmentRefs.scheduler ! ScheduleActivation( + constantData.activationAdapter, INIT_SIM_TICK, Some(unlockKey), ) @@ -86,7 +85,7 @@ object GridAgent extends DBFSAlgorithm { private def initializing( gridAgentInitData: GridAgentInitData )(implicit - values: GridAgentConstantData, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receivePartial { case (ctx, WrappedActivation(Activation(INIT_SIM_TICK))) => @@ -120,24 +119,24 @@ object GridAgent extends DBFSAlgorithm { subGridContainer, refSystem, TimeUtil.withDefaults.toZonedDateTime( - values.simonaConfig.simona.time.startDateTime + constantData.simonaConfig.simona.time.startDateTime ), TimeUtil.withDefaults.toZonedDateTime( - values.simonaConfig.simona.time.endDateTime + constantData.simonaConfig.simona.time.endDateTime ), ) val gridAgentController = new GridAgentController( ctx, - values.environmentRefs, - values.simStartTime, + constantData.environmentRefs, + constantData.simStartTime, TimeUtil.withDefaults - .toZonedDateTime(values.simonaConfig.simona.time.endDateTime), - values.simonaConfig.simona.runtime.participant, - values.simonaConfig.simona.output.participant, - values.resolution, - values.listener, + .toZonedDateTime(constantData.simonaConfig.simona.time.endDateTime), + constantData.simonaConfig.simona.runtime.participant, + constantData.simonaConfig.simona.output.participant, + constantData.resolution, + constantData.listener, ctx.log, ) @@ -165,20 +164,20 @@ object GridAgent extends DBFSAlgorithm { gridAgentInitData.superiorGridNodeUuids, gridAgentInitData.inferiorGridGates, PowerFlowParams( - values.simonaConfig.simona.powerflow.maxSweepPowerDeviation, - values.simonaConfig.simona.powerflow.newtonraphson.epsilon.toVector.sorted, - values.simonaConfig.simona.powerflow.newtonraphson.iterations, - values.simonaConfig.simona.powerflow.sweepTimeout, - values.simonaConfig.simona.powerflow.stopOnFailure, + constantData.simonaConfig.simona.powerflow.maxSweepPowerDeviation, + constantData.simonaConfig.simona.powerflow.newtonraphson.epsilon.toVector.sorted, + constantData.simonaConfig.simona.powerflow.newtonraphson.iterations, + constantData.simonaConfig.simona.powerflow.sweepTimeout, + constantData.simonaConfig.simona.powerflow.stopOnFailure, ), SimonaActorNaming.actorName(ctx.self), ) ctx.log.debug("Je suis initialized") - values.environmentRefs.scheduler ! Completion( - values.activationAdapter, - Some(values.resolution), + constantData.environmentRefs.scheduler ! Completion( + constantData.activationAdapter, + Some(constantData.resolution), ) idle(gridAgentBaseData) @@ -188,7 +187,7 @@ object GridAgent extends DBFSAlgorithm { * * @param gridAgentBaseData * state data of the actor - * @param values + * @param constantData * immutable [[GridAgent]] values * @param buffer * for [[GridAgentMessage]]s @@ -198,18 +197,18 @@ object GridAgent extends DBFSAlgorithm { private[grid] def idle( gridAgentBaseData: GridAgentBaseData )(implicit - values: GridAgentConstantData, + constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], ): Behavior[GridAgentMessage] = Behaviors.receivePartial { - case (_, msg @ WrappedPowerMessage(_)) => + case (_, msg: WrappedPowerMessage) => // needs to be set here to handle if the messages arrive too early // before a transition to GridAgentBehaviour took place buffer.stash(msg) Behaviors.same case (_, WrappedActivation(activation: Activation)) => - values.environmentRefs.scheduler ! Completion( - values.activationAdapter, + constantData.environmentRefs.scheduler ! Completion( + constantData.activationAdapter, Some(activation.tick), ) buffer.unstashAll(simulateGrid(gridAgentBaseData, activation.tick)) From d9f233a878298ab38b92d22950cca65f35a7d4ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 07:15:35 +0000 Subject: [PATCH 284/305] Bump com.sksamuel.scapegoat:scalac-scapegoat-plugin_2.13.12 (#755) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8b36a3241e..c906d29af3 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ ext { jtsVersion = '1.19.0' confluentKafkaVersion = '7.4.0' tscfgVersion = '1.0.0' - scapegoatVersion = '2.1.4' + scapegoatVersion = '2.1.5' testContainerVersion = '0.41.3' From 0dffae93632e4d78dc47e3ac4d3123b26b19d5ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 07:16:08 +0000 Subject: [PATCH 285/305] Bump org.scala-lang:scala-library from 2.13.12 to 2.13.13 Bumps [org.scala-lang:scala-library](https://github.com/scala/scala) from 2.13.12 to 2.13.13. - [Release notes](https://github.com/scala/scala/releases) - [Commits](https://github.com/scala/scala/compare/v2.13.12...v2.13.13) --- updated-dependencies: - dependency-name: org.scala-lang:scala-library dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c906d29af3..947731e542 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ ext { javaVersion = JavaVersion.VERSION_17 scalaVersion = '2.13' - scalaBinaryVersion = '2.13.12' + scalaBinaryVersion = '2.13.13' pekkoVersion = '1.0.2' jtsVersion = '1.19.0' confluentKafkaVersion = '7.4.0' From 136ab1072762bcc6852248c1fbc387a213468d3d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 10:20:32 +0100 Subject: [PATCH 286/305] Bumping scoverage version to 2.1.0 --- gradle/scripts/scoverage.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/scripts/scoverage.gradle b/gradle/scripts/scoverage.gradle index 0a2e0157e8..e8ac99cf1f 100644 --- a/gradle/scripts/scoverage.gradle +++ b/gradle/scripts/scoverage.gradle @@ -3,7 +3,7 @@ // https://github.com/scoverage/gradle-scoverage/issues/109 for details scoverage { - scoverageVersion = "2.0.11" + scoverageVersion = "2.1.0" scoverageScalaVersion = scalaBinaryVersion coverageOutputHTML = false coverageOutputXML = true From 7a0f35407f665e767d04e5700f8d4c03d1809ec9 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 13:51:37 +0100 Subject: [PATCH 287/305] enhance scaladoc --- .../TransformerControlGroupModel.scala | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index 737ea0217f..49c2d73761 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -144,6 +144,19 @@ object TransformerControlGroupModel { .map(_.getNode.getUuid) ) + /** Determine the regulation criterion of the nodes to control + * + * @param complexVoltage + * Collection of all known [[MeasurementUnitInput]] s + * @param vMax + * and + * @param vMin + * Voltage limits of the node + * @return + * The RegulationCriterion in this case a set of node uuids and optional + * voltage deviation + */ + private def regulationFunction( complexVoltage: Complex, vMax: Double, @@ -159,6 +172,15 @@ object TransformerControlGroupModel { } } + /** Function to harmonize contrary requests for regulation + * + * @param regulationRequests: + * Array of all regulation requests + * @return + * None in case of contrary requests, else the highest or lowest voltage + * depending of the direction for regulation + */ + private def harmonizationFunction : Array[Dimensionless] => Option[Dimensionless] = (regulationRequests: Array[Dimensionless]) => { From ee1479a5d681cedafe759d3ed278718ad5d4fb56 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 13:52:11 +0100 Subject: [PATCH 288/305] fix TransformerControlGroupModel and include reviewers feedback --- .../TransformerControlGroupModel.scala | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index 49c2d73761..a8045e5264 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -12,7 +12,10 @@ import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup -import edu.ie3.simona.model.control.TransformerControlGroupModel.RegulationCriterion +import edu.ie3.simona.model.control.TransformerControlGroupModel.{ + RegulationCriterion, + harmonizationFunction, +} import squants.{Dimensionless, Each} import java.util.UUID @@ -25,13 +28,9 @@ import scala.jdk.CollectionConverters._ * @param nodalRegulationCriterion * Mapping from nodal index to a partial function, that determines the * regulation need at this node - * @param harmonizeRegulationNeeds - * Partial function to harmonize different, possible contradictory regulation - * needs */ final case class TransformerControlGroupModel( - nodalRegulationCriterion: Map[UUID, RegulationCriterion], - harmonizeRegulationNeeds: Array[Dimensionless] => Option[Dimensionless], + nodalRegulationCriterion: Map[UUID, RegulationCriterion] ) { /** Based on the given successful power flow result, determine the difference @@ -64,7 +63,7 @@ final case class TransformerControlGroupModel( }.flatten Option .when(regulationNeeds.nonEmpty)( - harmonizeRegulationNeeds(regulationNeeds) + harmonizationFunction(regulationNeeds) ) .flatten } @@ -161,14 +160,16 @@ object TransformerControlGroupModel { complexVoltage: Complex, vMax: Double, vMin: Double, - ): Option[Dimensionless] = { - val vMag = complexVoltage.abs - vMag match { - case mag if mag > vMax => - Some(vMax - mag).map(Each(_)) - case mag if mag < vMin => - Some(vMin - mag).map(Each(_)) - case _ => None + ): RegulationCriterion = { (voltage: Complex) => + { + val vMag = voltage.abs + vMag match { + case mag if mag > vMax => + Some(vMax - mag).map(Each(_)) + case mag if mag < vMin => + Some(vMin - mag).map(Each(_)) + case _ => None + } } } @@ -228,8 +229,7 @@ object TransformerControlGroupModel { }.toMap TransformerControlGroupModel( - nodeUuidToRegulationCriterion, - harmonizationFunction, + nodeUuidToRegulationCriterion ) } } From 5fb97ff676d51988e675aa2b3f2655a12452976f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 13:52:35 +0100 Subject: [PATCH 289/305] include simonaConfig into GridAgent --- .../scala/edu/ie3/simona/agent/grid/GridAgent.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala index 5bb2fd5b7a..8cd2a6b1f6 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -63,13 +63,14 @@ object GridAgent extends DBFSAlgorithm { activationAdapter, ) - uninitialized(agentValues, buffer) + uninitialized(agentValues, buffer, simonaConfig) } } private def uninitialized(implicit constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], + simonaConfig: SimonaConfig, ): Behavior[GridAgentMessage] = Behaviors.receiveMessagePartial { case CreateGridAgent(gridAgentInitData, unlockKey) => @@ -78,12 +79,12 @@ object GridAgent extends DBFSAlgorithm { INIT_SIM_TICK, Some(unlockKey), ) - - initializing(gridAgentInitData) + initializing(gridAgentInitData, simonaConfig) } private def initializing( - gridAgentInitData: GridAgentInitData + gridAgentInitData: GridAgentInitData, + simonaConfig: SimonaConfig, )(implicit constantData: GridAgentConstantData, buffer: StashBuffer[GridAgentMessage], @@ -124,6 +125,7 @@ object GridAgent extends DBFSAlgorithm { TimeUtil.withDefaults.toZonedDateTime( constantData.simonaConfig.simona.time.endDateTime ), + simonaConfig, ) val gridAgentController = @@ -138,8 +140,7 @@ object GridAgent extends DBFSAlgorithm { constantData.resolution, constantData.listener, ctx.log, - simonaConfig, - ) + ) /* Reassure, that there are also calculation models for the given uuids */ val nodeToAssetAgentsMap: Map[UUID, Set[ActorRef[ParticipantMessage]]] = From 502f3755566329421a6f999969308cd525e7e45e Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 13:53:47 +0100 Subject: [PATCH 290/305] include simonaConfig into tests --- .../edu/ie3/simona/model/grid/TransformerModelSpec.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala index d88624026e..880ca12116 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/TransformerModelSpec.scala @@ -18,7 +18,7 @@ import edu.ie3.powerflow.model.NodeData.{PresetData, StateData} import edu.ie3.powerflow.model.StartData.WithForcedStartVoltages import edu.ie3.powerflow.model.enums.NodeType import edu.ie3.powerflow.model.{NodeData, PowerFlowResult} -import edu.ie3.simona.test.common.UnitSpec +import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec} import edu.ie3.simona.test.common.model.grid.{ TapTestData, TransformerTestData, @@ -36,7 +36,10 @@ import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.UUID -class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { +class TransformerModelSpec + extends UnitSpec + with TableDrivenPropertyChecks + with ConfigTestData { val quantityTolerance: Double = 1e-5 val testingTolerancePf = 1e-9 implicit val electricCurrentTolerance: squants.electro.ElectricCurrent = @@ -378,7 +381,7 @@ class TransformerModelSpec extends UnitSpec with TableDrivenPropertyChecks { refSystem, defaultSimulationStart, defaultSimulationEnd, - controlConfig = None, + simonaConfig, ) gridModel.gridComponents.transformers From 9076e3403daf74aa50fbfcb745f56859355239f5 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 14:47:09 +0100 Subject: [PATCH 291/305] fix TransformerControlGroupModelSpec --- .../TransformerControlGroupModelSpec.scala | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala index 2ea7876057..c0c47d92cd 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala @@ -26,21 +26,22 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { Symbol("buildTransformerControlModels") ) implicit val tolerance: Dimensionless = Each(1e-10) - val dut = GridModel invokePrivate buildTransformerControlModels( - Set( - UUID.fromString( - "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + val dut = + TransformerControlGroupModel invokePrivate buildTransformerControlModels( + Set( + UUID.fromString( + "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + ), + UUID.fromString( + "08b8d2ca-993d-45cd-9456-f009ecb47bc0" + ), + UUID.fromString( + "324f49e5-1c35-4c49-afb1-3cf41696bf93" + ), ), - UUID.fromString( - "08b8d2ca-993d-45cd-9456-f009ecb47bc0" - ), - UUID.fromString( - "324f49e5-1c35-4c49-afb1-3cf41696bf93" - ), - ), - 1.1, - 0.9, - ) + 1.1, + 0.9, + ) val uuidToIndex = Map( UUID.fromString( From 7fce4a4a81964cc65a7dbde207745cc5b4c1bf7c Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 14:55:00 +0100 Subject: [PATCH 292/305] fix GridSpec --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 49ada4cf9e..1e49031a52 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -546,7 +546,7 @@ class GridSpec ) val expectedUuids = Set(node1, node2).map(_.getUuid) - val actual = GridModel invokePrivate determineNodeUuids( + val actual = TransformerControlGroupModel invokePrivate determineNodeUuids( measurementUnits, selectedMeasurements, ) From d641373cda86e1065f3a8c3798b83cb00462f9d3 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 28 Feb 2024 14:57:38 +0100 Subject: [PATCH 293/305] fmt --- src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 1e49031a52..5311e5238a 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -546,10 +546,11 @@ class GridSpec ) val expectedUuids = Set(node1, node2).map(_.getUuid) - val actual = TransformerControlGroupModel invokePrivate determineNodeUuids( - measurementUnits, - selectedMeasurements, - ) + val actual = + TransformerControlGroupModel invokePrivate determineNodeUuids( + measurementUnits, + selectedMeasurements, + ) actual should contain theSameElementsAs expectedUuids } } From a9ece9837725a428c78b031bd6b4fe1696f9ec84 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 15:40:42 +0100 Subject: [PATCH 294/305] Language error message --- src/main/scala/edu/ie3/simona/model/grid/GridModel.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index da108c62e9..438de62f55 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -498,12 +498,12 @@ object GridModel { val measurementUnit = measurementUnits.getOrElse( measurement, throw new GridAgentInitializationException( - s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which UUID does not exist in this subnet." + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement unit whose UUID does not exist in this subnet." ), ) if (!measurementUnit.getVMag) throw new GridAgentInitializationException( - s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement which does not measure voltage magnitude." + s"${subGridContainer.getGridName} has a transformer control group (${control.transformer.toString}) with a measurement unit which does not measure voltage magnitude." ) } } From 75025707010945a11e253a20d685ae2fd5b1b228 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 15:56:13 +0100 Subject: [PATCH 295/305] Shortened syntax --- .../simona/model/control/GridControls.scala | 4 +- .../edu/ie3/simona/model/grid/GridModel.scala | 71 ++++++++----------- .../edu/ie3/simona/model/grid/GridSpec.scala | 10 +-- .../model/grid/BasicGridWithSwitches.scala | 2 +- 4 files changed, 37 insertions(+), 50 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/GridControls.scala b/src/main/scala/edu/ie3/simona/model/control/GridControls.scala index 2afa0f283d..b2d00cba17 100644 --- a/src/main/scala/edu/ie3/simona/model/control/GridControls.scala +++ b/src/main/scala/edu/ie3/simona/model/control/GridControls.scala @@ -19,7 +19,5 @@ object GridControls { /** Represents an empty GridControls group */ - def emptyGridControls: GridControls = GridControls( - Set.empty[TransformerControlGroupModel] - ) + def empty: GridControls = GridControls(Set.empty) } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 438de62f55..e2f093a471 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -11,7 +11,6 @@ import breeze.math.Complex import edu.ie3.datamodel.exceptions.InvalidGridException import edu.ie3.datamodel.models.input.connector._ import edu.ie3.datamodel.models.input.container.SubGridContainer -import edu.ie3.simona.agent.grid.GridAgentData.GridAgentInitData import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.exceptions.GridInconsistencyException import edu.ie3.simona.exceptions.agent.GridAgentInitializationException @@ -465,28 +464,27 @@ object GridModel { * @param maybeControlConfig * Config of ControlGroup */ - private def checkControlGroupsForMeasurement( + private def validateControlGroups( subGridContainer: SubGridContainer, maybeControlConfig: Option[SimonaConfig.Simona.Control], ): Unit = { - - val measurementUnits = - subGridContainer.getRawGrid.getMeasurementUnits.asScala - .map(measurement => measurement.getUuid -> measurement) - .toMap - - val transformerUnits2W = - subGridContainer.getRawGrid.getTransformer2Ws.asScala - .map(transformer2w => transformer2w.getUuid -> transformer2w) - .toMap - - val transformerUnits3W = - subGridContainer.getRawGrid.getTransformer3Ws.asScala - .map(transformer3w => transformer3w.getUuid -> transformer3w) - .toMap - - maybeControlConfig.foreach(control => - control.transformer.foreach(controlGroup => + maybeControlConfig.foreach { control => + val measurementUnits = + subGridContainer.getRawGrid.getMeasurementUnits.asScala + .map(measurement => measurement.getUuid -> measurement) + .toMap + + val transformerUnits2W = + subGridContainer.getRawGrid.getTransformer2Ws.asScala + .map(transformer2w => transformer2w.getUuid -> transformer2w) + .toMap + + val transformerUnits3W = + subGridContainer.getRawGrid.getTransformer3Ws.asScala + .map(transformer3w => transformer3w.getUuid -> transformer3w) + .toMap + + control.transformer.foreach { controlGroup => controlGroup.transformers.map(UUID.fromString).foreach { transformer => val transformerUnit2W = transformerUnits2W.get(transformer) val transformerUnit3W = transformerUnits3W.get(transformer) @@ -507,9 +505,10 @@ object GridModel { ) } } + } - ) - ) + } + } } private def buildAndValidate( @@ -602,31 +601,21 @@ object GridModel { ) /* Build transformer control groups */ - val maybeControlConfig: Option[SimonaConfig.Simona.Control] = - simonaConfig.simona.control match { - case Some(control) => simonaConfig.simona.control - case None => None - } - - val transformerControlGroups = maybeControlConfig + val transformerControlGroups = simonaConfig.simona.control .map { controlConfig => TransformerControlGroupModel.buildControlGroups( controlConfig.transformer, subGridContainer.getRawGrid.getMeasurementUnits, ) } - .getOrElse(Set.empty[TransformerControlGroupModel]) + .getOrElse(Set.empty) - /* Build grid related control strategies */ - val gridControls = GridControls(transformerControlGroups) - - val gridModel = - GridModel( - subGridContainer.getSubnet, - refSystem, - gridComponents, - gridControls, - ) + val gridModel = GridModel( + subGridContainer.getSubnet, + refSystem, + gridComponents, + GridControls(transformerControlGroups), + ) /** Check and validates the grid. Especially the consistency of the grid * model the connectivity of the grid model if there is InitData for @@ -637,7 +626,7 @@ object GridModel { // validate validateConsistency(gridModel) validateConnectivity(gridModel) - checkControlGroupsForMeasurement( + validateControlGroups( subGridContainer, simonaConfig.simona.control, ) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 5311e5238a..1fa4122da3 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -217,7 +217,7 @@ class GridSpec Set.empty[Transformer3wModel], switches, ), - GridControls(Set.empty[TransformerControlGroupModel]), + GridControls.empty, ) // get the private method for validation val validateConnectivity: PrivateMethod[Unit] = @@ -246,7 +246,7 @@ class GridSpec Set.empty[Transformer3wModel], Set.empty[SwitchModel], ), - GridControls(Set.empty[TransformerControlGroupModel]), + GridControls.empty, ) // get the private method for validation @@ -292,7 +292,7 @@ class GridSpec Set.empty[Transformer3wModel], switches, ), - GridControls.emptyGridControls, + GridControls.empty, ) // get the private method for validation @@ -397,7 +397,7 @@ class GridSpec Set.empty[Transformer3wModel], switches, ), - GridControls(Set.empty[TransformerControlGroupModel]), + GridControls.empty, ) // update the uuidToIndexMap @@ -449,7 +449,7 @@ class GridSpec Set.empty[Transformer3wModel], Set.empty[SwitchModel], ), - GridControls(Set.empty[TransformerControlGroupModel]), + GridControls.empty, ) // update the uuidToIndexMap diff --git a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala index d57d902bc1..bd709daa01 100644 --- a/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala +++ b/src/test/scala/edu/ie3/simona/test/common/model/grid/BasicGridWithSwitches.scala @@ -231,7 +231,7 @@ trait BasicGridWithSwitches extends BasicGrid { Set.empty[Transformer3wModel], gridSwitches, ), - GridControls.emptyGridControls, + GridControls.empty, ) } From b7c6a6f372877308d125723da7d1cc97e4bf4a5d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 16:36:15 +0100 Subject: [PATCH 296/305] More syntax changes --- .../TransformerControlGroupModel.scala | 69 +++++++++---------- .../edu/ie3/simona/model/grid/GridModel.scala | 2 +- .../simona/config/ConfigFailFastSpec.scala | 4 +- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index a8045e5264..2e277561e2 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -14,12 +14,11 @@ import edu.ie3.simona.config.SimonaConfig import edu.ie3.simona.config.SimonaConfig.TransformerControlGroup import edu.ie3.simona.model.control.TransformerControlGroupModel.{ RegulationCriterion, - harmonizationFunction, + harmonizeRegulationNeeds, } import squants.{Dimensionless, Each} import java.util.UUID -import scala.jdk.CollectionConverters._ /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, to what extent (here: @@ -63,7 +62,7 @@ final case class TransformerControlGroupModel( }.flatten Option .when(regulationNeeds.nonEmpty)( - harmonizationFunction(regulationNeeds) + harmonizeRegulationNeeds(regulationNeeds) ) .flatten } @@ -84,7 +83,7 @@ object TransformerControlGroupModel { */ def buildControlGroups( config: List[SimonaConfig.TransformerControlGroup], - measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementUnitInput: Set[MeasurementUnitInput], ): Set[TransformerControlGroupModel] = config.map { case TransformerControlGroup(measurements, _, vMax, vMin) => buildTransformerControlGroupModel( @@ -112,7 +111,7 @@ object TransformerControlGroupModel { * A [[TransformerControlGroupModel]] */ private def buildTransformerControlGroupModel( - measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementUnitInput: Set[MeasurementUnitInput], measurementConfigs: Set[String], vMax: Double, vMin: Double, @@ -133,10 +132,10 @@ object TransformerControlGroupModel { * A set of relevant nodal uuids */ private def determineNodeUuids( - measurementUnitInput: java.util.Set[MeasurementUnitInput], + measurementUnitInput: Set[MeasurementUnitInput], measurementConfigs: Set[String], ): Set[UUID] = Set.from( - measurementUnitInput.asScala + measurementUnitInput .filter(input => measurementConfigs.contains(input.getUuid.toString) && input.getVMag ) @@ -161,15 +160,12 @@ object TransformerControlGroupModel { vMax: Double, vMin: Double, ): RegulationCriterion = { (voltage: Complex) => - { - val vMag = voltage.abs - vMag match { - case mag if mag > vMax => - Some(vMax - mag).map(Each(_)) - case mag if mag < vMin => - Some(vMin - mag).map(Each(_)) - case _ => None - } + voltage.abs match { + case vMag if vMag > vMax => + Some(vMax - vMag).map(Each(_)) + case vMag if vMag < vMin => + Some(vMin - vMag).map(Each(_)) + case _ => None } } @@ -181,29 +177,28 @@ object TransformerControlGroupModel { * None in case of contrary requests, else the highest or lowest voltage * depending of the direction for regulation */ - - private def harmonizationFunction - : Array[Dimensionless] => Option[Dimensionless] = - (regulationRequests: Array[Dimensionless]) => { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) - val positiveRequests = regulationRequests.filter(_ > Each(0d)) - - (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { - case (true, true) => - /* There are requests for higher and lower voltages at the same time => do nothing! */ - None - case (true, false) => - /* There are only requests for lower voltages => decide for the lowest required voltage */ - negativeRequests.minOption - case (false, true) => - /* There are only requests for higher voltages => decide for the highest required voltage */ - positiveRequests.maxOption - case _ => - None - } - + private def harmonizeRegulationNeeds( + regulationRequests: Array[Dimensionless] + ): Option[Dimensionless] = { + val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val positiveRequests = regulationRequests.filter(_ > Each(0d)) + + (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { + case (true, true) => + /* There are requests for higher and lower voltages at the same time => do nothing! */ + None + case (true, false) => + /* There are only requests for lower voltages => decide for the lowest required voltage */ + negativeRequests.minOption + case (false, true) => + /* There are only requests for higher voltages => decide for the highest required voltage */ + positiveRequests.maxOption + case _ => + None } + } + /** Build a single control group model. Currently, only limit violation * prevention logic is captured: The nodal regulation need is equal to the * voltage change needed to comply with the given thresholds diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index e2f093a471..1eec288b80 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -605,7 +605,7 @@ object GridModel { .map { controlConfig => TransformerControlGroupModel.buildControlGroups( controlConfig.transformer, - subGridContainer.getRawGrid.getMeasurementUnits, + subGridContainer.getRawGrid.getMeasurementUnits.asScala.toSet, ) } .getOrElse(Set.empty) diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index 515bba93bc..3b587fac30 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -961,7 +961,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "throw an exception, if the measurements are empty" in { val dut = TransformerControlGroup( - List.empty[String], + List.empty, List("a16cf7ca-8bbf-46e1-a74e-ffa6513c89a8"), 1.02, 0.98, @@ -975,7 +975,7 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "throw an exception, if the transformers are empty" in { val dut = TransformerControlGroup( List("6888c53a-7629-4563-ac8e-840f80b03106"), - List.empty[String], + List.empty, 1.02, 0.98, ) From c74bad66d56171dc93c07a18f639e15af07ffea0 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 16:47:05 +0100 Subject: [PATCH 297/305] Unnecessary parameter --- .../control/TransformerControlGroupModel.scala | 14 ++++---------- .../control/TransformerControlGroupModelSpec.scala | 3 ++- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index 2e277561e2..f188e5804b 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -144,19 +144,14 @@ object TransformerControlGroupModel { /** Determine the regulation criterion of the nodes to control * - * @param complexVoltage - * Collection of all known [[MeasurementUnitInput]] s * @param vMax - * and + * Maximum voltage limit * @param vMin - * Voltage limits of the node + * Minimum voltage limit * @return - * The RegulationCriterion in this case a set of node uuids and optional - * voltage deviation + * The regulation need, if applicable */ - private def regulationFunction( - complexVoltage: Complex, vMax: Double, vMin: Double, ): RegulationCriterion = { (voltage: Complex) => @@ -218,9 +213,8 @@ object TransformerControlGroupModel { vMin: Double, ): TransformerControlGroupModel = { /* Determine the voltage regulation criterion for each of the available nodes */ - val voltage = Complex(1.0, 0.0) val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> regulationFunction(voltage, vMax, vMin) + uuid -> regulationFunction(vMax, vMin) }.toMap TransformerControlGroupModel( diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala index c0c47d92cd..ae827342d9 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala @@ -11,7 +11,6 @@ import breeze.math.Complex import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.powerflow.model.enums.NodeType -import edu.ie3.simona.model.grid.GridModel import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers import squants.{Dimensionless, Each} @@ -19,7 +18,9 @@ import squants.{Dimensionless, Each} import java.util.UUID class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { + implicit val tolerance: Dimensionless = Each(1e-10) + "Checking the function of transformer control groups" should { val buildTransformerControlModels = PrivateMethod[TransformerControlGroupModel]( From 5916a980d33abaaa9210aacd30b5f3cc2fa859c8 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 17:15:13 +0100 Subject: [PATCH 298/305] Removing obsolete test --- .../edu/ie3/simona/model/grid/GridSpec.scala | 97 ++----------------- 1 file changed, 6 insertions(+), 91 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index 1fa4122da3..bdf17b1170 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -6,17 +6,13 @@ package edu.ie3.simona.model.grid -import java.util.UUID import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs - import edu.ie3.datamodel.exceptions.InvalidGridException -import edu.ie3.datamodel.models.input.MeasurementUnitInput -import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils - import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} +import edu.ie3.simona.model.control.GridControls +import edu.ie3.simona.model.grid.GridModel.GridComponents import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ BasicGrid, @@ -24,11 +20,8 @@ import edu.ie3.simona.test.common.model.grid.{ FiveLinesWithNodes, } import edu.ie3.simona.test.common.{ConfigTestData, DefaultTestData, UnitSpec} -import testutils.TestObjectFactory -import scala.jdk.CollectionConverters.SetHasAsJava - -import edu.ie3.simona.model.grid.GridModel.GridComponents +import java.util.UUID class GridSpec extends UnitSpec @@ -470,89 +463,9 @@ class GridSpec gridModel.nodeUuidToIndexMap.keySet.toVector.sorted should be( nodes.map(node => node.uuid).toVector.sorted ) - } - } - - "build correct transformer control models" should { - /* Testing of distinct transformer control group building can be found in the spec for transformer control groups */ - - "determine node uuids correctly" in { - val determineNodeUuids = - PrivateMethod[Set[UUID]](Symbol("determineNodeUuids")) - - val node0 = TestObjectFactory.buildNodeInput( - false, - GermanVoltageLevelUtils.MV_10KV, - 1, - ) - val node1 = TestObjectFactory.buildNodeInput( - false, - GermanVoltageLevelUtils.MV_10KV, - 1, - ) - val node2 = TestObjectFactory.buildNodeInput( - false, - GermanVoltageLevelUtils.MV_10KV, - 1, - ) - val node3 = TestObjectFactory.buildNodeInput( - false, - GermanVoltageLevelUtils.MV_10KV, - 1, - ) - val measurementUnits = Set( - new MeasurementUnitInput( - UUID.fromString("3ad9e076-c02b-4cf9-8720-18e2bb541ede"), - "measurement_unit_0", - node0, - true, - false, - false, - false, - ), - new MeasurementUnitInput( - UUID.fromString("ab66fbb0-ece1-44b9-9341-86a884233ec4"), - "measurement_unit_1", - node1, - true, - false, - false, - false, - ), - new MeasurementUnitInput( - UUID.fromString("93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d"), - "measurement_unit_2", - node2, - true, - false, - false, - false, - ), - new MeasurementUnitInput( - UUID.fromString("8e84eb8a-2940-4900-b0ce-0eeb6bca8bae"), - "measurement_unit_3", - node3, - false, - false, - false, - false, - ), - ).asJava - val selectedMeasurements = Set( - "ab66fbb0-ece1-44b9-9341-86a884233ec4", - "93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d", - "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae", - ) - val expectedUuids = Set(node1, node2).map(_.getUuid) - - val actual = - TransformerControlGroupModel invokePrivate determineNodeUuids( - measurementUnits, - selectedMeasurements, - ) - actual should contain theSameElementsAs expectedUuids } + } "process a valid GridInputModel without an Exception" in new GridInputTestData { @@ -563,6 +476,8 @@ class GridSpec defaultSimulationEnd, simonaConfig, ) + } } + } From 38f1e66141a94e928eec92f0de8e28802ad1800f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 17:16:40 +0100 Subject: [PATCH 299/305] A more radical reduction of code... --- .../TransformerControlGroupModel.scala | 123 ++---------------- .../edu/ie3/simona/model/grid/GridModel.scala | 3 +- .../TransformerControlGroupModelSpec.scala | 49 ++----- 3 files changed, 23 insertions(+), 152 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index f188e5804b..ccfafe2143 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -7,7 +7,6 @@ package edu.ie3.simona.model.control import breeze.math.Complex -import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult import edu.ie3.simona.config.SimonaConfig @@ -18,18 +17,16 @@ import edu.ie3.simona.model.control.TransformerControlGroupModel.{ } import squants.{Dimensionless, Each} -import java.util.UUID - /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, to what extent (here: * voltage raise or reduction to achieve) * - * @param nodalRegulationCriterion + * @param regulationCriterion * Mapping from nodal index to a partial function, that determines the * regulation need at this node */ final case class TransformerControlGroupModel( - nodalRegulationCriterion: Map[UUID, RegulationCriterion] + regulationCriterion: RegulationCriterion ) { /** Based on the given successful power flow result, determine the difference @@ -38,33 +35,18 @@ final case class TransformerControlGroupModel( * * @param result * Power flow result to account for - * @param uuidToIndex - * Mapping from node's uuid to nodal index * @return * Optional voltage magnitude, that a transformer tap regulation needs to * achieve */ def determineRegulationNeed( - result: SuccessFullPowerFlowResult, - uuidToIndex: Map[UUID, Int], + result: SuccessFullPowerFlowResult ): Option[Dimensionless] = { val regulationNeeds = result.nodeData.flatMap { - case StateData(resultNodeIndex, _, voltage, _) => - /* Find possible matching criterion and evaluate it */ - nodalRegulationCriterion - .find { case (uuid, _) => - val index = uuidToIndex(uuid) - index == resultNodeIndex - } - .map { case (_, criterion) => - criterion(voltage) - } - }.flatten - Option - .when(regulationNeeds.nonEmpty)( - harmonizeRegulationNeeds(regulationNeeds) - ) - .flatten + case StateData(_, _, voltage, _) => + regulationCriterion(voltage) + } + harmonizeRegulationNeeds(regulationNeeds) } } @@ -76,72 +58,16 @@ object TransformerControlGroupModel { * * @param config * List of configs for control groups - * @param measurementUnitInput - * Set of [[MeasurementUnitInput]] s * @return * A set of control group business models */ def buildControlGroups( - config: List[SimonaConfig.TransformerControlGroup], - measurementUnitInput: Set[MeasurementUnitInput], + config: Iterable[SimonaConfig.TransformerControlGroup] ): Set[TransformerControlGroupModel] = config.map { - case TransformerControlGroup(measurements, _, vMax, vMin) => - buildTransformerControlGroupModel( - measurementUnitInput, - measurements.toSet, - vMax, - vMin, - ) + case TransformerControlGroup(_, _, vMax, vMin) => + TransformerControlGroupModel(regulationFunction(vMax, vMin)) }.toSet - /** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param measurementUnitInput - * Collection of all known [[MeasurementUnitInput]] s - * @param measurementConfigs - * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] - * s does belong to this control group - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ - private def buildTransformerControlGroupModel( - measurementUnitInput: Set[MeasurementUnitInput], - measurementConfigs: Set[String], - vMax: Double, - vMin: Double, - ): TransformerControlGroupModel = { - val nodeUuids = - determineNodeUuids(measurementUnitInput, measurementConfigs) - buildTransformerControlModels(nodeUuids, vMax, vMin) - } - - /** Determine the uuids of the nodes to control - * - * @param measurementUnitInput - * Collection of all known [[MeasurementUnitInput]] s - * @param measurementConfigs - * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] - * s does belong to this control group - * @return - * A set of relevant nodal uuids - */ - private def determineNodeUuids( - measurementUnitInput: Set[MeasurementUnitInput], - measurementConfigs: Set[String], - ): Set[UUID] = Set.from( - measurementUnitInput - .filter(input => - measurementConfigs.contains(input.getUuid.toString) && input.getVMag - ) - .map(_.getNode.getUuid) - ) - /** Determine the regulation criterion of the nodes to control * * @param vMax @@ -175,7 +101,7 @@ object TransformerControlGroupModel { private def harmonizeRegulationNeeds( regulationRequests: Array[Dimensionless] ): Option[Dimensionless] = { - val negativeRequests = regulationRequests.array.filter(_ < Each(0d)) + val negativeRequests = regulationRequests.filter(_ < Each(0d)) val positiveRequests = regulationRequests.filter(_ > Each(0d)) (negativeRequests.nonEmpty, positiveRequests.nonEmpty) match { @@ -194,31 +120,4 @@ object TransformerControlGroupModel { } - /** Build a single control group model. Currently, only limit violation - * prevention logic is captured: The nodal regulation need is equal to the - * voltage change needed to comply with the given thresholds - * - * @param nodeUuids - * Collection of all relevant node uuids - * @param vMax - * Upper permissible voltage magnitude - * @param vMin - * Lower permissible voltage magnitude - * @return - * A [[TransformerControlGroupModel]] - */ - private def buildTransformerControlModels( - nodeUuids: Set[UUID], - vMax: Double, - vMin: Double, - ): TransformerControlGroupModel = { - /* Determine the voltage regulation criterion for each of the available nodes */ - val nodeUuidToRegulationCriterion = nodeUuids.map { uuid => - uuid -> regulationFunction(vMax, vMin) - }.toMap - - TransformerControlGroupModel( - nodeUuidToRegulationCriterion - ) - } } diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index 1eec288b80..c3d5e3cff9 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -604,8 +604,7 @@ object GridModel { val transformerControlGroups = simonaConfig.simona.control .map { controlConfig => TransformerControlGroupModel.buildControlGroups( - controlConfig.transformer, - subGridContainer.getRawGrid.getMeasurementUnits.asScala.toSet, + controlConfig.transformer ) } .getOrElse(Set.empty) diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala index ae827342d9..364ca91c8c 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala @@ -11,50 +11,23 @@ import breeze.math.Complex import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult.ValidNewtonRaphsonPFResult import edu.ie3.powerflow.model.enums.NodeType +import edu.ie3.simona.model.control.TransformerControlGroupModel.RegulationCriterion import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers import squants.{Dimensionless, Each} -import java.util.UUID - class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { implicit val tolerance: Dimensionless = Each(1e-10) "Checking the function of transformer control groups" should { - val buildTransformerControlModels = - PrivateMethod[TransformerControlGroupModel]( - Symbol("buildTransformerControlModels") - ) - implicit val tolerance: Dimensionless = Each(1e-10) - val dut = - TransformerControlGroupModel invokePrivate buildTransformerControlModels( - Set( - UUID.fromString( - "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" - ), - UUID.fromString( - "08b8d2ca-993d-45cd-9456-f009ecb47bc0" - ), - UUID.fromString( - "324f49e5-1c35-4c49-afb1-3cf41696bf93" - ), - ), - 1.1, - 0.9, - ) + val regulationFunction = + PrivateMethod[RegulationCriterion](Symbol("regulationFunction")) + + val regulationCriterion = + TransformerControlGroupModel invokePrivate regulationFunction(1.1, 0.9) - val uuidToIndex = Map( - UUID.fromString( - "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" - ) -> 0, - UUID.fromString( - "08b8d2ca-993d-45cd-9456-f009ecb47bc0" - ) -> 1, - UUID.fromString( - "324f49e5-1c35-4c49-afb1-3cf41696bf93" - ) -> 2, - ) + val dut = TransformerControlGroupModel(regulationCriterion) "return no regulation need, if everything is fine" in { val result = ValidNewtonRaphsonPFResult( @@ -67,7 +40,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result, uuidToIndex) + val actual = dut.determineRegulationNeed(result) actual shouldBe None } @@ -83,7 +56,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result, uuidToIndex) + val actual = dut.determineRegulationNeed(result) actual shouldBe None } @@ -99,7 +72,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result, uuidToIndex) + val actual = dut.determineRegulationNeed(result) actual match { case Some(regulationNeed) => @@ -119,7 +92,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result, uuidToIndex) + val actual = dut.determineRegulationNeed(result) actual match { case Some(regulationNeed) => From 12a28e6852b40d9c1b481bde186e167c5dacab9e Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 28 Feb 2024 18:29:27 +0100 Subject: [PATCH 300/305] Including measured nodes in a different way --- .../TransformerControlGroupModel.scala | 58 ++++++++++--- .../edu/ie3/simona/model/grid/GridModel.scala | 3 +- .../TransformerControlGroupModelSpec.scala | 37 ++++++-- .../edu/ie3/simona/model/grid/GridSpec.scala | 86 ++++++++++++++++++- 4 files changed, 167 insertions(+), 17 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala index ccfafe2143..2354770480 100644 --- a/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala +++ b/src/main/scala/edu/ie3/simona/model/control/TransformerControlGroupModel.scala @@ -7,6 +7,7 @@ package edu.ie3.simona.model.control import breeze.math.Complex +import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.powerflow.model.NodeData.StateData import edu.ie3.powerflow.model.PowerFlowResult.SuccessFullPowerFlowResult import edu.ie3.simona.config.SimonaConfig @@ -17,16 +18,20 @@ import edu.ie3.simona.model.control.TransformerControlGroupModel.{ } import squants.{Dimensionless, Each} +import java.util.UUID + /** Business logic for a transformer control group. It's main purpose is to * determine, if there is any regulation need and if yes, to what extent (here: * voltage raise or reduction to achieve) * + * @param measuredNodes + * The nodes (with voltage measurement) to consider * @param regulationCriterion - * Mapping from nodal index to a partial function, that determines the - * regulation need at this node + * Function that determines the regulation need */ final case class TransformerControlGroupModel( - regulationCriterion: RegulationCriterion + measuredNodes: Set[UUID], + regulationCriterion: RegulationCriterion, ) { /** Based on the given successful power flow result, determine the difference @@ -35,17 +40,25 @@ final case class TransformerControlGroupModel( * * @param result * Power flow result to account for + * @param uuidToIndex + * Mapping from node's uuid to nodal index * @return * Optional voltage magnitude, that a transformer tap regulation needs to * achieve */ def determineRegulationNeed( - result: SuccessFullPowerFlowResult + result: SuccessFullPowerFlowResult, + uuidToIndex: Map[UUID, Int], ): Option[Dimensionless] = { - val regulationNeeds = result.nodeData.flatMap { - case StateData(_, _, voltage, _) => + val regulationNeeds = result.nodeData + .filter { case StateData(resultNodeIndex, _, _, _) => + measuredNodes.exists { uuid => + resultNodeIndex == uuidToIndex(uuid) + } + } + .flatMap { case StateData(_, _, voltage, _) => regulationCriterion(voltage) - } + } harmonizeRegulationNeeds(regulationNeeds) } } @@ -56,18 +69,43 @@ object TransformerControlGroupModel { /** Build business models for control groups * + * @param measurementUnitInput + * Set of [[MeasurementUnitInput]] s * @param config * List of configs for control groups * @return * A set of control group business models */ def buildControlGroups( - config: Iterable[SimonaConfig.TransformerControlGroup] + measurementUnitInput: Set[MeasurementUnitInput], + config: Iterable[SimonaConfig.TransformerControlGroup], ): Set[TransformerControlGroupModel] = config.map { - case TransformerControlGroup(_, _, vMax, vMin) => - TransformerControlGroupModel(regulationFunction(vMax, vMin)) + case TransformerControlGroup(measurements, _, vMax, vMin) => + val nodeUuids = + determineNodeUuids(measurementUnitInput, measurements.toSet) + TransformerControlGroupModel(nodeUuids, regulationFunction(vMax, vMin)) }.toSet + /** Determine the uuids of the nodes to control + * + * @param measurementUnitInput + * Collection of all known [[MeasurementUnitInput]] s + * @param measurementConfigs + * Collection of all uuids, denoting which of the [[MeasurementUnitInput]] + * s does belong to this control group + * @return + * A set of relevant nodal uuids + */ + private def determineNodeUuids( + measurementUnitInput: Set[MeasurementUnitInput], + measurementConfigs: Set[String], + ): Set[UUID] = + measurementUnitInput + .filter(input => + measurementConfigs.contains(input.getUuid.toString) && input.getVMag + ) + .map(_.getNode.getUuid) + /** Determine the regulation criterion of the nodes to control * * @param vMax diff --git a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala index c3d5e3cff9..f2eab5ff1d 100644 --- a/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala +++ b/src/main/scala/edu/ie3/simona/model/grid/GridModel.scala @@ -604,7 +604,8 @@ object GridModel { val transformerControlGroups = simonaConfig.simona.control .map { controlConfig => TransformerControlGroupModel.buildControlGroups( - controlConfig.transformer + subGridContainer.getRawGrid.getMeasurementUnits.asScala.toSet, + controlConfig.transformer, ) } .getOrElse(Set.empty) diff --git a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala index 364ca91c8c..67d762dca7 100644 --- a/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/control/TransformerControlGroupModelSpec.scala @@ -16,6 +16,8 @@ import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.matchers.QuantityMatchers import squants.{Dimensionless, Each} +import java.util.UUID + class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { implicit val tolerance: Dimensionless = Each(1e-10) @@ -27,7 +29,32 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { val regulationCriterion = TransformerControlGroupModel invokePrivate regulationFunction(1.1, 0.9) - val dut = TransformerControlGroupModel(regulationCriterion) + val dut = TransformerControlGroupModel( + Set( + UUID.fromString( + "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + ), + UUID.fromString( + "08b8d2ca-993d-45cd-9456-f009ecb47bc0" + ), + UUID.fromString( + "324f49e5-1c35-4c49-afb1-3cf41696bf93" + ), + ), + regulationCriterion, + ) + + val uuidToIndex = Map( + UUID.fromString( + "d4d650be-87b7-4cf6-be7f-03f0bbcde3e3" + ) -> 0, + UUID.fromString( + "08b8d2ca-993d-45cd-9456-f009ecb47bc0" + ) -> 1, + UUID.fromString( + "324f49e5-1c35-4c49-afb1-3cf41696bf93" + ) -> 2, + ) "return no regulation need, if everything is fine" in { val result = ValidNewtonRaphsonPFResult( @@ -40,7 +67,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result) + val actual = dut.determineRegulationNeed(result, uuidToIndex) actual shouldBe None } @@ -56,7 +83,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result) + val actual = dut.determineRegulationNeed(result, uuidToIndex) actual shouldBe None } @@ -72,7 +99,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result) + val actual = dut.determineRegulationNeed(result, uuidToIndex) actual match { case Some(regulationNeed) => @@ -92,7 +119,7 @@ class TransformerControlGroupModelSpec extends UnitSpec with QuantityMatchers { DenseMatrix.zeros(1, 1), ) - val actual = dut.determineRegulationNeed(result) + val actual = dut.determineRegulationNeed(result, uuidToIndex) actual match { case Some(regulationNeed) => diff --git a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala index bdf17b1170..53165fc018 100644 --- a/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/grid/GridSpec.scala @@ -10,8 +10,10 @@ import breeze.linalg.DenseMatrix import breeze.math.Complex import breeze.numerics.abs import edu.ie3.datamodel.exceptions.InvalidGridException +import edu.ie3.datamodel.models.input.MeasurementUnitInput +import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils import edu.ie3.simona.exceptions.GridInconsistencyException -import edu.ie3.simona.model.control.GridControls +import edu.ie3.simona.model.control.{GridControls, TransformerControlGroupModel} import edu.ie3.simona.model.grid.GridModel.GridComponents import edu.ie3.simona.test.common.input.{GridInputTestData, LineInputTestData} import edu.ie3.simona.test.common.model.grid.{ @@ -20,6 +22,7 @@ import edu.ie3.simona.test.common.model.grid.{ FiveLinesWithNodes, } import edu.ie3.simona.test.common.{ConfigTestData, DefaultTestData, UnitSpec} +import testutils.TestObjectFactory import java.util.UUID @@ -463,7 +466,88 @@ class GridSpec gridModel.nodeUuidToIndexMap.keySet.toVector.sorted should be( nodes.map(node => node.uuid).toVector.sorted ) + } + } + + "build correct transformer control models" should { + /* Testing of distinct transformer control group building can be found in the spec for transformer control groups */ + "determine node uuids correctly" in { + val determineNodeUuids = + PrivateMethod[Set[UUID]](Symbol("determineNodeUuids")) + + val node0 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1, + ) + val node1 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1, + ) + val node2 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1, + ) + val node3 = TestObjectFactory.buildNodeInput( + false, + GermanVoltageLevelUtils.MV_10KV, + 1, + ) + + val measurementUnits = Set( + new MeasurementUnitInput( + UUID.fromString("3ad9e076-c02b-4cf9-8720-18e2bb541ede"), + "measurement_unit_0", + node0, + true, + false, + false, + false, + ), + new MeasurementUnitInput( + UUID.fromString("ab66fbb0-ece1-44b9-9341-86a884233ec4"), + "measurement_unit_1", + node1, + true, + false, + false, + false, + ), + new MeasurementUnitInput( + UUID.fromString("93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d"), + "measurement_unit_2", + node2, + true, + false, + false, + false, + ), + new MeasurementUnitInput( + UUID.fromString("8e84eb8a-2940-4900-b0ce-0eeb6bca8bae"), + "measurement_unit_3", + node3, + false, + false, + false, + false, + ), + ) + val selectedMeasurements = Set( + "ab66fbb0-ece1-44b9-9341-86a884233ec4", + "93b4d0d8-cc67-41f5-9d5c-1cd6dbb2e70d", + "8e84eb8a-2940-4900-b0ce-0eeb6bca8bae", + ) + val expectedUuids = Set(node1, node2).map(_.getUuid) + + val actual = + TransformerControlGroupModel invokePrivate determineNodeUuids( + measurementUnits, + selectedMeasurements, + ) + actual should contain theSameElementsAs expectedUuids } } From b50a071698ac344f18a7050c7629aa539e7570a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:43:29 +0000 Subject: [PATCH 301/305] Bump ch.qos.logback:logback-classic from 1.5.0 to 1.5.1 (#758) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 947731e542..e043a1d639 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { /* logging */ implementation "com.typesafe.scala-logging:scala-logging_${scalaVersion}:3.9.5" // pekko scala logging - implementation "ch.qos.logback:logback-classic:1.5.0" + implementation "ch.qos.logback:logback-classic:1.5.1" /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' From 3b7cd2c4fac016ac91a611fde21bf928b8a2b078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:44:08 +0100 Subject: [PATCH 302/305] Bump de.undercouch.download from 5.5.0 to 5.6.0 (#759) * Bump de.undercouch.download from 5.5.0 to 5.6.0 Bumps [de.undercouch.download](https://github.com/michel-kraemer/gradle-download-task) from 5.5.0 to 5.6.0. - [Release notes](https://github.com/michel-kraemer/gradle-download-task/releases) - [Commits](https://github.com/michel-kraemer/gradle-download-task/compare/5.5.0...5.6.0) --- updated-dependencies: - dependency-name: de.undercouch.download dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * fix links * fix fix links --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: danielfeismann --- build.gradle | 2 +- docs/readthedocs/models/cts_model.md | 2 +- docs/readthedocs/models/thermal_grid_model.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e043a1d639..7097a0a779 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id 'pmd' // code check, working on source code id 'com.diffplug.spotless' version '6.25.0'// code format id "com.github.ben-manes.versions" version '0.51.0' - id "de.undercouch.download" version "5.5.0" // downloads plugin + id "de.undercouch.download" version "5.6.0" // downloads plugin id "kr.motd.sphinx" version "2.10.1" // documentation generation id "com.github.johnrengelman.shadow" version "8.1.1" // fat jar id "org.sonarqube" version "4.4.1.3373" // sonarqube diff --git a/docs/readthedocs/models/cts_model.md b/docs/readthedocs/models/cts_model.md index eea6fcfe0c..0ca51a7395 100644 --- a/docs/readthedocs/models/cts_model.md +++ b/docs/readthedocs/models/cts_model.md @@ -7,7 +7,7 @@ This storage model operates on volumes, although the functions it provides for o ## Attributes, Units and Remarks -Please refer to {doc}`PowerSystemDataModel - CTS Model ` for Attributes and Units used in this Model. +Please refer to {doc}`PowerSystemDataModel - CTS Model ` for Attributes and Units used in this Model. ## Calculations ### Maximal storage capacity diff --git a/docs/readthedocs/models/thermal_grid_model.md b/docs/readthedocs/models/thermal_grid_model.md index e7aa2c214e..fc16159552 100644 --- a/docs/readthedocs/models/thermal_grid_model.md +++ b/docs/readthedocs/models/thermal_grid_model.md @@ -5,4 +5,4 @@ The Thermal Grid Model introduces a coupling point to thermal system, equivalent ## Attributes, Units and Remarks -Please refer to {doc}`PowerSystemDataModel - Thermal Bus ` for Attributes and Units used in this Model. +Please refer to {doc}`PowerSystemDataModel - Thermal Bus ` for Attributes and Units used in this Model. From 417775ee5686c67af0637bb5a37cc766a8c36a17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:53:28 +0000 Subject: [PATCH 303/305] Bump org.mockito:mockito-core from 5.10.0 to 5.11.0 (#760) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7097a0a779..0712396ca2 100644 --- a/build.gradle +++ b/build.gradle @@ -102,7 +102,7 @@ dependencies { /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0' - testImplementation 'org.mockito:mockito-core:5.10.0' // mocking framework + testImplementation 'org.mockito:mockito-core:5.11.0' // mocking framework testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.18" testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0' From 77deb60e6714a487e5ae3cbfc48cdb9b2b2c000f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:00:16 +0000 Subject: [PATCH 304/305] Bump ch.qos.logback:logback-classic from 1.5.1 to 1.5.2 (#761) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0712396ca2..00887fd062 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { /* logging */ implementation "com.typesafe.scala-logging:scala-logging_${scalaVersion}:3.9.5" // pekko scala logging - implementation "ch.qos.logback:logback-classic:1.5.1" + implementation "ch.qos.logback:logback-classic:1.5.2" /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' From 32b4808a291fadf3f30890f3605156094b4ca8fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 07:28:14 +0000 Subject: [PATCH 305/305] Bump ch.qos.logback:logback-classic from 1.5.2 to 1.5.3 (#762) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 00887fd062..b4a0226708 100644 --- a/build.gradle +++ b/build.gradle @@ -97,7 +97,7 @@ dependencies { /* logging */ implementation "com.typesafe.scala-logging:scala-logging_${scalaVersion}:3.9.5" // pekko scala logging - implementation "ch.qos.logback:logback-classic:1.5.2" + implementation "ch.qos.logback:logback-classic:1.5.3" /* testing */ testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'