Skip to content

Commit

Permalink
Merge branch 'df/#1049-Introduce-ThermalDemandWrapper' into df/#878-t…
Browse files Browse the repository at this point in the history
…hermalGridIT

# Conflicts:
#	CHANGELOG.md
#	src/main/scala/edu/ie3/simona/model/participant/HpModel.scala
#	src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala
  • Loading branch information
danielfeismann committed Nov 25, 2024
2 parents 8c005bb + 202ecb1 commit e059f31
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `ApparentPower` to differentiate between different power types [#794](https://github.com/ie3-institute/simona/issues/794)
- Update/enhance config documentation [#1013](https://github.com/ie3-institute/simona/issues/1013)
- Create `CITATION.cff` [#1035](https://github.com/ie3-institute/simona/issues/1035)
- Introduce ThermalDemandWrapper [#1049](https://github.com/ie3-institute/simona/issues/1049)
- Integration test for thermal grids [#878](https://github.com/ie3-institute/simona/issues/878)

### Changed
Expand Down
37 changes: 4 additions & 33 deletions src/main/scala/edu/ie3/simona/model/participant/HpModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ 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.{ApparentPower, Kilovoltamperes}
import squants.energy.{KilowattHours, Kilowatts}
import squants.{Energy, Power, Temperature}
import squants.energy.Kilowatts
import squants.{Power, Temperature}

import java.time.ZonedDateTime
import java.util.UUID
Expand Down Expand Up @@ -180,11 +180,8 @@ final case class HpModel(

val demandHouse = thermalDemands.houseDemand
val demandThermalStorage = thermalDemands.heatStorageDemand

val noThermalStorageOrThermalStorageIsEmpty = determineThermalStorageStatus(
lastState,
currentThermalGridState,
)
val noThermalStorageOrThermalStorageIsEmpty =
currentThermalGridState.isThermalStorageEmpty

val turnHpOn =
(demandHouse.hasRequiredDemand && noThermalStorageOrThermalStorageIsEmpty) ||
Expand All @@ -205,32 +202,6 @@ 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.
*
* @param lastHpState
* Current state of the heat pump
* @param updatedGridState
* The updated state of the [[ThermalGrid]]
* @return
* boolean which is true, if there is no thermalStorage, or it's empty.
*/

private def determineThermalStorageStatus(
lastHpState: HpState,
updatedGridState: ThermalGridState,
): Boolean = {
implicit val tolerance: Energy = KilowattHours(1e-3)
val noThermalStorageOrThermalStorageIsEmpty: Boolean =
updatedGridState.storageState.isEmpty || updatedGridState.storageState
.exists(
_.storedEnergy =~ zeroKWh
)

noThermalStorageOrThermalStorageIsEmpty
}

/** Calculate state depending on whether heat pump is needed or not. Also
* calculate inner temperature change of thermal house and update its inner
* temperature.
Expand Down
21 changes: 19 additions & 2 deletions src/main/scala/edu/ie3/simona/model/thermal/ThermalGrid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import edu.ie3.simona.model.thermal.ThermalStorage.ThermalStorageState
import edu.ie3.simona.util.TickUtil.TickLong
import edu.ie3.util.quantities.QuantityUtils.RichQuantityDouble
import edu.ie3.util.scala.quantities.DefaultQuantities._
import squants.energy.Kilowatts
import squants.energy.{KilowattHours, Kilowatts}
import squants.{Energy, Power, Temperature}

import java.time.ZonedDateTime
Expand Down Expand Up @@ -750,7 +750,24 @@ object ThermalGrid {
final case class ThermalGridState(
houseState: Option[ThermalHouseState],
storageState: Option[ThermalStorageState],
)
) {

/** 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.
*
* @return
* boolean which is true, if there is no thermalStorage, or it's empty.
*/

def isThermalStorageEmpty: Boolean = {
implicit val tolerance: Energy = KilowattHours(1e-3)
storageState.isEmpty || storageState
.exists(
_.storedEnergy =~ zeroKWh
)
}
}

def startingState(thermalGrid: ThermalGrid): ThermalGridState =
ThermalGridState(
Expand Down
51 changes: 48 additions & 3 deletions src/test/scala/edu/ie3/simona/model/thermal/ThermalGridSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@

package edu.ie3.simona.model.thermal

import edu.ie3.simona.exceptions.InvalidParameterException
import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput
import edu.ie3.simona.model.thermal.ThermalGrid.ThermalEnergyDemand
import edu.ie3.simona.test.common.UnitSpec
import squants.energy.{MegawattHours, WattHours, Watts}
import squants.energy.{KilowattHours, MegawattHours, WattHours, Watts}
import squants.thermal.Celsius
import squants.{Energy, Power, Temperature}

class ThermalGridSpec extends UnitSpec {
import scala.jdk.CollectionConverters._

class ThermalGridSpec
extends UnitSpec
with ThermalHouseTestData
with ThermalStorageTestData {

implicit val tempTolerance: Temperature = Celsius(1e-3)
implicit val powerTolerance: Power = Watts(1e-3)
Expand Down Expand Up @@ -114,4 +119,44 @@ class ThermalGridSpec extends UnitSpec {
}
}
}
"ThermalGridState" should {
val thermalGridOnlyHouse = ThermalGrid(
new edu.ie3.datamodel.models.input.container.ThermalGrid(
thermalBusInput,
Set(thermalHouseInput).asJava,
Set.empty[ThermalStorageInput].asJava,
)
)

"return true when there is no storage" in {
val initialState = ThermalGrid.startingState(thermalGridOnlyHouse)
val result = initialState.isThermalStorageEmpty
result shouldBe true
}

val thermalGrid = ThermalGrid(
new edu.ie3.datamodel.models.input.container.ThermalGrid(
thermalBusInput,
Set(thermalHouseInput).asJava,
Set[ThermalStorageInput](thermalStorageInput).asJava,
)
)

"return true when all stored energy is effectively zero" in {
val initialState = ThermalGrid.startingState(thermalGrid)
val result = initialState.isThermalStorageEmpty
result shouldBe true
}

"return false when storage is not empty" in {
val initialState = ThermalGrid.startingState(thermalGrid)
val gridState = initialState.copy(storageState =
initialState.storageState.map(storageState =>
storageState.copy(storedEnergy = KilowattHours(1))
)
)
val result = gridState.isThermalStorageEmpty
result shouldBe false
}
}
}

0 comments on commit e059f31

Please sign in to comment.