From 6e9b40f1c004020a54500edc5dccc408e88c318b Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Sat, 24 Aug 2024 09:56:41 +0200 Subject: [PATCH 01/17] Refactoring of ThermalGrid.energyGrid to distinguish between demand of house and storage --- CHANGELOG.md | 1 + .../participant/hp/HpAgentFundamentals.scala | 6 +- .../simona/model/participant/HpModel.scala | 148 +++-- .../simona/model/thermal/ThermalGrid.scala | 105 +++- .../model/participant/HpModelSpec.scala | 537 ++++++++++++++---- .../ThermalGridWithHouseAndStorageSpec.scala | 72 ++- .../ThermalGridWithHouseOnlySpec.scala | 32 +- .../ThermalGridWithStorageOnlySpec.scala | 51 +- 8 files changed, 693 insertions(+), 259 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b25a5dbf..b1de2d3306 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated `Gradle` to version V8.10 [#829](https://github.com/ie3-institute/simona/issues/829) - Updated AUTHORS.md [#905](https://github.com/ie3-institute/simona/issues/905) - Prepare ThermalStorageTestData for Storage without storageVolumeLvlMin [#894](https://github.com/ie3-institute/simona/issues/894) +- Refactoring of `ThermalGrid.energyGrid` to distinguish between demand of house and storage [#928](https://github.com/ie3-institute/simona/issues/928) ### Fixed - Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 9add5d8ddc..7940120b4c 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -293,7 +293,11 @@ trait HpAgentFundamentals calcRelevantData: HpRelevantData, nodalVoltage: squants.Dimensionless, model: HpModel, - ): HpState = model.determineState(modelState, calcRelevantData) + ): HpState = { + val (_, _, state) = + model.determineState(modelState, calcRelevantData) + state + } /** Abstract definition, individual implementations found in individual agent * fundamental classes diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index 4d9fc68899..ad512a75e0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -11,16 +11,15 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHe import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.thermal.ThermalGrid.ThermalGridState +import edu.ie3.simona.model.thermal.ThermalGrid.{ThermalEnergyDemand, ThermalGridState} import edu.ie3.simona.model.thermal.{ThermalGrid, ThermalThreshold} import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions import edu.ie3.util.quantities.PowerSystemUnits import edu.ie3.util.scala.OperationInterval -import edu.ie3.util.scala.quantities.DefaultQuantities import edu.ie3.util.scala.quantities.DefaultQuantities._ -import squants.energy.Kilowatts -import squants.{Power, Temperature} +import squants.energy.{KilowattHours, Kilowatts} +import squants.{Energy, Power, Temperature} import java.time.ZonedDateTime import java.util.UUID @@ -116,19 +115,23 @@ final case class HpModel( * function calculates the heat pump's next state to get the actual active * power of this state use [[calculateActivePower]] with the generated state * - * @param state - * Current state of the heat pump + * @param lastState + * Last state of the heat pump * @param relevantData * data of heat pump including * @return - * next [[HpState]] + * Booleans if Hp can operate and can be out of operation plus next + * [[HpState]] */ def determineState( - state: HpState, + lastState: HpState, relevantData: HpRelevantData, - ): HpState = { - val turnOn = operatesInNextState(state, relevantData) - calcState(state, relevantData, turnOn) + ): (Boolean, Boolean, HpState) = { + val (turnOn, canOperate, canBeOutOfOperation, houseDemand, storageDemand) = + operatesInNextState(lastState, relevantData) + val updatedState = + calcState(lastState, relevantData, turnOn, houseDemand, storageDemand) + (canOperate, canBeOutOfOperation, updatedState) } /** Depending on the input, this function decides whether the heat pump will @@ -142,18 +145,63 @@ final case class HpModel( * @param relevantData * Relevant (external) data * @return - * boolean defining if heat pump runs in next time step + * boolean defining if heat pump runs in next time step, if it can be in + * operation and out of operation plus the demand of house and storage */ private def operatesInNextState( state: HpState, relevantData: HpRelevantData, - ): Boolean = { - val demand = thermalGrid.energyDemand( - relevantData.currentTick, - relevantData.ambientTemperature, - state.thermalGridState, + ): (Boolean, Boolean, Boolean, Boolean, Boolean) = { + val (demandHouse, demandThermalStorage, updatedState) = + thermalGrid.energyDemandAndUpdatedState( + relevantData.currentTick, + state.ambientTemperature.getOrElse(relevantData.ambientTemperature), + relevantData.ambientTemperature, + state.thermalGridState, + ) + + val ( + houseDemand, + heatStorageDemand, + noThermalStorageOrThermalStorageIsEmpty, + ) = determineDemandBooleans( + state, + updatedState, + demandHouse, + demandThermalStorage, ) - demand.hasRequiredDemand || (state.isRunning && demand.hasAdditionalDemand) + + val turnHpOn: Boolean = + houseDemand || heatStorageDemand + + val canOperate = + demandHouse.hasRequiredDemand || demandHouse.hasAdditionalDemand || + demandThermalStorage.hasRequiredDemand || demandThermalStorage.hasAdditionalDemand + val canBeOutOfOperation = + !(demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) + + (turnHpOn, canOperate, canBeOutOfOperation, houseDemand, heatStorageDemand) + } + + def determineDemandBooleans( + hpState: HpState, + updatedGridState: ThermalGridState, + demandHouse: ThermalEnergyDemand, + demandThermalStorage: ThermalEnergyDemand, + ): (Boolean, Boolean, Boolean) = { + implicit val tolerance: Energy = KilowattHours(1e-3) + val noThermalStorageOrThermalStorageIsEmpty: Boolean = + updatedGridState.storageState.isEmpty || updatedGridState.storageState + .exists( + _.storedEnergy =~ zeroKWH + ) + + val houseDemand = + (demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) || (hpState.isRunning && demandHouse.hasAdditionalDemand) + val heatStorageDemand = { + (demandThermalStorage.hasRequiredDemand) || (hpState.isRunning && demandThermalStorage.hasAdditionalDemand) + } + (houseDemand, heatStorageDemand, noThermalStorageOrThermalStorageIsEmpty) } /** Calculate state depending on whether heat pump is needed or not. Also @@ -173,11 +221,19 @@ final case class HpModel( state: HpState, relevantData: HpRelevantData, isRunning: Boolean, + houseDemand: Boolean, + storageDemand: Boolean, ): HpState = { + val lastStateStorageqDot = state.thermalGridState.storageState + .map(_.qDot) + .getOrElse(zeroKW) + val (newActivePower, newThermalPower) = if (isRunning) (pRated, pThermal) - else (DefaultQuantities.zeroKW, DefaultQuantities.zeroKW) + else if (lastStateStorageqDot < zeroKW) + (zeroKW, lastStateStorageqDot * (-1)) + else (zeroKW, zeroKW) /* Push thermal energy to the thermal grid and get its updated state in return */ val (thermalGridState, maybeThreshold) = @@ -205,23 +261,14 @@ final case class HpModel( lastState: HpState, ): ProvideFlexOptions = { /* Determine the operating state in the given tick */ - val updatedState = determineState(lastState, data) - - /* Determine the options we have */ - val thermalEnergyDemand = thermalGrid.energyDemand( - data.currentTick, - data.ambientTemperature, - lastState.thermalGridState, - ) - val canOperate = - thermalEnergyDemand.hasRequiredDemand || thermalEnergyDemand.hasAdditionalDemand - val canBeOutOfOperation = !thermalEnergyDemand.hasRequiredDemand + val (canOperate, canBeOutOfOperation, updatedHpState) + : (Boolean, Boolean, HpState) = determineState(lastState, data) val lowerBoundary = if (canBeOutOfOperation) zeroKW else - updatedState.activePower + updatedHpState.activePower val upperBoundary = if (canOperate) sRated * cosPhiRated @@ -230,7 +277,7 @@ final case class HpModel( ProvideMinMaxFlexOptions( uuid, - updatedState.activePower, + updatedHpState.activePower, lowerBoundary, upperBoundary, ) @@ -260,13 +307,44 @@ final case class HpModel( ): (HpState, FlexChangeIndicator) = { /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ val turnOn = setPower > (sRated * cosPhiRated * 0.5) - val updatedState = calcState(lastState, data, turnOn) + + val ( + thermalEnergyDemandHouse, + thermalEnergyDemandStorage, + updatedThermalGridState, + ) = + thermalGrid.energyDemandAndUpdatedState( + data.currentTick, + lastState.ambientTemperature.getOrElse(data.ambientTemperature), + data.ambientTemperature, + lastState.thermalGridState, + ) + + val ( + houseDemand, + heatStorageDemand, + noThermalStorageOrThermalStorageIsEmpty, + ) = determineDemandBooleans( + lastState, + updatedThermalGridState, + thermalEnergyDemandHouse, + thermalEnergyDemandStorage, + ) + + val updatedHpState: HpState = + calcState( + lastState, + data, + turnOn, + houseDemand, + heatStorageDemand, + ) ( - updatedState, + updatedHpState, FlexChangeIndicator( changesAtNextActivation = true, - updatedState.maybeThermalThreshold.map(_.tick), + updatedHpState.maybeThermalThreshold.map(_.tick), ), ) } 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 286b0e829f..3e983b6abe 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -43,60 +43,105 @@ final case class ThermalGrid( ) extends LazyLogging { /** Determine the energy demand of the total grid at the given instance in - * time + * time and returns it including the updatedState + * * @param tick * Questioned instance in time + * @param lastAmbientTemperature + * Ambient temperature until this tick * @param ambientTemperature * Ambient temperature in the instance in question * @param state * Currently applicable state of the thermal grid * @return - * The total energy demand of the grid + * The total energy demand of the house and the storage and an updated + * [[ThermalGridState]] */ - def energyDemand( + def energyDemandAndUpdatedState( tick: Long, + // FIXME this is also in state + lastAmbientTemperature: Temperature, ambientTemperature: Temperature, state: ThermalGridState, - ): ThermalEnergyDemand = { - /* First get the energy demand of the houses */ - val houseDemand = house - .zip(state.houseState) - .map { case (house, state) => - house.energyDemand( - tick, - ambientTemperature, - state, - ) + ): (ThermalEnergyDemand, ThermalEnergyDemand, ThermalGridState) = { + /* First get the energy demand of the houses but only if inner temperature is below target temperature */ + + val (houseDemand, updatedHouseState) = + house.zip(state.houseState).headOption match { + case Some((thermalHouse, lastHouseState)) => + val (updatedHouseState, updatedStorageState) = + thermalHouse.determineState( + tick, + lastHouseState, + lastAmbientTemperature, + ambientTemperature, + lastHouseState.qDot, + ) + if ( + updatedHouseState.innerTemperature < thermalHouse.targetTemperature | (lastHouseState.qDot > zeroKW && updatedHouseState.innerTemperature < thermalHouse.upperBoundaryTemperature) + ) { + ( + thermalHouse.energyDemand( + tick, + ambientTemperature, + updatedHouseState, + ), + Some(updatedHouseState), + ) + + } else { + (ThermalEnergyDemand.noDemand, Some(updatedHouseState)) + } + + case None => + (ThermalEnergyDemand.noDemand, None) } - .getOrElse(ThermalEnergyDemand.noDemand) /* Then go over the storages, see what they can provide and what they might be able to charge */ - val (storedEnergy, remainingCapacity) = { + val (storageDemand, updatedStorageState) = { + storage .zip(state.storageState) .map { case (storage, state) => - val usableEnergy = state.storedEnergy - val remaining = storage.getMaxEnergyThreshold - usableEnergy + val (updatedStorageState, _) = + storage.updateState(tick, state.qDot, state) + val storedEnergy = updatedStorageState.storedEnergy + val soc = storedEnergy / storage.getMaxEnergyThreshold + val storageRequired = { + if (soc == 0d) { + storage.getMaxEnergyThreshold - storedEnergy + + } else { + zeroMWH + } + } + + val storagePossible = storage.getMaxEnergyThreshold - storedEnergy ( - usableEnergy, - remaining, + ThermalEnergyDemand( + storageRequired, + storagePossible, + ), + Some(updatedStorageState), ) + } .getOrElse( - (zeroMWH, zeroMWH) + ThermalEnergyDemand(zeroMWH, zeroMWH), + None, ) } - val usedEnergy = - if (storedEnergy >= houseDemand.required) - houseDemand.required - else - storedEnergy - val finallyRemaining = remainingCapacity + usedEnergy - - ThermalEnergyDemand( - houseDemand.required - usedEnergy, - houseDemand.possible + finallyRemaining, + ( + ThermalEnergyDemand( + houseDemand.required, + houseDemand.possible, + ), + ThermalEnergyDemand( + storageDemand.required, + storageDemand.possible, + ), + ThermalGridState(updatedHouseState, updatedStorageState), ) } 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 e99a5c8c26..81c62e549d 100644 --- a/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/participant/HpModelSpec.scala @@ -208,14 +208,18 @@ class HpModelSpec val hp = hpModel(grid) hp.determineState(state, data) match { - case HpState( - isRunning, + case ( _, _, - activePower, - _, - ThermalGridState(Some(thermalHouseState), _), - maybeThreshold, + HpState( + isRunning, + _, + _, + activePower, + _, + ThermalGridState(Some(thermalHouseState), _), + maybeThreshold, + ), ) => isRunning shouldBe expectedRunningState activePower should approximate(Kilowatts(expectedActivePower)) @@ -234,166 +238,447 @@ class HpModelSpec "determining the flexibility options for different states" should { "deliver correct flexibility options" in { - val testCases = Table( - ("thermalState", "lastState", "expectedValues"), - // House is below lower temperature boundary - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), - Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + val testCases = + Table( + ("thermalState", "lastState", "expectedValues"), + // 1. Hp actually not running + // House is below lower temperature boundary + // Heat storage is empty + // hp must be turned on + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(0.0), + Kilowatts(0.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + None, + ), + (95.0, 95.0, 95.0), ), - HpState( - isRunning = false, - 0, - Some(hpData.ambientTemperature), - Kilowatts(0.0), - Kilowatts(0.0), + // 2. Same as before but heat storage is NOT empty + // should be possible to keep hp off + ( ThermalGridState( Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), - Some( - ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(0.0), + Kilowatts(0.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + ), ), + None, ), - None, + (0.0, 0.0, 95.0), ), - (95.0, 95.0, 95.0), - ), - // House is between target temperature and lower temperature boundary, Hp actually running - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), - Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + // 3. Hp actually running + // House is below lower temperature boundary + // Heat storage is empty + // Hp must run because of house and storage + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(0.0), + Kilowatts(0.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(0), Kilowatts(0)) + ), + ), + None, + ), + (95.0, 95.0, 95.0), ), - HpState( - isRunning = true, - 0, - Some(hpData.ambientTemperature), - Kilowatts(95.0), - Kilowatts(80.0), + // 4. Same as before but heat storage is NOT empty + // Hp should not run because of storage but can be turned on + ( ThermalGridState( - Some(ThermalHouseState(0L, Celsius(19), Kilowatts(80))), - Some( - ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(0.0), + Kilowatts(0.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(15), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + ), ), + None, ), - None, + (0.0, 0.0, 95.0), ), - (95.0, 0.0, 95.0), - ), - - // House is between target temperature and lower temperature boundary, Hp actually not running - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), - Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + // 5. Hp actually running + // House is between target temperature and lower temperature boundary + // Heat storage is empty + // Hp runs but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(0), Kilowatts(0)) + ), + ), + None, + ), + (95.0, 0.0, 95.0), ), - HpState( - isRunning = false, - 0, - Some(hpData.ambientTemperature), - Kilowatts(0.0), - Kilowatts(0.0), + // 6. Same as before but heat storage is NOT empty + // should be possible to keep hp off + ( ThermalGridState( Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), - Some( - ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + ), ), + None, ), - None, + (95.0, 0.0, 95.0), ), - (0.0, 0.0, 95.0), - ), - // Storage and house have remaining capacity - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(21), Kilowatts(80))), - Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + // 7. Hp actually NOT running + // House is between target temperature and lower temperature boundary + // Heat storage is empty + // Hp should run because of storage but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(0), Kilowatts(0)) + ), + ), + None, + ), + (95.0, 0.0, 95.0), ), - HpState( - isRunning = true, - 0, - Some(hpData.ambientTemperature), - Kilowatts(95.0), - Kilowatts(80.0), + // 8. Same as before but heat storage is NOT empty + // Hp should be off but able to turn on + ( ThermalGridState( - Some(ThermalHouseState(0L, Celsius(21), Kilowatts(80))), + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(20), Kilowatts(0)) + ), + ), + None, + ), + (0.0, 0.0, 95.0), ), - (95.0, 0.0, 95.0), - ), - - // Storage is full, House has capacity till upper boundary - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(21), Kilowatts(80))), - Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + // 9. Hp actually running + // House is between target temperature and upper temperature boundary + // Heat storage is empty + // Hp will run because of storage but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (95.0, 0.0, 95.0), ), - HpState( - isRunning = false, - 0, - Some(hpData.ambientTemperature), - Kilowatts(0.0), - Kilowatts(0.0), + // 10. Same as before but storage is NOT empty + // Hp should run but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (95.0, 0.0, 95.0), + ), + // 11. Hp actually not running + // House is between target temperature and upper temperature boundary + // Heat storage is empty + // Hp should run because of storage but can be turned off + ( ThermalGridState( - Some(ThermalHouseState(0L, Celsius(21), Kilowatts(80))), - Some( - ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), ), + Some(HouseTemperatureUpperBoundaryReached(0L)), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + (95.0, 0.0, 95.0), + ), + // 12. Same as before but storage is NOT empty + // Hp should not run but can be turned on for storage or house + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (0.0, 0.0, 95.0), ), - (0.0, 0.0, 95.0), - ), - // No capacity for flexibility at all because house is - // at upperTempBoundary and storage is at max capacity - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(22), Kilowatts(80))), - Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + // 13. Hp actually running + // House is at upper temperature boundary + // Heat storage is empty + // Hp should run because of storage but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (95.0, 0.0, 95.0), ), - HpState( - isRunning = true, - 0, - Some(hpData.ambientTemperature), - Kilowatts(95.0), - Kilowatts(80.0), + // 14. Same as before but storage is NOT empty + // Hp should run but can be turned off + ( ThermalGridState( - Some(ThermalHouseState(0L, Celsius(22), Kilowatts(80))), - Some( - ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), ), + Some(HouseTemperatureUpperBoundaryReached(0L)), ), - Some(HouseTemperatureUpperBoundaryReached(0L)), + (95.0, 0.0, 95.0), + ), + // 15. Hp actually not running + // House is at upper temperature boundary + // Heat storage is empty + // Hp should run because of storage but can be turned off + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(0), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (95.0, 0.0, 95.0), ), - (0.0, 0.0, 0.0), - ), - // No capacity for flexibility at all when storage is full and house has been (externally) heated up above upperTemperatureBoundary - ( - ThermalGridState( - Some(ThermalHouseState(0L, Celsius(25), Kilowatts(0))), - Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + // 16. Same as before but storage is NOT empty + // Hp should not run but can be turned on for storage + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(20), Kilowatts(0))), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (0.0, 0.0, 95.0), ), - HpState( - isRunning = false, - 0, - Some(hpData.ambientTemperature), - Kilowatts(95.0), - Kilowatts(80.0), + + // Storage is full, House has capacity till upper boundary + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(21), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(0.0), + Kilowatts(0.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(19), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + ), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (0.0, 0.0, 95.0), + ), + // No capacity for flexibility at all because house is + // at upperTempBoundary and storage is at max capacity + ( + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + ), + HpState( + isRunning = true, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(22), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + ), + ), + Some(HouseTemperatureUpperBoundaryReached(0L)), + ), + (0.0, 0.0, 0.0), + ), + + // No capacity for flexibility at all when storage is full and house has been (externally) heated up above upperTemperatureBoundary + ( ThermalGridState( Some(ThermalHouseState(0L, Celsius(25), Kilowatts(0))), - Some( - ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + Some(ThermalStorageState(0L, KilowattHours(500), Kilowatts(0))), + ), + HpState( + isRunning = false, + 0, + Some(hpData.ambientTemperature), + Kilowatts(95.0), + Kilowatts(80.0), + ThermalGridState( + Some(ThermalHouseState(0L, Celsius(25), Kilowatts(0))), + Some( + ThermalStorageState(0L, KilowattHours(500), Kilowatts(0)) + ), ), + None, ), - None, + (0.0, 0.0, 0.0), ), - (0.0, 0.0, 0.0), - ), - ) + ) // Run the test cases forAll(testCases) { 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 5d4fe69d88..1ea45a656d 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseAndStorageSpec.scala @@ -96,53 +96,51 @@ class ThermalGridWithHouseAndStorageSpec "deliver the house demand (no demand) with added flexibility by storage" in { val tick = 10800 // after three hours - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - ThermalGrid.startingState(thermalGrid), + val (houseDemand, storageDemand, updatedThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + tick, + testGridAmbientTemperature, + testGridAmbientTemperature, + ThermalGrid.startingState(thermalGrid), + ) + houseDemand.required should approximate(KilowattHours(0d)) + houseDemand.possible should approximate(KilowattHours(31.05009722d)) + storageDemand.required should approximate(KilowattHours(1150d)) + storageDemand.possible should approximate(KilowattHours(1150d)) + updatedThermalGridState.houseState shouldBe Some( + ThermalHouseState(10800, Kelvin(292.0799935185185), Kilowatts(0d)) ) - - gridDemand.required should approximate(KilowattHours(0d)) - gridDemand.possible should approximate( - KilowattHours(31.05009722 + 1150) + updatedThermalGridState.storageState shouldBe Some( + ThermalStorageState(10800, KilowattHours(0d), Kilowatts(0d)) ) } - "consider stored energy to reduce house demand" in { + "deliver the correct house and storage demand" in { val tick = 10800 // after three hours val startingState = ThermalGrid.startingState(thermalGrid) - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - startingState.copy(houseState = - startingState.houseState.map( - _.copy(innerTemperature = Celsius(16d)) - ) - ), - ) - - gridDemand.required should approximate(KilowattHours(45.60005555555534)) - gridDemand.possible should approximate(KilowattHours(1225.600055555)) - } - - "consider stored energy to reduce house demand if stored energy is not enough" in { - val tick = 10800 // after three hours + val (houseDemand, storageDemand, updatedThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + tick, + testGridAmbientTemperature, + testGridAmbientTemperature, + startingState.copy(houseState = + startingState.houseState.map( + _.copy(innerTemperature = Celsius(16d)) + ) + ), + ) - val startingState = ThermalGrid.startingState(thermalGrid) - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - startingState.copy(houseState = - startingState.houseState.map( - _.copy(innerTemperature = Celsius(3d)) - ) - ), + houseDemand.required should approximate(KilowattHours(45.6000555)) + houseDemand.possible should approximate(KilowattHours(75.600055555)) + storageDemand.required should approximate(KilowattHours(1150d)) + storageDemand.possible should approximate(KilowattHours(1150d)) + updatedThermalGridState.houseState shouldBe Some( + ThermalHouseState(10800, Celsius(15.959996296296296), Kilowatts(0d)) ) - gridDemand.required should approximate( - KilowattHours(238.64987499999984) + updatedThermalGridState.storageState shouldBe Some( + ThermalStorageState(10800, KilowattHours(0d), Kilowatts(0d)) ) - gridDemand.possible should approximate(KilowattHours(1418.64987499999)) } } 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 d2b48ff3b3..eb447d0fc4 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithHouseOnlySpec.scala @@ -14,9 +14,9 @@ import edu.ie3.simona.model.thermal.ThermalHouse.ThermalHouseThreshold.{ HouseTemperatureUpperBoundaryReached, } import edu.ie3.simona.test.common.UnitSpec -import squants.energy.{Kilowatts, Megawatts, WattHours, Watts} +import squants.energy._ import squants.thermal.Celsius -import squants.{Energy, Power, Temperature} +import squants.{Energy, Kelvin, Power, Temperature} import scala.jdk.CollectionConverters._ @@ -73,21 +73,29 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { "determining the energy demand" should { "exactly be the demand of the house" in { - val tick = 10800 // after three house - val houseDemand = thermalHouse.energyDemand( + val tick = 10800 // after three hours + val expectedHouseDemand = thermalHouse.energyDemand( tick, testGridAmbientTemperature, expectedHouseStartingState, ) - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - ThermalGrid.startingState(thermalGrid), - ) + val (houseDemand, storageDemand, updatedThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + tick, + testGridAmbientTemperature, + testGridAmbientTemperature, + ThermalGrid.startingState(thermalGrid), + ) - gridDemand.required should approximate(houseDemand.required) - gridDemand.possible should approximate(houseDemand.possible) + houseDemand.required should approximate(expectedHouseDemand.required) + houseDemand.possible should approximate(expectedHouseDemand.possible) + storageDemand.required should approximate(KilowattHours(0d)) + storageDemand.possible should approximate(KilowattHours(0d)) + updatedThermalGridState.houseState shouldBe Some( + ThermalHouseState(10800, Kelvin(292.0799935185185), Kilowatts(0d)) + ) + updatedThermalGridState.storageState shouldBe None } } @@ -127,7 +135,7 @@ class ThermalGridWithHouseOnlySpec extends UnitSpec with ThermalHouseTestData { } "not withdraw energy from the house, if actual consumption is given" in { - val tick = 0L // after three house + val tick = 0L // after three hours val gridState = ThermalGrid.startingState(thermalGrid) val (updatedGridState, reachedThreshold) = 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 bbb804c35f..93a45e3180 100644 --- a/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala +++ b/src/test/scala/edu/ie3/simona/model/thermal/ThermalGridWithStorageOnlySpec.scala @@ -80,31 +80,46 @@ class ThermalGridWithStorageOnlySpec "deliver the capabilities of the storage" in { val tick = 10800 // after three hours - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - ThermalGrid.startingState(thermalGrid), - ) - - gridDemand.required should approximate(KilowattHours(0d)) - gridDemand.possible should approximate(KilowattHours(1150d)) + val (houseDemand, storageDemand, updatedThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + tick, + testGridAmbientTemperature, + testGridAmbientTemperature, + ThermalGrid.startingState(thermalGrid), + ) + houseDemand.required should approximate(KilowattHours(0d)) + houseDemand.possible should approximate(KilowattHours(0d)) + storageDemand.required should approximate(KilowattHours(1150d)) + storageDemand.possible should approximate(KilowattHours(1150d)) + updatedThermalGridState.houseState shouldBe None + updatedThermalGridState.storageState shouldBe Some( + ThermalStorageState(10800, KilowattHours(0d), Kilowatts(0d)) + ) } "deliver the capabilities of a half full storage" in { val tick = 10800 // after three hours - val gridDemand = thermalGrid.energyDemand( - tick, - testGridAmbientTemperature, - ThermalGridState( - None, - Some(ThermalStorageState(0L, KilowattHours(575d), Kilowatts(0d))), - ), - ) + val (houseDemand, storageDemand, updatedThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + tick, + testGridAmbientTemperature, + testGridAmbientTemperature, + ThermalGridState( + None, + Some(ThermalStorageState(0L, KilowattHours(575d), Kilowatts(0d))), + ), + ) - gridDemand.required should approximate(KilowattHours(0d)) - gridDemand.possible should approximate(KilowattHours(575d)) + houseDemand.required should approximate(KilowattHours(0d)) + houseDemand.possible should approximate(KilowattHours(0d)) + storageDemand.required should approximate(KilowattHours(0d)) + storageDemand.possible should approximate(KilowattHours(575d)) + updatedThermalGridState.houseState shouldBe None + updatedThermalGridState.storageState shouldBe Some( + ThermalStorageState(10800L, KilowattHours(575d), Kilowatts(0d)) + ) } } From 67e2a4e433b0c7d5ef8931ae95299de116f15066 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Sat, 24 Aug 2024 10:00:39 +0200 Subject: [PATCH 02/17] fmt --- .../scala/edu/ie3/simona/model/participant/HpModel.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala index ad512a75e0..569bd48c10 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -11,7 +11,10 @@ import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPowerAndHe import edu.ie3.simona.model.SystemComponent import edu.ie3.simona.model.participant.HpModel.{HpRelevantData, HpState} import edu.ie3.simona.model.participant.control.QControl -import edu.ie3.simona.model.thermal.ThermalGrid.{ThermalEnergyDemand, ThermalGridState} +import edu.ie3.simona.model.thermal.ThermalGrid.{ + ThermalEnergyDemand, + ThermalGridState, +} import edu.ie3.simona.model.thermal.{ThermalGrid, ThermalThreshold} import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.ProvideFlexOptions import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions From 32dea34a90aac575aeaf263eb2be80fb8e369d1f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Sat, 26 Oct 2024 18:06:06 +0200 Subject: [PATCH 03/17] remove unused parameter --- .../simona/model/participant/HpModel.scala | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) 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 569bd48c10..3c02b58f09 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -133,7 +133,7 @@ final case class HpModel( val (turnOn, canOperate, canBeOutOfOperation, houseDemand, storageDemand) = operatesInNextState(lastState, relevantData) val updatedState = - calcState(lastState, relevantData, turnOn, houseDemand, storageDemand) + calcState(lastState, relevantData, turnOn) (canOperate, canBeOutOfOperation, updatedState) } @@ -224,8 +224,6 @@ final case class HpModel( state: HpState, relevantData: HpRelevantData, isRunning: Boolean, - houseDemand: Boolean, - storageDemand: Boolean, ): HpState = { val lastStateStorageqDot = state.thermalGridState.storageState .map(_.qDot) @@ -311,36 +309,11 @@ final case class HpModel( /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ val turnOn = setPower > (sRated * cosPhiRated * 0.5) - val ( - thermalEnergyDemandHouse, - thermalEnergyDemandStorage, - updatedThermalGridState, - ) = - thermalGrid.energyDemandAndUpdatedState( - data.currentTick, - lastState.ambientTemperature.getOrElse(data.ambientTemperature), - data.ambientTemperature, - lastState.thermalGridState, - ) - - val ( - houseDemand, - heatStorageDemand, - noThermalStorageOrThermalStorageIsEmpty, - ) = determineDemandBooleans( - lastState, - updatedThermalGridState, - thermalEnergyDemandHouse, - thermalEnergyDemandStorage, - ) - val updatedHpState: HpState = calcState( lastState, data, turnOn, - houseDemand, - heatStorageDemand, ) ( From e886345b083572f60a6d97665d4613cb42385c09 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 28 Oct 2024 09:25:43 +0100 Subject: [PATCH 04/17] remove unused parameter --- .../scala/edu/ie3/simona/model/participant/HpModel.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 3c02b58f09..e136de4d54 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -130,7 +130,7 @@ final case class HpModel( lastState: HpState, relevantData: HpRelevantData, ): (Boolean, Boolean, HpState) = { - val (turnOn, canOperate, canBeOutOfOperation, houseDemand, storageDemand) = + val (turnOn, canOperate, canBeOutOfOperation) = operatesInNextState(lastState, relevantData) val updatedState = calcState(lastState, relevantData, turnOn) @@ -149,12 +149,12 @@ final case class HpModel( * Relevant (external) data * @return * boolean defining if heat pump runs in next time step, if it can be in - * operation and out of operation plus the demand of house and storage + * operation and can be out of operation */ private def operatesInNextState( state: HpState, relevantData: HpRelevantData, - ): (Boolean, Boolean, Boolean, Boolean, Boolean) = { + ): (Boolean, Boolean, Boolean) = { val (demandHouse, demandThermalStorage, updatedState) = thermalGrid.energyDemandAndUpdatedState( relevantData.currentTick, @@ -183,7 +183,7 @@ final case class HpModel( val canBeOutOfOperation = !(demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) - (turnHpOn, canOperate, canBeOutOfOperation, houseDemand, heatStorageDemand) + (turnHpOn, canOperate, canBeOutOfOperation) } def determineDemandBooleans( From b893c0897a3a23b2725c8af9362bd7458dbb0bd2 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 28 Oct 2024 09:49:22 +0100 Subject: [PATCH 05/17] fix scapegoat code smell because of unnecessary store before return --- .../ie3/simona/agent/participant/hp/HpAgentFundamentals.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index a390f290b6..9eb908d1ac 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -314,9 +314,7 @@ trait HpAgentFundamentals nodalVoltage: squants.Dimensionless, model: HpModel, ): HpState = { - val (_, _, state) = - model.determineState(modelState, calcRelevantData) - state + model.determineState(modelState, calcRelevantData)._3 } /** Abstract definition, individual implementations found in individual agent From 23b2582f027a3869d7b09e623f550d1bbccfe686 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Mon, 28 Oct 2024 12:06:54 +0100 Subject: [PATCH 06/17] Proposal for separating state and operation point calculation --- .../simona/model/participant/HpModel.scala | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) 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 e136de4d54..1eb45443ec 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -118,7 +118,7 @@ final case class HpModel( * function calculates the heat pump's next state to get the actual active * power of this state use [[calculateActivePower]] with the generated state * - * @param lastState + * @param lastHpState * Last state of the heat pump * @param relevantData * data of heat pump including @@ -127,13 +127,34 @@ final case class HpModel( * [[HpState]] */ def determineState( - lastState: HpState, + lastHpState: HpState, relevantData: HpRelevantData, ): (Boolean, Boolean, HpState) = { + + // Use lastHpState and relevantData to update state of thermalGrid to the current tick + val (demandHouse, demandThermalStorage, currentThermalGridState) = + thermalGrid.energyDemandAndUpdatedState( + relevantData.currentTick, + lastHpState.ambientTemperature.getOrElse( + relevantData.ambientTemperature + ), + relevantData.ambientTemperature, + lastHpState.thermalGridState, + ) + + // Determining the operation point and limitations at this tick val (turnOn, canOperate, canBeOutOfOperation) = - operatesInNextState(lastState, relevantData) + operatesInNextState( + lastHpState, + currentThermalGridState, + relevantData, + demandHouse, + demandThermalStorage, + ) + + // Updating the HpState val updatedState = - calcState(lastState, relevantData, turnOn) + calcState(lastHpState, relevantData, turnOn) (canOperate, canBeOutOfOperation, updatedState) } @@ -143,39 +164,41 @@ final case class HpModel( * met or the heat pump currently is in operation and the grid is able to * handle additional energy * - * @param state - * Current state of the heat pump + * @param lastState + * last state of the heat pump + * @param currentThermalGridState + * to current tick updated state of the thermalGrid * @param relevantData * Relevant (external) data + * @param demandHouse + * ThermalEnergyDemand of the house + * @param demandThermalStorage + * ThermalEnergyDemand of the thermal storage * @return * boolean defining if heat pump runs in next time step, if it can be in * operation and can be out of operation */ private def operatesInNextState( - state: HpState, + lastState: HpState, + currentThermalGridState: ThermalGridState, relevantData: HpRelevantData, + demandHouse: ThermalEnergyDemand, + demandThermalStorage: ThermalEnergyDemand, ): (Boolean, Boolean, Boolean) = { - val (demandHouse, demandThermalStorage, updatedState) = - thermalGrid.energyDemandAndUpdatedState( - relevantData.currentTick, - state.ambientTemperature.getOrElse(relevantData.ambientTemperature), - relevantData.ambientTemperature, - state.thermalGridState, - ) val ( - houseDemand, - heatStorageDemand, + houseHasDemand, + heatStorageHasDemand, noThermalStorageOrThermalStorageIsEmpty, ) = determineDemandBooleans( - state, - updatedState, + lastState, + currentThermalGridState, demandHouse, demandThermalStorage, ) val turnHpOn: Boolean = - houseDemand || heatStorageDemand + houseHasDemand || heatStorageHasDemand val canOperate = demandHouse.hasRequiredDemand || demandHouse.hasAdditionalDemand || From 6be8e36fe31833c3e6b727be6572b2b3b9e69ff4 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 29 Oct 2024 11:30:30 +0100 Subject: [PATCH 07/17] aligning states of HpModel --- .../participant/hp/HpAgentFundamentals.scala | 4 +- .../simona/model/participant/HpModel.scala | 48 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 9eb908d1ac..dc9465e67b 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -189,7 +189,7 @@ trait HpAgentFundamentals val accompanyingResults = baseStateData.model.thermalGrid.results( tick, - updatedState.thermalGridState, + updatedState.currentThermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) @@ -254,7 +254,7 @@ trait HpAgentFundamentals ) val accompanyingResults = baseStateData.model.thermalGrid.results( currentTick, - lastModelState.thermalGridState, + lastModelState.currentThermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) 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 1eb45443ec..a3f04c0209 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -82,7 +82,7 @@ final case class HpModel( * [[HpModel.determineState]]. This state then is fed into the power * calculation logic by [[HpState]]. * - * @param modelState + * @param currentState * Current state of the heat pump * @param relevantData * data of heat pump including state of the heat pump @@ -90,9 +90,9 @@ final case class HpModel( * active power */ override protected def calculateActivePower( - modelState: HpState, + currentState: HpState, relevantData: HpRelevantData, - ): Power = modelState.activePower + ): Power = currentState.activePower /** "Calculate" the heat output of the heat pump. The hp's state is already * updated, because the calculation of apparent power in @@ -101,7 +101,7 @@ final case class HpModel( * * @param tick * Current simulation time for the calculation - * @param modelState + * @param currentState * Current state of the heat pump * @param data * Relevant (external) data for calculation @@ -110,20 +110,20 @@ final case class HpModel( */ override def calculateHeat( tick: Long, - modelState: HpState, + currentState: HpState, data: HpRelevantData, - ): Power = modelState.qDot + ): Power = currentState.qDot - /** Given a [[HpRelevantData]] object and the current [[HpState]], this - * function calculates the heat pump's next state to get the actual active - * power of this state use [[calculateActivePower]] with the generated state + /** Given a [[HpRelevantData]] object and the last [[HpState]], this function + * calculates the heat pump's next state to get the actual active power of + * this state use [[calculateActivePower]] with the generated state * * @param lastHpState * Last state of the heat pump * @param relevantData * data of heat pump including * @return - * Booleans if Hp can operate and can be out of operation plus next + * Booleans if Hp can operate and can be out of operation plus the updated * [[HpState]] */ def determineState( @@ -139,7 +139,7 @@ final case class HpModel( relevantData.ambientTemperature ), relevantData.ambientTemperature, - lastHpState.thermalGridState, + lastHpState.currentThermalGridState, ) // Determining the operation point and limitations at this tick @@ -210,7 +210,7 @@ final case class HpModel( } def determineDemandBooleans( - hpState: HpState, + lastHpState: HpState, updatedGridState: ThermalGridState, demandHouse: ThermalEnergyDemand, demandThermalStorage: ThermalEnergyDemand, @@ -223,9 +223,9 @@ final case class HpModel( ) val houseDemand = - (demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) || (hpState.isRunning && demandHouse.hasAdditionalDemand) + (demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) || (lastHpState.isRunning && demandHouse.hasAdditionalDemand) val heatStorageDemand = { - (demandThermalStorage.hasRequiredDemand) || (hpState.isRunning && demandThermalStorage.hasAdditionalDemand) + (demandThermalStorage.hasRequiredDemand) || (lastHpState.isRunning && demandThermalStorage.hasAdditionalDemand) } (houseDemand, heatStorageDemand, noThermalStorageOrThermalStorageIsEmpty) } @@ -234,8 +234,8 @@ final case class HpModel( * calculate inner temperature change of thermal house and update its inner * temperature. * - * @param state - * Current state of the heat pump + * @param lastState + * state of the heat pump until this tick * @param relevantData * data of heat pump including state of the heat pump * @param isRunning @@ -244,27 +244,27 @@ final case class HpModel( * next [[HpState]] */ private def calcState( - state: HpState, + lastState: HpState, relevantData: HpRelevantData, isRunning: Boolean, ): HpState = { - val lastStateStorageqDot = state.thermalGridState.storageState + val lastStateStorageQDot = lastState.currentThermalGridState.storageState .map(_.qDot) .getOrElse(zeroKW) val (newActivePower, newThermalPower) = if (isRunning) (pRated, pThermal) - else if (lastStateStorageqDot < zeroKW) - (zeroKW, lastStateStorageqDot * (-1)) + else if (lastStateStorageQDot < zeroKW) + (zeroKW, lastStateStorageQDot * (-1)) else (zeroKW, zeroKW) /* Push thermal energy to the thermal grid and get its updated state in return */ val (thermalGridState, maybeThreshold) = thermalGrid.updateState( relevantData.currentTick, - state.thermalGridState, - state.ambientTemperature.getOrElse(relevantData.ambientTemperature), + lastState.currentThermalGridState, + lastState.ambientTemperature.getOrElse(relevantData.ambientTemperature), relevantData.ambientTemperature, newThermalPower, ) @@ -411,7 +411,7 @@ object HpModel { * result active power * @param qDot * result heat power - * @param thermalGridState + * @param currentThermalGridState * Currently applicable state of the thermal grid * @param maybeThermalThreshold * An optional threshold of the thermal grid, indicating the next state @@ -423,7 +423,7 @@ object HpModel { ambientTemperature: Option[Temperature], activePower: Power, qDot: Power, - thermalGridState: ThermalGridState, + currentThermalGridState: ThermalGridState, maybeThermalThreshold: Option[ThermalThreshold], ) extends ModelState From 286f0ebad8d7f9b94dccf7a2bad139db0721ee61 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 29 Oct 2024 11:30:41 +0100 Subject: [PATCH 08/17] add scala doc --- .../edu/ie3/simona/model/participant/HpModel.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 a3f04c0209..c104571b9b 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -209,6 +209,20 @@ final case class HpModel( (turnHpOn, canOperate, canBeOutOfOperation) } + /** This method will return booleans whether there is a heat demand of house + * or thermal storage as well as a boolean indicating if there is no thermal + * storage or it is empty. + * + * @param lastHpState + * @param updatedGridState + * @param demandHouse + * @param demandThermalStorage + * @return + * First boolean: true, if house has heat demand Second boolean: true, if + * thermalStorage has heat demand Third boolean: true, if there is no + * thermalStorage or it's empty + */ + def determineDemandBooleans( lastHpState: HpState, updatedGridState: ThermalGridState, From f44dddff0798a43571e0440edeb78ef265b46284 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Fri, 1 Nov 2024 18:15:07 +0100 Subject: [PATCH 09/17] merging dev --- .../ie3/simona/agent/participant/hp/HpAgentFundamentals.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 58b9c402b1..128e1e7395 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -189,7 +189,7 @@ trait HpAgentFundamentals val accompanyingResults = baseStateData.model.thermalGrid.results( updatedState.tick, - updatedState.thermalGridState, + updatedState.currentThermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) @@ -254,7 +254,7 @@ trait HpAgentFundamentals ) val accompanyingResults = baseStateData.model.thermalGrid.results( updatedState.tick, - updatedState.thermalGridState, + updatedState.currentThermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) From 80fbc092122622856e269af10d4e7046a9d6c4f2 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 5 Nov 2024 16:36:39 +0100 Subject: [PATCH 10/17] remove not necessary headOption --- src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ee743d88ca..40de44725c 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( /* First get the energy demand of the houses but only if inner temperature is below target temperature */ val (houseDemand, updatedHouseState) = - house.zip(state.houseState).headOption match { + house.zip(state.houseState) match { case Some((thermalHouse, lastHouseState)) => val (updatedHouseState, updatedStorageState) = thermalHouse.determineState( From 1beb478839d9ec62e979df7ffa753f994d053c3a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 5 Nov 2024 16:36:47 +0100 Subject: [PATCH 11/17] break long line --- src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 40de44725c..074d80e0a4 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -78,7 +78,8 @@ final case class ThermalGrid( lastHouseState.qDot, ) if ( - updatedHouseState.innerTemperature < thermalHouse.targetTemperature | (lastHouseState.qDot > zeroKW && updatedHouseState.innerTemperature < thermalHouse.upperBoundaryTemperature) + updatedHouseState.innerTemperature < thermalHouse.targetTemperature | + (lastHouseState.qDot > zeroKW && updatedHouseState.innerTemperature < thermalHouse.upperBoundaryTemperature) ) { ( thermalHouse.energyDemand( From 07a65f11afef654dfdeae05de1208a95df2fa61f Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 5 Nov 2024 16:37:02 +0100 Subject: [PATCH 12/17] use wildcard for not used val --- src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 074d80e0a4..0d868e64df 100644 --- a/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala +++ b/src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala @@ -69,7 +69,7 @@ final case class ThermalGrid( val (houseDemand, updatedHouseState) = house.zip(state.houseState) match { case Some((thermalHouse, lastHouseState)) => - val (updatedHouseState, updatedStorageState) = + val (updatedHouseState, _) = thermalHouse.determineState( tick, lastHouseState, From 79e91c21efa356bc4d68184335e5eac170481f40 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 5 Nov 2024 16:45:24 +0100 Subject: [PATCH 13/17] rollback currentThermalGridState to thermalGridState --- .../agent/participant/hp/HpAgentFundamentals.scala | 4 ++-- .../edu/ie3/simona/model/participant/HpModel.scala | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala index 128e1e7395..58b9c402b1 100644 --- a/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala +++ b/src/main/scala/edu/ie3/simona/agent/participant/hp/HpAgentFundamentals.scala @@ -189,7 +189,7 @@ trait HpAgentFundamentals val accompanyingResults = baseStateData.model.thermalGrid.results( updatedState.tick, - updatedState.currentThermalGridState, + updatedState.thermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) @@ -254,7 +254,7 @@ trait HpAgentFundamentals ) val accompanyingResults = baseStateData.model.thermalGrid.results( updatedState.tick, - updatedState.currentThermalGridState, + updatedState.thermalGridState, )(baseStateData.startDate) val result = AccompaniedSimulationResult(power, accompanyingResults) 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 ccc295e240..4f3b1f92bc 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -139,7 +139,7 @@ final case class HpModel( relevantData.ambientTemperature ), relevantData.ambientTemperature, - lastHpState.currentThermalGridState, + lastHpState.thermalGridState, ) // Determining the operation point and limitations at this tick @@ -262,7 +262,7 @@ final case class HpModel( relevantData: HpRelevantData, isRunning: Boolean, ): HpState = { - val lastStateStorageQDot = lastState.currentThermalGridState.storageState + val lastStateStorageQDot = lastState.thermalGridState.storageState .map(_.qDot) .getOrElse(zeroKW) @@ -277,7 +277,7 @@ final case class HpModel( val (thermalGridState, maybeThreshold) = thermalGrid.updateState( relevantData.currentTick, - lastState.currentThermalGridState, + lastState.thermalGridState, lastState.ambientTemperature.getOrElse(relevantData.ambientTemperature), relevantData.ambientTemperature, newThermalPower, @@ -425,8 +425,8 @@ object HpModel { * result active power * @param qDot * result heat power - * @param currentThermalGridState - * Currently applicable state of the thermal grid + * @param thermalGridState + * applicable state of the thermal grid * @param maybeThermalThreshold * An optional threshold of the thermal grid, indicating the next state * change @@ -437,7 +437,7 @@ object HpModel { ambientTemperature: Option[Temperature], activePower: Power, qDot: Power, - currentThermalGridState: ThermalGridState, + thermalGridState: ThermalGridState, maybeThermalThreshold: Option[ThermalThreshold], ) extends ModelState From 71c9852a0c38526266f5afeaadb1b6e6a61cc756 Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Tue, 5 Nov 2024 16:45:36 +0100 Subject: [PATCH 14/17] scala doc format --- .../scala/edu/ie3/simona/model/participant/HpModel.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 4f3b1f92bc..41927fd2b0 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -218,9 +218,9 @@ final case class HpModel( * @param demandHouse * @param demandThermalStorage * @return - * First boolean: true, if house has heat demand Second boolean: true, if - * thermalStorage has heat demand Third boolean: true, if there is no - * thermalStorage or it's empty + * First boolean is true, if house has heat demand. Second boolean is true, + * if thermalStorage has heat demand. Third boolean is true, if there is no + * thermalStorage or it's empty. */ def determineDemandBooleans( From f819146eac5a7099b6381c239c5ba7943af3d01c Mon Sep 17 00:00:00 2001 From: Sebastian Peter Date: Wed, 13 Nov 2024 17:56:28 +0100 Subject: [PATCH 15/17] Tiny bit of code cleanup --- .../simona/model/participant/HpModel.scala | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) 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 41927fd2b0..9f0e94a9cf 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -223,7 +223,7 @@ final case class HpModel( * thermalStorage or it's empty. */ - def determineDemandBooleans( + private def determineDemandBooleans( lastHpState: HpState, updatedGridState: ThermalGridState, demandHouse: ThermalEnergyDemand, @@ -238,9 +238,8 @@ final case class HpModel( val houseDemand = (demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) || (lastHpState.isRunning && demandHouse.hasAdditionalDemand) - val heatStorageDemand = { - (demandThermalStorage.hasRequiredDemand) || (lastHpState.isRunning && demandThermalStorage.hasAdditionalDemand) - } + val heatStorageDemand = + demandThermalStorage.hasRequiredDemand || (lastHpState.isRunning && demandThermalStorage.hasAdditionalDemand) (houseDemand, heatStorageDemand, noThermalStorageOrThermalStorageIsEmpty) } @@ -270,7 +269,7 @@ final case class HpModel( if (isRunning) (pRated, pThermal) else if (lastStateStorageQDot < zeroKW) - (zeroKW, lastStateStorageQDot * (-1)) + (zeroKW, lastStateStorageQDot * -1) else (zeroKW, zeroKW) /* Push thermal energy to the thermal grid and get its updated state in return */ @@ -346,12 +345,11 @@ final case class HpModel( /* If the setpoint value is above 50 % of the electrical power, turn on the heat pump otherwise turn it off */ val turnOn = setPower > (sRated * cosPhiRated * 0.5) - val updatedHpState: HpState = - calcState( - lastState, - data, - turnOn, - ) + val updatedHpState = calcState( + lastState, + data, + turnOn, + ) ( updatedHpState, From 61acfb680ea1ac13088d6b0c89b9d54e142d743a Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 14 Nov 2024 09:45:37 +0100 Subject: [PATCH 16/17] grammar --- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 9f0e94a9cf..f555827013 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -211,7 +211,7 @@ final case class HpModel( /** This method will return booleans whether there is a heat demand of house * or thermal storage as well as a boolean indicating if there is no thermal - * storage or it is empty. + * storage, or it is empty. * * @param lastHpState * @param updatedGridState @@ -220,7 +220,7 @@ final case class HpModel( * @return * First boolean is true, if house has heat demand. Second boolean is true, * if thermalStorage has heat demand. Third boolean is true, if there is no - * thermalStorage or it's empty. + * thermalStorage, or it's empty. */ private def determineDemandBooleans( From 5790cff86f58e6d13c92d05aacc5cd0fc4731a6d Mon Sep 17 00:00:00 2001 From: danielfeismann Date: Thu, 14 Nov 2024 12:59:45 +0100 Subject: [PATCH 17/17] update scalaDoc --- src/main/scala/edu/ie3/simona/model/participant/HpModel.scala | 4 ++++ 1 file changed, 4 insertions(+) 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 f555827013..bf26b80fd8 100644 --- a/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala +++ b/src/main/scala/edu/ie3/simona/model/participant/HpModel.scala @@ -214,9 +214,13 @@ final case class HpModel( * storage, or it is empty. * * @param lastHpState + * Current state of the heat pump * @param updatedGridState + * The updated state of the [[ThermalGrid]] * @param demandHouse + * heat demand of the thermal house * @param demandThermalStorage + * heat demand of the thermal storage * @return * First boolean is true, if house has heat demand. Second boolean is true, * if thermalStorage has heat demand. Third boolean is true, if there is no