From 837d94dd476e22808c83a58821e404409ffbc50d Mon Sep 17 00:00:00 2001 From: Marvin Heintze Date: Wed, 11 Dec 2024 11:54:19 +0100 Subject: [PATCH 01/20] Duration in PowerFlowParams --- src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0235cb56de..ccf19adaea 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala @@ -6,7 +6,7 @@ package edu.ie3.simona.agent.grid -import java.time.Duration +import scala.concurrent.duration.Duration /** Holds all power flow configuration parameters used in * [[edu.ie3.simona.agent.grid]] From ee74051f96184d143e604a249ce2a0e67582c305 Mon Sep 17 00:00:00 2001 From: Marvin Heintze Date: Fri, 13 Dec 2024 13:12:40 +0100 Subject: [PATCH 02/20] changed Duration to FiniteDuration --- .../edu/ie3/simona/agent/grid/DBFSAlgorithm.scala | 15 ++++++++------- .../edu/ie3/simona/agent/grid/GridAgent.scala | 10 ++++++++-- .../ie3/simona/agent/grid/PowerFlowParams.scala | 4 ++-- 3 files changed, 18 insertions(+), 11 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 d0a23ea6da..7f2a5a4332 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -49,8 +49,9 @@ import org.apache.pekko.util.{Timeout => PekkoTimeout} import org.slf4j.Logger import squants.Each -import java.time.{Duration, ZonedDateTime} +import java.time.ZonedDateTime import java.util.UUID +import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success} @@ -1161,11 +1162,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { sweepValueStore: Option[SweepValueStore], nodeToAssetAgents: Map[UUID, Set[ActorRef[ParticipantMessage]]], refSystem: RefSystem, - askTimeout: Duration, + askTimeout: FiniteDuration, )(implicit ctx: ActorContext[GridAgent.Request] ): Boolean = { - implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) + implicit val timeout: PekkoTimeout = PekkoTimeout(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext ctx.log.debug(s"asking assets for power values: {}", nodeToAssetAgents) @@ -1239,11 +1240,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo: Int, subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgent.Request]], inferiorGridGates: Seq[SubGridGate], - askTimeout: Duration, + askTimeout: FiniteDuration, )(implicit ctx: ActorContext[GridAgent.Request] ): Boolean = { - implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) + implicit val timeout: PekkoTimeout = PekkoTimeout(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1310,11 +1311,11 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { currentSweepNo: Int, subGridGateToActorRef: Map[SubGridGate, ActorRef[GridAgent.Request]], superiorGridGates: Vector[SubGridGate], - askTimeout: Duration, + askTimeout: FiniteDuration, )(implicit ctx: ActorContext[GridAgent.Request] ): Boolean = { - implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) + implicit val timeout: PekkoTimeout = PekkoTimeout(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler 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 c9bca30ce1..04900bc158 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -29,10 +29,12 @@ import edu.ie3.util.TimeUtil import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} import org.apache.pekko.actor.typed.{ActorRef, Behavior} -import java.time.ZonedDateTime +import java.time.{Duration, ZonedDateTime} import java.time.temporal.ChronoUnit import java.util.UUID -import scala.language.postfixOps +import java.util.concurrent.TimeUnit +import scala.concurrent.duration.FiniteDuration +import scala.language.{implicitConversions, postfixOps} object GridAgent extends DBFSAlgorithm { @@ -166,6 +168,10 @@ object GridAgent extends DBFSAlgorithm { nodeUuid -> actorSet } + // TODO: Reminder: Can be removed after changing the config framework + implicit def convertDuration(duration: Duration): FiniteDuration = + FiniteDuration.apply(duration.toSeconds, TimeUnit.SECONDS) + // create the GridAgentBaseData val gridAgentBaseData = GridAgentBaseData( gridModel, 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 ccf19adaea..14e01a6b88 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/PowerFlowParams.scala @@ -6,7 +6,7 @@ package edu.ie3.simona.agent.grid -import scala.concurrent.duration.Duration +import scala.concurrent.duration.FiniteDuration /** Holds all power flow configuration parameters used in * [[edu.ie3.simona.agent.grid]] @@ -29,6 +29,6 @@ final case class PowerFlowParams( maxSweepPowerDeviation: Double, epsilon: Vector[Double], maxIterations: Int, - sweepTimeout: Duration, + sweepTimeout: FiniteDuration, stopOnFailure: Boolean, ) From 50f91a498cf0e8cd0f5123b3fb9e5966e9de2677 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 17 Feb 2025 18:24:20 +0100 Subject: [PATCH 03/20] Renamed some methods and variables within `ThermalGrid` and `ThermalHouse` --- CHANGELOG.md | 1 + .../simona/model/thermal/ThermalGrid.scala | 12 ++++---- .../simona/model/thermal/ThermalHouse.scala | 8 +++--- .../model/participant/HpModelSpec.scala | 28 +++++++++---------- .../ThermalGridWithHouseAndStorageSpec.scala | 12 +++++--- .../ThermalGridWithHouseOnlySpec.scala | 8 ++++-- .../model/thermal/ThermalHouseSpec.scala | 2 +- 7 files changed, 39 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f976cbefa4..78c77a4929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -131,6 +131,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Removing generated methods and cleaning up in config [#1170](https://github.com/ie3-institute/simona/issues/1170) - Changed `pvInput` values in `PvInputTestData` to more realistic values [#1144](https://github.com/ie3-institute/simona/issues/1144) - Refactor `RuntimeConfig` [#1172](https://github.com/ie3-institute/simona/issues/1172) +- Renamed some methods and variables within `ThermalGrid` and `ThermalHouse` [#1193](https://github.com/ie3-institute/simona/issues/1193) ### Fixed - Fix rendering of references in documentation [#505](https://github.com/ie3-institute/simona/issues/505) 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 6f253be704..d3ca12a59d 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -67,7 +67,7 @@ final case class ThermalGrid( house.zip(lastHpState.thermalGridState.houseState) match { case Some((thermalHouse, lastHouseState)) => val (updatedHouseState, _) = - thermalHouse.determineState( + thermalHouse.updateState( relevantData, lastHouseState, lastHpState.ambientTemperature.getOrElse( @@ -476,7 +476,7 @@ final case class ThermalGrid( ): (Option[ThermalHouseState], Option[ThermalThreshold], Power) = { (house, state.houseState) match { case (Some(thermalHouse), Some(lastHouseState)) => - val (newState, threshold) = thermalHouse.determineState( + val (newState, threshold) = thermalHouse.updateState( relevantData, lastHouseState, lastAmbientTemperature, @@ -489,7 +489,7 @@ final case class ThermalGrid( ) ) { val (fullHouseState, maybeFullHouseThreshold) = - thermalHouse.determineState( + thermalHouse.updateState( relevantData, lastHouseState, lastAmbientTemperature, @@ -580,8 +580,8 @@ 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(lastThermalGridState.houseState).map { - case (house, houseState) => - house.determineState( + case (thermalHouse, houseState) => + thermalHouse.updateState( relevantData, houseState, lastAmbientTemperature, @@ -678,7 +678,7 @@ final case class ThermalGrid( ) ), ) - val revisedHouseState = thermalHouse.determineState( + val revisedHouseState = thermalHouse.updateState( relevantData, 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 a16840a081..b6aa4a949c 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -16,7 +16,7 @@ import edu.ie3.simona.model.participant.HpModel.HpRelevantData import edu.ie3.simona.model.thermal.ThermalGrid.ThermalEnergyDemand import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureLowerBoundaryReached, - HouseTemperatureUpperBoundaryReached, + HouseTemperatureTargetOrUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalHouse.{ ThermalHouseState, @@ -234,7 +234,7 @@ final case class ThermalHouse( * @return * Updated state and the tick in which the next threshold is reached */ - def determineState( + def updateState( relevantData: HpRelevantData, state: ThermalHouseState, lastAmbientTemperature: Temperature, @@ -315,7 +315,7 @@ final case class ThermalHouse( upperBoundaryTemperature, innerTemperature, resultingQDot, - ).map(HouseTemperatureUpperBoundaryReached) + ).map(HouseTemperatureTargetOrUpperBoundaryReached) } else { /* House is in perfect balance */ None @@ -399,7 +399,7 @@ object ThermalHouse { final case class HouseTemperatureLowerBoundaryReached( override val tick: Long ) extends ThermalThreshold - final case class HouseTemperatureUpperBoundaryReached( + final case class HouseTemperatureTargetOrUpperBoundaryReached( override val tick: Long ) extends ThermalThreshold } 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 9964f7af3f..ee6b162a2a 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, + HouseTemperatureTargetOrUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions @@ -55,7 +55,7 @@ class HpModelSpec true, 95, 15.6, - Some(HouseTemperatureUpperBoundaryReached(31711)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(31711)), ), ( HpState( @@ -70,7 +70,7 @@ class HpModelSpec true, 95, 16.4, - Some(HouseTemperatureUpperBoundaryReached(30642)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(30642)), ), ( HpState( @@ -85,7 +85,7 @@ class HpModelSpec true, 95, 18.0, - Some(HouseTemperatureUpperBoundaryReached(27771)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(27771)), ), ( HpState( @@ -450,7 +450,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -471,7 +471,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -494,7 +494,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -515,7 +515,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (0.0, 0.0, 95.0), ), @@ -539,7 +539,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -560,7 +560,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -583,7 +583,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (95.0, 0.0, 95.0), ), @@ -605,7 +605,7 @@ class HpModelSpec Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (0.0, 0.0, 95.0), ), @@ -628,7 +628,7 @@ class HpModelSpec ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) ), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (0.0, 0.0, 95.0), ), @@ -651,7 +651,7 @@ class HpModelSpec ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) ), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(0L)), ), (0.0, 0.0, 0.0), ), 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 302834f9c4..95c7b7b541 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -12,7 +12,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, + HouseTemperatureTargetOrUpperBoundaryReached, } import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageThreshold.{ @@ -354,7 +354,7 @@ class ThermalGridWithHouseAndStorageSpec ), testGridQDotInfeed, ), - Some(HouseTemperatureUpperBoundaryReached(3600L)), + Some(HouseTemperatureTargetOrUpperBoundaryReached(3600L)), ) ) val maybeStorageState = Some( @@ -488,7 +488,11 @@ class ThermalGridWithHouseAndStorageSpec Some( ( ThermalHouseState(houseTick, _, revisedQDotHouse), - Some(HouseTemperatureUpperBoundaryReached(houseWarmTick)), + Some( + HouseTemperatureTargetOrUpperBoundaryReached( + houseWarmTick + ) + ), ) ), Some( @@ -562,7 +566,7 @@ class ThermalGridWithHouseAndStorageSpec case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( - HouseTemperatureUpperBoundaryReached(7372L) + HouseTemperatureTargetOrUpperBoundaryReached(7372L) ) } 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 4d1186869b..928687771d 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -12,7 +12,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, + HouseTemperatureTargetOrUpperBoundaryReached, } import edu.ie3.simona.test.common.UnitSpec import edu.ie3.util.scala.quantities.DefaultQuantities.{zeroKW, zeroKWh} @@ -216,7 +216,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { case _ => fail("Thermal grid state has been calculated wrong.") } reachedThreshold shouldBe Some( - HouseTemperatureUpperBoundaryReached(7372L) + HouseTemperatureTargetOrUpperBoundaryReached(7372L) ) } } @@ -238,7 +238,9 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { Some(ThermalHouseState(tick, innerTemperature, qDot)), None, ), - Some(HouseTemperatureUpperBoundaryReached(thresholdTick)), + Some( + HouseTemperatureTargetOrUpperBoundaryReached(thresholdTick) + ), ) => tick shouldBe 0L innerTemperature should approximate(Celsius(18.9999d)) diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala index 4438036f06..7f6778e09f 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala @@ -78,7 +78,7 @@ class ThermalHouseSpec extends UnitSpec with HpInputTestData { val initialHousestate = startingState(house) val lastAmbientTemperature = Temperature(15, Celsius) - val (thermalHouseState, threshold) = house.determineState( + val (thermalHouseState, threshold) = house.updateState( relevantData, initialHousestate, lastAmbientTemperature, From a11b486fe5aa19057309e6fd683064341bf3464e Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 14:44:42 +0100 Subject: [PATCH 04/20] Implementing result handling with NotifierConfig in new Participant Signed-off-by: Sebastian Peter --- CHANGELOG.md | 1 + .../agent/participant2/ParticipantAgent.scala | 47 +++++++-------- .../participant2/ParticipantAgentInit.scala | 9 ++- .../ParticipantResultHandler.scala | 58 +++++++++++++++++++ .../participant2/ParticipantModelShell.scala | 36 +++++++++++- .../ParticipantAgentInitSpec.scala | 6 ++ .../ParticipantAgentMockFactory.scala | 4 +- .../participant2/ParticipantAgentSpec.scala | 47 ++++++++++++--- 8 files changed, 168 insertions(+), 40 deletions(-) create mode 100644 src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1de94548..c8ac46b7ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `VoltageLimits` [#1133](https://github.com/ie3-institute/simona/issues/1133) - Introducing new ParticipantAgent and ParticipantModel [#1134](https://github.com/ie3-institute/simona/issues/1134) - Using new `ParticipantAgent.Request` messages everywhere [#1195](https://github.com/ie3-institute/simona/issues/1195) +- Implementing consideration of `NotifierConfig` into new participant [#1200](https://github.com/ie3-institute/simona/issues/1200) ### 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/agent/participant2/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala index 0f33542e1b..069e44587d 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala @@ -17,8 +17,6 @@ import edu.ie3.simona.agent.participant.data.Data.{ PrimaryData, PrimaryDataExtra, } -import edu.ie3.simona.event.ResultEvent -import edu.ie3.simona.event.ResultEvent.ParticipantResultEvent import edu.ie3.simona.exceptions.CriticalFailureException import edu.ie3.simona.model.participant2.ParticipantModelShell import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion @@ -227,7 +225,7 @@ object ParticipantAgent { modelShell: ParticipantModelShell[_, _], inputHandler: ParticipantInputHandler, gridAdapter: ParticipantGridAdapter, - resultListener: Iterable[ActorRef[ResultEvent]], + resultHandler: ParticipantResultHandler, parentData: Either[SchedulerData, FlexControlledData], ): Behavior[Request] = Behaviors.receivePartial { @@ -244,7 +242,7 @@ object ParticipantAgent { updatedShell, inputHandler, gridAdapter, - resultListener, + resultHandler, parentData, ) @@ -256,7 +254,7 @@ object ParticipantAgent { modelShell, coreWithActivation, gridAdapter, - resultListener, + resultHandler, parentData, ) @@ -264,7 +262,7 @@ object ParticipantAgent { updatedShell, updatedInputHandler, updatedGridAdapter, - resultListener, + resultHandler, parentData, ) @@ -276,7 +274,7 @@ object ParticipantAgent { modelShell, inputHandlerWithData, gridAdapter, - resultListener, + resultHandler, parentData, ) @@ -284,7 +282,7 @@ object ParticipantAgent { updatedShell, updatedInputHandler, updatedGridAdapter, - resultListener, + resultHandler, parentData, ) @@ -334,7 +332,7 @@ object ParticipantAgent { modelShell, inputHandler, updatedGridAdapter, - resultListener, + resultHandler, parentData, ) @@ -348,7 +346,7 @@ object ParticipantAgent { modelShell, inputHandler, gridAdapterFinished, - resultListener, + resultHandler, parentData, ) @@ -356,7 +354,7 @@ object ParticipantAgent { updatedShell, updatedInputHandler, updatedGridAdapter, - resultListener, + resultHandler, parentData, ) } @@ -373,8 +371,8 @@ object ParticipantAgent { * The [[ParticipantInputHandler]]. * @param gridAdapter * The [[ParticipantGridAdapter]]. - * @param listener - * The result listeners. + * @param resultHandler + * The [[ParticipantResultHandler]]. * @param parentData * The parent of this [[ParticipantAgent]]. * @return @@ -385,7 +383,7 @@ object ParticipantAgent { modelShell: ParticipantModelShell[_, _], inputHandler: ParticipantInputHandler, gridAdapter: ParticipantGridAdapter, - listener: Iterable[ActorRef[ResultEvent]], + resultHandler: ParticipantResultHandler, parentData: Either[SchedulerData, FlexControlledData], ): ( ParticipantModelShell[_, _], @@ -418,9 +416,7 @@ object ParticipantAgent { val results = newShell.determineResults(tick, gridAdapter.nodalVoltage) - results.modelResults.foreach { res => - listener.foreach(_ ! ParticipantResultEvent(res)) - } + results.modelResults.foreach(resultHandler.send) val newGridAdapter = gridAdapter.storePowerValue(results.totalPower, tick) @@ -450,7 +446,9 @@ object ParticipantAgent { case Flex(FlexActivation(tick)) => val shellWithFlex = if (isCalculationRequired(shell, inputHandler)) { - shell.updateFlexOptions(tick) + val newShell = shell.updateFlexOptions(tick) + resultHandler.send(newShell.determineFlexOptionsResult(tick)) + newShell } else shell @@ -468,15 +466,12 @@ object ParticipantAgent { val shellWithOP = shell.updateOperatingPoint(flexControl) // todo we determine results even if no new data arrived, and EM is also activated... - val results = - shellWithOP.determineResults( - flexControl.tick, - gridAdapter.nodalVoltage, - ) + val results = shellWithOP.determineResults( + flexControl.tick, + gridAdapter.nodalVoltage, + ) - results.modelResults.foreach { res => - listener.foreach(_ ! ParticipantResultEvent(res)) - } + results.modelResults.foreach(resultHandler.send) val gridAdapterWithResult = gridAdapter.storePowerValue( diff --git a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala index 88d13c85c5..d31af95eba 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala @@ -11,6 +11,7 @@ import edu.ie3.simona.agent.grid.GridAgent import edu.ie3.simona.agent.participant2.ParticipantAgent._ import edu.ie3.simona.config.RuntimeConfig.BaseRuntimeConfig import edu.ie3.simona.event.ResultEvent +import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.exceptions.CriticalFailureException import edu.ie3.simona.model.participant2.ParticipantModelShell import edu.ie3.simona.ontology.messages.SchedulerMessage.{ @@ -70,12 +71,15 @@ object ParticipantAgentInit { * The simulation start date and time. * @param simulationEnd * The simulation end date and time. + * @param notifierConfig + * The result configuration. */ final case class SimulationParameters( expectedPowerRequestTick: Long, requestVoltageDeviationTolerance: Dimensionless, simulationStart: ZonedDateTime, simulationEnd: ZonedDateTime, + notifierConfig: NotifierConfig, ) /** Starts the initialization process of a [[ParticipantAgent]]. @@ -380,7 +384,10 @@ object ParticipantAgentInit { simulationParams.expectedPowerRequestTick, simulationParams.requestVoltageDeviationTolerance, ), - participantRefs.resultListener, + ParticipantResultHandler( + participantRefs.resultListener, + simulationParams.notifierConfig, + ), parentData, ) } diff --git a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala new file mode 100644 index 0000000000..02974e2d91 --- /dev/null +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala @@ -0,0 +1,58 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.agent.participant2 + +import edu.ie3.datamodel.models.result.system.{ + FlexOptionsResult, + SystemParticipantResult, +} +import edu.ie3.simona.event.ResultEvent +import edu.ie3.simona.event.ResultEvent.{ + FlexOptionsResultEvent, + ParticipantResultEvent, +} +import edu.ie3.simona.event.notifier.NotifierConfig +import org.apache.pekko.actor.typed.ActorRef + +/** Handles all kind of results stemming from the participant by sending them to + * the result listener, if applicable. + * + * @param listener + * The actor reference to the result listener. + * @param config + * The result configuration. + */ +final case class ParticipantResultHandler( + private val listener: Iterable[ActorRef[ResultEvent]], + private val config: NotifierConfig, +) { + + /** Send the participant result to all listeners, if enabled. + * + * @param result + * The [[SystemParticipantResult]]. + */ + def send(result: SystemParticipantResult): Unit = + if (config.simulationResultInfo) { + listener.foreach( + _ ! ParticipantResultEvent(result) + ) + } + + /** Send the flex options result to all listeners, if enabled. + * + * @param result + * The [[FlexOptionsResult]]. + */ + def send(result: FlexOptionsResult): Unit = + if (config.flexResult) { + listener.foreach( + _ ! FlexOptionsResultEvent(result) + ) + } + +} diff --git a/src/main/scala/edu/ie3/simona/model/participant2/ParticipantModelShell.scala b/src/main/scala/edu/ie3/simona/model/participant2/ParticipantModelShell.scala index b9c5af8c6a..0570ca602c 100644 --- a/src/main/scala/edu/ie3/simona/model/participant2/ParticipantModelShell.scala +++ b/src/main/scala/edu/ie3/simona/model/participant2/ParticipantModelShell.scala @@ -7,7 +7,10 @@ package edu.ie3.simona.model.participant2 import edu.ie3.datamodel.models.input.system.SystemParticipantInput -import edu.ie3.datamodel.models.result.system.SystemParticipantResult +import edu.ie3.datamodel.models.result.system.{ + FlexOptionsResult, + SystemParticipantResult, +} import edu.ie3.simona.agent.participant.data.Data import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ComplexPower import edu.ie3.simona.agent.participant.data.Data.{ @@ -34,6 +37,7 @@ import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.simona.service.ServiceType import edu.ie3.simona.util.TickUtil.TickLong +import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble import edu.ie3.util.scala.OperationInterval import edu.ie3.util.scala.quantities.DefaultQuantities._ import edu.ie3.util.scala.quantities.ReactivePower @@ -235,14 +239,40 @@ final case class ParticipantModelShell[ ) } - /** Determines and returns results of the current operating point. + /** Determines flex options results for the current flex options, which have + * to have been calculated before. + * + * @param tick + * The current tick. + * @return + * The flex options results. + */ + def determineFlexOptionsResult( + tick: Long + ): FlexOptionsResult = { + val minMaxFlexOptions = + flexOptions match { + case flex: ProvideMinMaxFlexOptions => flex + } + + new FlexOptionsResult( + tick.toDateTime(simulationStartDate), + uuid, + minMaxFlexOptions.ref.toMegawatts.asMegaWatt, + minMaxFlexOptions.min.toMegawatts.asMegaWatt, + minMaxFlexOptions.max.toMegawatts.asMegaWatt, + ) + } + + /** Determines and returns results of the current operating point, which has + * to have been calculated before. * * @param tick * The current tick. * @param nodalVoltage * The current nodal voltage. * @return - * An updated [[ParticipantModelShell]]. + * The model results. */ def determineResults( tick: Long, diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala index 364cd92104..b8bea16c99 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala @@ -20,6 +20,7 @@ import edu.ie3.simona.agent.participant2.ParticipantAgentInit.{ } import edu.ie3.simona.config.RuntimeConfig.{LoadRuntimeConfig, PvRuntimeConfig} import edu.ie3.simona.event.ResultEvent +import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.ontology.messages.SchedulerMessage.{ Completion, ScheduleActivation, @@ -62,6 +63,11 @@ class ParticipantAgentInitSpec Each(1e-14), simulationStart, defaultSimulationStart.plus(2, ChronoUnit.DAYS), + NotifierConfig( + simulationResultInfo = false, + powerRequestReply = false, + flexResult = false, + ), ) "A ParticipantAgent that is not depending on external services" when { diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala index b1950a0164..d8f70158f6 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala @@ -33,7 +33,7 @@ object ParticipantAgentMockFactory { modelShell: ParticipantModelShell[_, _], inputHandler: ParticipantInputHandler, gridAdapter: ParticipantGridAdapter, - resultListener: Iterable[ActorRef[ResultEvent]], + resultHandler: ParticipantResultHandler, parent: Either[ (ActorRef[SchedulerMessage], ActorRef[ActorRef[Activation]]), (ActorRef[FlexResponse], ActorRef[ActorRef[FlexRequest]]), @@ -58,7 +58,7 @@ object ParticipantAgentMockFactory { modelShell, inputHandler, gridAdapter, - resultListener, + resultHandler, parentData, ) } diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala index 5395917d4b..e85542ca6c 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala @@ -29,6 +29,7 @@ import edu.ie3.simona.agent.participant2.ParticipantAgent.{ } import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.event.ResultEvent.ParticipantResultEvent +import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.model.participant2.{ ParticipantModelInit, ParticipantModelShell, @@ -63,6 +64,12 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { private implicit val activePowerTolerance: Power = Kilowatts(1e-10) private implicit val reactivePowerTolerance: ReactivePower = Kilovars(1e-10) + private val notifierConfig = NotifierConfig( + simulationResultInfo = true, + powerRequestReply = false, + flexResult = false, + ) + "A ParticipantAgent that is not controlled by EM" when { "not depending on external services" should { @@ -96,7 +103,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Left(scheduler.ref, receiveAdapter.ref), ) ) @@ -246,7 +256,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Left(scheduler.ref, receiveAdapter.ref), ) ) @@ -377,7 +390,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Left(scheduler.ref, receiveAdapter.ref), ) ) @@ -613,7 +629,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Left(scheduler.ref, receiveAdapter.ref), ) ) @@ -826,7 +845,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Right(em.ref, receiveAdapter.ref), ) ) @@ -962,7 +984,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Right(em.ref, receiveAdapter.ref), ) ) @@ -1134,7 +1159,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Right(em.ref, receiveAdapter.ref), ) ) @@ -1410,7 +1438,10 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { expectedRequestTick = 12 * 3600, requestVoltageDeviationTolerance = Each(1e-14), ), - Iterable(resultListener.ref), + ParticipantResultHandler( + Iterable(resultListener.ref), + notifierConfig, + ), Right(em.ref, receiveAdapter.ref), ) ) From addbfd8cc85dae0330fdcc1678d7c71092b6eca2 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 15:03:13 +0100 Subject: [PATCH 05/20] Testing FlexOptionResults Signed-off-by: Sebastian Peter --- .../participant2/ParticipantAgentSpec.scala | 143 +++++++++++++++++- 1 file changed, 141 insertions(+), 2 deletions(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala index e85542ca6c..55e39055d0 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala @@ -6,6 +6,7 @@ package edu.ie3.simona.agent.participant2 +import edu.ie3.datamodel.models.result.system.FlexOptionsResult import edu.ie3.simona.agent.grid.GridAgent import edu.ie3.simona.agent.grid.GridAgentMessages.{ AssetPowerChangedMessage, @@ -28,7 +29,10 @@ import edu.ie3.simona.agent.participant2.ParticipantAgent.{ RequestAssetPowerMessage, } import edu.ie3.simona.event.ResultEvent -import edu.ie3.simona.event.ResultEvent.ParticipantResultEvent +import edu.ie3.simona.event.ResultEvent.{ + FlexOptionsResultEvent, + ParticipantResultEvent, +} import edu.ie3.simona.event.notifier.NotifierConfig import edu.ie3.simona.model.participant2.{ ParticipantModelInit, @@ -67,7 +71,7 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { private val notifierConfig = NotifierConfig( simulationResultInfo = true, powerRequestReply = false, - flexResult = false, + flexResult = true, ) "A ParticipantAgent that is not controlled by EM" when { @@ -866,6 +870,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(3)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.start.toDateTime + result.getpRef() should equalWithTolerance(0.001.asMegaWatt) + result.getpMin() should equalWithTolerance(-0.001.asMegaWatt) + result.getpMax() should equalWithTolerance(0.003.asMegaWatt) + } + flexRef ! IssuePowerControl(operationInterval.start, Kilowatts(3)) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -913,6 +926,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.end.toDateTime + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(operationInterval.end) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1005,6 +1027,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(3)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.start.toDateTime + result.getpRef() should equalWithTolerance(0.001.asMegaWatt) + result.getpMin() should equalWithTolerance(-0.001.asMegaWatt) + result.getpMax() should equalWithTolerance(0.003.asMegaWatt) + } + flexRef ! IssuePowerControl(operationInterval.start, Kilowatts(3)) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1053,6 +1084,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(3)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe (12 * 3600).toDateTime + result.getpRef() should equalWithTolerance(0.001.asMegaWatt) + result.getpMin() should equalWithTolerance(-0.001.asMegaWatt) + result.getpMax() should equalWithTolerance(0.003.asMegaWatt) + } + flexRef ! IssueNoControl(12 * 3600) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1083,6 +1123,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.end.toDateTime + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(operationInterval.end) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1191,6 +1240,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe simulationStartDate + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(0) // outside of operation interval, 0 MW @@ -1235,6 +1293,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(4)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.start.toDateTime + result.getpRef() should equalWithTolerance(0.002.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.004.asMegaWatt) + } + flexRef ! IssuePowerControl(operationInterval.start, Kilowatts(3)) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1293,6 +1360,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(5)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe (12 * 3600).toDateTime + result.getpRef() should equalWithTolerance(0.003.asMegaWatt) + result.getpMin() should equalWithTolerance(0.001.asMegaWatt) + result.getpMax() should equalWithTolerance(0.005.asMegaWatt) + } + flexRef ! IssueNoControl(12 * 3600) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1334,6 +1410,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(8)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe (18 * 3600).toDateTime + result.getpRef() should equalWithTolerance(0.006.asMegaWatt) + result.getpMin() should equalWithTolerance(0.004.asMegaWatt) + result.getpMax() should equalWithTolerance(0.008.asMegaWatt) + } + flexRef ! IssueNoControl(18 * 3600) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1364,6 +1449,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.end.toDateTime + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(operationInterval.end) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1470,6 +1564,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe simulationStartDate + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(0) // outside of operation interval, 0 MW @@ -1514,6 +1617,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(3)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.start.toDateTime + result.getpRef() should equalWithTolerance(0.003.asMegaWatt) + result.getpMin() should equalWithTolerance(0.003.asMegaWatt) + result.getpMax() should equalWithTolerance(0.003.asMegaWatt) + } + flexRef ! IssuePowerControl(operationInterval.start, Kilowatts(3)) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1572,6 +1684,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(6)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe (12 * 3600).toDateTime + result.getpRef() should equalWithTolerance(0.006.asMegaWatt) + result.getpMin() should equalWithTolerance(0.006.asMegaWatt) + result.getpMax() should equalWithTolerance(0.006.asMegaWatt) + } + flexRef ! IssueNoControl(12 * 3600) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1613,6 +1734,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(3)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe (18 * 3600).toDateTime + result.getpRef() should equalWithTolerance(0.003.asMegaWatt) + result.getpMin() should equalWithTolerance(0.003.asMegaWatt) + result.getpMax() should equalWithTolerance(0.003.asMegaWatt) + } + flexRef ! IssueNoControl(18 * 3600) resultListener.expectMessageType[ParticipantResultEvent] match { @@ -1642,6 +1772,15 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { max should approximate(Kilowatts(0)) } + resultListener.expectMessageType[FlexOptionsResultEvent] match { + case FlexOptionsResultEvent(result: FlexOptionsResult) => + result.getInputModel shouldBe model.uuid + result.getTime shouldBe operationInterval.end.toDateTime + result.getpRef() should equalWithTolerance(0.asMegaWatt) + result.getpMin() should equalWithTolerance(0.asMegaWatt) + result.getpMax() should equalWithTolerance(0.asMegaWatt) + } + flexRef ! IssueNoControl(operationInterval.end) resultListener.expectMessageType[ParticipantResultEvent] match { From 60e92721143c941a2ccacc523c57f40d3a533111 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 15:47:09 +0100 Subject: [PATCH 06/20] Removing unused import Signed-off-by: Sebastian Peter --- .../simona/agent/participant2/ParticipantAgentMockFactory.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala index d8f70158f6..1bc44de52e 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentMockFactory.scala @@ -13,7 +13,6 @@ import edu.ie3.simona.agent.participant2.ParticipantAgent.{ Request, SchedulerData, } -import edu.ie3.simona.event.ResultEvent import edu.ie3.simona.model.participant2.ParticipantModelShell import edu.ie3.simona.ontology.messages.{Activation, SchedulerMessage} import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{ From 7794feef106f31e978d8345861098244078f85c6 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 17:07:20 +0100 Subject: [PATCH 07/20] Participant now sends `FlexResul` to EM Signed-off-by: Sebastian Peter --- CHANGELOG.md | 1 + .../agent/participant2/ParticipantAgent.scala | 16 ++- .../participant2/ParticipantAgentSpec.scala | 109 +++++++++++++++++- 3 files changed, 119 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1de94548..13d111442d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `VoltageLimits` [#1133](https://github.com/ie3-institute/simona/issues/1133) - Introducing new ParticipantAgent and ParticipantModel [#1134](https://github.com/ie3-institute/simona/issues/1134) - Using new `ParticipantAgent.Request` messages everywhere [#1195](https://github.com/ie3-institute/simona/issues/1195) +- Send `FlexResult` to EM [#1202](https://github.com/ie3-institute/simona/issues/1202) ### 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/agent/participant2/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala index 0f33542e1b..491b7ce370 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala @@ -494,11 +494,17 @@ object ParticipantAgent { throw new CriticalFailureException( "Received issue flex control while not controlled by EM" ), - _.emAgent ! FlexCompletion( - shellWithOP.uuid, - changeIndicator.changesAtNextActivation, - changeIndicator.changesAtTick, - ), + flexData => { + flexData.emAgent ! FlexResult( + shellWithOP.uuid, + results.totalPower, + ) + flexData.emAgent ! FlexCompletion( + shellWithOP.uuid, + changeIndicator.changesAtNextActivation, + changeIndicator.changesAtTick, + ) + }, ) (shellWithOP, gridAdapterWithResult) diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala index 5395917d4b..6eb261dd47 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentSpec.scala @@ -458,7 +458,7 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { gridAgent.expectMessageType[AssetPowerChangedMessage] match { case AssetPowerChangedMessage(p, q) => p should approximate(Kilowatts(3)) - q should approximate(Kilovars(1.452966314514)) + q should approximate(Kilovars(1.4529663145)) } participantAgent ! GridSimulationFinished(12 * 3600, 24 * 3600) @@ -854,6 +854,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -901,6 +908,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + em.expectMessage(FlexCompletion(model.uuid)) // TICK 24 * 3600: GridAgent requests power @@ -990,6 +1004,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -1038,6 +1059,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0004843221.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(1)) + result.q should approximate(Kilovars(0.4843221048)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -1068,6 +1096,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + em.expectMessage(FlexCompletion(model.uuid)) // TICK 24 * 3600: GridAgent requests power @@ -1174,6 +1209,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + // next model tick and next data tick are ignored, // because we are outside of operation interval em.expectMessage( @@ -1217,6 +1259,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + // next model tick and next data tick are both hour 12 em.expectMessage( FlexCompletion( @@ -1275,6 +1324,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -1316,6 +1372,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.002905932629.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(6)) + result.q should approximate(Kilovars(2.905932629)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -1346,6 +1409,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + // Since we left the operation interval, there are no more ticks to activate em.expectMessage(FlexCompletion(model.uuid)) @@ -1450,6 +1520,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + // next model tick and next data tick are ignored, // because we are outside of operation interval em.expectMessage( @@ -1493,6 +1570,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + // next data tick is hour 12 em.expectMessage( FlexCompletion( @@ -1548,7 +1632,14 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getInputModel shouldBe model.uuid result.getTime shouldBe (12 * 3600).toDateTime result.getP should equalWithTolerance(0.006.asMegaWatt) - result.getQ should equalWithTolerance(0.00290593263.asMegaVar) + result.getQ should equalWithTolerance(0.002905932629.asMegaVar) + } + + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(6)) + result.q should approximate(Kilovars(2.905932629)) } em.expectMessage( @@ -1592,6 +1683,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.00145296631.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(3)) + result.q should approximate(Kilovars(1.4529663145)) + } + em.expectMessage( FlexCompletion( model.uuid, @@ -1621,6 +1719,13 @@ class ParticipantAgentSpec extends ScalaTestWithActorTestKit with UnitSpec { result.getQ should equalWithTolerance(0.0.asMegaVar) } + em.expectMessageType[FlexResult] match { + case FlexResult(uuid, result) => + uuid shouldBe model.uuid + result.p should approximate(Kilowatts(0)) + result.q should approximate(Kilovars(0)) + } + // Since we left the operation interval, there are no more ticks to activate em.expectMessage(FlexCompletion(model.uuid)) From cd3d4ac76e0a02ec1688f2cf666aaf9d8d3ecdfa Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 18 Feb 2025 17:16:08 +0100 Subject: [PATCH 08/20] fix duration types --- CHANGELOG.md | 3 ++- .../scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala | 6 +++--- .../edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1de94548..1062ce494f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -181,7 +181,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactoring of `ThermalGrid.handleInfeed` to fix thermal storage recharge correctly when empty [#930](https://github.com/ie3-institute/simona/issues/930) - Move `ScheduleServiceActivation` out of `RegistrationResponseMessage` [#1143](https://github.com/ie3-institute/simona/issues/1143) - Check for runningHp when handling infeed to thermalGrid [#1167](https://github.com/ie3-institute/simona/issues/1167) - +- Fixed type of Durations [#1068](https://github.com/ie3-institute/simona/issues/1068) + ## [3.0.0] - 2023-08-07 ### Added 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 1a4f9eab0c..a4f4fe781a 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -43,13 +43,13 @@ import org.apache.pekko.actor.typed.scaladsl.{ StashBuffer, } import org.apache.pekko.actor.typed.{ActorRef, ActorSystem, Behavior, Scheduler} -import org.apache.pekko.util.{Timeout => PekkoTimeout} +import org.apache.pekko.util.{Timeout, Timeout => PekkoTimeout} import org.slf4j.Logger import squants.Each import java.time.ZonedDateTime import java.util.UUID -import scala.concurrent.duration.FiniteDuration +import scala.concurrent.duration.{Duration, FiniteDuration, MILLISECONDS} import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success} @@ -1129,7 +1129,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ): Boolean = { implicit val ec: ExecutionContext = ctx.executionContext - implicit val timeout: PekkoTimeout = PekkoTimeout.create(askTimeout) + implicit val timeout: PekkoTimeout = Timeout(askTimeout) implicit val system: ActorSystem[_] = ctx.system ctx.log.debug(s"asking assets for power values: {}", nodeToAssetAgents) 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 89614f68e2..bad8d4b285 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -47,6 +47,7 @@ import tech.units.indriya.ComparableQuantity import java.time.{Duration, ZonedDateTime} import java.util.UUID import javax.measure.quantity.Angle +import scala.concurrent.duration.{FiniteDuration, MINUTES} import scala.jdk.CollectionConverters.SetHasAsJava import scala.language.implicitConversions @@ -394,7 +395,7 @@ class PowerFlowSupportSpec 1e-5, Vector(1e-12), 50, - Duration.ofMinutes(30), + FiniteDuration.apply(30, MINUTES), stopOnFailure = true, ) From 45e2b2301c7ba047e8646dba8f9bbc1b7e61c89a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 18 Feb 2025 17:28:55 +0100 Subject: [PATCH 09/20] fmt --- src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a4f4fe781a..7d9074c945 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -49,7 +49,7 @@ import squants.Each import java.time.ZonedDateTime import java.util.UUID -import scala.concurrent.duration.{Duration, FiniteDuration, MILLISECONDS} +import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success} From eb78b631250acb5d587d95d13a09a47f29d5d6ed Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 18 Feb 2025 17:32:12 +0100 Subject: [PATCH 10/20] improve imports --- .../scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 7d9074c945..b320b0d6f8 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala @@ -43,7 +43,7 @@ import org.apache.pekko.actor.typed.scaladsl.{ StashBuffer, } import org.apache.pekko.actor.typed.{ActorRef, ActorSystem, Behavior, Scheduler} -import org.apache.pekko.util.{Timeout, Timeout => PekkoTimeout} +import org.apache.pekko.util.Timeout import org.slf4j.Logger import squants.Each @@ -1129,7 +1129,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { ): Boolean = { implicit val ec: ExecutionContext = ctx.executionContext - implicit val timeout: PekkoTimeout = Timeout(askTimeout) + implicit val timeout: Timeout = Timeout(askTimeout) implicit val system: ActorSystem[_] = ctx.system ctx.log.debug(s"asking assets for power values: {}", nodeToAssetAgents) @@ -1212,7 +1212,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { )(implicit ctx: ActorContext[GridAgent.Request] ): Boolean = { - implicit val timeout: PekkoTimeout = PekkoTimeout(askTimeout) + implicit val timeout: Timeout = Timeout(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler @@ -1283,7 +1283,7 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport { )(implicit ctx: ActorContext[GridAgent.Request] ): Boolean = { - implicit val timeout: PekkoTimeout = PekkoTimeout(askTimeout) + implicit val timeout: Timeout = Timeout(askTimeout) implicit val ec: ExecutionContext = ctx.executionContext implicit val scheduler: Scheduler = ctx.system.scheduler From 2789dbe9b470c6ffd8de8b2c5893323b646a909f Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 18:17:43 +0100 Subject: [PATCH 11/20] Some refactorings Signed-off-by: Sebastian Peter --- .../agent/participant2/ParticipantAgent.scala | 8 +++-- .../participant2/ParticipantAgentInit.scala | 35 ++++++++++++------- .../ParticipantResultHandler.scala | 4 +-- .../ParticipantAgentInitSpec.scala | 33 +++++++++-------- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala index 069e44587d..c9b07a9be9 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgent.scala @@ -416,7 +416,7 @@ object ParticipantAgent { val results = newShell.determineResults(tick, gridAdapter.nodalVoltage) - results.modelResults.foreach(resultHandler.send) + results.modelResults.foreach(resultHandler.maybeSend) val newGridAdapter = gridAdapter.storePowerValue(results.totalPower, tick) @@ -447,7 +447,9 @@ object ParticipantAgent { val shellWithFlex = if (isCalculationRequired(shell, inputHandler)) { val newShell = shell.updateFlexOptions(tick) - resultHandler.send(newShell.determineFlexOptionsResult(tick)) + resultHandler.maybeSend( + newShell.determineFlexOptionsResult(tick) + ) newShell } else shell @@ -471,7 +473,7 @@ object ParticipantAgent { gridAdapter.nodalVoltage, ) - results.modelResults.foreach(resultHandler.send) + results.modelResults.foreach(resultHandler.maybeSend) val gridAdapterWithResult = gridAdapter.storePowerValue( diff --git a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala index d31af95eba..cdd686ec7e 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInit.scala @@ -71,15 +71,12 @@ object ParticipantAgentInit { * The simulation start date and time. * @param simulationEnd * The simulation end date and time. - * @param notifierConfig - * The result configuration. */ final case class SimulationParameters( expectedPowerRequestTick: Long, requestVoltageDeviationTolerance: Dimensionless, simulationStart: ZonedDateTime, simulationEnd: ZonedDateTime, - notifierConfig: NotifierConfig, ) /** Starts the initialization process of a [[ParticipantAgent]]. @@ -87,8 +84,10 @@ object ParticipantAgentInit { * @param participantInput * The system participant model input that represents the physical model at * the core of the agent. - * @param config + * @param runtimeConfig * Runtime configuration that has to match the participant type. + * @param notifierConfig + * The result configuration. * @param participantRefs * A collection of actor references to actors required for initialization * and operation. @@ -101,7 +100,8 @@ object ParticipantAgentInit { */ def apply( participantInput: SystemParticipantInput, - config: BaseRuntimeConfig, + runtimeConfig: BaseRuntimeConfig, + notifierConfig: NotifierConfig, participantRefs: ParticipantRefs, simulationParams: SimulationParameters, parent: Either[ActorRef[SchedulerMessage], ActorRef[FlexResponse]], @@ -140,7 +140,8 @@ object ParticipantAgentInit { uninitialized( participantInput, - config, + runtimeConfig, + notifierConfig, participantRefs, simulationParams, parentData, @@ -151,7 +152,8 @@ object ParticipantAgentInit { */ private def uninitialized( participantInput: SystemParticipantInput, - config: BaseRuntimeConfig, + runtimeConfig: BaseRuntimeConfig, + notifierConfig: NotifierConfig, participantRefs: ParticipantRefs, simulationParams: SimulationParameters, parentData: Either[SchedulerData, FlexControlledData], @@ -167,7 +169,8 @@ object ParticipantAgentInit { waitingForPrimaryProxy( participantInput, - config, + runtimeConfig, + notifierConfig, participantRefs, simulationParams, parentData, @@ -180,7 +183,8 @@ object ParticipantAgentInit { */ private def waitingForPrimaryProxy( participantInput: SystemParticipantInput, - config: BaseRuntimeConfig, + runtimeConfig: BaseRuntimeConfig, + notifierConfig: NotifierConfig, participantRefs: ParticipantRefs, simulationParams: SimulationParameters, parentData: Either[SchedulerData, FlexControlledData], @@ -200,11 +204,12 @@ object ParticipantAgentInit { completeInitialization( ParticipantModelShell.createForPrimaryData( participantInput, - config, + runtimeConfig, primaryDataExtra, simulationParams.simulationStart, simulationParams.simulationEnd, ), + notifierConfig, expectedFirstData, participantRefs, simulationParams, @@ -215,7 +220,7 @@ object ParticipantAgentInit { // we're _not_ supposed to replay primary data, thus initialize the physical model val modelShell = ParticipantModelShell.createForPhysicalModel( participantInput, - config, + runtimeConfig, simulationParams.simulationStart, simulationParams.simulationEnd, ) @@ -226,6 +231,7 @@ object ParticipantAgentInit { // not requiring any secondary services, thus we're ready to go completeInitialization( modelShell, + notifierConfig, Map.empty, participantRefs, simulationParams, @@ -255,6 +261,7 @@ object ParticipantAgentInit { waitingForServices( modelShell, + notifierConfig, participantRefs, simulationParams, requiredServices.values.toSet, @@ -299,6 +306,7 @@ object ParticipantAgentInit { */ private def waitingForServices( modelShell: ParticipantModelShell[_, _], + notifierConfig: NotifierConfig, participantRefs: ParticipantRefs, simulationParams: SimulationParameters, expectedRegistrations: Set[ClassicRef], @@ -321,6 +329,7 @@ object ParticipantAgentInit { // all secondary services set up, ready to go completeInitialization( modelShell, + notifierConfig, newExpectedFirstData, participantRefs, simulationParams, @@ -330,6 +339,7 @@ object ParticipantAgentInit { // there's at least one more service to go, let's wait for confirmation waitingForServices( modelShell, + notifierConfig, participantRefs, simulationParams, newExpectedRegistrations, @@ -343,6 +353,7 @@ object ParticipantAgentInit { */ private def completeInitialization( modelShell: ParticipantModelShell[_, _], + notifierConfig: NotifierConfig, expectedData: Map[ClassicRef, Long], participantRefs: ParticipantRefs, simulationParams: SimulationParameters, @@ -386,7 +397,7 @@ object ParticipantAgentInit { ), ParticipantResultHandler( participantRefs.resultListener, - simulationParams.notifierConfig, + notifierConfig, ), parentData, ) diff --git a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala index 02974e2d91..8ee8e6e2a6 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant2/ParticipantResultHandler.scala @@ -36,7 +36,7 @@ final case class ParticipantResultHandler( * @param result * The [[SystemParticipantResult]]. */ - def send(result: SystemParticipantResult): Unit = + def maybeSend(result: SystemParticipantResult): Unit = if (config.simulationResultInfo) { listener.foreach( _ ! ParticipantResultEvent(result) @@ -48,7 +48,7 @@ final case class ParticipantResultHandler( * @param result * The [[FlexOptionsResult]]. */ - def send(result: FlexOptionsResult): Unit = + def maybeSend(result: FlexOptionsResult): Unit = if (config.flexResult) { listener.foreach( _ ! FlexOptionsResultEvent(result) diff --git a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala index b8bea16c99..11e3b27bdc 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant2/ParticipantAgentInitSpec.scala @@ -63,16 +63,11 @@ class ParticipantAgentInitSpec Each(1e-14), simulationStart, defaultSimulationStart.plus(2, ChronoUnit.DAYS), - NotifierConfig( - simulationResultInfo = false, - powerRequestReply = false, - flexResult = false, - ), ) "A ParticipantAgent that is not depending on external services" when { - val config = LoadRuntimeConfig() + val runtimeConfig = LoadRuntimeConfig() val operationStart = 10 * 3600L @@ -104,7 +99,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Left(scheduler.ref), @@ -150,7 +146,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Left(scheduler.ref), @@ -202,7 +199,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Right(em.ref), @@ -258,7 +256,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Right(em.ref), @@ -310,7 +309,7 @@ class ParticipantAgentInitSpec ) .build() - val config = PvRuntimeConfig() + val runtimeConfig = PvRuntimeConfig() "not controlled by EM" should { @@ -333,7 +332,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Left(scheduler.ref), @@ -392,7 +392,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Left(scheduler.ref), @@ -449,7 +450,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Right(em.ref), @@ -514,7 +516,8 @@ class ParticipantAgentInitSpec val participantAgent = spawn( ParticipantAgentInit( mockInput, - config, + runtimeConfig, + mock[NotifierConfig], refs, simulationParams, Right(em.ref), From 5202f662fde0804145db5b464efb565f2999819d Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Tue, 18 Feb 2025 18:18:30 +0100 Subject: [PATCH 12/20] Fixing changelog Signed-off-by: Sebastian Peter --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d111442d..ceb221d244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `VoltageLimits` [#1133](https://github.com/ie3-institute/simona/issues/1133) - Introducing new ParticipantAgent and ParticipantModel [#1134](https://github.com/ie3-institute/simona/issues/1134) - Using new `ParticipantAgent.Request` messages everywhere [#1195](https://github.com/ie3-institute/simona/issues/1195) -- Send `FlexResult` to EM [#1202](https://github.com/ie3-institute/simona/issues/1202) ### Changed - Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435) @@ -182,6 +181,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactoring of `ThermalGrid.handleInfeed` to fix thermal storage recharge correctly when empty [#930](https://github.com/ie3-institute/simona/issues/930) - Move `ScheduleServiceActivation` out of `RegistrationResponseMessage` [#1143](https://github.com/ie3-institute/simona/issues/1143) - Check for runningHp when handling infeed to thermalGrid [#1167](https://github.com/ie3-institute/simona/issues/1167) +- Send `FlexResult` to EM [#1202](https://github.com/ie3-institute/simona/issues/1202) ## [3.0.0] - 2023-08-07 From 89997938bb07a926ae57df97c3113bac2b68ce83 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 19 Feb 2025 07:05:37 +0100 Subject: [PATCH 13/20] fix tmp workaround durationConvert --- src/main/scala/edu/ie3/simona/config/SimonaConfig.scala | 2 +- 1 file changed, 1 insertion(+), 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 2fadd4aeb7..8319f01dd4 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -32,7 +32,7 @@ object SimonaConfig { // TODO: replace with finite duration implicit def durationConvert: ConfigConvert[Duration] = ConfigConvert.viaStringTry( - str => Try(Duration.parse(("PT" + str).toUpperCase)), + str => Try(Duration.parse(("P" + str).toUpperCase)), x => x.toString, ) From 060cb4d56cb93461fc396aff3b14ce04ad5b04e0 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Wed, 19 Feb 2025 07:53:52 +0100 Subject: [PATCH 14/20] adapt tmp workaround durationConvert --- src/main/scala/edu/ie3/simona/config/SimonaConfig.scala | 8 +++++++- 1 file changed, 7 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 8319f01dd4..030afe2572 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -32,7 +32,13 @@ object SimonaConfig { // TODO: replace with finite duration implicit def durationConvert: ConfigConvert[Duration] = ConfigConvert.viaStringTry( - str => Try(Duration.parse(("P" + str).toUpperCase)), + str => { + val adjustedStr = str.trim match { + case s if s.endsWith("d") => "P" + s.toUpperCase + case _ => "PT" + str.toUpperCase + } + Try(Duration.parse(adjustedStr)) + }, x => x.toString, ) From 029d895c0bc7b25490cdbdfb769d98ef1f11e17f Mon Sep 17 00:00:00 2001 From: staudtMarius Date: Wed, 19 Feb 2025 08:34:33 +0100 Subject: [PATCH 15/20] Replacing more durations. --- .../edu/ie3/simona/agent/grid/GridAgent.scala | 6 +++--- .../ie3/simona/config/ConfigFailFast.scala | 19 +++++------------- .../edu/ie3/simona/config/SimonaConfig.scala | 20 +++---------------- .../edu/ie3/simona/agent/em/EmAgentIT.scala | 2 +- .../ie3/simona/agent/grid/ThermalGridIT.scala | 2 +- ...FixedFeedInAgentModelCalculationSpec.scala | 2 +- .../HpAgentModelCalculationSpec.scala | 2 +- .../LoadAgentFixedModelCalculationSpec.scala | 2 +- ...LoadAgentProfileModelCalculationSpec.scala | 2 +- .../ParticipantAgent2ListenerSpec.scala | 2 +- .../ParticipantAgentExternalSourceSpec.scala | 4 ++-- .../PvAgentModelCalculationSpec.scala | 2 +- .../StorageAgentModelCalculationSpec.scala | 2 +- .../WecAgentModelCalculationSpec.scala | 4 ++-- .../simona/config/ConfigFailFastSpec.scala | 9 +++++---- 15 files changed, 29 insertions(+), 51 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 2f12d8afdf..6e6da389c0 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -57,9 +57,9 @@ object GridAgent extends DBFSAlgorithm { context.messageAdapter[Activation](msg => WrappedActivation(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 + + // this determines the agents regular time bin it wants to be triggered e.g. one hour + val resolution: Long = simonaConfig.simona.powerflow.resolution.toSeconds val simStartTime: ZonedDateTime = TimeUtil.withDefaults .toZonedDateTime(simonaConfig.simona.time.startDateTime) diff --git a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala index ea471a1ee1..ce26616f18 100644 --- a/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala +++ b/src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala @@ -43,7 +43,6 @@ import tech.units.indriya.unit.Units import java.time.ZonedDateTime import java.time.format.DateTimeParseException -import java.time.temporal.ChronoUnit import java.util.UUID import scala.util.{Failure, Success, Try} @@ -772,19 +771,11 @@ object ConfigFailFast extends LazyLogging { ): Unit = { // check if time bin is not smaller than in seconds - if ( - (powerFlow.resolution.getUnits.contains( - ChronoUnit.NANOS - ) && powerFlow.resolution.getNano != 0) || - (powerFlow.resolution.getUnits.contains( - ChronoUnit.MICROS - ) && powerFlow.resolution - .get(ChronoUnit.MICROS) != 0) || - (powerFlow.resolution.getUnits.contains( - ChronoUnit.MILLIS - ) && powerFlow.resolution - .get(ChronoUnit.MILLIS) != 0) - ) { + val hasNanos = (powerFlow.resolution.toNanos / 1e9) % 1 != 0 + val hasMicros = (powerFlow.resolution.toMicros / 1e6) % 1 != 0 + val hasMillis = (powerFlow.resolution.toMillis / 1e3) % 1 != 0 + + if (hasNanos || hasMicros || hasMillis) { throw new InvalidConfigParameterException( s"Invalid time resolution. Please ensure, that " + s"the time resolution for power flow calculation is at least rounded to a full second!" diff --git a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala index 030afe2572..e67e4b0cc8 100644 --- a/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala +++ b/src/main/scala/edu/ie3/simona/config/SimonaConfig.scala @@ -13,9 +13,8 @@ import pureconfig.error._ import pureconfig.generic.ProductHint import pureconfig.generic.auto._ -import java.time.Duration +import scala.concurrent.duration.{DurationInt, FiniteDuration} import scala.language.implicitConversions -import scala.util.Try final case class SimonaConfig( simona: SimonaConfig.Simona @@ -29,19 +28,6 @@ object SimonaConfig { implicit def productHint[T]: ProductHint[T] = ProductHint[T](ConfigFieldMapping(CamelCase, CamelCase)) - // TODO: replace with finite duration - implicit def durationConvert: ConfigConvert[Duration] = - ConfigConvert.viaStringTry( - str => { - val adjustedStr = str.trim match { - case s if s.endsWith("d") => "P" + s.toUpperCase - case _ => "PT" + str.toUpperCase - } - Try(Duration.parse(adjustedStr)) - }, - x => x.toString, - ) - /** Method to extract a config from a [[pureconfig.ConfigReader.Result]] * @param either * that may contain a config @@ -388,9 +374,9 @@ object SimonaConfig { final case class Powerflow( maxSweepPowerDeviation: Double, newtonraphson: Powerflow.Newtonraphson, - resolution: Duration = Duration.ofHours(1), + resolution: FiniteDuration = 1.hours, stopOnFailure: Boolean = false, - sweepTimeout: Duration = Duration.ofSeconds(30), + sweepTimeout: FiniteDuration = 30.seconds, ) object Powerflow { final case class Newtonraphson( diff --git a/src/test/scala/edu/ie3/simona/agent/em/EmAgentIT.scala b/src/test/scala/edu/ie3/simona/agent/em/EmAgentIT.scala index 9efa2145a9..ba54d5baf4 100644 --- a/src/test/scala/edu/ie3/simona/agent/em/EmAgentIT.scala +++ b/src/test/scala/edu/ie3/simona/agent/em/EmAgentIT.scala @@ -69,7 +69,7 @@ class EmAgentIT TimeUtil.withDefaults.toZonedDateTime("2020-01-02T02:00:00Z") private val resolution = - simonaConfig.simona.powerflow.resolution.getSeconds + simonaConfig.simona.powerflow.resolution.toSeconds private val outputConfigOn = NotifierConfig( simulationResultInfo = true, diff --git a/src/test/scala/edu/ie3/simona/agent/grid/ThermalGridIT.scala b/src/test/scala/edu/ie3/simona/agent/grid/ThermalGridIT.scala index a6549d63be..508b35b2e8 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/ThermalGridIT.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/ThermalGridIT.scala @@ -73,7 +73,7 @@ class ThermalGridIT TimeUtil.withDefaults.toZonedDateTime("2020-01-02T02:00:00Z") private val resolution = - simonaConfig.simona.powerflow.resolution.getSeconds + simonaConfig.simona.powerflow.resolution.toSeconds private val outputConfigOn = NotifierConfig( simulationResultInfo = true, 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 0b12d19506..e6174a6e12 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/FixedFeedInAgentModelCalculationSpec.scala @@ -101,7 +101,7 @@ class FixedFeedInAgentModelCalculationSpec voltageSensitiveInput.getUuid ) private val services = Iterable.empty - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds "A fixed feed in agent with model calculation " should { val initStateData = ParticipantInitializeStateData[ 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 4c3ec24f18..91b1245d59 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/HpAgentModelCalculationSpec.scala @@ -115,7 +115,7 @@ class HpAgentModelCalculationSpec private val services = Iterable( ActorWeatherService(weatherService.ref) ) - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds "A heat pump agent depending on no services" should { val initStateData = ParticipantInitializeStateData[ 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 640eee1164..6ffaba9066 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentFixedModelCalculationSpec.scala @@ -92,7 +92,7 @@ class LoadAgentFixedModelCalculationSpec voltageSensitiveInput.getUuid ) private val services = Iterable.empty - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: squants.Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(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 885f93916a..ec6d93f0fc 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/LoadAgentProfileModelCalculationSpec.scala @@ -92,7 +92,7 @@ class LoadAgentProfileModelCalculationSpec voltageSensitiveInput.getUuid ) private val services = Iterable.empty - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: squants.Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(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 7a06287d09..4e35c91514 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgent2ListenerSpec.scala @@ -99,7 +99,7 @@ class ParticipantAgent2ListenerSpec secondaryDataServices = services, simulationStartDate = defaultSimulationStart, simulationEndDate = defaultSimulationEnd, - resolution = simonaConfig.simona.powerflow.resolution.getSeconds, + resolution = simonaConfig.simona.powerflow.resolution.toSeconds, requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = outputConfig, 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 48f2c09f93..bb720bf7a6 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/ParticipantAgentExternalSourceSpec.scala @@ -123,7 +123,7 @@ class ParticipantAgentExternalSourceSpec flexResult = false, ) - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) @@ -139,7 +139,7 @@ class ParticipantAgentExternalSourceSpec secondaryDataServices = Iterable.empty, simulationStartDate = defaultSimulationStart, simulationEndDate = defaultSimulationEnd, - resolution = simonaConfig.simona.powerflow.resolution.getSeconds, + resolution = simonaConfig.simona.powerflow.resolution.toSeconds, requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, outputConfig = defaultOutputConfig, 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 0d742a6ba4..e511670bb4 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/PvAgentModelCalculationSpec.scala @@ -113,7 +113,7 @@ class PvAgentModelCalculationSpec private val withServices = Iterable( ActorWeatherService(weatherService.ref) ) - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) diff --git a/src/test/scala/edu/ie3/simona/agent/participant/StorageAgentModelCalculationSpec.scala b/src/test/scala/edu/ie3/simona/agent/participant/StorageAgentModelCalculationSpec.scala index df1541c8c9..12a537cb44 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/StorageAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/StorageAgentModelCalculationSpec.scala @@ -101,7 +101,7 @@ class StorageAgentModelCalculationSpec storageInputQv.getUuid ) private val services = Iterable.empty - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) 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 15a9407985..35b616625a 100644 --- a/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/participant/WecAgentModelCalculationSpec.scala @@ -116,7 +116,7 @@ class WecAgentModelCalculationSpec private val withServices = Iterable(ActorWeatherService(weatherService.ref)) - private val resolution = simonaConfig.simona.powerflow.resolution.getSeconds + private val resolution = simonaConfig.simona.powerflow.resolution.toSeconds private implicit val powerTolerance: squants.Power = Watts(0.1) private implicit val reactivePowerTolerance: ReactivePower = Vars(0.1) @@ -130,7 +130,7 @@ class WecAgentModelCalculationSpec inputModel = voltageSensitiveInput, simulationStartDate = simulationStartDate, simulationEndDate = simulationEndDate, - resolution = simonaConfig.simona.powerflow.resolution.getSeconds, + resolution = simonaConfig.simona.powerflow.resolution.toSeconds, requestVoltageDeviationThreshold = simonaConfig.simona.runtime.participant.requestVoltageDeviationThreshold, modelConfig = modelConfig, diff --git a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala index b035fd3279..e51296405e 100644 --- a/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala +++ b/src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala @@ -29,6 +29,7 @@ import edu.ie3.util.TimeUtil import java.time.temporal.ChronoUnit import java.time.{Duration, ZonedDateTime} +import scala.concurrent.duration.DurationInt class ConfigFailFastSpec extends UnitSpec with ConfigTestData { "Validating the configs" when { @@ -99,9 +100,9 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List(10, 30), 100, ), - Duration.of(3600, ChronoUnit.SECONDS), + 3600.seconds, stopOnFailure = false, - Duration.of(3600, ChronoUnit.SECONDS), + 3600.seconds, ) ) } @@ -116,9 +117,9 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData { List(10, 30), 100, ), - resolution = Duration.of(3600, ChronoUnit.NANOS), + resolution = 3600.nanos, stopOnFailure = false, - sweepTimeout = Duration.of(3600, ChronoUnit.SECONDS), + sweepTimeout = 3600.seconds, ) ) }.getMessage shouldBe "Invalid time resolution. Please ensure, that the time resolution for power flow calculation is at least rounded to a full second!" From 0ba6e01908c5d68d5b3a94171ffd7ff75c02cfd3 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 19 Feb 2025 10:17:02 +0100 Subject: [PATCH 16/20] Improving changelog Signed-off-by: Sebastian Peter --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d36bdd633e..ddf5e50b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -135,6 +135,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed `pvInput` values in `PvInputTestData` to more realistic values [#1144](https://github.com/ie3-institute/simona/issues/1144) - Refactor `RuntimeConfig` [#1172](https://github.com/ie3-institute/simona/issues/1172) - Renamed some methods and variables within `ThermalGrid` and `ThermalHouse` [#1193](https://github.com/ie3-institute/simona/issues/1193) +- Replaced Java Durations with Scala Durations [#1068](https://github.com/ie3-institute/simona/issues/1068) ### Fixed - Fix rendering of references in documentation [#505](https://github.com/ie3-institute/simona/issues/505) @@ -184,7 +185,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move `ScheduleServiceActivation` out of `RegistrationResponseMessage` [#1143](https://github.com/ie3-institute/simona/issues/1143) - Check for runningHp when handling infeed to thermalGrid [#1167](https://github.com/ie3-institute/simona/issues/1167) - Send `FlexResult` to EM [#1202](https://github.com/ie3-institute/simona/issues/1202) -- Fixed type of Durations [#1068](https://github.com/ie3-institute/simona/issues/1068) ## [3.0.0] - 2023-08-07 From ad2bd1c30c2968210884148e5e4fcebc8cad0861 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 19 Feb 2025 10:17:31 +0100 Subject: [PATCH 17/20] fmt Signed-off-by: Sebastian Peter --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddf5e50b95..fdc34fe10a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -185,7 +185,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move `ScheduleServiceActivation` out of `RegistrationResponseMessage` [#1143](https://github.com/ie3-institute/simona/issues/1143) - Check for runningHp when handling infeed to thermalGrid [#1167](https://github.com/ie3-institute/simona/issues/1167) - Send `FlexResult` to EM [#1202](https://github.com/ie3-institute/simona/issues/1202) - + ## [3.0.0] - 2023-08-07 ### Added From eace7f4ca7145de07b38757ad3e3a0a1b9869833 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 19 Feb 2025 10:23:46 +0100 Subject: [PATCH 18/20] Shortening code Signed-off-by: Sebastian Peter --- .../scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bad8d4b285..ca493ce2c4 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -395,7 +395,7 @@ class PowerFlowSupportSpec 1e-5, Vector(1e-12), 50, - FiniteDuration.apply(30, MINUTES), + FiniteDuration(30, MINUTES), stopOnFailure = true, ) From fac2a87cb69c49597265fb2227c93745e85796be Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 19 Feb 2025 10:25:50 +0100 Subject: [PATCH 19/20] Or even better... Signed-off-by: Sebastian Peter --- .../edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 ca493ce2c4..abffb45c90 100644 --- a/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala +++ b/src/test/scala/edu/ie3/simona/agent/grid/PowerFlowSupportSpec.scala @@ -44,10 +44,10 @@ import squants.energy.Megawatts import squants.{Dimensionless, Each} import tech.units.indriya.ComparableQuantity -import java.time.{Duration, ZonedDateTime} +import java.time.ZonedDateTime import java.util.UUID import javax.measure.quantity.Angle -import scala.concurrent.duration.{FiniteDuration, MINUTES} +import scala.concurrent.duration.DurationInt import scala.jdk.CollectionConverters.SetHasAsJava import scala.language.implicitConversions @@ -395,7 +395,7 @@ class PowerFlowSupportSpec 1e-5, Vector(1e-12), 50, - FiniteDuration(30, MINUTES), + 30.minutes, stopOnFailure = true, ) From bc30b36389bbf6acd413540c6de20cddcb7d7a78 Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 19 Feb 2025 10:34:16 +0100 Subject: [PATCH 20/20] Removing obsolete code Signed-off-by: Sebastian Peter --- src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala | 9 +-------- 1 file changed, 1 insertion(+), 8 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 6e6da389c0..eead7e5d05 100644 --- a/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala +++ b/src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala @@ -29,11 +29,8 @@ import edu.ie3.util.TimeUtil import org.apache.pekko.actor.typed.scaladsl.{Behaviors, StashBuffer} import org.apache.pekko.actor.typed.{ActorRef, Behavior} -import java.time.{Duration, ZonedDateTime} -import java.time.temporal.ChronoUnit +import java.time.ZonedDateTime import java.util.UUID -import java.util.concurrent.TimeUnit -import scala.concurrent.duration.FiniteDuration import scala.language.{implicitConversions, postfixOps} object GridAgent extends DBFSAlgorithm { @@ -175,10 +172,6 @@ object GridAgent extends DBFSAlgorithm { nodeUuid -> actorSet } - // TODO: Reminder: Can be removed after changing the config framework - implicit def convertDuration(duration: Duration): FiniteDuration = - FiniteDuration.apply(duration.toSeconds, TimeUnit.SECONDS) - // create the GridAgentBaseData val gridAgentBaseData = GridAgentBaseData( gridModel,