diff --git a/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java b/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java index 0761008a..07753b5e 100644 --- a/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java +++ b/src/main/java/edu/ie3/simona/api/ExtLinkInterface.java @@ -6,8 +6,8 @@ package edu.ie3.simona.api; +import edu.ie3.simona.api.data.ExtSimAdapterData; import edu.ie3.simona.api.exceptions.NoExtSimulationException; -import edu.ie3.simona.api.simulation.ExtSimAdapterData; import edu.ie3.simona.api.simulation.ExtSimulation; /** diff --git a/src/main/java/edu/ie3/simona/api/data/DataQueueExtSimulationExtSimulator.java b/src/main/java/edu/ie3/simona/api/data/DataQueueExtSimulationExtSimulator.java deleted file mode 100644 index 67d8cb0e..00000000 --- a/src/main/java/edu/ie3/simona/api/data/DataQueueExtSimulationExtSimulator.java +++ /dev/null @@ -1,22 +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; - -import java.util.concurrent.LinkedBlockingQueue; - -/** Data queue to allow data flow between SimonaAPI and an external simulation */ -public class DataQueueExtSimulationExtSimulator { - private final LinkedBlockingQueue receiverTriggerQueue = new LinkedBlockingQueue<>(); - - public void queueData(V data) throws InterruptedException { - this.receiverTriggerQueue.put(data); - } - - public V takeData() throws InterruptedException { - return this.receiverTriggerQueue.take(); - } -} diff --git a/src/main/java/edu/ie3/simona/api/data/ExtDataContainer.java b/src/main/java/edu/ie3/simona/api/data/ExtDataContainer.java deleted file mode 100644 index 224b9de7..00000000 --- a/src/main/java/edu/ie3/simona/api/data/ExtDataContainer.java +++ /dev/null @@ -1,10 +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 data that are exchanged between an external simulation and SimonaAPI */ -public interface ExtDataContainer {} diff --git a/src/main/java/edu/ie3/simona/api/data/ExtDataContainerQueue.java b/src/main/java/edu/ie3/simona/api/data/ExtDataContainerQueue.java new file mode 100644 index 00000000..a68c5d2f --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/ExtDataContainerQueue.java @@ -0,0 +1,35 @@ +/* + * © 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 edu.ie3.simona.api.data.container.ExtDataContainer; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.Function; + +/** Data queue to allow data flow between SimonaAPI and an external simulation */ +public final class ExtDataContainerQueue { + private final LinkedBlockingDeque receiverTriggerDeque = new LinkedBlockingDeque<>(); + + public void queueData(V data) throws InterruptedException { + receiverTriggerDeque.putLast(data); + } + + public V takeAll() throws InterruptedException { + return receiverTriggerDeque.takeFirst(); + } + + public R takeData(Function extractor) throws InterruptedException { + V data = receiverTriggerDeque.takeFirst(); + R result = extractor.apply(data); + + if (!data.isEmpty()) { + receiverTriggerDeque.putFirst(data); + } + + return result; + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java deleted file mode 100644 index 0a1430b6..00000000 --- a/src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java +++ /dev/null @@ -1,29 +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; - -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -import org.apache.pekko.actor.typed.ActorRef; - -/** - * Interface for a connection between SIMONA and an external simulation with data flow from external - * to SIMONA. - */ -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/ExtInputDataContainer.java b/src/main/java/edu/ie3/simona/api/data/ExtInputDataContainer.java deleted file mode 100644 index bec23e59..00000000 --- a/src/main/java/edu/ie3/simona/api/data/ExtInputDataContainer.java +++ /dev/null @@ -1,69 +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; - -import edu.ie3.datamodel.models.value.Value; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -/** Contains all inputs for SIMONA for a certain tick */ -public class ExtInputDataContainer implements ExtDataContainer { - - /** The tick, the input data is meant for */ - private final long tick; - - /** Map external id to an input value for SIMONA */ - private final Map dataMap; - - /** The next tick, when data will be provided, if available */ - private final Optional maybeNextTick; - - /** - * Container class for input data for SIMONA which can be read by SimonaAPI - * - * @param tick The tick, the input data is meant for - * @param dataMap data to be provided to SIMONA - * @param nextTick tick, when the next data will be provided - */ - public ExtInputDataContainer(long tick, Map dataMap, long nextTick) { - this.tick = tick; - this.dataMap = dataMap; - this.maybeNextTick = Optional.of(nextTick); - } - - public ExtInputDataContainer(long tick, Map dataMap) { - this.tick = tick; - this.dataMap = dataMap; - this.maybeNextTick = Optional.empty(); - } - - public ExtInputDataContainer(long tick) { - this(tick, new HashMap<>()); - } - - public ExtInputDataContainer(long tick, long nextTick) { - this(tick, new HashMap<>(), nextTick); - } - - public long getTick() { - return tick; - } - - public Map getSimonaInputMap() { - return dataMap; - } - - public Optional getMaybeNextTick() { - return maybeNextTick; - } - - /** Adds a value to the input map */ - public void addValue(String id, Value value) { - dataMap.put(id, value); - } -} diff --git a/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java deleted file mode 100644 index 4d9ea51a..00000000 --- a/src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java +++ /dev/null @@ -1,31 +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; - -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -import org.apache.pekko.actor.typed.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/simulation/ExtSimAdapterData.java b/src/main/java/edu/ie3/simona/api/data/ExtSimAdapterData.java similarity index 91% rename from src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java rename to src/main/java/edu/ie3/simona/api/data/ExtSimAdapterData.java index 59f81b1e..175ff38b 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ExtSimAdapterData.java +++ b/src/main/java/edu/ie3/simona/api/data/ExtSimAdapterData.java @@ -4,10 +4,10 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation; +package edu.ie3.simona.api.data; -import edu.ie3.simona.api.simulation.ontology.ControlMessageToExt; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import edu.ie3.simona.api.ontology.simulation.ControlMessageToExt; +import edu.ie3.simona.api.ontology.simulation.ControlResponseMessageFromExt; import java.util.concurrent.LinkedBlockingQueue; import org.apache.pekko.actor.typed.ActorRef; diff --git a/src/main/java/edu/ie3/simona/api/data/connection/BiDirectional.java b/src/main/java/edu/ie3/simona/api/data/connection/BiDirectional.java new file mode 100644 index 00000000..0908ec55 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/BiDirectional.java @@ -0,0 +1,54 @@ +/* + * © 2025. 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.connection; + +import edu.ie3.simona.api.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.DataResponseMessageToExt; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * Enables bidirectional communication when extended by an external data connection. + * + * @param type of message to SIMONA + * @param type of response messages to ext + */ +public abstract class BiDirectional< + M extends DataMessageFromExt, R extends DataResponseMessageToExt> + extends ExtInputDataConnection implements ExtOutputDataConnection { + + /** Data message queue containing messages from SIMONA */ + public final LinkedBlockingQueue receiveTriggerQueue = new LinkedBlockingQueue<>(); + + protected BiDirectional() { + super(); + } + + public final void queueExtResponseMsg(R msg) throws InterruptedException { + receiveTriggerQueue.put(msg); + } + + public final R receiveAny() throws InterruptedException { + return receiveTriggerQueue.take(); + } + + @SuppressWarnings("unchecked") + public final T receiveWithType(Class expectedMessageClass) + throws InterruptedException { + // blocks until actor puts something here + R msg = receiveTriggerQueue.take(); + + if (msg.getClass().equals(expectedMessageClass)) { + return (T) msg; + } else + throw new RuntimeException( + "Received unexpected message '" + + msg + + "', expected type '" + + expectedMessageClass + + "'"); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtDataConnection.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java rename to src/main/java/edu/ie3/simona/api/data/connection/ExtDataConnection.java index 9de5c6a3..7a2f53dd 100644 --- a/src/main/java/edu/ie3/simona/api/data/ExtDataConnection.java +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtDataConnection.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data; +package edu.ie3.simona.api.data.connection; /** 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/connection/ExtEmDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtEmDataConnection.java new file mode 100644 index 00000000..f1ee7857 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtEmDataConnection.java @@ -0,0 +1,132 @@ +/* + * © 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.connection; + +import edu.ie3.datamodel.models.result.system.FlexOptionsResult; +import edu.ie3.datamodel.models.value.PValue; +import edu.ie3.simona.api.data.model.em.FlexOptionRequestValue; +import edu.ie3.simona.api.data.model.em.FlexOptions; +import edu.ie3.simona.api.mapping.DataType; +import edu.ie3.simona.api.ontology.em.*; +import java.util.*; +import org.slf4j.Logger; + +/** Enables data connection of em data between SIMONA and SimonaAPI */ +public class ExtEmDataConnection + extends BiDirectional { + + public final EmMode mode; + + /** Assets that are controlled by external simulation */ + private final List controlled; + + public ExtEmDataConnection(List controlled, EmMode mode) { + super(); + + this.mode = mode; + this.controlled = controlled; + } + + /** Returns a list of the uuids of the em agents that expect external set points */ + public List getControlledEms() { + return new ArrayList<>(controlled); + } + + public boolean useCommunication() { + return mode == EmMode.EM_COMMUNICATION; + } + + public void sendFlexRequests( + long tick, Map data, Optional maybeNextTick, Logger log) { + if (data.isEmpty()) { + log.warn("No em flex requests found! Sending no em data to SIMONA for tick {}.", tick); + } else { + log.debug("Provided SIMONA with em flex requests."); + + Map> emFlexRequests = new HashMap<>(); + data.forEach((receiver, requests) -> emFlexRequests.put(receiver, requests.emEntities())); + + sendExtMsg(new ProvideFlexRequestData(tick, emFlexRequests, maybeNextTick)); + } + } + + /** + * Sends the em flex options and to SIMONA. + * + * @param tick current tick + * @param data to be sent + * @param maybeNextTick option for the next tick in the simulation + * @param log logger + */ + public void sendFlexOptions( + long tick, Map> data, Optional maybeNextTick, Logger log) { + if (data.isEmpty()) { + log.warn("No em flex options found! Sending no em data to SIMONA for tick {}.", tick); + } else { + log.debug("Provided SIMONA with em flex options."); + sendExtMsg(new ProvideEmFlexOptionData(tick, data, maybeNextTick)); + } + } + + /** + * Sends the em set points to SIMONA. + * + * @param tick current tick + * @param data to be sent + * @param maybeNextTick option for the next tick in the simulation + * @param log logger + */ + public void sendSetPoints( + long tick, Map data, Optional maybeNextTick, Logger log) { + if (data.isEmpty()) { + log.warn("No em set points found! Sending no em data to SIMONA for tick {}.", tick); + } else { + log.debug("Provided SIMONA with em set points."); + sendExtMsg(new ProvideEmSetPointData(tick, data, maybeNextTick)); + } + } + + /** + * Method to request em flexibility options from SIMONA. + * + * @param tick for which set points are requested + * @param emEntities for which set points are requested + * @return an {@link FlexOptionsResponse} message + * @throws InterruptedException - on interruptions + */ + public Map requestEmFlexResults( + long tick, Map> emEntities) throws InterruptedException { + sendExtMsg(new RequestEmFlexResults(tick, emEntities)); + return receiveWithType(FlexOptionsResponse.class).flexOptions(); + } + + public void requestCompletion(long tick) { + sendExtMsg(new RequestEmCompletion(tick)); + } + + public enum EmMode { + SET_POINT("setPoint"), + EM_COMMUNICATION("emCommunication"), + EM_OPTIMIZATION("emOptimization"), + ; + + public final String mode; + + EmMode(String mode) { + this.mode = mode; + } + + public static EmMode fromDataType(DataType dataType) { + return switch (dataType) { + case EXT_EM_INPUT -> EmMode.SET_POINT; + case EXT_EM_COMMUNICATION -> EmMode.EM_COMMUNICATION; + case EXT_EM_OPTIMIZER -> EmMode.EM_OPTIMIZATION; + default -> throw new IllegalStateException("Unexpected data type: " + dataType); + }; + } + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtEvDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtEvDataConnection.java new file mode 100644 index 00000000..c0ef8de9 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtEvDataConnection.java @@ -0,0 +1,88 @@ +/* + * © 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.connection; + +import edu.ie3.simona.api.data.model.ev.EvModel; +import edu.ie3.simona.api.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.ev.*; +import edu.ie3.simona.api.ontology.simulation.ControlResponseMessageFromExt; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.apache.pekko.actor.typed.ActorRef; + +public class ExtEvDataConnection + extends BiDirectional { + + public ExtEvDataConnection() { + super(); + } + + /** Actor reference to service that handles ev data within SIMONA */ + private ActorRef dataService; + + /** Actor reference to adapter that handles scheduler control flow in SIMONA */ + private ActorRef extSimAdapter; + + /** + * Requests currently available evcs charging stations lots from SIMONA. This method blocks until + * having received a response from SIMONA. + * + * @return a mapping from evcs uuid to the amount of available charging station lots + * @throws InterruptedException if the thread running this has been interrupted during the + * blocking operation + */ + public Map requestAvailablePublicEvcs() throws InterruptedException { + sendExtMsg(new RequestEvcsFreeLots()); + + return receiveWithType(ProvideEvcsFreeLots.class).evcs(); + } + + /** + * Requests prices at all EVCS station at current tick. This method blocks until having received a + * response from SIMONA. + * + * @return mapping from evcs uuid to current price + * @throws InterruptedException if the thread running this has been interrupted during the + * blocking operation + */ + public Map requestCurrentPrices() throws InterruptedException { + sendExtMsg(new RequestCurrentPrices()); + + return receiveWithType(ProvideCurrentPrices.class).prices(); + } + + /** + * Request the charged EVs that are departing from their charging stations at the current tick. + * SIMONA returns the charged departing vehicles with updated battery SOC. This method blocks + * until having received a response from SIMONA. + * + * @param departures the departing EV UUIDs per charging station UUID + * @return all charged departing vehicles + * @throws InterruptedException if the thread running this has been interrupted during the + * blocking operation + */ + public List requestDepartingEvs(Map> departures) + throws InterruptedException { + sendExtMsg(new RequestDepartingEvs(departures)); + + return receiveWithType(ProvideDepartingEvs.class).departedEvs(); + } + + /** + * Provide all EVs that are arriving at some charging station to SIMONA. Method returns right away + * without expecting an answer from SIMONA. + * + * @param arrivals the arriving EV models per charging station UUID + * @param maybeNextTick the next tick at which new arrivals are expected, or empty if simulation + * is about to end + */ + public void provideArrivingEvs(Map> arrivals, Optional maybeNextTick) { + sendExtMsg(new ProvideArrivingEvs(arrivals, maybeNextTick)); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtInputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtInputDataConnection.java new file mode 100644 index 00000000..56418995 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtInputDataConnection.java @@ -0,0 +1,52 @@ +/* + * © 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.connection; + +import edu.ie3.simona.api.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.ScheduleDataServiceMessage; +import edu.ie3.simona.api.ontology.simulation.ControlResponseMessageFromExt; +import org.apache.pekko.actor.typed.ActorRef; + +/** + * Abstract base class for a connection between SIMONA and an external simulation with data flow + * from external to SIMONA. + */ +public abstract class ExtInputDataConnection + implements ExtDataConnection { + + /** Actor reference to service that handles data within SIMONA */ + private ActorRef dataService; + + /** Actor reference to adapter that handles scheduler control flow in SIMONA */ + private ActorRef extSimAdapter; + + /** + * Sets the actor refs for data and control flow + * + * @param extResultDataService actor ref to the adapter of the data service for data messages + * @param extSimAdapter actor ref to the extSimAdapter + */ + public final void setActorRefs( + ActorRef extResultDataService, + ActorRef extSimAdapter) { + this.dataService = extResultDataService; + this.extSimAdapter = extSimAdapter; + } + + /** + * Send information from the external simulation to SIMONA's external data service. Furthermore, + * ExtSimAdapter within SIMONA is instructed to activate the external data service with the + * current tick. + * + * @param msg the data/information that is sent to SIMONA's result data service + */ + public final void sendExtMsg(M msg) { + dataService.tell(msg); + // we need to schedule data receiver activation with scheduler + extSimAdapter.tell(new ScheduleDataServiceMessage(dataService)); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtOutputDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtOutputDataConnection.java new file mode 100644 index 00000000..ea63cbb0 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtOutputDataConnection.java @@ -0,0 +1,35 @@ +/* + * © 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.connection; + +import edu.ie3.simona.api.ontology.DataResponseMessageToExt; + +/** + * Interface for a connection between SIMONA and an external simulation with data flow from SIMONA + * to external. + * + * @param type of response messages to ext + */ +public interface ExtOutputDataConnection { + + /** Queues message from SIMONA that should be handled by the external simulation. */ + void queueExtResponseMsg(T msg) throws InterruptedException; + + T receiveAny() throws InterruptedException; + + /** + * Waits until a message of given type is added to the queue. If the message has a different type, + * a RuntimeException is thrown. This method blocks until having received a response from SIMONA. + * + * @param expectedMessageClass the expected class of the message to be received + * @return a message of the expected type once it has been received + * @param the type of the expected message + * @throws InterruptedException if the thread running this has been interrupted during the + * blocking operation + */ + R receiveWithType(Class expectedMessageClass) throws InterruptedException; +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnection.java new file mode 100644 index 00000000..2452ee6c --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnection.java @@ -0,0 +1,55 @@ +/* + * © 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.connection; + +import edu.ie3.datamodel.models.value.Value; +import edu.ie3.simona.api.ontology.primary.PrimaryDataMessageFromExt; +import edu.ie3.simona.api.ontology.primary.ProvidePrimaryData; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.slf4j.Logger; + +/** Enables data connection of primary data between SIMONA and SimonaAPI */ +public class ExtPrimaryDataConnection extends ExtInputDataConnection { + + private final Map> valueClasses; + + public ExtPrimaryDataConnection(Map> valueClasses) { + this.valueClasses = valueClasses; + } + + /** Returns a list of the uuids of the system participants that expect external primary data */ + public List getPrimaryDataAssets() { + return valueClasses.keySet().stream().toList(); + } + + /** + * @param uuid of the model + * @return an option for the value class associated with the model. + */ + public Optional> getValueClass(UUID uuid) { + return Optional.ofNullable(valueClasses.get(uuid)); + } + + public void sendPrimaryData( + long tick, Map data, Optional maybeNextTick, Logger log) { + if (data.isEmpty()) { + log.warn("No primary data found! Sending no primary data to SIMONA for tick {}.", tick); + } else { + log.debug("Provided SIMONA with primary data."); + log.info("Data: {}", data); + provideData(tick, data, maybeNextTick); + } + } + + /** Provide primary data from an external simulation in one tick. */ + public void provideData(long tick, Map primaryData, Optional maybeNextTick) { + sendExtMsg(new ProvidePrimaryData(tick, primaryData, maybeNextTick)); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtResultDataConnection.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtResultDataConnection.java new file mode 100644 index 00000000..4015e675 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtResultDataConnection.java @@ -0,0 +1,100 @@ +/* + * © 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.connection; + +import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.simona.api.ontology.result.ProvideResultEntities; +import edu.ie3.simona.api.ontology.result.RequestResultEntities; +import edu.ie3.simona.api.ontology.result.ResultDataMessageFromExt; +import edu.ie3.simona.api.ontology.result.ResultDataResponseMessageToExt; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** Enables data connection of results between SIMONA and SimonaAPI */ +public class ExtResultDataConnection + extends BiDirectional { + + /** Map uuid to external id of grid related entities */ + private final List gridResults; + + /** Map uuid to external id of system participants */ + private final List participantResults; + + /** Map uuid to external id of participant flex options */ + private final List flexResults; + + public ExtResultDataConnection( + List participantResults, List gridResults, List flexResults) { + this.participantResults = participantResults; + this.gridResults = gridResults; + this.flexResults = flexResults; + } + + public List getGridResultDataAssets() { + return gridResults; + } + + public List getParticipantResultDataAssets() { + return participantResults; + } + + public List getFlexOptionAssets() { + return flexResults; + } + + /** Method that an external simulation can request results from SIMONA as a list. */ + private List requestResultList(long tick) throws InterruptedException { + List allExtEntities = + Stream.concat( + Stream.concat(getFlexOptionAssets().stream(), getGridResultDataAssets().stream()), + getParticipantResultDataAssets().stream()) + .toList(); + sendExtMsg(new RequestResultEntities(tick, allExtEntities)); + return receiveWithType(ProvideResultEntities.class).results(); + } + + private List requestFlexOptionResultsList(long tick) throws InterruptedException { + sendExtMsg(new RequestResultEntities(tick, getFlexOptionAssets())); + return receiveWithType(ProvideResultEntities.class).results(); + } + + private List requestGridResultsList(long tick) throws InterruptedException { + sendExtMsg(new RequestResultEntities(tick, getGridResultDataAssets())); + return receiveWithType(ProvideResultEntities.class).results(); + } + + private List requestParticipantResultsList(long tick) throws InterruptedException { + sendExtMsg(new RequestResultEntities(tick, getParticipantResultDataAssets())); + return receiveWithType(ProvideResultEntities.class).results(); + } + + /** + * Method that an external simulation can request results from SIMONA as a map string to object. + */ + public Map requestResults(long tick) throws InterruptedException { + return createResultMap(requestResultList(tick)); + } + + public Map requestFlexOptionResults(long tick) throws InterruptedException { + return createResultMap(requestFlexOptionResultsList(tick)); + } + + public Map requestGridResults(long tick) throws InterruptedException { + return createResultMap(requestGridResultsList(tick)); + } + + public Map requestParticipantResults(long tick) throws InterruptedException { + return createResultMap(requestParticipantResultsList(tick)); + } + + protected Map createResultMap(List results) { + return results.stream().collect(Collectors.toMap(ResultEntity::getInputModel, i -> i)); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/connection/ExtResultListener.java b/src/main/java/edu/ie3/simona/api/data/connection/ExtResultListener.java new file mode 100644 index 00000000..0147d10c --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/connection/ExtResultListener.java @@ -0,0 +1,49 @@ +/* + * © 2025. 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.connection; + +import edu.ie3.simona.api.ontology.result.ResultDataResponseMessageToExt; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * External result listener. This listener is similar to the {@link ExtResultDataConnection}, but is + * not able to request results from SIMONA. + */ +public class ExtResultListener implements ExtOutputDataConnection { + + /** Data message queue containing messages from SIMONA */ + public final LinkedBlockingQueue receiveTriggerQueue = + new LinkedBlockingQueue<>(); + + public ExtResultListener() {} + + public final void queueExtResponseMsg(ResultDataResponseMessageToExt msg) + throws InterruptedException { + receiveTriggerQueue.put(msg); + } + + public final ResultDataResponseMessageToExt receiveAny() throws InterruptedException { + return receiveTriggerQueue.take(); + } + + @SuppressWarnings("unchecked") + public final T receiveWithType( + Class expectedMessageClass) throws InterruptedException { + // blocks until actor puts something here + ResultDataResponseMessageToExt msg = receiveTriggerQueue.take(); + + if (msg.getClass().equals(expectedMessageClass)) { + return (T) msg; + } else + throw new RuntimeException( + "Received unexpected message '" + + msg + + "', expected type '" + + expectedMessageClass + + "'"); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/container/ExtDataContainer.java b/src/main/java/edu/ie3/simona/api/data/container/ExtDataContainer.java new file mode 100644 index 00000000..792dc0fe --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/container/ExtDataContainer.java @@ -0,0 +1,22 @@ +/* + * © 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.container; + +import java.util.HashMap; +import java.util.Map; + +/** Interface for data that are exchanged between an external simulation and SimonaAPI */ +public interface ExtDataContainer { + boolean isEmpty(); + + // private helper methods + default Map copyAndClear(Map map) { + Map result = new HashMap<>(map); + map.clear(); + return result; + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/container/ExtInputDataContainer.java b/src/main/java/edu/ie3/simona/api/data/container/ExtInputDataContainer.java new file mode 100644 index 00000000..dc14924d --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/container/ExtInputDataContainer.java @@ -0,0 +1,120 @@ +/* + * © 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.container; + +import edu.ie3.datamodel.models.value.PValue; +import edu.ie3.datamodel.models.value.Value; +import edu.ie3.simona.api.data.model.em.FlexOptionRequestValue; +import edu.ie3.simona.api.data.model.em.FlexOptions; +import java.util.*; + +/** Contains all inputs for SIMONA for a certain tick */ +public final class ExtInputDataContainer implements ExtDataContainer { + + /** The tick, the input data is meant for */ + private final long tick; + + /** The next tick, when data will be provided, if available */ + private final Optional maybeNextTick; + + // primary map + /** Map external id to primary input value for SIMONA */ + private final Map primaryData = new HashMap<>(); + + // em maps + private final Map flexRequests = new HashMap<>(); + private final Map> flexOptions = new HashMap<>(); + private final Map setPoints = new HashMap<>(); + + /** + * Container class for input data for SIMONA which can be read by SimonaAPI + * + * @param tick The tick, the input data is meant for + * @param nextTick tick, when the next data will be provided + */ + public ExtInputDataContainer(long tick, long nextTick) { + this.tick = tick; + this.maybeNextTick = Optional.of(nextTick); + } + + public ExtInputDataContainer(long tick) { + this.tick = tick; + this.maybeNextTick = Optional.empty(); + } + + @Override + public boolean isEmpty() { + return primaryData.isEmpty() + && flexRequests.isEmpty() + && flexOptions.isEmpty() + && setPoints.isEmpty(); + } + + public long getTick() { + return tick; + } + + public Optional getMaybeNextTick() { + return maybeNextTick; + } + + // add data + public void addPrimaryValue(UUID id, Value value) { + primaryData.put(id, value); + } + + public void addRequest(UUID requester, List emEntities) { + flexRequests.put(requester, new FlexOptionRequestValue(requester, emEntities)); + } + + public void addFlexOptions(UUID id, List flexOption) { + if (!flexOptions.containsKey(id)) { + List flexOptionValues = new ArrayList<>(flexOption); + flexOptions.put(id, flexOptionValues); + } else { + flexOptions.get(id).addAll(flexOption); + } + } + + public void addSetPoint(UUID id, PValue setPoint) { + setPoints.put(id, setPoint); + } + + public Map extractPrimaryData() { + return copyAndClear(primaryData); + } + + // extract and delete data + public Map extractFlexRequests() { + return copyAndClear(flexRequests); + } + + public Map> extractFlexOptions() { + return copyAndClear(flexOptions); + } + + public Map extractSetPoints() { + return copyAndClear(setPoints); + } + + // data to string + public String primaryDataString() { + return primaryData.toString(); + } + + public String flexRequestsString() { + return flexRequests.toString(); + } + + public String flexOptionsString() { + return flexOptions.toString(); + } + + public String setPointsString() { + return setPoints.toString(); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/results/ExtResultContainer.java b/src/main/java/edu/ie3/simona/api/data/container/ExtResultContainer.java similarity index 55% rename from src/main/java/edu/ie3/simona/api/data/results/ExtResultContainer.java rename to src/main/java/edu/ie3/simona/api/data/container/ExtResultContainer.java index 30ad84d1..1c71dc4f 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ExtResultContainer.java +++ b/src/main/java/edu/ie3/simona/api/data/container/ExtResultContainer.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.results; +package edu.ie3.simona.api.data.container; import static edu.ie3.util.quantities.PowerSystemUnits.PU; @@ -12,9 +12,10 @@ import edu.ie3.datamodel.models.result.ResultEntity; import edu.ie3.datamodel.models.result.connector.LineResult; import edu.ie3.datamodel.models.result.system.SystemParticipantResult; -import edu.ie3.simona.api.data.ExtDataContainer; +import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.UUID; import javax.measure.quantity.Dimensionless; import tech.units.indriya.ComparableQuantity; import tech.units.indriya.quantity.Quantities; @@ -32,28 +33,47 @@ public class ExtResultContainer implements ExtDataContainer { * Map external id to result from SIMONA ATTENTION: The time stamp of the result entities is not * necessarily corresponding to the tick */ - private final Map simonaResultsMap; + private final Map resultMap; /** * Container class for result data from SIMONA * * @param tick current tick - * @param simonaResultsMap results from SIMONA with external id as key + * @param resultMap results from SIMONA with external id as key * @param nextTick tick the external simulation can expect the next results */ - public ExtResultContainer( - long tick, Map simonaResultsMap, Optional nextTick) { + public ExtResultContainer(long tick, Map resultMap, Optional nextTick) { this.tick = tick; - this.simonaResultsMap = simonaResultsMap; + this.resultMap = resultMap; this.maybeNextTick = nextTick; } - public ExtResultContainer(long tick, Map simonaResultsMap) { - this(tick, simonaResultsMap, Optional.empty()); + public ExtResultContainer(long tick, Map resultMap) { + this(tick, resultMap, Optional.empty()); } - public Map getResults() { - return simonaResultsMap; + @Override + public boolean isEmpty() { + return resultMap.isEmpty(); + } + + public Map getResults() { + return resultMap; + } + + @SuppressWarnings("unchecked") + public Map getResults(Class clazz) { + Map result = new HashMap<>(); + + for (Map.Entry entry : resultMap.entrySet()) { + ResultEntity resultEntity = entry.getValue(); + + if (entry.getValue().getClass().equals(clazz)) { + result.put(entry.getKey(), (R) resultEntity); + } + } + + return result; } public Long getTick() { @@ -64,16 +84,34 @@ public Optional getNextTick() { return maybeNextTick; } + /** Returns the result for a certain asset. */ + public ResultEntity getResult(UUID assetId) { + return resultMap.get(assetId); + } + /** - * Returns the voltage deviation for certain asset, if this asset provided a {@link NodeResult} + * Returns the voltage deviation in pu for certain asset, if this asset provided a {@link + * NodeResult} */ - public double getVoltageDeviation(String assetId) { - if (simonaResultsMap.get(assetId) instanceof NodeResult nodeResult) { + public double getVoltageDeviation(UUID assetId) { + if (resultMap.get(assetId) instanceof NodeResult nodeResult) { ComparableQuantity vMagDev = Quantities.getQuantity(-1.0, PU).add(nodeResult.getvMag()); return vMagDev.getValue().doubleValue(); } else { - throw new IllegalArgumentException("VOLTAGE DEVIATION is only available for NodeResult's!"); + throw new IllegalArgumentException( + "VOLTAGE DEVIATION is only available for NodeResult's! AssetId: " + assetId); + } + } + + /** + * Returns the voltage deviation for certain asset, if this asset provided a {@link NodeResult} + */ + public double getVoltage(UUID assetId) { + if (resultMap.get(assetId) instanceof NodeResult nodeResult) { + return nodeResult.getvMag().getValue().doubleValue(); + } else { + throw new IllegalArgumentException("VOLTAGE is only available for NodeResult's!"); } } @@ -81,8 +119,8 @@ public double getVoltageDeviation(String assetId) { * Returns the active power in kW for certain asset, if this asset provided a {@link * SystemParticipantResult} */ - public double getActivePower(String assetId) { - if (simonaResultsMap.get(assetId) instanceof SystemParticipantResult systemParticipantResult) { + public double getActivePower(UUID assetId) { + if (resultMap.get(assetId) instanceof SystemParticipantResult systemParticipantResult) { return systemParticipantResult.getP().getValue().doubleValue(); } else { throw new IllegalArgumentException( @@ -94,8 +132,8 @@ public double getActivePower(String assetId) { * Returns the reactive power in kVAr for certain asset, if this asset provided a {@link * SystemParticipantResult} */ - public double getReactivePower(String assetId) { - if (simonaResultsMap.get(assetId) instanceof SystemParticipantResult systemParticipantResult) { + public double getReactivePower(UUID assetId) { + if (resultMap.get(assetId) instanceof SystemParticipantResult systemParticipantResult) { return systemParticipantResult.getQ().getValue().doubleValue(); } else { throw new IllegalArgumentException( @@ -104,7 +142,7 @@ public double getReactivePower(String assetId) { } /** Returns the line loading for certain asset, if this asset provided a {@link LineResult} */ - public double getLineLoading(String assetId) { + public double getLineLoading(UUID assetId) { throw new IllegalArgumentException("LINE LOADING is not implemented yet!"); } } diff --git a/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java b/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java deleted file mode 100644 index 6079a2eb..00000000 --- a/src/main/java/edu/ie3/simona/api/data/em/ExtEmDataConnection.java +++ /dev/null @@ -1,88 +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.em; - -import edu.ie3.datamodel.models.value.PValue; -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.DataMessageFromExt; -import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; -import org.apache.pekko.actor.typed.ActorRef; -import org.slf4j.Logger; - -/** Enables data connection of em data between SIMONA and SimonaAPI */ -public class ExtEmDataConnection implements ExtInputDataConnection { - - /** Actor reference to service that handles ev data within SIMONA */ - private ActorRef emDataService; - - /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; - - /** Assets that provide primary data to SIMONA */ - private final Map extEmMapping; - - public ExtEmDataConnection(Map extEmMapping) { - this.extEmMapping = extEmMapping; - } - - @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(); - } - - /** Provide primary data from an external simulation for one tick. */ - public void provideEmData(Long tick, Map emData, Optional maybeNextTick) { - sendExtMsg(new ProvideEmSetPointData(tick, emData, maybeNextTick)); - } - - /** - * Send information from the external simulation to SIMONA's external primary data service. - * Furthermore, ExtSimAdapter within SIMONA is instructed to activate the ev data service with the - * current tick. - * - * @param msg the data/information that is sent to SIMONA's external primary data service - */ - public void sendExtMsg(EmDataMessageFromExt msg) { - emDataService.tell(msg); - // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(emDataService)); - } -} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java b/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java deleted file mode 100644 index 564a87ad..00000000 --- a/src/main/java/edu/ie3/simona/api/data/ev/ExtEvDataConnection.java +++ /dev/null @@ -1,150 +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.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.DataMessageFromExt; -import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -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.typed.ActorRef; - -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 ActorRef dataService; - - /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; - - @Override - public void setActorRefs( - ActorRef dataService, - ActorRef extSimAdapter) { - this.dataService = dataService; - this.extSimAdapter = extSimAdapter; - } - - /** - * Requests currently available evcs charging stations lots from SIMONA. This method blocks until - * having received a response from SIMONA. - * - * @return a mapping from evcs uuid to the amount of available charging station lots - * @throws InterruptedException if the thread running this has been interrupted during the - * blocking operation - */ - public Map requestAvailablePublicEvcs() throws InterruptedException { - sendExtMsg(new RequestEvcsFreeLots()); - - return receiveWithType(ProvideEvcsFreeLots.class).evcs(); - } - - /** - * Requests prices at all EVCS station at current tick. This method blocks until having received a - * response from SIMONA. - * - * @return mapping from evcs uuid to current price - * @throws InterruptedException if the thread running this has been interrupted during the - * blocking operation - */ - public Map requestCurrentPrices() throws InterruptedException { - sendExtMsg(new RequestCurrentPrices()); - - return receiveWithType(ProvideCurrentPrices.class).prices(); - } - - /** - * Request the charged EVs that are departing from their charging stations at the current tick. - * SIMONA returns the charged departing vehicles with updated battery SOC. This method blocks - * until having received a response from SIMONA. - * - * @param departures the departing EV UUIDs per charging station UUID - * @return all charged departing vehicles - * @throws InterruptedException if the thread running this has been interrupted during the - * blocking operation - */ - public List requestDepartingEvs(Map> departures) - throws InterruptedException { - sendExtMsg(new RequestDepartingEvs(departures)); - - return receiveWithType(ProvideDepartingEvs.class).departedEvs(); - } - - /** - * Provide all EVs that are arriving at some charging station to SIMONA. Method returns right away - * without expecting an answer from SIMONA. - * - * @param arrivals the arriving EV models per charging station UUID - * @param maybeNextTick the next tick at which new arrivals are expected, or empty if simulation - * is about to end - */ - public void provideArrivingEvs(Map> arrivals, Optional maybeNextTick) { - sendExtMsg(new ProvideArrivingEvs(arrivals, maybeNextTick)); - } - - /** - * Send information from the external ev simulation to SIMONA's ev data service. Furthermore, - * ExtSimAdapter within SIMONA is instructed to activate the ev data service with the current - * tick. - * - * @param msg the data/information that is sent to SIMONA's ev data service - */ - public void sendExtMsg(EvDataMessageFromExt msg) { - dataService.tell(msg); - // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataService)); - } - - /** - * Queues message from SIMONA that should be handled by the external ev simulation. - * - * @param extEvResponse the message to be handled - * @throws InterruptedException if the thread running this has been interrupted during waiting for - * the message to be queued - */ - public void queueExtResponseMsg(EvDataResponseMessageToExt extEvResponse) - throws InterruptedException { - receiveTriggerQueue.put(extEvResponse); - } - - /** - * Waits until a message of given type is added to the queue. If the message has a different type, - * a RuntimeException is thrown. This method blocks until having received a response from SIMONA. - * - * @param expectedMessageClass the expected class of the message to be received - * @return a message of the expected type once it has been received - * @param the type of the expected message - * @throws InterruptedException if the thread running this has been interrupted during the - * blocking operation - */ - @SuppressWarnings("unchecked") - private T receiveWithType(Class expectedMessageClass) - throws InterruptedException { - - // blocks until actor puts something here - EvDataResponseMessageToExt evMessage = receiveTriggerQueue.take(); - - if (evMessage.getClass().equals(expectedMessageClass)) { - return (T) evMessage; - } else - throw new RuntimeException( - "Received unexpected message '" - + evMessage - + "', expected type '" - + expectedMessageClass - + "'"); - } -} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/EmSetPointResult.java b/src/main/java/edu/ie3/simona/api/data/model/em/EmSetPointResult.java new file mode 100644 index 00000000..cbe72fff --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/EmSetPointResult.java @@ -0,0 +1,40 @@ +/* + * © 2025. 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.model.em; + +import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.value.PValue; +import java.time.ZonedDateTime; +import java.util.Optional; +import java.util.UUID; + +/** Em set point result. */ +public class EmSetPointResult extends ResultEntity { + + private final PValue setPoint; + + public EmSetPointResult(ZonedDateTime time, UUID inputModel, PValue setPoint) { + super(time, inputModel); + this.setPoint = setPoint; + } + + public Optional getSetPoint() { + return Optional.ofNullable(setPoint); + } + + @Override + public String toString() { + return "EmSetPointResult{" + + "time=" + + getTime() + + ", inputModel=" + + getInputModel() + + ", setPoint=" + + getSetPoint() + + '}'; + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionRequestValue.java b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionRequestValue.java new file mode 100644 index 00000000..ec9a9a3a --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionRequestValue.java @@ -0,0 +1,13 @@ +/* + * © 2025. 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.model.em; + +import edu.ie3.datamodel.models.value.Value; +import java.util.List; +import java.util.UUID; + +public record FlexOptionRequestValue(UUID requester, List emEntities) implements Value {} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionValue.java b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionValue.java new file mode 100644 index 00000000..c32cc06b --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptionValue.java @@ -0,0 +1,13 @@ +/* + * © 2025. 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.model.em; + +import edu.ie3.datamodel.models.value.Value; +import java.util.Map; +import java.util.UUID; + +public record FlexOptionValue(Map flexOptions) implements Value {} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptions.java b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptions.java new file mode 100644 index 00000000..abc10063 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/FlexOptions.java @@ -0,0 +1,17 @@ +/* + * © 2025. 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.model.em; + +import java.util.UUID; +import javax.measure.quantity.Power; +import tech.units.indriya.ComparableQuantity; + +public record FlexOptions( + UUID sender, + ComparableQuantity pMin, + ComparableQuantity pRef, + ComparableQuantity pMax) {} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/FlexRequestResult.java b/src/main/java/edu/ie3/simona/api/data/model/em/FlexRequestResult.java new file mode 100644 index 00000000..7843e816 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/FlexRequestResult.java @@ -0,0 +1,24 @@ +/* + * © 2025. 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.model.em; + +import edu.ie3.datamodel.models.result.ResultEntity; +import java.time.ZonedDateTime; +import java.util.UUID; + +public class FlexRequestResult extends ResultEntity { + + /** + * Standard constructor which includes auto generation of the resulting output models uuid. + * + * @param time date and time when the result is produced + * @param inputModel uuid of the input model that produces the result + */ + public FlexRequestResult(ZonedDateTime time, UUID inputModel) { + super(time, inputModel); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/model/em/NoSetPointValue.java b/src/main/java/edu/ie3/simona/api/data/model/em/NoSetPointValue.java new file mode 100644 index 00000000..62d94c18 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/data/model/em/NoSetPointValue.java @@ -0,0 +1,17 @@ +/* + * © 2025. 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.model.em; + +import edu.ie3.datamodel.models.value.PValue; +import javax.measure.quantity.Power; +import tech.units.indriya.ComparableQuantity; + +public class NoSetPointValue extends PValue { + public NoSetPointValue(ComparableQuantity p) { + super(p); + } +} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/model/EvModel.java b/src/main/java/edu/ie3/simona/api/data/model/ev/EvModel.java similarity index 96% rename from src/main/java/edu/ie3/simona/api/data/ev/model/EvModel.java rename to src/main/java/edu/ie3/simona/api/data/model/ev/EvModel.java index 2ea3082d..04c1fd05 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/model/EvModel.java +++ b/src/main/java/edu/ie3/simona/api/data/model/ev/EvModel.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.model; +package edu.ie3.simona.api.data.model.ev; import java.util.UUID; import javax.measure.quantity.Energy; diff --git a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java b/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java deleted file mode 100644 index ce03e274..00000000 --- a/src/main/java/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnection.java +++ /dev/null @@ -1,88 +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.primarydata; - -import edu.ie3.datamodel.models.value.Value; -import edu.ie3.simona.api.data.ExtInputDataConnection; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; -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 edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; -import org.apache.pekko.actor.typed.ActorRef; -import org.slf4j.Logger; - -/** Enables data connection of primary data between SIMONA and SimonaAPI */ -public class ExtPrimaryDataConnection implements ExtInputDataConnection { - - /** Actor reference to service that handles primary data within SIMONA */ - private ActorRef dataService; - - /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; - - /** Assets that provide primary data to SIMONA */ - private final Map extPrimaryDataMapping; - - public ExtPrimaryDataConnection(Map extPrimaryDataMapping) { - this.extPrimaryDataMapping = extPrimaryDataMapping; - } - - @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(); - } - - /** Provide primary data from an external simulation in one tick. */ - public void providePrimaryData( - Long tick, Map primaryData, Optional maybeNextTick) { - sendExtMsg(new ProvidePrimaryData(tick, primaryData, maybeNextTick)); - } - - /** - * Send information from the external simulation to SIMONA's external primary data service. - * Furthermore, ExtSimAdapter within SIMONA is instructed to activate the ev data service with the - * current tick. - * - * @param msg the data/information that is sent to SIMONA's external primary data service - */ - public void sendExtMsg(PrimaryDataMessageFromExt msg) { - dataService.tell(msg); - // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataService)); - } -} diff --git a/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java b/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java deleted file mode 100644 index 3a93a7f2..00000000 --- a/src/main/java/edu/ie3/simona/api/data/results/ExtResultDataConnection.java +++ /dev/null @@ -1,156 +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.results; - -import edu.ie3.datamodel.models.result.NodeResult; -import edu.ie3.datamodel.models.result.ResultEntity; -import edu.ie3.datamodel.models.result.system.SystemParticipantResult; -import edu.ie3.simona.api.data.ExtOutputDataConnection; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; -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; -import edu.ie3.simona.api.data.results.ontology.ResultDataMessageFromExt; -import edu.ie3.simona.api.data.results.ontology.ResultDataResponseMessageToExt; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.LinkedBlockingQueue; -import org.apache.pekko.actor.typed.ActorRef; - -/** Enables data connection of results between SIMONA and SimonaAPI */ -public class ExtResultDataConnection implements ExtOutputDataConnection { - - /** Data message queue containing messages from SIMONA */ - public final LinkedBlockingQueue receiveTriggerQueue = - new LinkedBlockingQueue<>(); - - /** Actor reference to service that handles result data within SIMONA */ - private ActorRef extResultDataService; - - /** Actor reference to the dataServiceAdapter */ - private ActorRef dataServiceActivation; - - /** Actor reference to adapter that handles scheduler control flow in SIMONA */ - private ActorRef extSimAdapter; - - /** Map uuid to external id of grid related entities */ - private final Map gridResultAssetMapping; - - /** Map uuid to external id of system participants */ - private final Map participantResultAssetMapping; - - public ExtResultDataConnection( - Map participantResultAssetMapping, Map gridResultAssetMapping) { - this.participantResultAssetMapping = participantResultAssetMapping; - this.gridResultAssetMapping = gridResultAssetMapping; - } - - /** - * 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 - */ - public void setActorRefs( - ActorRef extResultDataService, - ActorRef dataServiceActivation, - ActorRef extSimAdapter) { - this.extResultDataService = extResultDataService; - this.dataServiceActivation = dataServiceActivation; - this.extSimAdapter = extSimAdapter; - } - - public List getGridResultDataAssets() { - return gridResultAssetMapping.keySet().stream().toList(); - } - - public List getParticipantResultDataAssets() { - return participantResultAssetMapping.keySet().stream().toList(); - } - - /** Method that an external simulation can request results from SIMONA as a list. */ - private List requestResultList(long tick) throws InterruptedException { - sendExtMsg(new RequestResultEntities(tick)); - return receiveWithType(ProvideResultEntities.class).results(); - } - - /** - * Method that an external simulation can request results from SIMONA as a map string to object. - */ - public Map requestResults(long tick) throws InterruptedException { - return createResultMap(requestResultList(tick)); - } - - protected Map createResultMap(List results) { - Map resultMap = new HashMap<>(); - results.forEach( - result -> { - if (result instanceof NodeResult nodeResult) { - resultMap.put(gridResultAssetMapping.get(nodeResult.getInputModel()), nodeResult); - } else if (result instanceof SystemParticipantResult systemParticipantResult) { - resultMap.put( - participantResultAssetMapping.get(systemParticipantResult.getInputModel()), - systemParticipantResult); - } else { - throw new IllegalArgumentException( - "ExtResultData can only handle NodeResult's and SystemParticipantResult's!"); - } - }); - return resultMap; - } - - /** - * Send information from the external simulation to SIMONA's external data service. Furthermore, - * ExtSimAdapter within SIMONA is instructed to activate the external data service with the - * current tick. - * - * @param msg the data/information that is sent to SIMONA's result data service - */ - public void sendExtMsg(ResultDataMessageFromExt msg) { - extResultDataService.tell(msg); - // we need to schedule data receiver activation with scheduler - extSimAdapter.tell(new ScheduleDataServiceMessage(dataServiceActivation)); - } - - /** Queues message from SIMONA that should be handled by the external simulation. */ - public void queueExtResponseMsg(ResultDataResponseMessageToExt msg) throws InterruptedException { - receiveTriggerQueue.put(msg); - } - - /** - * Waits until a message of given type is added to the queue. If the message has a different type, - * a RuntimeException is thrown. This method blocks until having received a response from SIMONA. - * - * @param expectedMessageClass the expected class of the message to be received - * @return a message of the expected type once it has been received - * @param the type of the expected message - * @throws InterruptedException if the thread running this has been interrupted during the - * blocking operation - */ - @SuppressWarnings("unchecked") - private T receiveWithType( - Class expectedMessageClass) throws InterruptedException { - - // blocks until actor puts something here - ResultDataResponseMessageToExt msg = receiveTriggerQueue.take(); - - if (msg.getClass().equals(expectedMessageClass)) { - return (T) msg; - } else - throw new RuntimeException( - "Received unexpected message '" - + msg - + "', expected type '" - + expectedMessageClass - + "'"); - } -} diff --git a/src/main/java/edu/ie3/simona/api/exceptions/ExtDataConnectionException.java b/src/main/java/edu/ie3/simona/api/exceptions/ExtDataConnectionException.java new file mode 100644 index 00000000..e409729c --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/exceptions/ExtDataConnectionException.java @@ -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.api.exceptions; + +import edu.ie3.simona.api.data.connection.ExtDataConnection; + +public class ExtDataConnectionException extends RuntimeException { + + public ExtDataConnectionException(Class connectionClass) { + this( + "The external data connection '" + + connectionClass.getSimpleName() + + "' could not be build!"); + } + + public ExtDataConnectionException(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 index f4a242b3..9c403556 100644 --- a/src/main/java/edu/ie3/simona/api/exceptions/NoExtSimulationException.java +++ b/src/main/java/edu/ie3/simona/api/exceptions/NoExtSimulationException.java @@ -11,7 +11,10 @@ public class NoExtSimulationException extends RuntimeException { public NoExtSimulationException(Class linkClass) { - this("No external simulation was set up in ExtLinkInterface: ." + linkClass.getSimpleName()); + this( + "No external simulation was set up in ExtLinkInterface: " + + linkClass.getSimpleName() + + "."); } public NoExtSimulationException(final String message) { diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java b/src/main/java/edu/ie3/simona/api/mapping/DataType.java similarity index 75% rename from src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java rename to src/main/java/edu/ie3/simona/api/mapping/DataType.java index 67bfaa12..42794233 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/mapping/DataType.java +++ b/src/main/java/edu/ie3/simona/api/mapping/DataType.java @@ -4,15 +4,18 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.mapping; +package edu.ie3.simona.api.mapping; import edu.ie3.datamodel.exceptions.ParsingException; public enum DataType { EXT_PRIMARY_INPUT("primary_input"), EXT_EM_INPUT("em_input"), + EXT_EM_COMMUNICATION("em_communication"), + EXT_EM_OPTIMIZER("em_optimizer"), EXT_GRID_RESULT("grid_result"), - EXT_PARTICIPANT_RESULT("participant_result"); + EXT_PARTICIPANT_RESULT("participant_result"), + EXT_FLEX_OPTIONS_RESULT("flex_options_result"); public final String type; @@ -26,6 +29,7 @@ public static DataType parse(String type) throws ParsingException { case "em_input" -> EXT_EM_INPUT; case "grid_result" -> EXT_GRID_RESULT; case "participant_result" -> EXT_PARTICIPANT_RESULT; + case "flex_options_result" -> EXT_FLEX_OPTIONS_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/mapping/ExtEntityEntry.java similarity index 76% rename from src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java rename to src/main/java/edu/ie3/simona/api/mapping/ExtEntityEntry.java index 1444c3e1..f07f5171 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityEntry.java +++ b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityEntry.java @@ -4,10 +4,11 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.mapping; +package edu.ie3.simona.api.mapping; import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme; import edu.ie3.datamodel.models.input.InputEntity; +import java.util.Optional; import java.util.UUID; /** @@ -15,14 +16,11 @@ * * @param uuid SIMONA uuid * @param id external id - * @param columnScheme data types the external asset expects + * @param columnScheme option for 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 - DataType dataType) + UUID uuid, String id, Optional columnScheme, DataType dataType) implements InputEntity { public String toString() { diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityFactory.java similarity index 86% rename from src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java rename to src/main/java/edu/ie3/simona/api/mapping/ExtEntityFactory.java index 9a820258..86829cde 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityFactory.java +++ b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityFactory.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.mapping; +package edu.ie3.simona.api.mapping; import edu.ie3.datamodel.exceptions.FactoryException; import edu.ie3.datamodel.exceptions.ParsingException; @@ -46,11 +46,6 @@ protected ExtEntityEntry buildModel(EntityData data) { throw new FactoryException(e); } - return new ExtEntityEntry( - simonaUuid, - extId, - columnScheme - .orElseThrow(), // FIXME: Interim version -> ColumnScheme should handle more data types - inputType); + return new ExtEntityEntry(simonaUuid, extId, columnScheme, inputType); } } diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityMapping.java similarity index 96% rename from src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java rename to src/main/java/edu/ie3/simona/api/mapping/ExtEntityMapping.java index 8fd033e6..0201a921 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMapping.java +++ b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityMapping.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.mapping; +package edu.ie3.simona.api.mapping; import java.util.*; import java.util.stream.Collectors; diff --git a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSource.java b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityMappingSource.java similarity index 98% rename from src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSource.java rename to src/main/java/edu/ie3/simona/api/mapping/ExtEntityMappingSource.java index 1d24d7ff..f540f1c9 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSource.java +++ b/src/main/java/edu/ie3/simona/api/mapping/ExtEntityMappingSource.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.mapping; +package edu.ie3.simona.api.mapping; import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.EntityData; diff --git a/src/main/java/edu/ie3/simona/api/data/ontology/DataMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/DataMessageFromExt.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ontology/DataMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/DataMessageFromExt.java index 66a79ed9..14a0a5f5 100644 --- a/src/main/java/edu/ie3/simona/api/data/ontology/DataMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/DataMessageFromExt.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ontology; +package edu.ie3.simona.api.ontology; /** Data related messages that are sent from the external simulation to SIMONA */ public interface DataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ontology/DataResponseMessageToExt.java b/src/main/java/edu/ie3/simona/api/ontology/DataResponseMessageToExt.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ontology/DataResponseMessageToExt.java rename to src/main/java/edu/ie3/simona/api/ontology/DataResponseMessageToExt.java index 2eb2f29c..a191eaf2 100644 --- a/src/main/java/edu/ie3/simona/api/data/ontology/DataResponseMessageToExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/DataResponseMessageToExt.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ontology; +package edu.ie3.simona.api.ontology; /** Data related messages that are sent from SIMONA to the external simulation */ public interface DataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java b/src/main/java/edu/ie3/simona/api/ontology/ScheduleDataServiceMessage.java similarity index 77% rename from src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java rename to src/main/java/edu/ie3/simona/api/ontology/ScheduleDataServiceMessage.java index 029b840d..4cc0fc98 100644 --- a/src/main/java/edu/ie3/simona/api/data/ontology/ScheduleDataServiceMessage.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ScheduleDataServiceMessage.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ontology; +package edu.ie3.simona.api.ontology; -import edu.ie3.simona.api.simulation.ontology.ControlResponseMessageFromExt; +import edu.ie3.simona.api.ontology.simulation.ControlResponseMessageFromExt; import org.apache.pekko.actor.typed.ActorRef; public record ScheduleDataServiceMessage(ActorRef dataService) diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/EmCompletion.java b/src/main/java/edu/ie3/simona/api/ontology/em/EmCompletion.java new file mode 100644 index 00000000..100de1bd --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/EmCompletion.java @@ -0,0 +1,9 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +public record EmCompletion() implements EmDataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/em/ontology/EmDataMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/em/EmDataMessageFromExt.java similarity index 76% rename from src/main/java/edu/ie3/simona/api/data/em/ontology/EmDataMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/em/EmDataMessageFromExt.java index 5125e292..7d2376c0 100644 --- a/src/main/java/edu/ie3/simona/api/data/em/ontology/EmDataMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/em/EmDataMessageFromExt.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.em.ontology; +package edu.ie3.simona.api.ontology.em; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.DataMessageFromExt; /** Messages that are sent from an external data simulation which provides em data to SIMONA */ public interface EmDataMessageFromExt extends DataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/EmDataResponseMessageToExt.java b/src/main/java/edu/ie3/simona/api/ontology/em/EmDataResponseMessageToExt.java new file mode 100644 index 00000000..71f0d800 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/EmDataResponseMessageToExt.java @@ -0,0 +1,11 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import edu.ie3.simona.api.ontology.DataResponseMessageToExt; + +public interface EmDataResponseMessageToExt extends DataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/EmSetPointDataResponse.java b/src/main/java/edu/ie3/simona/api/ontology/em/EmSetPointDataResponse.java new file mode 100644 index 00000000..c7a6c6e5 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/EmSetPointDataResponse.java @@ -0,0 +1,15 @@ +/* + * © 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.ontology.em; + +import edu.ie3.simona.api.data.model.em.EmSetPointResult; +import java.util.Map; +import java.util.UUID; + +/** Message that provides em data (set points) to an external simulation. */ +public record EmSetPointDataResponse(Map emData) + implements EmDataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/FlexOptionsResponse.java b/src/main/java/edu/ie3/simona/api/ontology/em/FlexOptionsResponse.java new file mode 100644 index 00000000..6fe7bdea --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/FlexOptionsResponse.java @@ -0,0 +1,15 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import edu.ie3.datamodel.models.result.system.FlexOptionsResult; +import java.util.Map; +import java.util.UUID; + +/** Message that provides em data (flexibility options) to an external simulation. */ +public record FlexOptionsResponse(Map flexOptions) + implements EmDataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/FlexRequestResponse.java b/src/main/java/edu/ie3/simona/api/ontology/em/FlexRequestResponse.java new file mode 100644 index 00000000..69f8a1c4 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/FlexRequestResponse.java @@ -0,0 +1,15 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import edu.ie3.simona.api.data.model.em.FlexRequestResult; +import java.util.Map; +import java.util.UUID; + +/** Message that provides em data (flexibility requests) to an external simulation. */ +public record FlexRequestResponse(Map flexRequests) + implements EmDataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmFlexOptionData.java b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmFlexOptionData.java new file mode 100644 index 00000000..3d8d0e53 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmFlexOptionData.java @@ -0,0 +1,18 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import edu.ie3.simona.api.data.model.em.FlexOptions; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** Message that provides em data (flexibility options) from an external simulation. */ +public record ProvideEmFlexOptionData( + long tick, Map> flexOptions, Optional maybeNextTick) + implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/em/ontology/ProvideEmSetPointData.java b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmSetPointData.java similarity index 89% rename from src/main/java/edu/ie3/simona/api/data/em/ontology/ProvideEmSetPointData.java rename to src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmSetPointData.java index dc505dca..f9c6ae7c 100644 --- a/src/main/java/edu/ie3/simona/api/data/em/ontology/ProvideEmSetPointData.java +++ b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideEmSetPointData.java @@ -4,14 +4,14 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.em.ontology; +package edu.ie3.simona.api.ontology.em; import edu.ie3.datamodel.models.value.PValue; import java.util.Map; import java.util.Optional; import java.util.UUID; -/** Message that provides em data (set points) from an external simulation */ +/** Message that provides em data (set points) from an external simulation. */ public record ProvideEmSetPointData( long tick, Map emData, Optional maybeNextTick) implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/ProvideFlexRequestData.java b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideFlexRequestData.java new file mode 100644 index 00000000..119b8e43 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/ProvideFlexRequestData.java @@ -0,0 +1,17 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +/** Message that provides em data (flex requests) from an external simulation. */ +public record ProvideFlexRequestData( + long tick, Map> flexRequests, Optional maybeNextTick) + implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/RequestControlledEmFlexResults.java b/src/main/java/edu/ie3/simona/api/ontology/em/RequestControlledEmFlexResults.java new file mode 100644 index 00000000..e701b391 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/RequestControlledEmFlexResults.java @@ -0,0 +1,14 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import java.util.Set; +import java.util.UUID; + +/** Request em set flex options from SIMONA via external simulation. */ +public record RequestControlledEmFlexResults(Set emEntities) + implements EmDataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmCompletion.java b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmCompletion.java new file mode 100644 index 00000000..209d8e20 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmCompletion.java @@ -0,0 +1,9 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +public record RequestEmCompletion(long tick) implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmFlexResults.java b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmFlexResults.java new file mode 100644 index 00000000..b90a7a83 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmFlexResults.java @@ -0,0 +1,15 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** Request em set points from SIMONA in the given tick. */ +public record RequestEmFlexResults(long tick, Map> emEntities) + implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmSetPoints.java b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmSetPoints.java new file mode 100644 index 00000000..b143c838 --- /dev/null +++ b/src/main/java/edu/ie3/simona/api/ontology/em/RequestEmSetPoints.java @@ -0,0 +1,14 @@ +/* + * © 2025. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ + +package edu.ie3.simona.api.ontology.em; + +import java.util.List; +import java.util.UUID; + +/** Request em set points from SIMONA in the given tick. */ +public record RequestEmSetPoints(long tick, List emEntities) + implements EmDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/ev/EvDataMessageFromExt.java similarity index 70% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/EvDataMessageFromExt.java index 2eb04bdf..a3c71012 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/EvDataMessageFromExt.java @@ -4,8 +4,8 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.DataMessageFromExt; public interface EvDataMessageFromExt extends DataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataResponseMessageToExt.java b/src/main/java/edu/ie3/simona/api/ontology/ev/EvDataResponseMessageToExt.java similarity index 74% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataResponseMessageToExt.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/EvDataResponseMessageToExt.java index 59a49503..b5ed6c4e 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/EvDataResponseMessageToExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/EvDataResponseMessageToExt.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; -import edu.ie3.simona.api.data.ontology.DataResponseMessageToExt; +import edu.ie3.simona.api.ontology.DataResponseMessageToExt; /** Messages that are sent from SIMONA to the external ev simulation */ public interface EvDataResponseMessageToExt extends DataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideArrivingEvs.java b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideArrivingEvs.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideArrivingEvs.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/ProvideArrivingEvs.java index da9b5724..8ec7e1ff 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideArrivingEvs.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideArrivingEvs.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; -import edu.ie3.simona.api.data.ev.model.EvModel; +import edu.ie3.simona.api.data.model.ev.EvModel; import java.util.List; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideCurrentPrices.java b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideCurrentPrices.java similarity index 92% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideCurrentPrices.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/ProvideCurrentPrices.java index 9688d621..24bfe58a 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideCurrentPrices.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideCurrentPrices.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideDepartingEvs.java b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideDepartingEvs.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideDepartingEvs.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/ProvideDepartingEvs.java index 4f1e5637..df71882b 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideDepartingEvs.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideDepartingEvs.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; -import edu.ie3.simona.api.data.ev.model.EvModel; +import edu.ie3.simona.api.data.model.ev.EvModel; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideEvcsFreeLots.java b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideEvcsFreeLots.java similarity index 93% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideEvcsFreeLots.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/ProvideEvcsFreeLots.java index 29264570..b2e27129 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/ProvideEvcsFreeLots.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/ProvideEvcsFreeLots.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestCurrentPrices.java b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestCurrentPrices.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestCurrentPrices.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/RequestCurrentPrices.java index f16adfb9..6a158446 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestCurrentPrices.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestCurrentPrices.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; /** Request current charging prices per charging station. */ public record RequestCurrentPrices() implements EvDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestDepartingEvs.java b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestDepartingEvs.java similarity index 92% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestDepartingEvs.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/RequestDepartingEvs.java index 7aabcb06..398277a4 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestDepartingEvs.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestDepartingEvs.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; import java.util.List; import java.util.Map; diff --git a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestEvcsFreeLots.java b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestEvcsFreeLots.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestEvcsFreeLots.java rename to src/main/java/edu/ie3/simona/api/ontology/ev/RequestEvcsFreeLots.java index b394f5b0..57d5f67b 100644 --- a/src/main/java/edu/ie3/simona/api/data/ev/ontology/RequestEvcsFreeLots.java +++ b/src/main/java/edu/ie3/simona/api/ontology/ev/RequestEvcsFreeLots.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.ev.ontology; +package edu.ie3.simona.api.ontology.ev; /** Request the number of free lots per charging station from SIMONA */ public record RequestEvcsFreeLots() implements EvDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/primarydata/ontology/PrimaryDataMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/primary/PrimaryDataMessageFromExt.java similarity index 74% rename from src/main/java/edu/ie3/simona/api/data/primarydata/ontology/PrimaryDataMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/primary/PrimaryDataMessageFromExt.java index e7eb7ae6..529cb275 100644 --- a/src/main/java/edu/ie3/simona/api/data/primarydata/ontology/PrimaryDataMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/primary/PrimaryDataMessageFromExt.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.primarydata.ontology; +package edu.ie3.simona.api.ontology.primary; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.DataMessageFromExt; /** Messages that are sent from an external primary data simulation to SIMONA */ public interface PrimaryDataMessageFromExt extends DataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/primarydata/ontology/ProvidePrimaryData.java b/src/main/java/edu/ie3/simona/api/ontology/primary/ProvidePrimaryData.java similarity index 90% rename from src/main/java/edu/ie3/simona/api/data/primarydata/ontology/ProvidePrimaryData.java rename to src/main/java/edu/ie3/simona/api/ontology/primary/ProvidePrimaryData.java index 2c316323..9b3382df 100644 --- a/src/main/java/edu/ie3/simona/api/data/primarydata/ontology/ProvidePrimaryData.java +++ b/src/main/java/edu/ie3/simona/api/ontology/primary/ProvidePrimaryData.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.primarydata.ontology; +package edu.ie3.simona.api.ontology.primary; import edu.ie3.datamodel.models.value.Value; import java.util.Map; diff --git a/src/main/java/edu/ie3/simona/api/data/results/ontology/ProvideResultEntities.java b/src/main/java/edu/ie3/simona/api/ontology/result/ProvideResultEntities.java similarity index 92% rename from src/main/java/edu/ie3/simona/api/data/results/ontology/ProvideResultEntities.java rename to src/main/java/edu/ie3/simona/api/ontology/result/ProvideResultEntities.java index 0c0d003f..dc1ad242 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ontology/ProvideResultEntities.java +++ b/src/main/java/edu/ie3/simona/api/ontology/result/ProvideResultEntities.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.results.ontology; +package edu.ie3.simona.api.ontology.result; import edu.ie3.datamodel.models.result.ResultEntity; import java.util.List; diff --git a/src/main/java/edu/ie3/simona/api/data/results/ontology/RequestResultEntities.java b/src/main/java/edu/ie3/simona/api/ontology/result/RequestResultEntities.java similarity index 53% rename from src/main/java/edu/ie3/simona/api/data/results/ontology/RequestResultEntities.java rename to src/main/java/edu/ie3/simona/api/ontology/result/RequestResultEntities.java index 8ef656b0..4d97c6d5 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ontology/RequestResultEntities.java +++ b/src/main/java/edu/ie3/simona/api/ontology/result/RequestResultEntities.java @@ -4,7 +4,11 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.results.ontology; +package edu.ie3.simona.api.ontology.result; + +import java.util.List; +import java.util.UUID; /** Request calculated results from SIMONA in the current tick */ -public record RequestResultEntities(Long tick) implements ResultDataMessageFromExt {} +public record RequestResultEntities(long tick, List requestedResults) + implements ResultDataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/result/ResultDataMessageFromExt.java similarity index 74% rename from src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/result/ResultDataMessageFromExt.java index 83b2e318..13fa9ce3 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/result/ResultDataMessageFromExt.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.results.ontology; +package edu.ie3.simona.api.ontology.result; -import edu.ie3.simona.api.data.ontology.DataMessageFromExt; +import edu.ie3.simona.api.ontology.DataMessageFromExt; /** Messages that are sent from an external simulation to the SIMONA */ public interface ResultDataMessageFromExt extends DataMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataResponseMessageToExt.java b/src/main/java/edu/ie3/simona/api/ontology/result/ResultDataResponseMessageToExt.java similarity index 75% rename from src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataResponseMessageToExt.java rename to src/main/java/edu/ie3/simona/api/ontology/result/ResultDataResponseMessageToExt.java index 311ff1f4..a01dd96a 100644 --- a/src/main/java/edu/ie3/simona/api/data/results/ontology/ResultDataResponseMessageToExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/result/ResultDataResponseMessageToExt.java @@ -4,9 +4,9 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.data.results.ontology; +package edu.ie3.simona.api.ontology.result; -import edu.ie3.simona.api.data.ontology.DataResponseMessageToExt; +import edu.ie3.simona.api.ontology.DataResponseMessageToExt; /** Messages that are sent from SIMONA to the external simulation that needs results */ public interface ResultDataResponseMessageToExt extends DataResponseMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/ActivationMessage.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/ActivationMessage.java similarity index 88% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/ActivationMessage.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/ActivationMessage.java index f6b7f133..0b8784df 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/ActivationMessage.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/ActivationMessage.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; /** * Message that the external simulation is activated with by SIMONA diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/CompletionMessage.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/CompletionMessage.java similarity index 90% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/CompletionMessage.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/CompletionMessage.java index 35364c9b..ae8eb12e 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/CompletionMessage.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/CompletionMessage.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; import java.util.Optional; diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/ControlMessageToExt.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/ControlMessageToExt.java similarity index 86% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/ControlMessageToExt.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/ControlMessageToExt.java index 601b1624..b0de22f2 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/ControlMessageToExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/ControlMessageToExt.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; /** Interface for control messages from the SIMONA to the external simulation */ public interface ControlMessageToExt {} diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/ControlResponseMessageFromExt.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/ControlResponseMessageFromExt.java similarity index 86% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/ControlResponseMessageFromExt.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/ControlResponseMessageFromExt.java index f3df0973..418f69da 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/ControlResponseMessageFromExt.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/ControlResponseMessageFromExt.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; /** Interface for control messages from the external simulation to SIMONA */ public interface ControlResponseMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationCompleted.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationCompleted.java similarity index 87% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationCompleted.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationCompleted.java index c46ca045..35d4c90c 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationCompleted.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationCompleted.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; /** Message returned to SIMONA indicating that the external simulation terminated */ public record TerminationCompleted() implements ControlResponseMessageFromExt {} diff --git a/src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationMessage.java b/src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationMessage.java similarity index 90% rename from src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationMessage.java rename to src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationMessage.java index c281d041..d406129c 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ontology/TerminationMessage.java +++ b/src/main/java/edu/ie3/simona/api/ontology/simulation/TerminationMessage.java @@ -4,7 +4,7 @@ * Research group Distribution grid planning and operation */ -package edu.ie3.simona.api.simulation.ontology; +package edu.ie3.simona.api.ontology.simulation; /** * Message that is sent once SIMONA is terminating, indicating that the external simulation should 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 76923312..63f750db 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java +++ b/src/main/java/edu/ie3/simona/api/simulation/ExtCoSimulation.java @@ -6,35 +6,38 @@ package edu.ie3.simona.api.simulation; +import static java.util.Collections.emptyList; + import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.models.value.PValue; 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.ExtEmDataConnection; -import edu.ie3.simona.api.data.primarydata.ExtPrimaryDataConnection; -import edu.ie3.simona.api.data.results.ExtResultContainer; -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 edu.ie3.simona.api.data.ExtDataContainerQueue; +import edu.ie3.simona.api.data.connection.ExtEmDataConnection; +import edu.ie3.simona.api.data.connection.ExtEmDataConnection.EmMode; +import edu.ie3.simona.api.data.connection.ExtPrimaryDataConnection; +import edu.ie3.simona.api.data.connection.ExtResultDataConnection; +import edu.ie3.simona.api.data.container.ExtInputDataContainer; +import edu.ie3.simona.api.data.container.ExtResultContainer; +import edu.ie3.simona.api.exceptions.ExtDataConnectionException; +import edu.ie3.simona.api.mapping.DataType; +import edu.ie3.simona.api.ontology.em.*; +import java.util.*; import org.slf4j.Logger; /** * Abstract class for an external co-simulation with the structure: external api - ext-co-simulation - * - extsimulation - simonaAPI - simona It contains all function to transfer primary data and em - * data to SIMONA and results to the external co-simulation. + * - ext-simulation - simonaAPI - simona + * + *

It contains all function to transfer primary data and em data to SIMONA and results to the + * external co-simulation. */ public abstract class ExtCoSimulation extends ExtSimulation { /** Queue for the data connection from the external co-simulation to SimonaAPI */ - protected final DataQueueExtSimulationExtSimulator - dataQueueExtCoSimulatorToSimonaApi; + protected final ExtDataContainerQueue queueToSimona; /** Queue for the data connection from SimonaAPI to the external co-simulation */ - protected final DataQueueExtSimulationExtSimulator - dataQueueSimonaApiToExtCoSimulator; + protected final ExtDataContainerQueue queueToExt; /** Name of the external co-simulation */ protected final String extSimulatorName; @@ -42,50 +45,50 @@ public abstract class ExtCoSimulation extends ExtSimulation { protected ExtCoSimulation(String simulationName, String extSimulatorName) { super(simulationName); this.extSimulatorName = extSimulatorName; - this.dataQueueExtCoSimulatorToSimonaApi = new DataQueueExtSimulationExtSimulator<>(); - this.dataQueueSimonaApiToExtCoSimulator = new DataQueueExtSimulationExtSimulator<>(); + this.queueToSimona = new ExtDataContainerQueue<>(); + this.queueToExt = new ExtDataContainerQueue<>(); } + // connection helper methods + /** * Builds an {@link ExtPrimaryDataConnection}. * - * @param mapping between the external simulation and SIMONA. + * @param assetToValueClasses between primary asset and its value class. * @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."); + public static ExtPrimaryDataConnection buildPrimaryConnection( + Map> assetToValueClasses, Logger log) { + + if (assetToValueClasses.isEmpty()) { + log.warn("No primary data connection was created."); + throw new ExtDataConnectionException(ExtPrimaryDataConnection.class); } else { - log.info("Primary connection with {} entities created.", primaryMapping.size()); - } + log.info("Primary data connection with {} entities created.", assetToValueClasses.size()); - return extPrimaryDataConnection; + return new ExtPrimaryDataConnection(assetToValueClasses); + } } /** * Builds an {@link ExtEmDataConnection}. * - * @param mapping between the external simulation and SIMONA. + * @param controlled uuids for controlled em agents. * @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."); + public static ExtEmDataConnection buildEmConnection( + List controlled, EmMode mode, Logger log) { + if (controlled.isEmpty()) { + log.warn("Em data connection with 0 controlled entities created. This might lead to errors!"); } else { - log.info("Em connection with {} entities created.", emMapping.size()); + log.info("Em data connection with {} controlled entities created.", controlled.size()); } - return extEmDataConnection; + log.info("Em mode: {}", mode); + + return new ExtEmDataConnection(controlled, mode); } /** @@ -95,28 +98,61 @@ protected static ExtEmDataConnection buildEmConnection(ExtEntityMapping mapping, * @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."); + public static ExtResultDataConnection buildResultConnection( + Map> mapping, Logger log) { + List participantResults = + mapping.getOrDefault(DataType.EXT_PARTICIPANT_RESULT, emptyList()); + List gridResults = mapping.getOrDefault(DataType.EXT_GRID_RESULT, emptyList()); + List flexResults = mapping.getOrDefault(DataType.EXT_FLEX_OPTIONS_RESULT, emptyList()); + + if (participantResults.isEmpty() && gridResults.isEmpty() && flexResults.isEmpty()) { + log.warn("No result connection was created."); + throw new ExtDataConnectionException(ExtResultDataConnection.class); } else { log.info( - "Result connection with {} participants and {} grid assets created.", - resultParticipantMapping.size(), - resultGridMapping.size()); + "Result connection with {} participants, {} grid assets and {} flex option mappings created.", + participantResults.size(), + gridResults.size(), + flexResults.size()); + return new ExtResultDataConnection(participantResults, gridResults, flexResults); } + } + + private void checkTick(long expectedTick) throws InterruptedException { + long dataTick = queueToSimona.takeData(ExtInputDataContainer::getTick); - return extResultDataConnection; + if (dataTick != expectedTick) { + throw new RuntimeException( + String.format( + "Provided input data for tick %d, but SIMONA expects input data for tick %d", + dataTick, expectedTick)); + } } + // primary data methods + /** - * Function to send primary data to SIMONA using ExtPrimaryData + * Function to send primary data to SIMONA using the given {@link ExtPrimaryDataConnection}. This + * method will take a value from the {@link #queueToSimona}. + * + * @param extPrimaryDataConnection the connection to SIMONA + * @param tick for which data is sent + * @param maybeNextTick option for the next tick data is sent + * @param log logger + */ + protected void sendPrimaryDataToSimona( + ExtPrimaryDataConnection extPrimaryDataConnection, + long tick, + Optional maybeNextTick, + Logger log) + throws InterruptedException { + checkTick(tick); + Map inputData = queueToSimona.takeData(ExtInputDataContainer::extractPrimaryData); + sendPrimaryDataToSimona(extPrimaryDataConnection, tick, inputData, maybeNextTick, log); + } + + /** + * Function to send primary data to SIMONA using the given {@link ExtPrimaryDataConnection}. * * @param extPrimaryDataConnection the connection to SIMONA * @param tick for which data is sent @@ -127,18 +163,44 @@ protected static ExtResultDataConnection buildResultConnection( protected void sendPrimaryDataToSimona( ExtPrimaryDataConnection extPrimaryDataConnection, long tick, - Map dataMap, + Map dataMap, Optional maybeNextTick, Logger log) { log.debug("Wait for Primary Data from {}", extSimulatorName); log.debug("Received Primary Data from {}", extSimulatorName); - extPrimaryDataConnection.convertAndSend(tick, dataMap, maybeNextTick, log); + extPrimaryDataConnection.sendPrimaryData(tick, dataMap, maybeNextTick, log); log.debug("Provided Primary Data to SIMONA!"); } + // energy management data methods + + /** + * Function to send em set point data to SIMONA using the given {@link ExtEmDataConnection}. This + * method will take a value from the {@link #queueToSimona}. + * + *

{@code 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 maybeNextTick option for the next tick data is sent + * @param log logger + * @throws InterruptedException if the fetching of data is interrupted + */ + protected void sendEmSetPointsToSimona( + ExtEmDataConnection extEmDataConnection, long tick, Optional maybeNextTick, Logger log) + throws InterruptedException { + checkTick(tick); + Map inputData = queueToSimona.takeData(ExtInputDataContainer::extractSetPoints); + + sendEmSetPointsToSimona(extEmDataConnection, tick, inputData, maybeNextTick, log); + } + /** - * 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. + * Function to send em set point data to SIMONA using the given {@link ExtEmDataConnection}. + * + *

{@code 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 @@ -146,33 +208,156 @@ protected void sendPrimaryDataToSimona( * @param maybeNextTick option for the next tick data is sent * @param log logger */ - protected void sendEmDataToSimona( + protected void sendEmSetPointsToSimona( ExtEmDataConnection extEmDataConnection, long tick, - Map dataMap, + Map dataMap, Optional maybeNextTick, Logger log) { - log.debug("Received EmData from {}", extSimulatorName); - extEmDataConnection.convertAndSend(tick, dataMap, maybeNextTick, log); - log.debug("Provided EmData to SIMONA!"); + log.debug("Received em set points from {}", extSimulatorName); + extEmDataConnection.sendSetPoints(tick, dataMap, maybeNextTick, log); + log.debug("Provided em set points to SIMONA!"); + } + + protected void useFlexCommunication( + ExtEmDataConnection extEmDataConnection, long tick, Optional maybeNextTick, Logger log) + throws InterruptedException { + // handle flex requests + boolean notFinished = true; + + while (notFinished) { + + long extTick = queueToSimona.takeData(ExtInputDataContainer::getTick); + + log.warn("Current simulator tick: {}, SIMONA tick: {}", extTick, tick); + + if (tick == extTick) { + ExtInputDataContainer container = queueToSimona.takeAll(); + + log.warn("Flex requests: {}", container.flexRequestsString()); + log.warn("Flex options: {}", container.flexOptionsString()); + log.warn("Set points: {}", container.setPointsString()); + + // send received data to SIMONA + var requests = container.extractFlexRequests(); + var options = container.extractFlexOptions(); + var setPoints = container.extractSetPoints(); + + extEmDataConnection.sendFlexRequests(tick, requests, maybeNextTick, log); + + extEmDataConnection.sendFlexOptions(tick, options, maybeNextTick, log); + + extEmDataConnection.sendSetPoints(tick, setPoints, maybeNextTick, log); + + log.warn("Unhandled flex requests: {}", container.flexRequestsString()); + log.warn("Unhandled flex options: {}", container.flexOptionsString()); + log.warn("Unhandled set points: {}", container.setPointsString()); + + if (requests.isEmpty() && options.isEmpty() && setPoints.isEmpty()) { + log.info("Requesting a service completion for tick: {}.", tick); + extEmDataConnection.requestCompletion(tick); + } + + } else { + notFinished = false; + + log.info("External simulator finished tick {}. Request completion.", tick); + extEmDataConnection.requestCompletion(tick); + } + + EmDataResponseMessageToExt received = extEmDataConnection.receiveAny(); + + Map results = new HashMap<>(); + + if (received instanceof EmCompletion) { + notFinished = false; + log.info("Finished for tick: {}", tick); + + } else if (received instanceof FlexRequestResponse flexRequestResponse) { + results.putAll(flexRequestResponse.flexRequests()); + + } else if (received instanceof FlexOptionsResponse flexOptionsResponse) { + results.putAll(flexOptionsResponse.flexOptions()); + + } else if (received instanceof EmSetPointDataResponse setPointDataResponse) { + results.putAll(setPointDataResponse.emData()); + + } else { + log.warn("Received unsupported data response: {}", received); + } + + log.warn("Results to ext: {}", results); + + ExtResultContainer resultContainer = new ExtResultContainer(tick, results, maybeNextTick); + + queueToExt.queueData(resultContainer); + } + } + + // result data methods + + /** + * Function to send only participant result data from SIMONA to the external simulation using the + * given {@link ExtResultDataConnection} + */ + protected void sendParticipantResultsToExt( + ExtResultDataConnection connection, long tick, Optional nextTick, Logger log) + throws InterruptedException { + sendSingleResultType( + "participant", connection.requestParticipantResults(tick), tick, nextTick, log); + } + + /** + * Function to send only grid result data from SIMONA to the external simulation using the given + * {@link ExtResultDataConnection} + */ + protected void sendGridResultsToExt( + ExtResultDataConnection connection, long tick, Optional nextTick, Logger log) + throws InterruptedException { + sendSingleResultType("grid", connection.requestGridResults(tick), tick, nextTick, log); + } + + /** + * Function to send only flex option result data from SIMONA to the external simulation using the + * given {@link ExtResultDataConnection} + */ + protected void sendFlexOptionResultsToExt( + ExtResultDataConnection connection, long tick, Optional nextTick, Logger log) + throws InterruptedException { + sendSingleResultType( + "flex option", connection.requestFlexOptionResults(tick), tick, nextTick, log); } /** - * Function to get result data from SIMONA using the available {@link ExtResultDataConnection} + * Function to send all result data from SIMONA to the external simulation using the given {@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 + * @throws InterruptedException if the fetching of data is interrupted */ - protected void sendDataToExt( + protected void sendResultToExt( ExtResultDataConnection connection, long tick, Optional maybeNextTick, Logger log) throws InterruptedException { log.debug("Request results from SIMONA!"); - Map resultsToBeSend = connection.requestResults(tick); + Map resultsToBeSend = connection.requestResults(tick); log.debug("Received results from SIMONA!"); - dataQueueSimonaApiToExtCoSimulator.queueData( - new ExtResultContainer(tick, resultsToBeSend, maybeNextTick)); + queueToExt.queueData(new ExtResultContainer(tick, resultsToBeSend, maybeNextTick)); log.debug("Sent results to {}", extSimulatorName); } + + private void sendSingleResultType( + String type, + Map resultsToBeSend, + long tick, + Optional nextTick, + Logger log) + throws InterruptedException { + log.info("Request results from SIMONA for {} for tick {}!", type, tick); + + queueToExt.queueData(new ExtResultContainer(tick, resultsToBeSend, nextTick)); + log.info("Sent {} results for tick {} to {}", type, tick, 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 0e52a819..79599be5 100644 --- a/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java +++ b/src/main/java/edu/ie3/simona/api/simulation/ExtSimulation.java @@ -6,8 +6,9 @@ package edu.ie3.simona.api.simulation; -import edu.ie3.simona.api.data.ExtDataConnection; -import edu.ie3.simona.api.simulation.ontology.*; +import edu.ie3.simona.api.data.ExtSimAdapterData; +import edu.ie3.simona.api.data.connection.ExtDataConnection; +import edu.ie3.simona.api.ontology.simulation.*; import java.util.Optional; import java.util.Set; diff --git a/src/test/groovy/edu/ie3/simona/api/data/connection/ExtEmDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtEmDataConnectionTest.groovy new file mode 100644 index 00000000..eb49e8e2 --- /dev/null +++ b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtEmDataConnectionTest.groovy @@ -0,0 +1,67 @@ +package edu.ie3.simona.api.data.connection + +import edu.ie3.simona.api.data.connection.ExtEmDataConnection.EmMode +import edu.ie3.simona.api.ontology.DataMessageFromExt +import edu.ie3.simona.api.ontology.ScheduleDataServiceMessage +import edu.ie3.simona.api.ontology.em.ProvideEmSetPointData +import edu.ie3.simona.api.test.common.DataServiceTestData +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit +import spock.lang.Shared +import spock.lang.Specification + +class ExtEmDataConnectionTest extends Specification implements DataServiceTestData { + + @Shared + ActorTestKit testKit + + @Shared + List controlled = [inputUuid] + + def setupSpec() { + testKit = ActorTestKit.create() + } + + def cleanupSpec() { + testKit.shutdownTestKit() + testKit = null + } + + def "ExtEmDataConnection should provide em data correctly"() { + given: + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) + def extEmDataConnection = new ExtEmDataConnection(controlled, EmMode.SET_POINT) + extEmDataConnection.setActorRefs( + dataService.ref(), + extSimAdapter.ref() + ) + + def emData = Map.of(inputUuid, pValue) + + when: + extEmDataConnection.sendSetPoints(0L, emData, Optional.of(900L), log) + + then: + dataService.expectMessage(new ProvideEmSetPointData(0, emData, Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) + } + + def "ExtEmDataConnection should send no message, if input data is empty"() { + given: + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) + def extEmDataConnection = new ExtEmDataConnection(controlled, EmMode.SET_POINT) + extEmDataConnection.setActorRefs( + dataService.ref(), + extSimAdapter.ref() + ) + def inputDataMap = [:] as Map + + when: + extEmDataConnection.sendSetPoints(0L, inputDataMap, Optional.of(900L), log) + + then: + dataService.expectNoMessage() + } + +} diff --git a/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtEvDataConnectionTest.groovy similarity index 88% rename from src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy rename to src/test/groovy/edu/ie3/simona/api/data/connection/ExtEvDataConnectionTest.groovy index ea925b95..905bd407 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/ev/ExtEvDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtEvDataConnectionTest.groovy @@ -1,9 +1,16 @@ -package edu.ie3.simona.api.data.ev - -import edu.ie3.simona.api.data.ev.model.EvModel -import edu.ie3.simona.api.data.ev.ontology.* -import edu.ie3.simona.api.data.ontology.DataMessageFromExt -import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage +package edu.ie3.simona.api.data.connection + + +import edu.ie3.simona.api.data.model.ev.EvModel +import edu.ie3.simona.api.ontology.DataMessageFromExt +import edu.ie3.simona.api.ontology.ScheduleDataServiceMessage +import edu.ie3.simona.api.ontology.ev.ProvideArrivingEvs +import edu.ie3.simona.api.ontology.ev.ProvideCurrentPrices +import edu.ie3.simona.api.ontology.ev.ProvideDepartingEvs +import edu.ie3.simona.api.ontology.ev.ProvideEvcsFreeLots +import edu.ie3.simona.api.ontology.ev.RequestCurrentPrices +import edu.ie3.simona.api.ontology.ev.RequestDepartingEvs +import edu.ie3.simona.api.ontology.ev.RequestEvcsFreeLots import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification diff --git a/src/test/groovy/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnectionTest.groovy new file mode 100644 index 00000000..ee0f0b43 --- /dev/null +++ b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtPrimaryDataConnectionTest.groovy @@ -0,0 +1,67 @@ +package edu.ie3.simona.api.data.connection + +import edu.ie3.datamodel.models.value.PValue +import edu.ie3.datamodel.models.value.Value +import edu.ie3.simona.api.ontology.DataMessageFromExt +import edu.ie3.simona.api.ontology.ScheduleDataServiceMessage +import edu.ie3.simona.api.ontology.primary.ProvidePrimaryData +import edu.ie3.simona.api.test.common.DataServiceTestData +import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit +import spock.lang.Shared +import spock.lang.Specification + +class ExtPrimaryDataConnectionTest extends Specification implements DataServiceTestData { + + @Shared + ActorTestKit testKit + + @Shared + Map> assetToValueClasses = [ (inputUuid): PValue] as Map + + def setupSpec() { + testKit = ActorTestKit.create() + } + + def cleanupSpec() { + testKit.shutdownTestKit() + testKit = null + } + + def "ExtPrimaryDataConnection should provide primary data correctly"() { + given: + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) + def extPrimaryDataConnection = new ExtPrimaryDataConnection(assetToValueClasses) + extPrimaryDataConnection.setActorRefs( + dataService.ref(), + extSimAdapter.ref() + ) + + def primaryData = Map.of(inputUuid, pValue as Value) + + when: + extPrimaryDataConnection.provideData(0L, primaryData, Optional.of(900L)) + + then: + dataService.expectMessage(new ProvidePrimaryData(0L, primaryData, Optional.of(900L))) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) + } + + def "ExtPrimaryDataConnection should send no message, if input data is empty"() { + given: + def dataService = testKit.createTestProbe(DataMessageFromExt) + def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) + def extPrimaryDataConnection = new ExtPrimaryDataConnection(assetToValueClasses) + extPrimaryDataConnection.setActorRefs( + dataService.ref(), + extSimAdapter.ref() + ) + def inputDataMap = [:] + + when: + extPrimaryDataConnection.sendPrimaryData(0L, inputDataMap, Optional.empty(), log) + + then: + dataService.expectNoMessage() + } +} diff --git a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtResultDataConnectionTest.groovy similarity index 55% rename from src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy rename to src/test/groovy/edu/ie3/simona/api/data/connection/ExtResultDataConnectionTest.groovy index 3bf9a64f..e53e4898 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultDataConnectionTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/connection/ExtResultDataConnectionTest.groovy @@ -1,18 +1,14 @@ -package edu.ie3.simona.api.data.results +package edu.ie3.simona.api.data.connection import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.connector.LineResult -import edu.ie3.simona.api.data.ontology.DataMessageFromExt -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 -import edu.ie3.simona.api.data.results.ontology.ResultDataResponseMessageToExt -import edu.ie3.simona.api.simulation.ExtSimulation +import edu.ie3.simona.api.ontology.DataMessageFromExt +import edu.ie3.simona.api.ontology.ScheduleDataServiceMessage +import edu.ie3.simona.api.ontology.result.ProvideResultEntities +import edu.ie3.simona.api.ontology.result.RequestResultEntities +import edu.ie3.simona.api.ontology.result.ResultDataResponseMessageToExt import edu.ie3.simona.api.test.common.DataServiceTestData -import org.apache.pekko.actor.ActorSystem import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit -import org.apache.pekko.testkit.TestProbe -import org.apache.pekko.testkit.javadsl.TestKit import spock.lang.Shared import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -28,10 +24,13 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe ActorTestKit testKit @Shared - Map participantResultAssetMapping = Map.of(inputUuid, "Load") + List participantResultAssets = [inputUuid] @Shared - Map gridResultAssetMapping = [:] + List gridResultAssets = [] + + @Shared + List flexResultAssets = [] class WrongResultDataResponseMessageToExt implements ResultDataResponseMessageToExt {} @@ -47,12 +46,10 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe def "ExtResultsData should request and receive results correctly as ModelResultEntity"() { given: def dataService = testKit.createTestProbe(DataMessageFromExt) - def dataServiceActivation = testKit.createTestProbe(DataMessageFromExt) def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) + def extResultDataConnection = new ExtResultDataConnection(participantResultAssets, gridResultAssets, flexResultAssets) extResultDataConnection.setActorRefs( dataService.ref(), - dataServiceActivation.ref(), extSimAdapter.ref() ) @@ -64,20 +61,18 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe def receivedResults = extResultDataConnection.requestResults(0L) then: - dataService.expectMessage(new RequestResultEntities(0L)) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataServiceActivation.ref())) - receivedResults.get("Load") == loadResult + dataService.expectMessage(new RequestResultEntities(0L, [inputUuid])) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) + receivedResults.get(inputUuid) == loadResult } def "ExtResultsData should fail if wrong response is sent"() { given: def dataService = testKit.createTestProbe(DataMessageFromExt) - def dataServiceActivation = testKit.createTestProbe(DataMessageFromExt) def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) + def extResultDataConnection = new ExtResultDataConnection(participantResultAssets, gridResultAssets, flexResultAssets) extResultDataConnection.setActorRefs( dataService.ref(), - dataServiceActivation.ref(), extSimAdapter.ref() ) @@ -89,38 +84,20 @@ class ExtResultDataConnectionTest extends Specification implements DataServiceTe extResultDataConnection.requestResults(0L) then: - dataService.expectMessage(new RequestResultEntities(0L)) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataServiceActivation.ref())) + dataService.expectMessage(new RequestResultEntities(0L, [inputUuid])) + extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) thrown RuntimeException } def "ExtResultData should convert a list of result entities correctly to a map of resultAssetMappingId to result entity"() { given: - def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) + def extResultDataConnection = new ExtResultDataConnection(participantResultAssets, gridResultAssets, flexResultAssets) when: def mapOfResults = extResultDataConnection.createResultMap([loadResult]) then: mapOfResults.size() == 1 - mapOfResults.get("Load") == loadResult - } - - def "ExtResultData should throw an exception, if a result with a wrong data type was provided"() { - given: - def extResultDataConnection = new ExtResultDataConnection(participantResultAssetMapping, gridResultAssetMapping) - Quantity iAMag = Quantities.getQuantity(100, StandardUnits.ELECTRIC_CURRENT_MAGNITUDE) - Quantity iAAng = Quantities.getQuantity(45, StandardUnits.ELECTRIC_CURRENT_ANGLE) - Quantity iBMag = Quantities.getQuantity(150, StandardUnits.ELECTRIC_CURRENT_MAGNITUDE) - Quantity iBAng = Quantities.getQuantity(30, StandardUnits.ELECTRIC_CURRENT_ANGLE) - def wrongResult = new LineResult( - ZonedDateTime.parse("2020-01-30T17:26:44Z"), inputUuid, iAMag, iAAng, iBMag, iBAng - ) - - when: - extResultDataConnection.createResultMap([wrongResult]) - - then: - thrown IllegalArgumentException + mapOfResults.get(inputUuid) == loadResult } } \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultContainerTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/container/ExtResultContainerTest.groovy similarity index 80% rename from src/test/groovy/edu/ie3/simona/api/data/results/ExtResultContainerTest.groovy rename to src/test/groovy/edu/ie3/simona/api/data/container/ExtResultContainerTest.groovy index b86f6aef..9ec09b35 100644 --- a/src/test/groovy/edu/ie3/simona/api/data/results/ExtResultContainerTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/data/container/ExtResultContainerTest.groovy @@ -1,4 +1,4 @@ -package edu.ie3.simona.api.data.results +package edu.ie3.simona.api.data.container import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.NodeResult @@ -25,13 +25,11 @@ class ExtResultContainerTest extends Specification implements DataServiceTestDat def "ExtResultContainer should return voltage deviation correctly"() { given: - def resultMap = Map.of( - "Node", nodeResult - ) + def resultMap = Map.of(nodeUuid, nodeResult) def extResultContainer = new ExtResultContainer(0L, resultMap) when: - def calculatedVoltageDeviation = extResultContainer.getVoltageDeviation("Node") + def calculatedVoltageDeviation = extResultContainer.getVoltageDeviation(nodeUuid) then: calculatedVoltageDeviation == -0.05d @@ -39,13 +37,11 @@ class ExtResultContainerTest extends Specification implements DataServiceTestDat def "ExtResultContainer should throw an exception, if voltage deviation was requested for a not NodeResult"() { given: - def resultMap = Map.of( - "Load", loadResult - ) + def resultMap = Map.of(inputUuid, loadResult) def extResultContainer = new ExtResultContainer(0L, resultMap) when: - extResultContainer.getVoltageDeviation("Load") + extResultContainer.getVoltageDeviation(inputUuid) then: thrown IllegalArgumentException @@ -53,13 +49,11 @@ class ExtResultContainerTest extends Specification implements DataServiceTestDat def "ExtResultContainer should return active power correctly"() { given: - def resultMap = Map.of( - "Load", loadResult - ) + def resultMap = Map.of(inputUuid, loadResult) def extResultContainer = new ExtResultContainer(0L, resultMap) when: - def returnedActivePower = extResultContainer.getActivePower("Load") + def returnedActivePower = extResultContainer.getActivePower(inputUuid) then: returnedActivePower == 10d @@ -67,13 +61,11 @@ class ExtResultContainerTest extends Specification implements DataServiceTestDat def "ExtResultContainer should return reactive power correctly"() { given: - def resultMap = Map.of( - "Load", loadResult - ) + def resultMap = Map.of(inputUuid, loadResult) def extResultContainer = new ExtResultContainer(0L, resultMap) when: - def returnedReactivePower = extResultContainer.getReactivePower("Load") + def returnedReactivePower = extResultContainer.getReactivePower(inputUuid) then: returnedReactivePower == 5d @@ -82,12 +74,12 @@ class ExtResultContainerTest extends Specification implements DataServiceTestDat def "ExtResultContainer should throw an exception, if active power was requested for a not SystemParticipantResult"() { given: def resultMap = Map.of( - "Node", nodeResult + nodeUuid, nodeResult ) def extResultContainer = new ExtResultContainer(0L, resultMap) when: - extResultContainer.getActivePower("Node") + extResultContainer.getActivePower(nodeUuid) then: thrown IllegalArgumentException diff --git a/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy deleted file mode 100644 index 7b0f4ecb..00000000 --- a/src/test/groovy/edu/ie3/simona/api/data/em/ExtEmDataConnectionTest.groovy +++ /dev/null @@ -1,94 +0,0 @@ -package edu.ie3.simona.api.data.em - -import edu.ie3.datamodel.models.value.PValue -import edu.ie3.datamodel.models.value.Value -import edu.ie3.simona.api.data.em.ontology.ProvideEmSetPointData -import edu.ie3.simona.api.data.ontology.DataMessageFromExt -import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage -import edu.ie3.simona.api.test.common.DataServiceTestData -import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit -import spock.lang.Shared -import spock.lang.Specification - -class ExtEmDataConnectionTest extends Specification implements DataServiceTestData { - - @Shared - ActorTestKit testKit - - @Shared - Map extEmDataMapping = Map.of( - "Em", - inputUuid - ) - - def setupSpec() { - testKit = ActorTestKit.create() - } - - def cleanupSpec() { - testKit.shutdownTestKit() - testKit = null - } - - def "ExtEmDataConnection should provide em data correctly"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) - extEmDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - - def emData = [:] as HashMap - def uuid = UUID.randomUUID() - emData.put(uuid.toString(), pValue) - - def convertedEmData = Map.of(uuid, pValue as PValue) - - when: - extEmDataConnection.provideEmData(0L, convertedEmData, Optional.of(900L)) - - then: - dataService.expectMessage(new ProvideEmSetPointData(0, convertedEmData, Optional.of(900L))) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) - } - - def "ExtEmDataConnection should convert input data correctly"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) - extEmDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - def inputDataMap = Map.of("Em", pValue) - - when: - extEmDataConnection.convertAndSend(0L, inputDataMap, Optional.of(900L), log) - - then: - dataService.expectMessage(new ProvideEmSetPointData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) - } - - def "ExtEmDataConnection should send no message, if input data for a not requested asset was provided"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extEmDataConnection = new ExtEmDataConnection(extEmDataMapping) - extEmDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - def inputDataMap = Map.of("Load", pValue) - - when: - extEmDataConnection.convertAndSend(0L, inputDataMap, Optional.of(900L), log) - - then: - dataService.expectNoMessage() - } - -} diff --git a/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy b/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy deleted file mode 100644 index 8cc119a1..00000000 --- a/src/test/groovy/edu/ie3/simona/api/data/primarydata/ExtPrimaryDataConnectionTest.groovy +++ /dev/null @@ -1,92 +0,0 @@ -package edu.ie3.simona.api.data.primarydata - -import edu.ie3.datamodel.models.value.Value -import edu.ie3.simona.api.data.ontology.DataMessageFromExt -import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage -import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData -import edu.ie3.simona.api.test.common.DataServiceTestData -import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit -import spock.lang.Shared -import spock.lang.Specification - -class ExtPrimaryDataConnectionTest extends Specification implements DataServiceTestData { - - @Shared - ActorTestKit testKit - - @Shared - Map extPrimaryDataMapping = Map.of( - "Pv", - inputUuid - ) - - def setupSpec() { - testKit = ActorTestKit.create() - } - - def cleanupSpec() { - testKit.shutdownTestKit() - testKit = null - } - - def "ExtPrimaryDataConnection should provide primary data correctly"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) - extPrimaryDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - - def primaryData = [:] as HashMap - def uuid = UUID.randomUUID() - primaryData.put(uuid.toString(), pValue) - - def convertedPrimaryData = Map.of(uuid, pValue as Value) - - when: - extPrimaryDataConnection.providePrimaryData(0L, convertedPrimaryData, Optional.of(900L)) - - then: - dataService.expectMessage(new ProvidePrimaryData(0L, convertedPrimaryData, Optional.of(900L))) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) - } - - def "ExtPrimaryDataConnection should convert input data correctly"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) - extPrimaryDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - def inputDataMap = Map.of("Pv", pValue) - - when: - extPrimaryDataConnection.convertAndSend(0L, inputDataMap, Optional.of(900L), log) - - then: - dataService.expectMessage(new ProvidePrimaryData(0L, Map.of(inputUuid, pValue), Optional.of(900L))) - extSimAdapter.expectMessage(new ScheduleDataServiceMessage(dataService.ref())) - } - - def "ExtPrimaryDataConnection should send no message, if input data for a not requested asset was provided"() { - given: - def dataService = testKit.createTestProbe(DataMessageFromExt) - def extSimAdapter = testKit.createTestProbe(ScheduleDataServiceMessage) - def extPrimaryDataConnection = new ExtPrimaryDataConnection(extPrimaryDataMapping) - extPrimaryDataConnection.setActorRefs( - dataService.ref(), - extSimAdapter.ref() - ) - def inputDataMap = Map.of("Load", pValue) - - when: - extPrimaryDataConnection.convertAndSend(0L, inputDataMap, Optional.empty(), log) - - then: - dataService.expectNoMessage() - } -} diff --git a/src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSourceTest.groovy b/src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingSourceTest.groovy similarity index 96% rename from src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSourceTest.groovy rename to src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingSourceTest.groovy index 2589e219..3dabbe77 100644 --- a/src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingSourceTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingSourceTest.groovy @@ -1,4 +1,4 @@ -package edu.ie3.simona.api.simulation.mapping +package edu.ie3.simona.api.mapping import edu.ie3.datamodel.models.input.NodeInput import spock.lang.Specification diff --git a/src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingTest.groovy b/src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingTest.groovy similarity index 84% rename from src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingTest.groovy rename to src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingTest.groovy index 9f49f614..11194ced 100644 --- a/src/test/groovy/edu/ie3/simona/api/simulation/mapping/ExtEntityMappingTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/mapping/ExtEntityMappingTest.groovy @@ -1,6 +1,9 @@ -package edu.ie3.simona.api.simulation.mapping +package edu.ie3.simona.api.mapping import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme +import edu.ie3.simona.api.mapping.DataType +import edu.ie3.simona.api.mapping.ExtEntityEntry +import edu.ie3.simona.api.mapping.ExtEntityMapping import spock.lang.Shared import spock.lang.Specification @@ -12,7 +15,7 @@ class ExtEntityMappingTest extends Specification { ExtEntityEntry extResultEntry = new ExtEntityEntry( loadUuid, "Load", - ColumnScheme.parse("p").get(), + ColumnScheme.parse("p"), DataType.EXT_PARTICIPANT_RESULT ) @@ -20,7 +23,7 @@ class ExtEntityMappingTest extends Specification { ExtEntityEntry extInputEntry = new ExtEntityEntry( loadUuid, "Load", - ColumnScheme.parse("p").get(), + ColumnScheme.parse("p"), DataType.EXT_PRIMARY_INPUT ) diff --git a/src/test/groovy/edu/ie3/simona/api/simulation/ExtCoSimulationTest.groovy b/src/test/groovy/edu/ie3/simona/api/simulation/ExtCoSimulationTest.groovy index 2903384c..0896d846 100644 --- a/src/test/groovy/edu/ie3/simona/api/simulation/ExtCoSimulationTest.groovy +++ b/src/test/groovy/edu/ie3/simona/api/simulation/ExtCoSimulationTest.groovy @@ -1,9 +1,10 @@ package edu.ie3.simona.api.simulation -import edu.ie3.datamodel.io.naming.timeseries.ColumnScheme -import edu.ie3.simona.api.simulation.mapping.DataType -import edu.ie3.simona.api.simulation.mapping.ExtEntityEntry -import edu.ie3.simona.api.simulation.mapping.ExtEntityMapping +import edu.ie3.datamodel.models.value.PValue +import edu.ie3.datamodel.models.value.SValue +import edu.ie3.datamodel.models.value.Value +import edu.ie3.simona.api.data.connection.ExtEmDataConnection.EmMode +import edu.ie3.simona.api.mapping.DataType import org.slf4j.Logger import org.slf4j.LoggerFactory import spock.lang.Shared @@ -18,35 +19,28 @@ class ExtCoSimulationTest extends Specification { given: UUID uuid1 = UUID.randomUUID() UUID uuid2 = UUID.randomUUID() - UUID uuid3 = UUID.randomUUID() - ExtEntityMapping mapping = new ExtEntityMapping([ - new ExtEntityEntry(uuid1, "primary1", ColumnScheme.ACTIVE_POWER, DataType.EXT_PRIMARY_INPUT), - new ExtEntityEntry(uuid2, "em1", ColumnScheme.ACTIVE_POWER, DataType.EXT_EM_INPUT), - new ExtEntityEntry(uuid3, "primary2", ColumnScheme.ACTIVE_POWER, DataType.EXT_PRIMARY_INPUT), - ]) + Map> assetsToClasses = [ + (uuid1): PValue, + (uuid2): SValue + ] as Map when: - def actual = ExtCoSimulation.buildPrimaryConnection(mapping, log) + def actual = ExtCoSimulation.buildPrimaryConnection(assetsToClasses, log) then: - actual.getPrimaryDataAssets() == [uuid3, uuid1] + actual.getPrimaryDataAssets() == [uuid1, uuid2] } def "An ExtCoSimulation can build an em data connection correctly"() { given: UUID uuid1 = UUID.randomUUID() UUID uuid2 = UUID.randomUUID() - UUID uuid3 = UUID.randomUUID() - ExtEntityMapping mapping = new ExtEntityMapping([ - new ExtEntityEntry(uuid1, "em1", ColumnScheme.ACTIVE_POWER, DataType.EXT_EM_INPUT), - new ExtEntityEntry(uuid2, "em2", ColumnScheme.ACTIVE_POWER, DataType.EXT_EM_INPUT), - new ExtEntityEntry(uuid3, "primary1", ColumnScheme.ACTIVE_POWER, DataType.EXT_PRIMARY_INPUT), - ]) + def controlled = [uuid1, uuid2] when: - def actual = ExtCoSimulation.buildEmConnection(mapping, log) + def actual = ExtCoSimulation.buildEmConnection(controlled, EmMode.SET_POINT, log) then: actual.getControlledEms() == [uuid1, uuid2] @@ -58,11 +52,11 @@ class ExtCoSimulationTest extends Specification { UUID uuid2 = UUID.randomUUID() UUID uuid3 = UUID.randomUUID() - ExtEntityMapping mapping = new ExtEntityMapping([ - new ExtEntityEntry(uuid1, "grid_result", ColumnScheme.ACTIVE_POWER, DataType.EXT_GRID_RESULT), - new ExtEntityEntry(uuid2, "participant_result", ColumnScheme.ACTIVE_POWER, DataType.EXT_PARTICIPANT_RESULT), - new ExtEntityEntry(uuid3, "primary1", ColumnScheme.ACTIVE_POWER, DataType.EXT_PRIMARY_INPUT), - ]) + def mapping = [ + (DataType.EXT_GRID_RESULT) : [uuid1], + (DataType.EXT_PARTICIPANT_RESULT): [uuid2], + (DataType.EXT_FLEX_OPTIONS_RESULT): [uuid3] + ] when: def actual = ExtCoSimulation.buildResultConnection(mapping, log) diff --git a/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy b/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy index 7b24d955..de00d9b3 100644 --- a/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy +++ b/src/test/groovy/edu/ie3/simona/api/simulation/ExtSimulationSpec.groovy @@ -1,7 +1,13 @@ package edu.ie3.simona.api.simulation -import edu.ie3.simona.api.data.ExtDataConnection -import edu.ie3.simona.api.simulation.ontology.* +import edu.ie3.simona.api.data.ExtSimAdapterData +import edu.ie3.simona.api.data.connection.ExtDataConnection +import edu.ie3.simona.api.ontology.simulation.ActivationMessage +import edu.ie3.simona.api.ontology.simulation.CompletionMessage +import edu.ie3.simona.api.ontology.simulation.ControlMessageToExt +import edu.ie3.simona.api.ontology.simulation.ControlResponseMessageFromExt +import edu.ie3.simona.api.ontology.simulation.TerminationCompleted +import edu.ie3.simona.api.ontology.simulation.TerminationMessage import org.apache.pekko.actor.testkit.typed.javadsl.ActorTestKit import spock.lang.Shared import spock.lang.Specification diff --git a/src/test/resources/edu/ie3/simona/api/simulation/mapping/ext_entity_mapping.csv b/src/test/resources/edu/ie3/simona/api/mapping/ext_entity_mapping.csv similarity index 100% rename from src/test/resources/edu/ie3/simona/api/simulation/mapping/ext_entity_mapping.csv rename to src/test/resources/edu/ie3/simona/api/mapping/ext_entity_mapping.csv