Skip to content

Commit

Permalink
Merge branch 'refs/heads/dev' into df/#729-additional-tests-thermal-h…
Browse files Browse the repository at this point in the history
…ouse

# Conflicts:
#	CHANGELOG.md
  • Loading branch information
danielfeismann committed Jul 5, 2024
2 parents e202c18 + 9a4b0eb commit e8b02bf
Show file tree
Hide file tree
Showing 20 changed files with 265 additions and 64 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Consider scaling factor with flex options [#734](https://github.com/ie3-institute/simona/issues/734)
- Implementation of Energy Management Agents [#204](https://github.com/ie3-institute/simona/issues/204)
- Providing documentation for EmAgent protocols and algorithms [#774](https://github.com/ie3-institute/simona/issues/774)
- Option to flush out `CylindricalStorageResults` [#826](https://github.com/ie3-institute/simona/issues/826)
- Printing the directory of log to terminal upon simulation failure [#626](https://github.com/ie3-institute/simona/issues/626)
- Additional tests to check flexibility options of thermal house and storage [#729](https://github.com/ie3-institute/simona/issues/729)

### Changed
Expand All @@ -51,6 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactoring of `GridAgent` messages [#736](https://github.com/ie3-institute/simona/issues/736)
- Rewrote PVModelTest from groovy to scala [#646](https://github.com/ie3-institute/simona/issues/646)
- Making configuration of `RefSystem` via config optional [#769](https://github.com/ie3-institute/simona/issues/769)
- Updated PSDM to version 5.1.0 [#835](https://github.com/ie3-institute/simona/issues/835)

### Fixed
- Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658)
Expand All @@ -66,6 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Default RefSystem using the unit `Volt` for low voltage grids [#811](https://github.com/ie3-institute/simona/issues/811)
- Fixed grid within GridSpec test [#806](https://github.com/ie3-institute/simona/issues/806)
- Fixed log entry after power flow calculation [#814](https://github.com/ie3-institute/simona/issues/814)
- Delete "Indices and tables" on the index page [#375](https://github.com/ie3-institute/simona/issues/375)

## [3.0.0] - 2023-08-07

Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {
id "kr.motd.sphinx" version "2.10.1" // documentation generation
id "com.github.johnrengelman.shadow" version "8.1.1" // fat jar
id "org.sonarqube" version "5.0.0.4638" // sonarqube
id "org.scoverage" version "8.0.3" // scala code coverage scoverage
id "org.scoverage" version "8.1" // scala code coverage scoverage
id "com.github.maiflai.scalatest" version "0.32" // run scalatest without specific spec task
id 'org.hidetake.ssh' version '2.11.2'
id 'net.thauvin.erik.gradle.semver' version '1.0.4' // semantic versioning
Expand All @@ -31,7 +31,7 @@ ext {
tscfgVersion = '1.0.0'
scapegoatVersion = '2.1.6'

testContainerVersion = '0.41.3'
testContainerVersion = '0.41.4'

scriptsLocation = 'gradle' + File.separator + 'scripts' + File.separator // location of script plugins
}
Expand Down Expand Up @@ -75,7 +75,7 @@ dependencies {
/* Exclude our own nested dependencies */
exclude group: 'com.github.ie3-institute'
}
implementation('com.github.ie3-institute:PowerSystemDataModel:5.0.1') {
implementation('com.github.ie3-institute:PowerSystemDataModel:5.1.0') {
exclude group: 'org.apache.logging.log4j'
exclude group: 'org.slf4j'
/* Exclude our own nested dependencies */
Expand Down Expand Up @@ -103,7 +103,7 @@ dependencies {
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
testImplementation 'org.scalatestplus:mockito-3-4_2.13:3.2.10.0'
testImplementation 'org.mockito:mockito-core:5.12.0' // mocking framework
testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.18"
testImplementation "org.scalatest:scalatest_${scalaVersion}:3.2.19"
testRuntimeOnly 'com.vladsch.flexmark:flexmark-all:0.64.8' //scalatest html output
testImplementation group: 'org.pegdown', name: 'pegdown', version: '1.6.0'
testImplementation "org.apache.pekko:pekko-testkit_${scalaVersion}:${pekkoVersion}" // pekko testkit
Expand Down Expand Up @@ -145,7 +145,7 @@ dependencies {
implementation "com.sksamuel.avro4s:avro4s-core_${scalaVersion}:4.1.2"

implementation 'org.apache.commons:commons-math3:3.6.1' // apache commons math3
implementation 'org.apache.poi:poi-ooxml:5.2.5' // used for FilenameUtils
implementation 'org.apache.poi:poi-ooxml:5.3.0' // used for FilenameUtils
implementation 'javax.measure:unit-api:2.2'
implementation 'tech.units:indriya:2.2' // quantities
implementation "org.typelevel:squants_${scalaVersion}:1.8.3"
Expand Down
2 changes: 1 addition & 1 deletion docs/readthedocs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
html_theme = 'sphinx_rtd_theme'
html_short_title = "simona"
htmlhelp_basename = 'simona-doc'
html_use_index = True
html_use_index = False
html_show_sourcelink = False
html_static_path = ['_static']

Expand Down
27 changes: 27 additions & 0 deletions docs/readthedocs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,33 @@ simona.output.participant.individualConfigs = [
]
```

#### Output configuration of thermal elements

To use the default configuration the default notifier has to be used. By setting "simulationResult" to true, the thermal elements is enabled to return its results.

```
simona.output.thermal.defaultConfig = {
notifier = "default",
simulationResult = true
}
```

The default configuration applies to all models except the ones with individual configurations assigned.
If individual configurations have to be performed for certain thermal elements, these must be listed with the corresponding notifier as in the following example.

```
simona.output.thermal.individualConfigs = [
{
notifier = "house",
simulationResult = true
},
{
notifier = "cylindricalstorage",
simulationResult = true
}
]
```

Further model classes which can be used to load the outcome of a system simulation are described in [PSDM](https://powersystemdatamodel.readthedocs.io/en/latest/models/models.html#result).
Data sources and data sinks are explained in the [I/O-capabilities](https://powersystemdatamodel.readthedocs.io/en/latest/io/basiciousage.html) section of the PSDM.

Expand Down
7 changes: 0 additions & 7 deletions docs/readthedocs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,3 @@ Institute of Energy Systems, Energy Efficiency and Energy Economics at TU Dortmu
models
developersguide
references

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
4 changes: 4 additions & 0 deletions input/samples/vn_simona/vn_simona.conf
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ simona.output.thermal = {
{
notifier = "house",
simulationResult = true
},
{
notifier = "cylindricalstorage",
simulationResult = true
}
]
}
Expand Down
91 changes: 65 additions & 26 deletions src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ package edu.ie3.simona.config
import com.typesafe.config.{Config, ConfigException}
import com.typesafe.scalalogging.LazyLogging
import edu.ie3.simona.config.SimonaConfig.Simona.Output.Sink.InfluxDb1x
import edu.ie3.simona.config.SimonaConfig.{
BaseOutputConfig,
RefSystemConfig,
ResultKafkaParams,
Simona,
TransformerControlGroup,
}
import edu.ie3.simona.config.SimonaConfig._
import edu.ie3.simona.exceptions.InvalidConfigParameterException
import edu.ie3.simona.io.result.ResultSinkType
import edu.ie3.simona.model.participant.load.{LoadModelBehaviour, LoadReference}
Expand Down Expand Up @@ -144,6 +138,11 @@ case object ConfigFailFast extends LazyLogging {
simonaConfig.simona.output.participant
)

/* Check all output configurations for thermal models */
checkThermalOutputConfig(
simonaConfig.simona.output.thermal
)

/* Check power flow resolution configuration */
checkPowerFlowResolutionConfiguration(simonaConfig.simona.powerflow)

Expand Down Expand Up @@ -429,8 +428,8 @@ case object ConfigFailFast extends LazyLogging {

/** Sanity checks for a [[SimonaConfig.RefSystemConfig]]
*
* @param refSystem
* the [[SimonaConfig.RefSystemConfig]] that should be checked
* @param refSystems
* a list of [[SimonaConfig.RefSystemConfig]]s that should be checked
*/

private def checkRefSystem(refSystems: List[RefSystemConfig]): Unit = {
Expand Down Expand Up @@ -556,11 +555,23 @@ case object ConfigFailFast extends LazyLogging {
)
)

checkDefaultBaseOutputConfig(
subConfig.defaultConfig,
defaultString = "default",
)
checkIndividualParticipantsOutputConfigs(subConfig.individualConfigs)
implicit val elementType: String = "participant"

checkDefaultBaseOutputConfig(subConfig.defaultConfig)
checkIndividualOutputConfigs(subConfig.individualConfigs)
}

/** Check the config sub tree for output parameterization
*
* @param subConfig
* Output sub config tree for participants
*/
private def checkThermalOutputConfig(
subConfig: SimonaConfig.Simona.Output.Thermal
): Unit = {
implicit val elementType: String = "thermal"
checkDefaultBaseOutputConfig(subConfig.defaultConfig)
checkIndividualOutputConfigs(subConfig.individualConfigs)
}

/** Checks resolution of power flow calculation
Expand Down Expand Up @@ -657,26 +668,26 @@ case object ConfigFailFast extends LazyLogging {
*/
private def checkDefaultBaseOutputConfig(
config: SimonaConfig.BaseOutputConfig,
defaultString: String,
): Unit = {
defaultString: String = "default",
)(implicit elementType: String): Unit = {
if (
StringUtils
.cleanString(config.notifier)
.toLowerCase != StringUtils.cleanString(defaultString).toLowerCase
)
logger.warn(
s"You provided '${config.notifier}' as model type for the default participant output config. This will not be considered!"
s"You provided '${config.notifier}' as model type for the default $elementType output config. This will not be considered!"
)
}

/** Checks the participant output configurations on duplicates
/** Checks the given output configurations on duplicates
*
* @param configs
* List of individual config entries
*/
private def checkIndividualParticipantsOutputConfigs(
private def checkIndividualOutputConfigs(
configs: List[SimonaConfig.BaseOutputConfig]
): Unit = {
)(implicit elementType: String): Unit = {
val duplicateKeys = configs
.map(config => StringUtils.cleanString(config.notifier).toLowerCase())
.groupMapReduce(identity)(_ => 1)(_ + _)
Expand All @@ -687,33 +698,61 @@ case object ConfigFailFast extends LazyLogging {

if (duplicateKeys.nonEmpty)
throw new InvalidConfigParameterException(
s"There are multiple output configurations for participant types '${duplicateKeys.mkString(",")}'."
s"There are multiple output configurations for $elementType types '${duplicateKeys.mkString(",")}'."
)

implicit val exceptedNotifiers: Set[NotifierIdentifier.Value] =
elementType match {
case "participant" =>
NotifierIdentifier.getParticipantIdentifiers
case "thermal" =>
NotifierIdentifier.getThermalIdentifiers
case other =>
throw new InvalidConfigParameterException(
s"The output config for $other has no notifiers!"
)
}

configs.foreach(checkBaseOutputConfig)
}

/** Check the content of a [[BaseOutputConfig]]
*
* @param config
* to be checked
* @param exceptedNotifiers
* a set of all valid identifiers
*/
private def checkBaseOutputConfig(config: BaseOutputConfig): Unit = {
checkNotifierIdentifier(config.notifier)
private def checkBaseOutputConfig(
config: BaseOutputConfig
)(implicit exceptedNotifiers: Set[NotifierIdentifier.Value]): Unit = {
checkNotifierIdentifier(config.notifier, exceptedNotifiers)
}

/** Check the validity of the identifier String
*
* @param id
* identifier String to check
* @param exceptedNotifiers
* a set of all valid identifiers
*/
private def checkNotifierIdentifier(id: String): Unit = {
private def checkNotifierIdentifier(
id: String,
exceptedNotifiers: Set[NotifierIdentifier.Value],
): Unit = {
try {
NotifierIdentifier(id)
val notifier = NotifierIdentifier(id)

if (!exceptedNotifiers.contains(notifier)) {
throw new InvalidConfigParameterException(
s"The identifier '$id' you provided is not valid. Valid input: ${exceptedNotifiers.map(_.toString).mkString(",")}"
)
}

} catch {
case e: NoSuchElementException =>
throw new InvalidConfigParameterException(
s"The identifier '$id' you provided is not valid. Valid input: ${NotifierIdentifier.values.map(_.toString).mkString(",")}",
s"The identifier '$id' you provided is not valid. Valid input: ${exceptedNotifiers.map(_.toString).mkString(",")}",
e,
)
}
Expand Down
19 changes: 17 additions & 2 deletions src/main/scala/edu/ie3/simona/main/RunSimona.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import edu.ie3.simona.sim.setup.SimonaSetup
import edu.ie3.util.scala.quantities.QuantityUtil
import org.apache.pekko.util.Timeout

import java.nio.file.Path
import java.util.Locale
import scala.concurrent.duration.FiniteDuration
import scala.util.Random
Expand Down Expand Up @@ -39,7 +40,7 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging {

val successful = run(simonaSetup)

printGoodbye()
printGoodbye(successful, simonaSetup.logOutputDir)

// prevents cutting of the log when having a fast simulation
Thread.sleep(1000)
Expand All @@ -54,7 +55,10 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging {
)
}

private def printGoodbye(): Unit = {
private def printGoodbye(
successful: Boolean,
outputPath: String = "",
): Unit = {
val myWords = Array(
"\"Vielleicht ist heute ein besonders guter Tag zum Sterben.\" - Worf (in Star Trek: Der erste Kontakt)",
"\"Assimiliert das!\" - Worf (in Star Trek: Der erste Kontakt)",
Expand All @@ -68,6 +72,17 @@ trait RunSimona[T <: SimonaSetup] extends LazyLogging {
val randIdx = rand.nextInt(myWords.length)
logger.info(myWords(randIdx))
logger.info("Goodbye!")

if (!successful) {
// to ensure that the link to the log is printed last
Thread.sleep(1000)

val path = Path.of(outputPath).resolve("simona.log").toUri

logger.error(
s"Simulation stopped due to the occurrence of an error! The full log can be found here: $path"
)
}
}

/** Method to be implemented to setup everything that is necessary for a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ object SampleWeatherSource {
else
Vector.empty[CoordinateDistance].asJava
}

override def findCornerPoints(
point: Point,
distance: ComparableQuantity[Length],
): util.List[CoordinateDistance] = {
// just a dummy implementation, because this is just a sample weather source
getClosestCoordinates(point, 4, distance)
}

override def validate(): Unit = {
/* nothing to do here */
}
}

// these lists contain the hourly weather values for each first of the month of 2011 + january of
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/edu/ie3/simona/sim/setup/SimonaSetup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ trait SimonaSetup {
*/
val args: Array[String]

/** Directory of the log output.
*/
def logOutputDir: String

/** Creates the runtime event listener
*
* @param context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class SimonaStandaloneSetup(
override val args: Array[String],
) extends SimonaSetup {

override def logOutputDir: String = resultFileHierarchy.logOutputDir

override def gridAgents(
context: ActorContext[_],
environmentRefs: EnvironmentRefs,
Expand Down
Loading

0 comments on commit e8b02bf

Please sign in to comment.