Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into jb/#671-externaldatase…
Browse files Browse the repository at this point in the history
…rvice

# Conflicts:
#	src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala
  • Loading branch information
Johannes Bao committed Jul 12, 2024
2 parents ddcaa59 + b714917 commit 50450a0
Show file tree
Hide file tree
Showing 37 changed files with 3,310 additions and 557 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ 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)
- Implementation of StorageAgent [#309](https://github.com/ie3-institute/simona/issues/309)

### Changed
- Adapted to changed data source in PSDM [#435](https://github.com/ie3-institute/simona/issues/435)
Expand All @@ -50,6 +53,8 @@ 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)
- Refactor `WeatherSource` and `WeatherSourceWrapper` [#180](https://github.com/ie3-institute/simona/issues/180)

### Fixed
- Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658)
Expand All @@ -65,6 +70,9 @@ 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)
- Fixed provision of controllingEms within buildParticipantToActorRef [#841](https://github.com/ie3-institute/simona/issues/841)
- Simulation stopping at unhandled messages in `DBFSAlgorithm` [#821](https://github.com/ie3-institute/simona/issues/821)

## [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 @@ -80,7 +80,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 @@ -114,7 +114,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 @@ -156,7 +156,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
37 changes: 37 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 Expand Up @@ -196,6 +223,16 @@ The load reference can scale the load model behaviour to reach the given annual
If an individual configuration is to be assigned, the default configuration parameters must be adjusted accordingly.
Runtime configurations of other system participants are done similarly, except that model behavior and reference are not defined.

### Storage runtime configuration

The storage model takes parameters for the initial state of charge (SOC) and the target SOC for electrical energy storages, with 0.0 <= SOC <= 1.0.
The initial SOC defaults to 0%, while the target SOC is optional. When no target SOC is set, the reference behavior (see flexibility messages) of storages is 0 kW.

initialSoc = "0.0"
targetSoc = "1.0"

Individual configuration can be assigned accordingly.

## Event configuration

Tba:
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`
2 changes: 0 additions & 2 deletions input/samples/vn_simona/fullGrid/storage_input.csv

This file was deleted.

13 changes: 13 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 Expand Up @@ -158,6 +162,15 @@ simona.runtime.participant.hp = {
individualConfigs = []
}

simona.runtime.participant.storage = {
defaultConfig = {
calculateMissingReactivePowerWithModel = false
uuids = ["default"]
scaling = 1.0
}
individualConfigs = []
}

# # # # #
# ATTENTION: calculateMissingReactivePowerWithModel and scaling is ignored here.
# # # # #
Expand Down
13 changes: 13 additions & 0 deletions src/main/resources/config/config-template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ EvcsRuntimeConfig {
lowestEvSoc: Double | 0.2 # Defines the lowest possible state of charge (SoC) that an EV is allowed to uncharge in vehicle to grid (V2G) mode
}

#@define extends BaseRuntimeConfig
StorageRuntimeConfig {
baseRuntimeConfig: BaseRuntimeConfig # this entry is ignored by the config generator,
# but cannot removed bc otherwise StorageRuntimeConfig is handled as String
initialSoc: Double | 0 # Defines initial soc of storages as a share of capacity, 0-1
#@optional
targetSoc: Double
}

#@define extends BaseRuntimeConfig
EmRuntimeConfig {
# # # # #
Expand Down Expand Up @@ -324,6 +333,10 @@ simona.runtime.participant = {
defaultConfig = HpRuntimeConfig # Mandatory default config (uuids are ignored, best provide "default")
individualConfigs = [HpRuntimeConfig]
}
storage = {
defaultConfig = StorageRuntimeConfig # Mandatory default config (uuids are ignored, best provide "default")
individualConfigs = [StorageRuntimeConfig]
}
em = {
defaultConfig = EmRuntimeConfig # Mandatory default config (uuids are ignored, best provide "default")
individualConfigs = [EmRuntimeConfig]
Expand Down
26 changes: 11 additions & 15 deletions src/main/scala/edu/ie3/simona/agent/grid/DBFSAlgorithm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,13 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
// return to Idle
idle(cleanedGridAgentBaseData)

case _ =>
// preventing "match may not be exhaustive"
Behaviors.unhandled
// handles power request that arrive to early
case (requestGridPower: RequestGridPower, _) =>
ctx.log.debug(
s"Received the message $requestGridPower too early. Stash away!"
)
buffer.stash(requestGridPower)
Behaviors.same
}
}

Expand Down Expand Up @@ -783,28 +787,20 @@ trait DBFSAlgorithm extends PowerFlowSupport with GridResultsSupport {
// happens only when we received slack data and power values before we received a request to provide grid data
// (only possible when first simulation triggered and this agent is faster in this state as the request
// by a superior grid arrives)
case (powerResponse: PowerResponse, _: GridAgentBaseData) =>
case (powerResponse: PowerResponse, _) =>
ctx.log.debug(
"Received Request for Grid Power too early. Stashing away"
)

buffer.stash(powerResponse)
Behaviors.same

// happens only when we received slack data and power values before we received a request to provide grid
// (only possible when first simulation triggered and this agent is faster
// with its power flow calculation in this state as the request by a superior grid arrives)
case (powerResponse: PowerResponse, _: PowerFlowDoneData) =>
case (requestGridPower: RequestGridPower, _) =>
ctx.log.debug(
"Received Request for Grid Power too early. Stashing away"
s"Received the message $requestGridPower too early. Stashing away!"
)

buffer.stash(powerResponse)
buffer.stash(requestGridPower)
Behaviors.same

case _ =>
// preventing "match may not be exhaustive"
Behaviors.unhandled
}
}

Expand Down
96 changes: 85 additions & 11 deletions src/main/scala/edu/ie3/simona/agent/grid/GridAgentController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import edu.ie3.simona.agent.participant.hp.HpAgent
import edu.ie3.simona.agent.participant.load.LoadAgent
import edu.ie3.simona.agent.participant.pv.PvAgent
import edu.ie3.simona.agent.participant.statedata.ParticipantStateData.ParticipantInitializeStateData
import edu.ie3.simona.agent.participant.storage.StorageAgent
import edu.ie3.simona.agent.participant.wec.WecAgent
import edu.ie3.simona.config.SimonaConfig
import edu.ie3.simona.config.SimonaConfig._
Expand Down Expand Up @@ -127,8 +128,7 @@ class GridAgentController(
curSysPart,
) =>
curSysPart match {
case entity @ (_: BmInput | _: ChpInput | _: EvInput |
_: StorageInput) =>
case entity @ (_: BmInput | _: ChpInput | _: EvInput) =>
(
notProcessedElements + entity.getClass.getSimpleName,
availableSystemParticipants,
Expand Down Expand Up @@ -208,7 +208,17 @@ class GridAgentController(
//log.info(s"Built Participant = $participant")
val node = participant.getNode


val controllingEm =
participant.getControllingEm.toScala
.map(_.getUuid)
.map(uuid =>
allEms.getOrElse(
uuid,
throw new CriticalFailureException(
s"EM actor with UUID $uuid not found."
),
)
)

val actorRef = buildParticipantActor(
participantsConfig.requestVoltageDeviationThreshold,
Expand All @@ -217,14 +227,7 @@ class GridAgentController(
participant,
thermalIslandGridsByBusId,
environmentRefs,
participant.getControllingEm.toScala.map(_.getUuid).map(
uuid => allEms.getOrElse(
uuid,
throw new CriticalFailureException(
s"Actor for EM $uuid not found."
),
),
)
controllingEm,
)
introduceAgentToEnvironment(actorRef)
// return uuid to actorRef
Expand Down Expand Up @@ -442,6 +445,20 @@ class GridAgentController(
s"Unable to find thermal island grid for heat pump '${hpInput.getUuid}' with thermal bus '${hpInput.getThermalBus.getUuid}'."
)
}
case input: StorageInput =>
buildStorage(
input,
participantConfigUtil.getOrDefault[StorageRuntimeConfig](
input.getUuid
),
environmentRefs.primaryServiceProxy,
simulationStartDate,
simulationEndDate,
resolution,
requestVoltageDeviationThreshold,
outputConfigUtil.getOrDefault(NotifierIdentifier.Storage),
maybeControllingEm,
)
case input: SystemParticipantInput =>
throw new NotImplementedError(
s"Building ${input.getClass.getSimpleName} is not implemented, yet."
Expand Down Expand Up @@ -803,6 +820,63 @@ class GridAgentController(
)
.toTyped

/** Creates a storage agent and determines the needed additional information
* for later initialization of the agent.
*
* @param storageInput
* Storage input model to derive information from
* @param modelConfiguration
* User-provided configuration for this specific storage model
* @param primaryServiceProxy
* Reference to the primary data service proxy
* @param simulationStartDate
* First wall clock time in simulation
* @param simulationEndDate
* Last wall clock time in simulation
* @param resolution
* Frequency of power flow calculations
* @param requestVoltageDeviationThreshold
* Maximum deviation in p.u. of request voltages to be considered equal
* @param outputConfig
* Configuration of the output behavior
* @param maybeControllingEm
* The parent EmAgent, if applicable
* @return
* The [[StorageAgent]] 's [[ActorRef]]
*/
private def buildStorage(
storageInput: StorageInput,
modelConfiguration: SimonaConfig.StorageRuntimeConfig,
primaryServiceProxy: ClassicRef,
simulationStartDate: ZonedDateTime,
simulationEndDate: ZonedDateTime,
resolution: Long,
requestVoltageDeviationThreshold: Double,
outputConfig: NotifierConfig,
maybeControllingEm: Option[ActorRef[FlexResponse]] = None,
): ActorRef[ParticipantMessage] =
gridAgentContext.toClassic
.simonaActorOf(
StorageAgent.props(
environmentRefs.scheduler.toClassic,
ParticipantInitializeStateData(
storageInput,
modelConfiguration,
primaryServiceProxy,
None,
simulationStartDate,
simulationEndDate,
resolution,
requestVoltageDeviationThreshold,
outputConfig,
maybeControllingEm,
),
listener.map(_.toClassic),
),
storageInput.getId,
)
.toTyped

/** Builds an [[EmAgent]] from given input
*
* @param emInput
Expand Down
Loading

0 comments on commit 50450a0

Please sign in to comment.