summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-power/src/main
diff options
context:
space:
mode:
authorHongyu He <hongyuhe.cs@googlemail.com>2021-06-11 17:42:47 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-11 17:42:47 +0200
commit885137dd79f76a63aee1bcaecbc0c9e9dec80d3a (patch)
tree7be6cb364eabdf0efa5091b1bf0fc5b8a28e0298 /opendc-simulator/opendc-simulator-power/src/main
parent1768292251957da5ce6411ecc7d2dffebf8709c8 (diff)
simulator: Add model for UPS
This change adds a new model for the UPS to the OpenDC simulator power subsystem.
Diffstat (limited to 'opendc-simulator/opendc-simulator-power/src/main')
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt4
-rw-r--r--opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt107
2 files changed, 109 insertions, 2 deletions
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
index ed3175c7..11034a57 100644
--- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt
@@ -33,8 +33,8 @@ import org.opendc.simulator.resources.*
*/
public class SimPdu(
interpreter: SimResourceInterpreter,
- public val idlePower: Double = 0.0,
- public val lossCoefficient: Double = 0.0,
+ private val idlePower: Double = 0.0,
+ private val lossCoefficient: Double = 0.0,
) : SimPowerInlet() {
/**
* The [SimResourceDistributor] that distributes the electricity over the PDU outlets.
diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt
new file mode 100644
index 00000000..f9431d21
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.power
+
+import org.opendc.simulator.resources.*
+
+/**
+ * A model of an Uninterruptible Power Supply (UPS).
+ *
+ * This model aggregates multiple power sources into a single source in order to ensure that power is always available.
+ *
+ * @param interpreter The underlying [SimResourceInterpreter] to drive the simulation under the hood.
+ * @param idlePower The idle power consumption of the UPS independent of the load.
+ * @param lossCoefficient The coefficient for the power loss of the UPS proportional to the load.
+ */
+public class SimUps(
+ interpreter: SimResourceInterpreter,
+ private val idlePower: Double = 0.0,
+ private val lossCoefficient: Double = 0.0,
+) : SimPowerOutlet() {
+ /**
+ * The resource aggregator used to combine the input sources.
+ */
+ private val aggregator = SimResourceAggregatorMaxMin(interpreter)
+
+ /**
+ * Create a new UPS outlet.
+ */
+ public fun newInlet(): SimPowerInlet {
+ val forward = SimResourceForwarder(isCoupled = true)
+ aggregator.addInput(forward)
+ return Inlet(forward)
+ }
+
+ override fun onConnect(inlet: SimPowerInlet) {
+ val consumer = inlet.createConsumer()
+ aggregator.startConsumer(object : SimResourceConsumer by consumer {
+ override fun onNext(ctx: SimResourceContext): SimResourceCommand {
+ return when (val cmd = consumer.onNext(ctx)) {
+ is SimResourceCommand.Consume -> {
+ val duration = cmd.work / cmd.limit
+ val loss = computePowerLoss(cmd.limit)
+ val newLimit = cmd.limit + loss
+
+ SimResourceCommand.Consume(duration * newLimit, newLimit, cmd.deadline)
+ }
+ is SimResourceCommand.Idle -> {
+ val loss = computePowerLoss(0.0)
+ if (loss > 0.0)
+ SimResourceCommand.Consume(Double.POSITIVE_INFINITY, loss, cmd.deadline)
+ else
+ cmd
+ }
+ else -> cmd
+ }
+ }
+ })
+ }
+
+ override fun onDisconnect(inlet: SimPowerInlet) {
+ aggregator.cancel()
+ }
+
+ /**
+ * Compute the power loss that occurs in the UPS.
+ */
+ private fun computePowerLoss(load: Double): Double {
+ // See https://download.schneider-electric.com/files?p_Doc_Ref=SPD_NRAN-66CK3D_EN
+ return idlePower + lossCoefficient * load
+ }
+
+ /**
+ * A UPS inlet.
+ */
+ public inner class Inlet(private val forwarder: SimResourceTransformer) : SimPowerInlet(), AutoCloseable {
+ override fun createConsumer(): SimResourceConsumer = forwarder
+
+ /**
+ * Remove the inlet from the PSU.
+ */
+ override fun close() {
+ forwarder.close()
+ }
+
+ override fun toString(): String = "SimPsu.Inlet"
+ }
+}