Skip to content

Commit

Permalink
Merge branch 'dev' into pp/#753-new-test-grid-for-simona
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.md
  • Loading branch information
sebastian-peter committed Mar 6, 2024
2 parents ac7dc4a + 32b4808 commit fb3d28c
Show file tree
Hide file tree
Showing 19 changed files with 830 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added smart charging logic [#31](https://github.com/ie3-institute/simona/issues/31) and flex calculation in `EvcsAgent` [#332](https://github.com/ie3-institute/simona/issues/332)
- Enhance output quotes of `RunSimona` [#743](https://github.com/ie3-institute/simona/issues/743)
- Printing logs of failed tests [#747](https://github.com/ie3-institute/simona/issues/747)
- Models for measurements within the grid structure [#89](https://github.com/ie3-institute/simona/issues/89)
- Config possibility for transformer control groups [#90](https://github.com/ie3-institute/simona/issues/90)
- New Test Grid for Simona [#753](https://github.com/ie3-institute/simona/issues/753)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ dependencies {

/* logging */
implementation "com.typesafe.scala-logging:scala-logging_${scalaVersion}:3.9.5" // pekko scala logging
implementation "ch.qos.logback:logback-classic:1.5.2"
implementation "ch.qos.logback:logback-classic:1.5.3"

/* testing */
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
Expand Down
39 changes: 39 additions & 0 deletions docs/readthedocs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,42 @@ Secondary convergence criterion for the power flow calculation is the number of
Resolution of the power flow calculation:

`simona.powerflow.resolution = "3600s"`

## Transformer Control Group configuration

It's possible to add a voltage control function to a transformer or group of transformers. This requires measurements within the network to be under voltage control and at least one corresponding transformer.
The voltage control will attempt to adjust the voltage by changing the tap position of the corresponding transformer. If changing the tap position would cause a voltage limit to be exceeded, the initial voltage deviation cannot be reduced by the voltage control system.

Transformer control groups must contain at least one transformer and one measurement. And can be configured as shown in this example for two transformer control groups:
```
simona.control.transformer = [
{
transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"],
measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"],
vMin = 0.98,
vMax = 1.02
}
, {
transformers = ["1132dbf4-e8a1-44ae-8415-f42d4497aa1d"],
measurements = ["7686b818-a0ba-465c-8e4e-f7d3c4e171fc"],
vMin = 0.98,
vMax = 1.02
}
]
```

UUID of transformer in control group:

`transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"]`

UUID of measurement in control group:

`measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"]`

Minimum Voltage Limit in p.u.:

`vMin = 0.98`

Maximum Voltage Limit in p.u.:

`vMax = 1.02`
8 changes: 8 additions & 0 deletions docs/readthedocs/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ models/load_model
models/pv_model
models/wec_model
```

## Measurement and Control
```{toctree}
---
maxdepth: 1
---
models/measurement_control
```
5 changes: 5 additions & 0 deletions docs/readthedocs/models/measurement_control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(measurement_control)=

# Transformer Control Groups

Transformer control group can be used to implement control functionalities like long-range control for active voltage stability. For this purpose, network areas and transformers can be logically linked to a control group via measuring points. If a deviation from the target voltage magnitude is detected at one of the measuring points, the transformer is switched to the appropriate tap position to solve the deviation, provided that no limit values are violated at other measuring points. This requires that only measuring points are included in control groups that can also be influenced by the associated transformer.
14 changes: 14 additions & 0 deletions input/samples/vn_simona/vn_simona.conf
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,17 @@ simona.powerflow.newtonraphson.epsilon = [1E-12]
simona.powerflow.newtonraphson.iterations = 50
simona.powerflow.resolution = "3600s"
simona.powerflow.stopOnFailure = true

simona.control.transformer = [
{
transformers = ["31a2b9bf-e785-4475-aa44-1c34646e8c79"],
measurements = ["923f2d69-3093-4198-86e4-13d2d1c220f8"],
vMin = 0.98,
vMax = 1.02
}, {
transformers = ["1132dbf4-e8a1-44ae-8415-f42d4497aa1d"],
measurements = ["7686b818-a0ba-465c-8e4e-f7d3c4e171fc"],
vMin = 0.98,
vMax = 1.02
}
]
16 changes: 16 additions & 0 deletions src/main/resources/config/config-template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ GridOutputConfig {
transformers3w: boolean | false
}

#@define
TransformerControlGroup {
measurements: [string]
transformers: [string]
vMax: Double
vMin: Double
}

##################################################################
# Agentsim
##################################################################
Expand Down Expand Up @@ -333,3 +341,11 @@ simona.event.listener = [
eventsToProcess = [string]
}
]

##################################################################
# Configuration of Control Schemes
##################################################################
#@optional
simona.control = {
transformer = [TransformerControlGroup]
}
10 changes: 6 additions & 4 deletions src/main/scala/edu/ie3/simona/agent/grid/GridAgent.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ object GridAgent extends DBFSAlgorithm {
activationAdapter,
)

uninitialized(agentValues, buffer)
uninitialized(agentValues, buffer, simonaConfig)
}
}

private def uninitialized(implicit
constantData: GridAgentConstantData,
buffer: StashBuffer[GridAgentMessage],
simonaConfig: SimonaConfig,
): Behavior[GridAgentMessage] =
Behaviors.receiveMessagePartial {
case CreateGridAgent(gridAgentInitData, unlockKey) =>
Expand All @@ -78,12 +79,12 @@ object GridAgent extends DBFSAlgorithm {
INIT_SIM_TICK,
Some(unlockKey),
)

initializing(gridAgentInitData)
initializing(gridAgentInitData, simonaConfig)
}

private def initializing(
gridAgentInitData: GridAgentInitData
gridAgentInitData: GridAgentInitData,
simonaConfig: SimonaConfig,
)(implicit
constantData: GridAgentConstantData,
buffer: StashBuffer[GridAgentMessage],
Expand Down Expand Up @@ -124,6 +125,7 @@ object GridAgent extends DBFSAlgorithm {
TimeUtil.withDefaults.toZonedDateTime(
constantData.simonaConfig.simona.time.endDateTime
),
simonaConfig,
)

val gridAgentController =
Expand Down
60 changes: 60 additions & 0 deletions src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import edu.ie3.simona.config.SimonaConfig.{
BaseOutputConfig,
RefSystemConfig,
ResultKafkaParams,
Simona,
TransformerControlGroup,
}
import edu.ie3.simona.exceptions.InvalidConfigParameterException
import edu.ie3.simona.io.result.ResultSinkType
Expand Down Expand Up @@ -143,6 +145,9 @@ case object ConfigFailFast extends LazyLogging {

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

/* Check control scheme definitions */
simonaConfig.simona.control.foreach(checkControlSchemes)
}

/** Checks for valid sink configuration
Expand Down Expand Up @@ -583,6 +588,61 @@ case object ConfigFailFast extends LazyLogging {
}
}

/** Check the validity of control scheme definitions
*
* @param control
* Control scheme definitions
*/
private def checkControlSchemes(control: Simona.Control): Unit = {
control.transformer.foreach(checkTransformerControl)
}

/** Check the suitability of transformer control group definition.
*
* One important check cannot be performed at this place, as input data is
* not available, yet: Do the measurements belong to a region, that can be
* influenced by the transformer? This is partly addressed in
* [[edu.ie3.simona.agent.grid.GridAgentFailFast]]
*
* @param transformerControlGroup
* Transformer control group definition
*/
private def checkTransformerControl(
transformerControlGroup: TransformerControlGroup
): Unit = {
val lowerBoundary = 0.8
val upperBoundary = 1.2
transformerControlGroup match {
case TransformerControlGroup(measurements, transformers, vMax, vMin) =>
if (measurements.isEmpty)
throw new InvalidConfigParameterException(
s"A transformer control group (${transformerControlGroup.toString}) cannot have no measurements assigned."
)
if (transformers.isEmpty)
throw new InvalidConfigParameterException(
s"A transformer control group (${transformerControlGroup.toString}) cannot have no transformers assigned."
)
if (vMin < 0)
throw new InvalidConfigParameterException(
"The minimum permissible voltage magnitude of a transformer control group has to be positive."
)
if (vMax < vMin)
throw new InvalidConfigParameterException(
s"The minimum permissible voltage magnitude of a transformer control group (${transformerControlGroup.toString}) must be smaller than the maximum permissible voltage magnitude."
)
if (vMin < lowerBoundary)
throw new InvalidConfigParameterException(
s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " +
s"by invalid parametrization of one control groups where vMin is lower than the lower boundary (0.8 of nominal Voltage)!"
)
if (vMax > upperBoundary)
throw new InvalidConfigParameterException(
s"A control group (${transformerControlGroup.toString}) which control boundaries exceed the limit of +- 20% of nominal voltage! This may be caused " +
s"by invalid parametrization of one control groups where vMax is higher than the upper boundary (1.2 of nominal Voltage)!"
)
}
}

/** Check the default config
*
* @param config
Expand Down
85 changes: 85 additions & 0 deletions src/main/scala/edu/ie3/simona/config/SimonaConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,45 @@ object SimonaConfig {

}

final case class TransformerControlGroup(
measurements: scala.List[java.lang.String],
transformers: scala.List[java.lang.String],
vMax: scala.Double,
vMin: scala.Double,
)
object TransformerControlGroup {
def apply(
c: com.typesafe.config.Config,
parentPath: java.lang.String,
$tsCfgValidator: $TsCfgValidator,
): SimonaConfig.TransformerControlGroup = {
SimonaConfig.TransformerControlGroup(
measurements =
$_L$_str(c.getList("measurements"), parentPath, $tsCfgValidator),
transformers =
$_L$_str(c.getList("transformers"), parentPath, $tsCfgValidator),
vMax = $_reqDbl(parentPath, c, "vMax", $tsCfgValidator),
vMin = $_reqDbl(parentPath, c, "vMin", $tsCfgValidator),
)
}
private def $_reqDbl(
parentPath: java.lang.String,
c: com.typesafe.config.Config,
path: java.lang.String,
$tsCfgValidator: $TsCfgValidator,
): scala.Double = {
if (c == null) 0
else
try c.getDouble(path)
catch {
case e: com.typesafe.config.ConfigException =>
$tsCfgValidator.addBadPath(parentPath + path, e)
0
}
}

}

final case class VoltLvlConfig(
id: java.lang.String,
vNom: java.lang.String,
Expand Down Expand Up @@ -896,6 +935,7 @@ object SimonaConfig {
}

final case class Simona(
control: scala.Option[SimonaConfig.Simona.Control],
event: SimonaConfig.Simona.Event,
gridConfig: SimonaConfig.Simona.GridConfig,
input: SimonaConfig.Simona.Input,
Expand All @@ -906,6 +946,41 @@ object SimonaConfig {
time: SimonaConfig.Simona.Time,
)
object Simona {
final case class Control(
transformer: scala.List[SimonaConfig.TransformerControlGroup]
)
object Control {
def apply(
c: com.typesafe.config.Config,
parentPath: java.lang.String,
$tsCfgValidator: $TsCfgValidator,
): SimonaConfig.Simona.Control = {
SimonaConfig.Simona.Control(
transformer = $_LSimonaConfig_TransformerControlGroup(
c.getList("transformer"),
parentPath,
$tsCfgValidator,
)
)
}
private def $_LSimonaConfig_TransformerControlGroup(
cl: com.typesafe.config.ConfigList,
parentPath: java.lang.String,
$tsCfgValidator: $TsCfgValidator,
): scala.List[SimonaConfig.TransformerControlGroup] = {
import scala.jdk.CollectionConverters._
cl.asScala
.map(cv =>
SimonaConfig.TransformerControlGroup(
cv.asInstanceOf[com.typesafe.config.ConfigObject].toConfig,
parentPath,
$tsCfgValidator,
)
)
.toList
}
}

final case class Event(
listener: scala.Option[
scala.List[SimonaConfig.Simona.Event.Listener$Elm]
Expand Down Expand Up @@ -2585,6 +2660,16 @@ object SimonaConfig {
$tsCfgValidator: $TsCfgValidator,
): SimonaConfig.Simona = {
SimonaConfig.Simona(
control =
if (c.hasPathOrNull("control"))
scala.Some(
SimonaConfig.Simona.Control(
c.getConfig("control"),
parentPath + "control.",
$tsCfgValidator,
)
)
else None,
event = SimonaConfig.Simona.Event(
if (c.hasPathOrNull("event")) c.getConfig("event")
else com.typesafe.config.ConfigFactory.parseString("event{}"),
Expand Down
23 changes: 23 additions & 0 deletions src/main/scala/edu/ie3/simona/model/control/GridControls.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* © 2024. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/

package edu.ie3.simona.model.control

/** Collection of grid-related control strategies
*
* @param transformerControlGroups
* Transformer control groups
*/
final case class GridControls(
transformerControlGroups: Set[TransformerControlGroupModel]
)

object GridControls {

/** Represents an empty GridControls group
*/
def empty: GridControls = GridControls(Set.empty)
}
Loading

0 comments on commit fb3d28c

Please sign in to comment.