All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.ie3.simona.api.simulation.ExtSimulation Maven / Gradle / Ivy

/*
 * © 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.simulation;

import edu.ie3.simona.api.data.ExtData;
import edu.ie3.simona.api.data.ev.ExtEvData;
import edu.ie3.simona.api.data.ev.ExtEvSimulation;
import edu.ie3.simona.api.simulation.ontology.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Every external simulation must extend this class in order to get triggered by the main
 * simulation.
 */
public abstract class ExtSimulation implements Runnable {

  private ExtSimAdapterData data;

  protected ExtSimulation() {}

  public void run() {
    try {
      // now we can start the loop
      boolean simulationFinished = false;
      while (!simulationFinished) {
        simulationFinished = takeAndHandleMessage();
      }
    } catch (InterruptedException ie) {
      // This is the topmost method in the thread call stack,
      // so we handle the exception ourselves
      Thread.currentThread().interrupt();
    }
  }

  /**
   * Blocks until the next message is received and handles it.
   *
   * @return true if simulation is terminated after handling this message
   * @throws InterruptedException if the thread running this has been interrupted (possibly during
   *     blocking)
   */
  private boolean takeAndHandleMessage() throws InterruptedException {
    // take() will block until an object is ready for us
    final ControlMessageToExt msg = data.receiveMessageQueue.take();

    if (msg.getClass().equals(ActivationMessage.class)) {
      final ActivationMessage activationMessage = (ActivationMessage) msg;
      Optional newTrigger;

      if (activationMessage.tick() == -1L) {
        newTrigger = initialize(); // this is blocking until initialization has finished
      } else {
        newTrigger =
            doActivity(
                activationMessage
                    .tick()); // this is blocking until processing of this tick has finished
      }
      data.send(new CompletionMessage(newTrigger));

      return newTrigger.isEmpty();
    } else if (msg.getClass().equals(TerminationMessage.class)) {
      final TerminationMessage terminationMsg = (TerminationMessage) msg;
      terminate(terminationMsg.simulationSuccessful());
      data.send(new TerminationCompleted());

      return true;
    } else {
      throw new IllegalArgumentException("Invalid message " + msg + " received.");
    }
  }

  /**
   * This method is called when the external simulation needs to be initialized
   *
   * @return The first regular tick at which this external simulation wants to be triggered, if
   *     applicable.
   */
  protected abstract Optional initialize();

  /**
   * This method is called for every tick of the external simulation that is triggered.
   *
   * @param tick The current tick
   * @return The next tick at which this external simulation wants to be triggered, if applicable.
   */
  protected abstract Optional doActivity(long tick);

  /**
   * This method is called when the main simulation wants to terminate.
   *
   * @param simulationSuccessful Whether the simulation was run successfully or has ended with an
   *     error
   */
  protected void terminate(Boolean simulationSuccessful) {
    // to be overwritten in subclass
  }

  public final List> getRequiredAdapters() {
    ArrayList> classes = new ArrayList<>();

    if (this instanceof ExtEvSimulation) classes.add(ExtEvData.class);

    return classes;
  }

  public final void setup(ExtSimAdapterData data, List adapters) {
    this.data = data;

    // todo sanity check if all required data is available
    for (ExtData adapter : adapters) {
      if (adapter instanceof ExtEvData && this instanceof ExtEvSimulation)
        ((ExtEvSimulation) this).setExtEvData((ExtEvData) adapter);
    }
  }

  /**
   * Provides the program arguments that the main simulation was started with
   *
   * @return the main args
   */
  protected String[] getMainArgs() {
    return data.getMainArgs();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy