Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Renaming power fields in `EvModel` [#208](https://github.com/ie3-institute/simonaAPI/issues/208)
- Enhancing external data connections [#219](https://github.com/ie3-institute/simonaAPI/issues/219)

## [0.5.0] - 2024-08-09

Expand Down
21 changes: 13 additions & 8 deletions src/main/java/edu/ie3/simona/api/ExtLinkInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@

package edu.ie3.simona.api;

import edu.ie3.simona.api.data.ExtDataSimulation;
import edu.ie3.simona.api.exceptions.NoExtSimulationException;
import edu.ie3.simona.api.simulation.ExtSimAdapterData;
import edu.ie3.simona.api.simulation.ExtSimulation;
import java.util.List;

/**
* Every external simulation has to provide a class {@code edu.ie3.simona.api.ExtLink} which
* implements this interface.
*
* <p>{@link #getExtSimulation()} and {@link #getExtDataSimulations()} can return references to the
* same object, if that object implements both {@link ExtSimulation} and one or more variants of
* {@link ExtDataSimulation}.
*/
public interface ExtLinkInterface {
ExtSimulation getExtSimulation();
/** Returns the external simulation. */
default ExtSimulation getExtSimulation() {
throw new NoExtSimulationException(this.getClass());
}

List<ExtDataSimulation> getExtDataSimulations();
/**
* Method to set up an external simulation. Everything that needs to be set up before the external
* simulation can be retrieved should be done here.
*
* @param data used for setting up the external simulation
*/
void setup(ExtSimAdapterData data);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@

package edu.ie3.simona.api.data;

public interface ExtData {}
/** Interface that defines a data connection between SIMONA and an external simulation. */
public interface ExtDataConnection {}
16 changes: 0 additions & 16 deletions src/main/java/edu/ie3/simona/api/data/ExtDataSimulation.java

This file was deleted.

21 changes: 21 additions & 0 deletions src/main/java/edu/ie3/simona/api/data/ExtInputDataConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* © 2024. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/

package edu.ie3.simona.api.data;

import org.apache.pekko.actor.ActorRef;

public interface ExtInputDataConnection extends ExtDataConnection {

/**
* Sets the actor refs for data and control flow.
*
* @param dataService actor ref to the adapter of the data service for schedule activation
* messages
* @param extSimAdapter actor ref to the extSimAdapter
*/
void setActorRefs(ActorRef dataService, ActorRef extSimAdapter);
}
13 changes: 0 additions & 13 deletions src/main/java/edu/ie3/simona/api/data/ExtOutputData.java

This file was deleted.

27 changes: 27 additions & 0 deletions src/main/java/edu/ie3/simona/api/data/ExtOutputDataConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* © 2024. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/

package edu.ie3.simona.api.data;

import org.apache.pekko.actor.ActorRef;

/**
* Interface for a connection between SIMONA and an external simulation with data flow from SIMONA
* to external
*/
public interface ExtOutputDataConnection extends ExtDataConnection {

/**
* Sets the actor refs for data and control flow
*
* @param extResultDataService actor ref to the adapter of the data service for data messages
* @param dataServiceActivation actor ref to the adapter of the data service for schedule
* activation messages
* @param extSimAdapter actor ref to the extSimAdapter
*/
void setActorRefs(
ActorRef extResultDataService, ActorRef dataServiceActivation, ActorRef extSimAdapter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@
package edu.ie3.simona.api.data.em;

import edu.ie3.datamodel.models.value.PValue;
import edu.ie3.simona.api.data.ExtData;
import edu.ie3.simona.api.data.ExtInputDataContainer;
import edu.ie3.datamodel.models.value.Value;
import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.em.ontology.EmDataMessageFromExt;
import edu.ie3.simona.api.data.em.ontology.ProvideEmSetPointData;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.pekko.actor.ActorRef;
import org.slf4j.Logger;

/** Enables data connection of em data between SIMONA and SimonaAPI */
public class ExtEmData implements ExtData {
public class ExtEmDataConnection implements ExtInputDataConnection {

/** Actor reference to service that handles ev data within SIMONA */
private ActorRef emDataService;
Expand All @@ -27,16 +29,33 @@ public class ExtEmData implements ExtData {
/** Assets that provide primary data to SIMONA */
private final Map<String, UUID> extEmMapping;

public ExtEmData(Map<String, UUID> extEmMapping) {
public ExtEmDataConnection(Map<String, UUID> extEmMapping) {
this.extEmMapping = extEmMapping;
}

/** Sets the actor refs for data and control flow */
@Override
public void setActorRefs(ActorRef emDataService, ActorRef extSimAdapter) {
this.emDataService = emDataService;
this.extSimAdapter = extSimAdapter;
}

public void convertAndSend(
long tick, Map<String, Value> data, Optional<Long> maybeNextTick, Logger log) {
// filtering the data and converting the keys
Map<UUID, PValue> 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<UUID> getControlledEms() {
return extEmMapping.values().stream().toList();
Expand All @@ -59,26 +78,4 @@ public void sendExtMsg(EmDataMessageFromExt msg) {
// we need to schedule data receiver activation with scheduler
extSimAdapter.tell(new ScheduleDataServiceMessage(emDataService), ActorRef.noSender());
}

/** Converts an input data package from an external simulation to a map of set points */
public Map<UUID, PValue> convertExternalInputToEmSetPoints(
ExtInputDataContainer extInputDataContainer) {
Map<UUID, PValue> emDataForSimona = new HashMap<>();
extInputDataContainer
.getSimonaInputMap()
.forEach(
(id, value) -> {
if (extEmMapping.containsKey(id)) {
if (value instanceof PValue pValue) {
emDataForSimona.put(extEmMapping.get(id), pValue);
} else {
throw new IllegalArgumentException("EmData can only handle PValue's!");
}
} else {
throw new IllegalArgumentException(
"Input for asset with id " + id + " was provided, but it wasn't requested!");
}
});
return emDataForSimona;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,30 @@

package edu.ie3.simona.api.data.ev;

import edu.ie3.simona.api.data.ExtData;
import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.ev.model.EvModel;
import edu.ie3.simona.api.data.ev.ontology.*;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.pekko.actor.ActorRef;

public class ExtEvData implements ExtData {
public class ExtEvDataConnection implements ExtInputDataConnection {
/** Data message queue containing messages from SIMONA */
public final LinkedBlockingQueue<EvDataResponseMessageToExt> receiveTriggerQueue =
new LinkedBlockingQueue<>();

/** Actor reference to service that handles ev data within SIMONA */
private final ActorRef dataService;
private ActorRef dataService;

/** Actor reference to adapter that handles scheduler control flow in SIMONA */
private final ActorRef extSimAdapter;
private ActorRef extSimAdapter;

// important trigger queue must be the same as hold in actor
// to make it safer one might consider asking the actor for ara reference on its trigger queue?!
public ExtEvData(ActorRef dataService, ActorRef extSimAdapter) {
@Override
public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) {
this.dataService = dataService;
this.extSimAdapter = extSimAdapter;
}
Expand Down
23 changes: 0 additions & 23 deletions src/main/java/edu/ie3/simona/api/data/ev/ExtEvSimulation.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
package edu.ie3.simona.api.data.primarydata;

import edu.ie3.datamodel.models.value.Value;
import edu.ie3.simona.api.data.ExtData;
import edu.ie3.simona.api.data.ExtInputDataContainer;
import edu.ie3.simona.api.data.ExtInputDataConnection;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import edu.ie3.simona.api.data.primarydata.ontology.PrimaryDataMessageFromExt;
import edu.ie3.simona.api.data.primarydata.ontology.ProvidePrimaryData;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.pekko.actor.ActorRef;
import org.slf4j.Logger;

/** Enables data connection of primary data between SIMONA and SimonaAPI */
public class ExtPrimaryData implements ExtData {
public class ExtPrimaryDataConnection implements ExtInputDataConnection {

/** Actor reference to service that handles ev data within SIMONA */
/** Actor reference to service that handles primary data within SIMONA */
private ActorRef dataService;

/** Actor reference to adapter that handles scheduler control flow in SIMONA */
Expand All @@ -27,16 +28,33 @@ public class ExtPrimaryData implements ExtData {
/** Assets that provide primary data to SIMONA */
private final Map<String, UUID> extPrimaryDataMapping;

public ExtPrimaryData(Map<String, UUID> extPrimaryDataMapping) {
public ExtPrimaryDataConnection(Map<String, UUID> extPrimaryDataMapping) {
this.extPrimaryDataMapping = extPrimaryDataMapping;
}

/** Sets the actor refs for data and control flow */
@Override
public void setActorRefs(ActorRef dataService, ActorRef extSimAdapter) {
this.dataService = dataService;
this.extSimAdapter = extSimAdapter;
}

public void convertAndSend(
long tick, Map<String, Value> data, Optional<Long> maybeNextTick, Logger log) {
// filtering the data and converting the keys
Map<UUID, Value> 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<UUID> getPrimaryDataAssets() {
return extPrimaryDataMapping.values().stream().toList();
Expand All @@ -60,22 +78,4 @@ public void sendExtMsg(PrimaryDataMessageFromExt msg) {
// we need to schedule data receiver activation with scheduler
extSimAdapter.tell(new ScheduleDataServiceMessage(dataService), ActorRef.noSender());
}

/** Converts an input data package from an external simulation to a map of primary data */
public Map<UUID, Value> convertExternalInputToPrimaryData(
ExtInputDataContainer extInputDataContainer) {
Map<UUID, Value> primaryDataForSimona = new HashMap<>();
extInputDataContainer
.getSimonaInputMap()
.forEach(
(id, value) -> {
if (extPrimaryDataMapping.containsKey(id)) {
primaryDataForSimona.put(extPrimaryDataMapping.get(id), value);
} else {
throw new IllegalArgumentException(
"Input for asset with id " + id + " was provided, but it wasn't requested!");
}
});
return primaryDataForSimona;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import edu.ie3.datamodel.models.result.ModelResultEntity;
import edu.ie3.datamodel.models.result.NodeResult;
import edu.ie3.datamodel.models.result.system.SystemParticipantResult;
import edu.ie3.simona.api.data.ExtOutputData;
import edu.ie3.simona.api.data.ExtOutputDataConnection;
import edu.ie3.simona.api.data.ontology.ScheduleDataServiceMessage;
import edu.ie3.simona.api.data.results.ontology.ProvideResultEntities;
import edu.ie3.simona.api.data.results.ontology.RequestResultEntities;
Expand All @@ -23,7 +23,7 @@
import org.apache.pekko.actor.ActorRef;

/** Enables data connection of results between SIMONA and SimonaAPI */
public class ExtResultData implements ExtOutputData {
public class ExtResultDataConnection implements ExtOutputDataConnection {

/** Data message queue containing messages from SIMONA */
public final LinkedBlockingQueue<ResultDataResponseMessageToExt> receiveTriggerQueue =
Expand All @@ -44,7 +44,7 @@ public class ExtResultData implements ExtOutputData {
/** Map uuid to external id of system participants */
private final Map<UUID, String> participantResultAssetMapping;

public ExtResultData(
public ExtResultDataConnection(
Map<UUID, String> participantResultAssetMapping, Map<UUID, String> gridResultAssetMapping) {
this.participantResultAssetMapping = participantResultAssetMapping;
this.gridResultAssetMapping = gridResultAssetMapping;
Expand Down
Loading