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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased/Snapshot]

### Added
- Added support for external em communication [#304](https://github.com/ie3-institute/simonaAPI/issues/304)

### Changed
- Removed Jenkinsfile [#290](https://github.com/ie3-institute/simonaAPI/issues/290)
- Adapted dependabot workflow and added CODEOWNERS [#294](https://github.com/ie3-institute/simonaAPI/issues/294)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
package edu.ie3.simona.api.data.connection;

import edu.ie3.simona.api.data.model.em.EmSetPoint;
import edu.ie3.simona.api.ontology.em.EmDataMessageFromExt;
import edu.ie3.simona.api.ontology.em.EmDataResponseMessageToExt;
import edu.ie3.simona.api.ontology.em.ProvideEmSetPointData;
import edu.ie3.simona.api.data.model.em.ExtendedFlexOptionsResult;
import edu.ie3.simona.api.data.model.em.FlexOptionRequest;
import edu.ie3.simona.api.data.model.em.FlexOptions;
import edu.ie3.simona.api.ontology.em.*;
import java.util.*;
import org.slf4j.Logger;

Expand All @@ -34,11 +35,47 @@ public List<UUID> getControlledEms() {
return new ArrayList<>(controlled);
}

/**
* Sends the em flex requests to SIMONA.
*
* @param tick current tick
* @param data receiver to flex request, that should be sent to SIMONA
* @param maybeNextTick option for the next tick in the simulation
* @param log logger
*/
public void sendFlexRequests(
long tick, Map<UUID, FlexOptionRequest> data, Optional<Long> maybeNextTick, Logger log) {
if (data.isEmpty()) {
log.debug("No em flex requests found! Sending no em data to SIMONA for tick {}.", tick);
} else {
log.debug("Provided SIMONA with em flex requests.");
sendExtMsg(new ProvideFlexRequest(tick, data, maybeNextTick));
}
}

/**
* Sends the em flex options to SIMONA.
*
* @param tick current tick
* @param data receiver to flex options, that should be sent to SIMONA
* @param maybeNextTick option for the next tick in the simulation
* @param log logger
*/
public void sendFlexOptions(
long tick, Map<UUID, List<FlexOptions>> data, Optional<Long> maybeNextTick, Logger log) {
if (data.isEmpty()) {
log.debug("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 ProvideEmFlexOption(tick, data, maybeNextTick));
}
}

/**
* Sends the em set points to SIMONA.
*
* @param tick current tick
* @param setPoints to be sent
* @param setPoints receiver to set point, that should be sent to SIMONA
* @param maybeNextTick option for the next tick in the simulation
* @param log logger
*/
Expand All @@ -48,10 +85,35 @@ public void sendSetPoints(
log.debug("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, setPoints, maybeNextTick));
sendExtMsg(new ProvideEmSetPoint(tick, setPoints, 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<UUID, ExtendedFlexOptionsResult> requestEmFlexResults(
long tick, List<UUID> emEntities, boolean disaggregated) throws InterruptedException {
sendExtMsg(new RequestEmFlexResults(tick, emEntities, disaggregated));
return receiveWithType(FlexOptionsResponse.class).receiverToFlexOptions();
}

/**
* Method to request the completion of the em service in SIMONA for the given tick.
*
* @param tick for which the em service should stop
* @return an option for the next tick in SIMONA
*/
public Optional<Long> requestCompletion(long tick) throws InterruptedException {
sendExtMsg(new RequestEmCompletion(tick));
return receiveWithType(EmCompletion.class).maybeNextTick();
}

/** Mode of the em connection */
public enum EmMode {
BASE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
public final class ExtPrimaryDataConnection
extends ExtInputDataConnection<PrimaryDataMessageFromExt> {

private final Map<UUID, Class<Value>> valueClasses;
private final Map<UUID, Class<? extends Value>> valueClasses;

public ExtPrimaryDataConnection(Map<UUID, Class<Value>> valueClasses) {
public ExtPrimaryDataConnection(Map<UUID, Class<? extends Value>> valueClasses) {
this.valueClasses = valueClasses;
}

Expand All @@ -34,7 +34,7 @@ public List<UUID> getPrimaryDataAssets() {
* @param uuid of the model
* @return an option for the value class associated with the model.
*/
public Optional<Class<Value>> getValueClass(UUID uuid) {
public Optional<Class<? extends Value>> getValueClass(UUID uuid) {
return Optional.ofNullable(valueClasses.get(uuid));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.Map;

/** Interface for data that are exchanged between an external simulation and SimonaAPI */
public sealed interface ExtDataContainer permits ExtInputContainer, ExtResultContainer {
public sealed interface ExtDataContainer permits ExtInputContainer, ExtOutputContainer {

/** Returns true, if the container is empty. */
boolean isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,14 @@ public void addPrimaryValue(UUID asset, Value value) {
* @param receiver the uuid of the agent, that will receive the request
* @param sender option for the uuid of the sender
*/
public void addRequest(UUID receiver, Optional<UUID> sender) {
public void addRequest(UUID receiver, UUID sender) {
flexRequests.put(receiver, new FlexOptionRequest(receiver, sender));
}

public void addRequest(UUID receiver, FlexOptionRequest request) {
flexRequests.put(receiver, request);
}

/**
* Method for adding flex options to a given receiver.
*
Expand All @@ -113,8 +117,8 @@ public void addFlexOptions(UUID receiver, List<FlexOptions> flexOption) {
* @param asset that will receive the set point
* @param power of the set point
*/
public void addSetPoint(UUID asset, PValue power) {
setPoints.put(asset, new EmSetPoint(asset, power));
public void addSetPoint(UUID asset, UUID sender, PValue power) {
setPoints.put(asset, new EmSetPoint(asset, sender, power));
}

/**
Expand All @@ -123,7 +127,7 @@ public void addSetPoint(UUID asset, PValue power) {
* @param setPoint given set point
*/
public void addSetPoint(EmSetPoint setPoint) {
setPoints.put(setPoint.receiver, setPoint);
setPoints.put(setPoint.receiver(), setPoint);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* © 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.result.ResultEntity;
import edu.ie3.simona.api.data.model.em.EmData;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

/** Contains all SIMONA results for a certain tick. */
public final class ExtOutputContainer implements ExtDataContainer {

/** Tick for which the results are meant for. */
private final long tick;

/** Tick when the external simulation can expect the next results from SIMONA. */
private final Optional<Long> maybeNextTick;

/**
* Map: receiver uuid to result from SIMONA.
*
* <p>ATTENTION: The time stamp of the result entities is not necessarily corresponding to the
* tick
*/
private final Map<UUID, ResultEntity> resultMap;

/** Map: receiver uuid to {@link EmData} from SIMONA. */
private final Map<UUID, EmData> emDataMap;

/**
* Container class for result data from SIMONA.
*
* @param tick current tick
* @param nextTick tick the external simulation can expect the next results
*/
public ExtOutputContainer(long tick, Optional<Long> nextTick) {
this.tick = tick;
this.resultMap = new HashMap<>();
this.emDataMap = new HashMap<>();
this.maybeNextTick = nextTick;
}

public ExtOutputContainer(long tick) {
this(tick, Optional.empty());
}

@Override
public boolean isEmpty() {
return resultMap.isEmpty() && emDataMap.isEmpty();
}

public void addResult(UUID receiver, ResultEntity result) {
resultMap.put(receiver, result);
}

public void addResults(Map<UUID, ResultEntity> result) {
this.resultMap.putAll(result);
}

public void addEmData(UUID receiver, EmData emData) {
emDataMap.put(receiver, emData);
}

public void addEmData(Map<UUID, EmData> emData) {
this.emDataMap.putAll(emData);
}

/** Returns a map: uuid to result. */
public Map<UUID, ResultEntity> getResults() {
return resultMap;
}

public Map<UUID, EmData> getEmData() {
return emDataMap;
}

/**
* Method to extract results of a specific type.
*
* @param clazz of the results
* @return a map: uuid to requested result, or an empty map, if no results for the requested type
* are present
* @param <R> result type
*/
@SuppressWarnings("unchecked")
public <R extends ResultEntity> Map<UUID, R> getResults(Class<R> clazz) {
Map<UUID, R> result = new HashMap<>();

for (Map.Entry<UUID, ResultEntity> entry : resultMap.entrySet()) {
ResultEntity resultEntity = entry.getValue();

if (entry.getValue().getClass().equals(clazz)) {
// add the result, if the found result is of the requested type
result.put(entry.getKey(), (R) resultEntity);
}
}

return result;
}

/** Returns the tick the data is provided for. */
public long getTick() {
return tick;
}

/** Returns an option for the next tick, when data will be provided. */
public Optional<Long> getMaybeNextTick() {
return maybeNextTick;
}

/** Returns the result for a certain asset. */
public ResultEntity getResult(UUID assetId) {
return resultMap.get(assetId);
}
}
Loading