diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e0b797202..ea0aa6525f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed FixedFeedModelSpec [#861](https://github.com/ie3-institute/simona/issues/861) - Fixing duration calculation in result events [#801](https://github.com/ie3-institute/simona/issues/801) - Handle MobSim requests for current prices [#892](https://github.com/ie3-institute/simona/issues/892) +- Fix determineState of ThermalHouse [#926](https://github.com/ie3-institute/simona/issues/926) ## [3.0.0] - 2023-08-07 diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 7af9279611..4d9fc68899 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -185,6 +185,7 @@ final case class HpModel( relevantData.currentTick, state.thermalGridState, state.ambientTemperature.getOrElse(relevantData.ambientTemperature), + relevantData.ambientTemperature, newThermalPower, ) 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 85b41b35ff..325a90b316 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -105,8 +105,10 @@ final case class ThermalGrid( * Instance in time * @param state * Currently applicable state + * @param lastAmbientTemperature + * Ambient temperature valid up until (not including) the current tick * @param ambientTemperature - * Ambient temperature + * Current ambient temperature * @param qDot * Thermal energy balance * @return @@ -115,19 +117,28 @@ final case class ThermalGrid( def updateState( tick: Long, state: ThermalGridState, + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, qDot: Power, ): (ThermalGridState, Option[ThermalThreshold]) = if (qDot > zeroKW) - handleInfeed(tick, ambientTemperature, state, qDot) + handleInfeed(tick, lastAmbientTemperature, ambientTemperature, state, qDot) else - handleConsumption(tick, ambientTemperature, state, qDot) + handleConsumption( + tick, + lastAmbientTemperature, + ambientTemperature, + state, + qDot, + ) /** Handles the case, when a grid has infeed. First, heat up all the houses to * their maximum temperature, then fill up the storages * @param tick * Current tick + * @param lastAmbientTemperature + * Ambient temperature valid up until (not including) the current tick * @param ambientTemperature - * Ambient temperature + * Current ambient temperature * @param state * Current state of the houses * @param qDot @@ -137,6 +148,7 @@ final case class ThermalGrid( */ private def handleInfeed( tick: Long, + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, state: ThermalGridState, qDot: Power, @@ -163,6 +175,7 @@ final case class ThermalGrid( thermalHouse.determineState( tick, lastHouseState, + lastAmbientTemperature, ambientTemperature, qDot, ) @@ -177,6 +190,7 @@ final case class ThermalGrid( thermalHouse.determineState( tick, lastHouseState, + lastAmbientTemperature, ambientTemperature, zeroKW, ) @@ -248,8 +262,10 @@ final case class ThermalGrid( * * @param tick * Current tick + * @param lastAmbientTemperature + * Ambient temperature valid up until (not including) the current tick * @param ambientTemperature - * Ambient temperature + * Current ambient temperature * @param state * Current state of the houses * @param qDot @@ -259,6 +275,7 @@ final case class ThermalGrid( */ private def handleConsumption( tick: Long, + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, state: ThermalGridState, qDot: Power, @@ -269,6 +286,7 @@ final case class ThermalGrid( house.determineState( tick, houseState, + lastAmbientTemperature, ambientTemperature, zeroMW, ) @@ -287,6 +305,7 @@ final case class ThermalGrid( maybeUpdatedStorageState, state.houseState, state.storageState, + lastAmbientTemperature, ambientTemperature, qDot, ) @@ -319,8 +338,10 @@ final case class ThermalGrid( * Previous thermal house state before a first update was performed * @param formerStorageState * Previous thermal storage state before a first update was performed + * @param lastAmbientTemperature + * Ambient temperature valid up until (not including) the current tick * @param ambientTemperature - * Ambient temperature + * Current ambient temperature * @param qDot * Thermal influx * @return @@ -334,6 +355,7 @@ final case class ThermalGrid( ], formerHouseState: Option[ThermalHouseState], formerStorageState: Option[ThermalStorageState], + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, qDot: Power, ): ( @@ -367,6 +389,7 @@ final case class ThermalGrid( "Impossible to find no house state" ) ), + lastAmbientTemperature, ambientTemperature, thermalStorage.getChargingPower, ) 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 f86c7f9f19..547a639d08 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalHouse.scala @@ -298,19 +298,22 @@ final case class ThermalHouse( /** Update the current state of the house * * @param tick - * current instance in time + * Current instance in time * @param state - * currently applicable state + * Currently applicable state + * @param lastAmbientTemperature + * Ambient temperature valid up until (not including) the current tick * @param ambientTemperature - * Ambient temperature + * Current ambient temperature * @param qDot - * new thermal influx + * New thermal influx * @return * Updated state and the tick in which the next threshold is reached */ def determineState( tick: Long, state: ThermalHouseState, + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, qDot: Power, ): (ThermalHouseState, Option[ThermalThreshold]) = { @@ -319,7 +322,7 @@ final case class ThermalHouse( state.qDot, duration, state.innerTemperature, - ambientTemperature, + lastAmbientTemperature, ) /* Calculate the next given threshold */ 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 1dbf544c19..cf5d5ec7ef 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -165,6 +165,7 @@ class ThermalGridWithHouseAndStorageSpec thermalGrid invokePrivate handleConsumption( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, externalQDot, ) @@ -201,6 +202,7 @@ class ThermalGridWithHouseAndStorageSpec thermalGrid invokePrivate handleConsumption( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, externalQDot, ) @@ -254,6 +256,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), None, testGridAmbientTemperature, + testGridAmbientTemperature, testGridQDotConsumption, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -296,6 +299,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, + ambientTemperature, zeroInflux, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -338,6 +342,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, + ambientTemperature, testGridQDotInfeed, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -380,6 +385,7 @@ class ThermalGridWithHouseAndStorageSpec maybeHouseState.map(_._1), maybeStorageState.map(_._1), ambientTemperature, + ambientTemperature, zeroInflux, ) match { case (maybeRevisedHouseState, maybeRevisedStorageState) => @@ -441,6 +447,7 @@ class ThermalGridWithHouseAndStorageSpec formerHouseState, formerStorageState, ambientTemperature, + ambientTemperature, zeroInflux, ) match { case ( @@ -487,6 +494,7 @@ class ThermalGridWithHouseAndStorageSpec thermalGrid invokePrivate handleInfeed( tick, testGridAmbientTemperature, + testGridAmbientTemperature, initialGridState, externalQDot, ) @@ -532,6 +540,7 @@ class ThermalGridWithHouseAndStorageSpec thermalGrid invokePrivate handleInfeed( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, externalQDot, ) 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 99ed500efb..d2b48ff3b3 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -106,6 +106,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { thermalGrid invokePrivate handleConsumption( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, externalQDot, ) @@ -133,6 +134,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { thermalGrid invokePrivate handleConsumption( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, testGridQDotConsumption, ) @@ -167,6 +169,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { thermalGrid invokePrivate handleInfeed( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, testGridQDotInfeed, ) @@ -193,6 +196,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridAmbientTemperature, + testGridAmbientTemperature, testGridQDotInfeed, ) match { case ( @@ -215,6 +219,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridAmbientTemperature, + testGridAmbientTemperature, testGridQDotConsumption, ) match { case ( @@ -237,6 +242,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { 0L, ThermalGrid.startingState(thermalGrid), testGridAmbientTemperature, + testGridAmbientTemperature, Megawatts(0d), ) match { case ( diff --git a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala index 7455f282ae..1a0e553fdc 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -115,6 +115,7 @@ class ThermalGridWithStorageOnlySpec thermalGrid invokePrivate handleConsumption( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, testGridQDotConsumptionHigh, ) @@ -147,6 +148,7 @@ class ThermalGridWithStorageOnlySpec thermalGrid invokePrivate handleInfeed( tick, testGridAmbientTemperature, + testGridAmbientTemperature, gridState, testGridQDotInfeed, ) @@ -171,6 +173,7 @@ class ThermalGridWithStorageOnlySpec 0L, ThermalGrid.startingState(thermalGrid), testGridAmbientTemperature, + testGridAmbientTemperature, testGridQDotInfeed, ) @@ -203,6 +206,7 @@ class ThermalGridWithStorageOnlySpec ) ), testGridAmbientTemperature, + testGridAmbientTemperature, testGridQDotConsumptionHigh, ) match { case ( @@ -225,6 +229,7 @@ class ThermalGridWithStorageOnlySpec 0L, ThermalGrid.startingState(thermalGrid), testGridAmbientTemperature, + testGridAmbientTemperature, Kilowatts(0d), ) updatedState match { 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 56e1cac144..20131046bf 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalHouseSpec.scala @@ -6,8 +6,14 @@ package edu.ie3.simona.model.thermal +import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.HouseTemperatureLowerBoundaryReached +import edu.ie3.simona.model.thermal.ThermalHouse.{ + ThermalHouseState, + startingState, +} import edu.ie3.simona.test.common.UnitSpec import edu.ie3.simona.test.common.input.HpInputTestData +import edu.ie3.util.scala.quantities.DefaultQuantities.zeroKW import edu.ie3.util.scala.quantities.WattsPerKelvin import org.scalatest.prop.TableFor3 import squants.energy._ @@ -92,6 +98,31 @@ class ThermalHouseSpec extends UnitSpec with HpInputTestData { newInnerTemperature should approximate(Temperature(29, Celsius)) } + "Check for the correct state of house when ambient temperature changes" in { + val house = thermalHouse(18, 22) + val initialHousestate = startingState(house) + val lastAmbientTemperature = Temperature(15, Celsius) + val ambientTemperature = Temperature(-20, Celsius) + + val (thermalHouseState, threshold) = house.determineState( + 3600L, + initialHousestate, + lastAmbientTemperature, + ambientTemperature, + zeroKW, + ) + + thermalHouseState match { + case ThermalHouseState(tick, temperature, qDot) => + tick shouldBe 3600L + temperature should approximate(Kelvin(292.64986111)) + qDot shouldBe zeroKW + case unexpected => + fail(s"Expected a thermalHouseState but got none $unexpected.") + } + threshold shouldBe Some(HouseTemperatureLowerBoundaryReached(4967)) + } + "Check build method" in { val thermalTestHouse = thermalHouse(18, 22)