diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a5642ea..8e65bda3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Renaming power fields in `EvModel` [#208](https://github.com/ie3-institute/simonaAPI/issues/208)
+- Enhancing external data connections [#219](https://github.com/ie3-institute/simonaAPI/issues/219)
## [0.5.0] - 2024-08-09
diff --git a/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java b/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java
index e69a27c1..0761008a 100644
--- a/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java
+++ b/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java
@@ -6,20 +6,25 @@
package edu.ie3.simona.api;
-import edu.ie3.simona.api.data.ExtDataSimulation;
+import edu.ie3.simona.api.exceptions.NoExtSimulationException;
+import edu.ie3.simona.api.simulation.ExtSimAdapterData;
import edu.ie3.simona.api.simulation.ExtSimulation;
-import java.util.List;
/**
* Every external simulation has to provide a class {@code edu.ie3.simona.api.ExtLink} which
* implements this interface.
- *
- *
{@link #getExtSimulation()} and {@link #getExtDataSimulations()} can return references to the
- * same object, if that object implements both {@link ExtSimulation} and one or more variants of
- * {@link ExtDataSimulation}.
*/
public interface ExtLinkInterface {
- ExtSimulation getExtSimulation();
+ /** Returns the external simulation. */
+ default ExtSimulation getExtSimulation() {
+ throw new NoExtSimulationException(this.getClass());
+ }
- List getExtDataSimulations();
+ /**
+ * Method to set up an external simulation. Everything that needs to be set up before the external
+ * simulation can be retrieved should be done here.
+ *
+ * @param data used for setting up the external simulation
+ */
+ void setup(ExtSimAdapterData data);
}
diff --git a/src/main/java/edu/ie3/simona/api/data/ExtData.java b/src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java
similarity index 61%
rename from src/main/java/edu/ie3/simona/api/data/ExtData.java
rename to src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java
index fd35fe7a..9de5c6a3 100644
--- a/src/main/java/edu/ie3/simona/api/data/ExtData.java
+++ b/src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java
@@ -6,4 +6,5 @@
package edu.ie3.simona.api.data;
-public interface ExtData {}
+/** Interface that defines a data connection between SIMONA and an external simulation. */
+public interface ExtDataConnection {}
diff --git a/src/main/java/edu/ie3/simona/api/data/ExtDataSimulation.java b/src/main/java/edu/ie3/simona/api/data/ExtDataSimulation.java
deleted file mode 100644
index ffb06ec1..00000000
--- a/src/main/java/edu/ie3/simona/api/data/ExtDataSimulation.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * © 2021. TU Dortmund University,
- * Institute of Energy Systems, Energy Efficiency and Energy Economics,
- * Research group Distribution grid planning and operation
- */
-
-package edu.ie3.simona.api.data;
-
-/**
- * Represents a data flow inside the external simulation. An external simulation can operate
- * multiple data flows of different types. For each data type, there needs to be an interface
- * extending this interface which provides methods that receive a data adapter.
- *
- * See {@link edu.ie3.simona.api.data.ev.ExtEvSimulation} for an example.
- */
-public interface ExtDataSimulation {}
diff --git a/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java
new file mode 100644
index 00000000..d8a29a75
--- /dev/null
+++ b/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java
@@ -0,0 +1,21 @@
+/*
+ * © 2024. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+ */
+
+package edu.ie3.simona.api.data;
+
+import org.apache.pekko.actor.ActorRef;
+
+public interface ExtInputDataConnection extends ExtDataConnection {
+
+ /**
+ * Sets the actor refs for data and control flow.
+ *
+ * @param dataService actor ref to the adapter of the data service for schedule activation
+ * messages
+ * @param extSimAdapter actor ref to the extSimAdapter
+ */
+ void setActorRefs(ActorRef dataService, ActorRef extSimAdapter);
+}
diff --git a/src/main/java/edu/ie3/simona/api/data/ExtOutputData.java b/src/main/java/edu/ie3/simona/api/data/ExtOutputData.java
deleted file mode 100644
index 80d949a4..00000000
--- a/src/main/java/edu/ie3/simona/api/data/ExtOutputData.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * © 2024. TU Dortmund University,
- * Institute of Energy Systems, Energy Efficiency and Energy Economics,
- * Research group Distribution grid planning and operation
- */
-
-package edu.ie3.simona.api.data;
-
-/**
- * Interface for a connection between SIMONA and an external simulation with data flow from SIMONA
- * to external
- */
-public interface ExtOutputData extends ExtData {}
diff --git a/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java
new file mode 100644
index 00000000..6ac15e75
--- /dev/null
+++ b/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java
@@ -0,0 +1,27 @@
+/*
+ * © 2024. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+ */
+
+package edu.ie3.simona.api.data;
+
+import org.apache.pekko.actor.ActorRef;
+
+/**
+ * Interface for a connection between SIMONA and an external simulation with data flow from SIMONA
+ * to external
+ */
+public interface ExtOutputDataConnection extends ExtDataConnection {
+
+ /**
+ * Sets the actor refs for data and control flow
+ *
+ * @param extResultDataService actor ref to the adapter of the data service for data messages
+ * @param dataServiceActivation actor ref to the adapter of the data service for schedule
+ * activation messages
+ * @param extSimAdapter actor ref to the extSimAdapter
+ */
+ void setActorRefs(
+ ActorRef extResultDataService, ActorRef dataServiceActivation, ActorRef extSimAdapter);
+}
diff --git a/src/main/java/edu/ie3/simona/api/data/em/ExtEmData.java b/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java
similarity index 65%
rename from src/main/java/edu/ie3/simona/api/data/em/ExtEmData.java
rename to src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java
index 3e80ddf4..5a0bbaa6 100644
--- a/src/main/java/edu/ie3/simona/api/data/em/ExtEmData.java
+++ b/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java
@@ -7,16 +7,18 @@
package edu.ie3.simona.api.data.em;
import edu.ie3.datamodel.models.value.PValue;
-import edu.ie3.simona.api.data.ExtData;
-import edu.ie3.simona.api.data.ExtInputDataContainer;
+import edu.ie3.datamodel.models.value.Value;
+import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.em.ontology.EmDataMessageFromExt;
import edu.ie3.simona.api.data.em.ontology.ProvideEmSetPointData;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import java.util.*;
+import java.util.stream.Collectors;
import org.apache.pekko.actor.ActorRef;
+import org.slf4j.Logger;
/** Enables data connection of em data between SIMONA and SimonaAPI */
-public class ExtEmData implements ExtData {
+public class ExtEmDataConnection implements ExtInputDataConnection {
/** Actor reference to service that handles ev data within SIMONA */
private ActorRef emDataService;
@@ -27,16 +29,33 @@ public class ExtEmData implements ExtData {
/** Assets that provide primary data to SIMONA */
private final Map extEmMapping;
- public ExtEmData(Map extEmMapping) {
+ public ExtEmDataConnection(Map extEmMapping) {
this.extEmMapping = extEmMapping;
}
- /** Sets the actor refs for data and control flow */
+ @Override
public void setActorRefs(ActorRef emDataService, ActorRef extSimAdapter) {
this.emDataService = emDataService;
this.extSimAdapter = extSimAdapter;
}
+ public void convertAndSend(
+ long tick, Map data, Optional maybeNextTick, Logger log) {
+ // filtering the data and converting the keys
+ Map convertedMap =
+ data.entrySet().stream()
+ .filter(e -> extEmMapping.containsKey(e.getKey()))
+ .collect(
+ Collectors.toMap(e -> extEmMapping.get(e.getKey()), e -> (PValue) e.getValue()));
+
+ if (convertedMap.isEmpty()) {
+ log.warn("No em data found! Sending no em data to SIMONA for tick {}.", tick);
+ } else {
+ log.debug("Provided SIMONA with em data.");
+ provideEmData(tick, convertedMap, maybeNextTick);
+ }
+ }
+
/** Returns a list of the uuids of the em agents that expect external set points */
public List getControlledEms() {
return extEmMapping.values().stream().toList();
@@ -59,26 +78,4 @@ public void sendExtMsg(EmDataMessageFromExt msg) {
// we need to schedule data receiver activation with scheduler
extSimAdapter.tell(new ScheduleDataServiceMessage(emDataService), ActorRef.noSender());
}
-
- /** Converts an input data package from an external simulation to a map of set points */
- public Map convertExternalInputToEmSetPoints(
- ExtInputDataContainer extInputDataContainer) {
- Map emDataForSimona = new HashMap<>();
- extInputDataContainer
- .getSimonaInputMap()
- .forEach(
- (id, value) -> {
- if (extEmMapping.containsKey(id)) {
- if (value instanceof PValue pValue) {
- emDataForSimona.put(extEmMapping.get(id), pValue);
- } else {
- throw new IllegalArgumentException("EmData can only handle PValue's!");
- }
- } else {
- throw new IllegalArgumentException(
- "Input for asset with id " + id + " was provided, but it wasn't requested!");
- }
- });
- return emDataForSimona;
- }
}
diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvData.java b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java
similarity index 92%
rename from src/main/java/edu/ie3/simona/api/data/ev/ExtEvData.java
rename to src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java
index 303ff1fc..53a71e87 100644
--- a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvData.java
+++ b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java
@@ -6,28 +6,30 @@
package edu.ie3.simona.api.data.ev;
-import edu.ie3.simona.api.data.ExtData;
+import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.ev.model.EvModel;
import edu.ie3.simona.api.data.ev.ontology.*;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.pekko.actor.ActorRef;
-public class ExtEvData implements ExtData {
+public class ExtEvDataConnection implements ExtInputDataConnection {
/** Data message queue containing messages from SIMONA */
public final LinkedBlockingQueue receiveTriggerQueue =
new LinkedBlockingQueue<>();
/** Actor reference to service that handles ev data within SIMONA */
- private final ActorRef dataService;
+ private ActorRef dataService;
/** Actor reference to adapter that handles scheduler control flow in SIMONA */
- private final ActorRef extSimAdapter;
+ private ActorRef extSimAdapter;
- // important trigger queue must be the same as hold in actor
- // to make it safer one might consider asking the actor for ara reference on its trigger queue?!
- public ExtEvData(ActorRef dataService, ActorRef extSimAdapter) {
+ @Override
+ public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) {
this.dataService = dataService;
this.extSimAdapter = extSimAdapter;
}
diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvSimulation.java b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvSimulation.java
deleted file mode 100644
index b14fb1f3..00000000
--- a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvSimulation.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * © 2021. TU Dortmund University,
- * Institute of Energy Systems, Energy Efficiency and Energy Economics,
- * Research group Distribution grid planning and operation
- */
-
-package edu.ie3.simona.api.data.ev;
-
-import edu.ie3.simona.api.data.ExtDataSimulation;
-
-/**
- * An external simulation that provides an ev mobility simulation should implement this interface
- * and handle the ExtEvData that is handed over.
- */
-public interface ExtEvSimulation extends ExtDataSimulation {
-
- /**
- * Hand over an ExtEvData which enables communication regarding ev movements.
- *
- * @param evData the ev data
- */
- void setExtEvData(ExtEvData evData);
-}
diff --git a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryData.java b/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java
similarity index 66%
rename from src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryData.java
rename to src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java
index 048353b8..10fe1842 100644
--- a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryData.java
+++ b/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java
@@ -7,18 +7,19 @@
package edu.ie3.simona.api.data.primarydata;
import edu.ie3.datamodel.models.value.Value;
-import edu.ie3.simona.api.data.ExtData;
-import edu.ie3.simona.api.data.ExtInputDataContainer;
+import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import edu.ie3.simona.api.data.primarydata.ontology.PrimaryDataMessageFromExt;
import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData;
import java.util.*;
+import java.util.stream.Collectors;
import org.apache.pekko.actor.ActorRef;
+import org.slf4j.Logger;
/** Enables data connection of primary data between SIMONA and SimonaAPI */
-public class ExtPrimaryData implements ExtData {
+public class ExtPrimaryDataConnection implements ExtInputDataConnection {
- /** Actor reference to service that handles ev data within SIMONA */
+ /** Actor reference to service that handles primary data within SIMONA */
private ActorRef dataService;
/** Actor reference to adapter that handles scheduler control flow in SIMONA */
@@ -27,16 +28,33 @@ public class ExtPrimaryData implements ExtData {
/** Assets that provide primary data to SIMONA */
private final Map extPrimaryDataMapping;
- public ExtPrimaryData(Map extPrimaryDataMapping) {
+ public ExtPrimaryDataConnection(Map extPrimaryDataMapping) {
this.extPrimaryDataMapping = extPrimaryDataMapping;
}
- /** Sets the actor refs for data and control flow */
+ @Override
public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) {
this.dataService = dataService;
this.extSimAdapter = extSimAdapter;
}
+ public void convertAndSend(
+ long tick, Map data, Optional maybeNextTick, Logger log) {
+ // filtering the data and converting the keys
+ Map convertedMap =
+ data.entrySet().stream()
+ .filter(e -> extPrimaryDataMapping.containsKey(e.getKey()))
+ .collect(
+ Collectors.toMap(e -> extPrimaryDataMapping.get(e.getKey()), Map.Entry::getValue));
+
+ if (convertedMap.isEmpty()) {
+ log.warn("No primary data found! Sending no primary data to SIMONA for tick {}.", tick);
+ } else {
+ log.debug("Provided SIMONA with primary data.");
+ providePrimaryData(tick, convertedMap, maybeNextTick);
+ }
+ }
+
/** Returns a list of the uuids of the system participants that expect external primary data */
public List getPrimaryDataAssets() {
return extPrimaryDataMapping.values().stream().toList();
@@ -60,22 +78,4 @@ public void sendExtMsg(PrimaryDataMessageFromExt msg) {
// we need to schedule data receiver activation with scheduler
extSimAdapter.tell(new ScheduleDataServiceMessage(dataService), ActorRef.noSender());
}
-
- /** Converts an input data package from an external simulation to a map of primary data */
- public Map convertExternalInputToPrimaryData(
- ExtInputDataContainer extInputDataContainer) {
- Map primaryDataForSimona = new HashMap<>();
- extInputDataContainer
- .getSimonaInputMap()
- .forEach(
- (id, value) -> {
- if (extPrimaryDataMapping.containsKey(id)) {
- primaryDataForSimona.put(extPrimaryDataMapping.get(id), value);
- } else {
- throw new IllegalArgumentException(
- "Input for asset with id " + id + " was provided, but it wasn't requested!");
- }
- });
- return primaryDataForSimona;
- }
}
diff --git a/src/main/java/edu/ie3/simona/api/data/results/ExtResultData.java b/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java
similarity index 97%
rename from src/main/java/edu/ie3/simona/api/data/results/ExtResultData.java
rename to src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java
index 389d62b7..de90fa41 100644
--- a/src/main/java/edu/ie3/simona/api/data/results/ExtResultData.java
+++ b/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java
@@ -9,7 +9,7 @@
import edu.ie3.datamodel.models.result.ModelResultEntity;
import edu.ie3.datamodel.models.result.NodeResult;
import edu.ie3.datamodel.models.result.system.SystemParticipantResult;
-import edu.ie3.simona.api.data.ExtOutputData;
+import edu.ie3.simona.api.data.ExtOutputDataConnection;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import edu.ie3.simona.api.data.results.ontology.ProvideResultEntities;
import edu.ie3.simona.api.data.results.ontology.RequestResultEntities;
@@ -23,7 +23,7 @@
import org.apache.pekko.actor.ActorRef;
/** Enables data connection of results between SIMONA and SimonaAPI */
-public class ExtResultData implements ExtOutputData {
+public class ExtResultDataConnection implements ExtOutputDataConnection {
/** Data message queue containing messages from SIMONA */
public final LinkedBlockingQueue receiveTriggerQueue =
@@ -44,7 +44,7 @@ public class ExtResultData implements ExtOutputData {
/** Map uuid to external id of system participants */
private final Map participantResultAssetMapping;
- public ExtResultData(
+ public ExtResultDataConnection(
Map participantResultAssetMapping, Map gridResultAssetMapping) {
this.participantResultAssetMapping = participantResultAssetMapping;
this.gridResultAssetMapping = gridResultAssetMapping;
diff --git a/src/main/java/edu/ie3/simona/api/exceptions/ConversionException.java b/src/main/java/edu/ie3/simona/api/exceptions/ConversionException.java
deleted file mode 100644
index c9fb5477..00000000
--- a/src/main/java/edu/ie3/simona/api/exceptions/ConversionException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * © 2024. TU Dortmund University,
- * Institute of Energy Systems, Energy Efficiency and Energy Economics,
- * Research group Distribution grid planning and operation
- */
-
-package edu.ie3.simona.api.exceptions;
-
-public class ConversionException extends Exception {
-
- public ConversionException(final String message) {
- super(message);
- }
-}
diff --git a/src/main/java/edu/ie3/simona/api/exceptions/NoExtSimulationException.java b/src/main/java/edu/ie3/simona/api/exceptions/NoExtSimulationException.java
new file mode 100644
index 00000000..f4a242b3
--- /dev/null
+++ b/src/main/java/edu/ie3/simona/api/exceptions/NoExtSimulationException.java
@@ -0,0 +1,20 @@
+/*
+ * © 2024. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+ */
+
+package edu.ie3.simona.api.exceptions;
+
+import edu.ie3.simona.api.ExtLinkInterface;
+
+public class NoExtSimulationException extends RuntimeException {
+
+ public NoExtSimulationException(Class extends ExtLinkInterface> linkClass) {
+ this("No external simulation was set up in ExtLinkInterface: ." + linkClass.getSimpleName());
+ }
+
+ public NoExtSimulationException(final String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java b/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java
index 9d926d51..f07ec9bd 100644
--- a/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java
+++ b/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java
@@ -7,14 +7,18 @@
package edu.ie3.simona.api.simulation;
import edu.ie3.datamodel.models.result.ModelResultEntity;
+import edu.ie3.datamodel.models.value.Value;
import edu.ie3.simona.api.data.DataQueueExtSimulationExtSimulator;
import edu.ie3.simona.api.data.ExtInputDataContainer;
-import edu.ie3.simona.api.data.em.ExtEmData;
-import edu.ie3.simona.api.data.primarydata.ExtPrimaryData;
+import edu.ie3.simona.api.data.em.ExtEmDataConnection;
+import edu.ie3.simona.api.data.primarydata.ExtPrimaryDataConnection;
import edu.ie3.simona.api.data.results.ExtResultContainer;
-import edu.ie3.simona.api.data.results.ExtResultData;
+import edu.ie3.simona.api.data.results.ExtResultDataConnection;
+import edu.ie3.simona.api.simulation.mapping.DataType;
+import edu.ie3.simona.api.simulation.mapping.ExtEntityMapping;
import java.util.Map;
import java.util.Optional;
+import java.util.UUID;
import org.slf4j.Logger;
/**
@@ -42,42 +46,133 @@ protected ExtCoSimulation(String simulationName, String extSimulatorName) {
this.dataQueueSimonaApiToExtCoSimulator = new DataQueueExtSimulationExtSimulator<>();
}
- /** Function to send primary data to SIMONA using ExtPrimaryData */
- protected void sendPrimaryDataToSimona(ExtPrimaryData extPrimaryData, long tick, Logger log)
- throws InterruptedException {
+ /**
+ * Builds an {@link ExtPrimaryDataConnection}.
+ *
+ * @param mapping between the external simulation and SIMONA.
+ * @param log logger
+ * @return an ext primary data connection
+ */
+ protected static ExtPrimaryDataConnection buildPrimaryConnection(
+ ExtEntityMapping mapping, Logger log) {
+ Map primaryMapping = mapping.getExtId2UuidMapping(DataType.EXT_PRIMARY_INPUT);
+ ExtPrimaryDataConnection extPrimaryDataConnection =
+ new ExtPrimaryDataConnection(primaryMapping);
+
+ if (primaryMapping.isEmpty()) {
+ log.warn("Primary with 0 entities created.");
+ } else {
+ log.info("Primary connection with {} entities created.", primaryMapping.size());
+ }
+
+ return extPrimaryDataConnection;
+ }
+
+ /**
+ * Builds an {@link ExtEmDataConnection}.
+ *
+ * @param mapping between the external simulation and SIMONA.
+ * @param log logger
+ * @return an ext em data connection
+ */
+ protected static ExtEmDataConnection buildEmConnection(ExtEntityMapping mapping, Logger log) {
+ Map emMapping = mapping.getExtId2UuidMapping(DataType.EXT_EM_INPUT);
+ ExtEmDataConnection extEmDataConnection = new ExtEmDataConnection(emMapping);
+
+ if (emMapping.isEmpty()) {
+ log.warn("Em connection with 0 entities created.");
+ } else {
+ log.info("Em connection with {} entities created.", emMapping.size());
+ }
+
+ return extEmDataConnection;
+ }
+
+ /**
+ * Builds an {@link ExtResultDataConnection}.
+ *
+ * @param mapping between the external simulation and SIMONA.
+ * @param log logger
+ * @return an ext result data connection
+ */
+ protected static ExtResultDataConnection buildResultConnection(
+ ExtEntityMapping mapping, Logger log) {
+ Map resultParticipantMapping =
+ mapping.getExtUuid2IdMapping(DataType.EXT_PARTICIPANT_RESULT);
+ Map resultGridMapping = mapping.getExtUuid2IdMapping(DataType.EXT_GRID_RESULT);
+ ExtResultDataConnection extResultDataConnection =
+ new ExtResultDataConnection(resultParticipantMapping, resultGridMapping);
+
+ if (resultParticipantMapping.isEmpty() && resultGridMapping.isEmpty()) {
+ log.warn("Result connection with 0 participants and 0 grid assets created.");
+ } else {
+ log.info(
+ "Result connection with {} participants and {} grid assets created.",
+ resultParticipantMapping.size(),
+ resultGridMapping.size());
+ }
+
+ return extResultDataConnection;
+ }
+
+ /**
+ * Function to send primary data to SIMONA using ExtPrimaryData
+ *
+ * @param extPrimaryDataConnection the connection to SIMONA
+ * @param tick for which data is sent
+ * @param dataMap map: id to value
+ * @param maybeNextTick option for the next tick data is sent
+ * @param log logger
+ */
+ protected void sendPrimaryDataToSimona(
+ ExtPrimaryDataConnection extPrimaryDataConnection,
+ long tick,
+ Map dataMap,
+ Optional maybeNextTick,
+ Logger log) {
log.debug("Wait for Primary Data from {}", extSimulatorName);
- ExtInputDataContainer inputData = dataQueueExtCoSimulatorToSimonaApi.takeData();
log.debug("Received Primary Data from {}", extSimulatorName);
- extPrimaryData.providePrimaryData(
- tick,
- extPrimaryData.convertExternalInputToPrimaryData(inputData),
- inputData.getMaybeNextTick());
+ extPrimaryDataConnection.convertAndSend(tick, dataMap, maybeNextTick, log);
log.debug("Provided Primary Data to SIMONA!");
}
/**
* Function to send em data to SIMONA using ExtPrimaryData nextTick is necessary, because the em
* agents have an own scheduler that should know, when the next set point arrives.
+ *
+ * @param extEmDataConnection the connection to SIMONA
+ * @param tick for which data is sent
+ * @param dataMap map: id to value
+ * @param maybeNextTick option for the next tick data is sent
+ * @param log logger
*/
- protected void sendEmDataToSimona(ExtEmData extEmData, long tick, long nextTick, Logger log)
- throws InterruptedException {
- log.debug("Wait for EmData from {}", extSimulatorName);
- ExtInputDataContainer inputData = dataQueueExtCoSimulatorToSimonaApi.takeData();
+ protected void sendEmDataToSimona(
+ ExtEmDataConnection extEmDataConnection,
+ long tick,
+ Map dataMap,
+ Optional maybeNextTick,
+ Logger log) {
log.debug("Received EmData from {}", extSimulatorName);
- extEmData.provideEmData(
- tick, extEmData.convertExternalInputToEmSetPoints(inputData), Optional.of(nextTick));
+ extEmDataConnection.convertAndSend(tick, dataMap, maybeNextTick, log);
log.debug("Provided EmData to SIMONA!");
}
- /** Function to get result data from SIMONA using ExtResultData */
- protected void sendResultsToExtCoSimulator(
- ExtResultData extResultData, long tick, Optional nextTick, Logger log)
+ /**
+ * Function to get result data from SIMONA using the available {@link ExtResultDataConnection}
+ *
+ * @param connection the connection to SIMONA
+ * @param tick for which data is received
+ * @param maybeNextTick option for the next tick data is received
+ * @param log logger
+ */
+ protected void sendDataToExt(
+ ExtResultDataConnection connection, long tick, Optional maybeNextTick, Logger log)
throws InterruptedException {
log.debug("Request results from SIMONA!");
- Map resultsToBeSend = extResultData.requestResults(tick);
+ Map resultsToBeSend = connection.requestResults(tick);
log.debug("Received results from SIMONA!");
dataQueueSimonaApiToExtCoSimulator.queueData(
- new ExtResultContainer(tick, resultsToBeSend, nextTick));
+ new ExtResultContainer(tick, resultsToBeSend, maybeNextTick));
log.debug("Sent results to {}", extSimulatorName);
}
}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java b/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java
index 2be68558..0e52a819 100644
--- a/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java
+++ b/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java
@@ -6,13 +6,10 @@
package edu.ie3.simona.api.simulation;
-import edu.ie3.simona.api.data.ExtData;
-import edu.ie3.simona.api.data.ev.ExtEvData;
-import edu.ie3.simona.api.data.ev.ExtEvSimulation;
+import edu.ie3.simona.api.data.ExtDataConnection;
import edu.ie3.simona.api.simulation.ontology.*;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Optional;
+import java.util.Set;
/**
* Every external simulation must extend this class in order to get triggered by the main
@@ -104,22 +101,14 @@ protected void terminate(Boolean simulationSuccessful) {
// to be overwritten in subclass
}
- public final List> getRequiredAdapters() {
- ArrayList> classes = new ArrayList<>();
-
- if (this instanceof ExtEvSimulation) classes.add(ExtEvData.class);
-
- return classes;
- }
-
- public final void setup(ExtSimAdapterData data, List adapters) {
+ /**
+ * Method to set the external simulation adapter data. This method should be called during {@link
+ * edu.ie3.simona.api.ExtLinkInterface#setup(ExtSimAdapterData)}.
+ *
+ * @param data to set up
+ */
+ public final void setAdapterData(ExtSimAdapterData data) {
this.data = data;
-
- // todo sanity check if all required data is available
- for (ExtData adapter : adapters) {
- if (adapter instanceof ExtEvData && this instanceof ExtEvSimulation)
- ((ExtEvSimulation) this).setExtEvData((ExtEvData) adapter);
- }
}
/**
@@ -131,5 +120,11 @@ protected String[] getMainArgs() {
return data.getMainArgs();
}
- public abstract List getDataConnections();
+ /** Returns the name of this external simulation. */
+ public final String getSimulationName() {
+ return simulationName;
+ }
+
+ /** Returns all {@link ExtDataConnection} of this simulation. */
+ public abstract Set getDataConnections();
}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java b/src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java
new file mode 100644
index 00000000..67bfaa12
--- /dev/null
+++ b/src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java
@@ -0,0 +1,32 @@
+/*
+ * © 2024. TU Dortmund University,
+ * Institute of Energy Systems, Energy Efficiency and Energy Economics,
+ * Research group Distribution grid planning and operation
+ */
+
+package edu.ie3.simona.api.simulation.mapping;
+
+import edu.ie3.datamodel.exceptions.ParsingException;
+
+public enum DataType {
+ EXT_PRIMARY_INPUT("primary_input"),
+ EXT_EM_INPUT("em_input"),
+ EXT_GRID_RESULT("grid_result"),
+ EXT_PARTICIPANT_RESULT("participant_result");
+
+ public final String type;
+
+ DataType(String type) {
+ this.type = type;
+ }
+
+ public static DataType parse(String type) throws ParsingException {
+ return switch (type) {
+ case "primary_input" -> EXT_PRIMARY_INPUT;
+ case "em_input" -> EXT_EM_INPUT;
+ case "grid_result" -> EXT_GRID_RESULT;
+ case "participant_result" -> EXT_PARTICIPANT_RESULT;
+ default -> throw new ParsingException("Data type " + type + " is not supported!");
+ };
+ }
+}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java
index 23460236..1444c3e1 100644
--- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java
+++ b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java
@@ -16,31 +16,28 @@
* @param uuid SIMONA uuid
* @param id external id
* @param columnScheme data types the external asset expects
- * @param resultType data types the external asset expects
+ * @param dataType data types the external asset expects
*/
public record ExtEntityEntry(
UUID uuid,
String id,
ColumnScheme columnScheme, // FIXME: placeholder -> ColumnScheme should handle more data types
- String resultType)
+ DataType dataType)
implements InputEntity {
- public static final String EXT_INPUT = "input";
- public static final String EXT_RESULT_PARTICIPANT = "result_participant";
- public static final String EXT_RESULT_GRID = "result_grid";
public String toString() {
return "ExtEntityEntry={"
+ "UUID="
- + uuid()
+ + uuid
+ ", "
- + "ExtId="
- + id()
+ + "extId="
+ + id
+ ", "
- + "ColumnScheme="
- + columnScheme()
+ + "columnScheme="
+ + columnScheme
+ ", "
- + "ResultType="
- + resultType()
+ + "dataType="
+ + dataType
+ "}";
}
}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java
index 343c577b..9a820258 100644
--- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java
+++ b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java
@@ -6,6 +6,8 @@
package edu.ie3.simona.api.simulation.mapping;
+import edu.ie3.datamodel.exceptions.FactoryException;
+import edu.ie3.datamodel.exceptions.ParsingException;
import edu.ie3.datamodel.io.factory.EntityData;
import edu.ie3.datamodel.io.factory.EntityFactory;
import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme;
@@ -22,7 +24,7 @@ public class ExtEntityFactory extends EntityFactory
public static final String DATA_TYPE = "dataType";
public ExtEntityFactory() {
- super(new Class[] {ExtEntityEntry.class});
+ super(ExtEntityEntry.class);
}
@Override
@@ -36,7 +38,13 @@ protected ExtEntityEntry buildModel(EntityData data) {
UUID simonaUuid = data.getUUID(SIMONA_UUID);
String extId = data.getField(EXT_ID);
Optional columnScheme = ColumnScheme.parse(data.getField(COLUMN_SCHEME));
- String inputType = data.getField(DATA_TYPE);
+
+ DataType inputType;
+ try {
+ inputType = DataType.parse(data.getField(DATA_TYPE));
+ } catch (ParsingException e) {
+ throw new FactoryException(e);
+ }
return new ExtEntityEntry(
simonaUuid,
diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java
index a0826fda..8fd033e6 100644
--- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java
+++ b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java
@@ -7,14 +7,16 @@
package edu.ie3.simona.api.simulation.mapping;
import java.util.*;
+import java.util.stream.Collectors;
/** Contains the mapping between SIMONA uuid, the external id and the data type the assets hold */
public class ExtEntityMapping {
- private final List extEntities;
+ private final Map> extEntities;
public ExtEntityMapping(List extEntityEntryList) {
- this.extEntities = extEntityEntryList;
+ this.extEntities =
+ extEntityEntryList.stream().collect(Collectors.groupingBy(ExtEntityEntry::dataType));
}
/**
@@ -23,15 +25,9 @@ public ExtEntityMapping(List extEntityEntryList) {
* @param dataType data type the external asset expects
* @return Mapping external id to SIMONA uuid
*/
- public Map getExtId2UuidMapping(String dataType) {
- Map extId2UuidMapping = new HashMap<>();
- extEntities.forEach(
- ent -> {
- if (Objects.equals(ent.resultType(), dataType)) {
- extId2UuidMapping.put(ent.id(), ent.uuid());
- }
- });
- return extId2UuidMapping;
+ public Map getExtId2UuidMapping(DataType dataType) {
+ return extEntities.getOrDefault(dataType, Collections.emptyList()).stream()
+ .collect(Collectors.toMap(ExtEntityEntry::id, ExtEntityEntry::uuid));
}
/**
@@ -40,14 +36,8 @@ public Map getExtId2UuidMapping(String dataType) {
* @param dataType data type the external asset expects
* @return Mapping SIMONA uuid to external id
*/
- public Map getExtUuid2IdMapping(String dataType) {
- Map extUuid2IdMapping = new HashMap<>();
- extEntities.forEach(
- ent -> {
- if (Objects.equals(ent.resultType(), dataType)) {
- extUuid2IdMapping.put(ent.uuid(), ent.id());
- }
- });
- return extUuid2IdMapping;
+ public Map getExtUuid2IdMapping(DataType dataType) {
+ return extEntities.getOrDefault(dataType, Collections.emptyList()).stream()
+ .collect(Collectors.toMap(ExtEntityEntry::uuid, ExtEntityEntry::id));
}
}
diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingCsvSource.java b/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingCsvSource.java
deleted file mode 100644
index e1bf9204..00000000
--- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingCsvSource.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * © 2024. TU Dortmund University,
- * Institute of Energy Systems, Energy Efficiency and Energy Economics,
- * Research group Distribution grid planning and operation
- */
-
-package edu.ie3.simona.api.simulation.mapping;
-
-import edu.ie3.datamodel.exceptions.SourceException;
-import edu.ie3.datamodel.io.factory.EntityData;
-import edu.ie3.datamodel.io.naming.FileNamingStrategy;
-import edu.ie3.datamodel.io.source.csv.CsvDataSource;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.*;
-import java.util.stream.Stream;
-
-/** Source that is capable of providing information around external mapping from csv files. */
-public class ExtEntityMappingCsvSource extends ExtEntityMappingSource {
-
- private final ExtEntityMapping extEntities;
-
- private final CsvDataSource dataSource;
-
- private final Path mappingPath;
-
- public ExtEntityMappingCsvSource(
- String csvSep, Path folderPath, FileNamingStrategy fileNamingStrategy) {
- super();
- this.dataSource = new CsvDataSource(csvSep, folderPath, fileNamingStrategy);
- this.mappingPath = folderPath;
- this.extEntities = buildExtEntityMapping();
- }
-
- public ExtEntityMapping getMapping() {
- return extEntities;
- }
-
- /**
- * Method to retrieve the fields found in the source.
- *
- * @return an option for the found fields
- */
- public Optional> getSourceFields() throws SourceException {
- return dataSource.getSourceFields(ExtEntityEntry.class);
- }
-
- /**
- * Builds the mapping from CSV
- *
- * @return Mapping external id and SIMONA uuid
- */
- protected final ExtEntityMapping buildExtEntityMapping() {
- return new ExtEntityMapping(buildStream().map(this::createExtEntityEntry).toList());
- }
-
- private Stream