Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External simulation: Providing information about next tick of MobSim #777

Merged
merged 25 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8b973ad
Providing detailed information about next tick per agent
sebastian-peter Mar 22, 2024
7c482ea
Removing unused scheduleKey
sebastian-peter Mar 22, 2024
3cd05a8
Towards a functioning ExtEvDataService...
sebastian-peter Mar 22, 2024
6fc8187
Removing PhaseSwitch implementation and utilization
sebastian-peter Mar 22, 2024
a49c0ff
Merge branch 'dev' into sp/#776-ext-sim-next-tick
sebastian-peter Apr 2, 2024
19bed20
More implementation & cleanup
sebastian-peter Apr 2, 2024
2ac0ceb
Adapting to changes in simonaAPI interface
sebastian-peter Apr 9, 2024
cf8237f
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Jun 21, 2024
b862035
Adapting changelog to changed issue
sebastian-peter Jun 21, 2024
54963e1
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Jul 23, 2024
46e5cbb
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Jul 23, 2024
500bc4d
Providing test for empty arrivals
sebastian-peter Jul 24, 2024
5d32101
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Aug 8, 2024
2d32cf3
Adapt to changed ev protocol
sebastian-peter Aug 8, 2024
a5753d5
Handling requests also in case activation has already arrived
sebastian-peter Aug 9, 2024
cfde81d
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Aug 9, 2024
1da5700
Explanatory commentary
sebastian-peter Aug 9, 2024
2b40f2e
Updating simonaAPI to release version 0.5
sebastian-peter Aug 9, 2024
1f0a885
Refactoring old EvMovement classes
sebastian-peter Aug 12, 2024
22450d0
Updating UML documentation related to mobility simulation (class diag…
sebastian-peter Aug 12, 2024
98a2016
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Aug 12, 2024
f74c24a
Improved format
sebastian-peter Aug 12, 2024
99d94e1
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
sebastian-peter Aug 14, 2024
fe0512a
Merge branch 'dev' into sp/#776-ext-sim-next-tick
danielfeismann Aug 15, 2024
d4308df
Merge branch 'refs/heads/dev' into sp/#776-ext-sim-next-tick
danielfeismann Aug 15, 2024
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 @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated PSDM to version 5.1.0 [#835](https://github.com/ie3-institute/simona/issues/835)
- Refactor `WeatherSource` and `WeatherSourceWrapper` [#180](https://github.com/ie3-institute/simona/issues/180)
- Remove unnecessary dependency `pekko-connectors-csv` [#857](https://github.com/ie3-institute/simona/issues/857)
- External simulation should provide information about next tick of MobSim [#776](https://github.com/ie3-institute/simona/issues/776)

### Fixed
- Removed a repeated line in the documentation of vn_simona config [#658](https://github.com/ie3-institute/simona/issues/658)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ dependencies {
exclude group: 'edu.ie3'
}

implementation('com.github.ie3-institute:simonaAPI:0.4.0') {
implementation('com.github.ie3-institute:simonaAPI:0.5-SNAPSHOT') {
exclude group: 'org.apache.logging.log4j'
exclude group: 'org.slf4j'
/* Exclude our own nested dependencies */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import edu.ie3.simona.model.participant.{
SystemParticipant,
}
import edu.ie3.simona.ontology.messages.Activation
import edu.ie3.simona.ontology.messages.SchedulerMessage.ScheduleActivation
import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage.{
FlexResponse,
IssueFlexControl,
Expand All @@ -59,7 +58,6 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{
}
import edu.ie3.simona.util.SimonaConstants.INIT_SIM_TICK
import edu.ie3.util.scala.quantities.ReactivePower
import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorRefOps
import org.apache.pekko.actor.typed.{ActorRef => TypedActorRef}
import org.apache.pekko.actor.{ActorRef, FSM}
import squants.{Dimensionless, Power}
Expand Down Expand Up @@ -355,36 +353,21 @@ abstract class ParticipantAgent[
isYetTriggered,
),
) =>
/* We yet have received at least one data provision message. Handle all messages, that follow up for this tick, by
* adding the received data to the collection state data and checking, if everything is at its place */
val unexpectedSender = baseStateData.foreseenDataTicks.exists {
case (ref, None) => msg.serviceRef == ref
case _ => false
}

if (data.contains(msg.serviceRef) || unexpectedSender) {
if (data.contains(msg.serviceRef)) {
/* Update the yet received information */
val updatedData = data + (msg.serviceRef -> Some(msg.data))

/* If we have received unexpected data, we also have not been scheduled before */
if (unexpectedSender)
scheduler ! ScheduleActivation(
self.toTyped,
msg.tick,
msg.unlockKey,
)

/* Depending on if a next data tick can be foreseen, either update the entry in the base state data or remove
* it */
val foreSeenDataTicks =
val foreseenDataTicks =
baseStateData.foreseenDataTicks + (msg.serviceRef -> msg.nextDataTick)
val updatedBaseStateData = BaseStateData.updateBaseStateData(
baseStateData,
baseStateData.resultValueStore,
baseStateData.requestValueStore,
baseStateData.voltageValueStore,
baseStateData.additionalActivationTicks,
foreSeenDataTicks,
foreseenDataTicks,
)
val updatedStateData: DataCollectionStateData[PD] = stateData
.copy(
Expand Down Expand Up @@ -611,16 +594,13 @@ abstract class ParticipantAgent[
actorRef -> None
}

val unforeseenPossible =
baseStateData.foreseenDataTicks.exists(_._2.isEmpty)

val nextStateData = DataCollectionStateData(
baseStateData,
expectedSenders,
yetTriggered = true,
)

if (expectedSenders.nonEmpty || unforeseenPossible) {
if (expectedSenders.nonEmpty) {
/* Do await provision messages in HandleInformation */
goto(HandleInformation) using nextStateData
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ import edu.ie3.simona.model.participant.{
SystemParticipant,
}
import edu.ie3.simona.ontology.messages.Activation
import edu.ie3.simona.ontology.messages.SchedulerMessage.{
Completion,
ScheduleActivation,
}
import edu.ie3.simona.ontology.messages.SchedulerMessage.Completion
import edu.ie3.simona.ontology.messages.flex.FlexibilityMessage._
import edu.ie3.simona.ontology.messages.flex.MinMaxFlexibilityMessage.ProvideMinMaxFlexOptions
import edu.ie3.simona.ontology.messages.services.ServiceMessage.{
Expand Down Expand Up @@ -514,36 +511,6 @@ protected trait ParticipantAgentFundamentals[
}
}

val unexpectedSender = baseStateData.foreseenDataTicks.exists {
case (ref, None) => msg.serviceRef == ref
case _ => false
}

/* If we have received unexpected data, we also have not been scheduled before */
if (unexpectedSender) {
baseStateData match {
case modelStateData: ParticipantModelBaseStateData[_, _, _, _] =>
val maybeEmAgent = modelStateData.flexStateData.map(_.emAgent)

maybeEmAgent match {
case Some(emAgent) =>
emAgent ! ScheduleFlexRequest(
modelStateData.model.getUuid,
msg.tick,
msg.unlockKey,
)
case None =>
scheduler ! ScheduleActivation(
self.toTyped,
msg.tick,
msg.unlockKey,
)
}
case _ =>
false
}
}

/* If the sender announces a new next tick, add it to the list of expected ticks, else remove the current entry */
val foreseenDataTicks =
baseStateData.foreseenDataTicks + (msg.serviceRef -> msg.nextDataTick)
Expand Down Expand Up @@ -1098,9 +1065,9 @@ protected trait ParticipantAgentFundamentals[
false
}

// Only for completing initialization:
// if we are EM-managed, there is no new tick for the
// scheduler, since we are activated by the EmAgent from now on
// If we're completing initialization and we're EM-managed:
// There is no new tick for the scheduler,
// since we are activated by the EmAgent from now on
scheduler ! Completion(
self.toTyped,
maybeNextTick.filterNot(_ => emManaged),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ protected trait EvcsAgentFundamentals
.getOrElse(tick, Map.empty)
.collectFirst {
// filter secondary data for arriving EVs data
case (_, arrivingEvsData: ArrivingEvsData) =>
case (_, arrivingEvsData: ArrivingEvs) =>
arrivingEvsData.arrivals
}
.getOrElse(Seq.empty)
Expand Down Expand Up @@ -318,7 +318,7 @@ protected trait EvcsAgentFundamentals
.values
.collectFirst {
// filter secondary data for arriving EVs data
case _: ArrivingEvsData =>
case _: ArrivingEvs =>
handleArrivingEvsAndGoIdle(
tick,
scheduler,
Expand Down Expand Up @@ -485,32 +485,39 @@ protected trait EvcsAgentFundamentals
val relevantData =
createCalcRelevantData(modelBaseStateData, tick)

val lastState = getLastOrInitialStateData(modelBaseStateData, tick)
val updatedBaseStateData = {
if (relevantData.arrivals.nonEmpty) {
val lastState = getLastOrInitialStateData(modelBaseStateData, tick)

val currentEvs = modelBaseStateData.model.determineCurrentEvs(
relevantData,
lastState,
)
val currentEvs = modelBaseStateData.model.determineCurrentEvs(
relevantData,
lastState,
)

// if new EVs arrived, a new scheduling must be calculated.
val newSchedule = modelBaseStateData.model.calculateNewScheduling(
relevantData,
currentEvs,
)
// if new EVs arrived, a new scheduling must be calculated.
val newSchedule = modelBaseStateData.model.calculateNewScheduling(
relevantData,
currentEvs,
)

// create new current state
val newState = EvcsState(currentEvs, newSchedule, tick)
// create new current state
val newState = EvcsState(currentEvs, newSchedule, tick)

val updatedStateDataStore = ValueStore.updateValueStore(
modelBaseStateData.stateDataStore,
tick,
newState,
)
val updatedStateDataStore = ValueStore.updateValueStore(
modelBaseStateData.stateDataStore,
tick,
newState,
)

/* Update the base state data with the updated result value store and relevant data store */
val updatedBaseStateData = modelBaseStateData.copy(
stateDataStore = updatedStateDataStore
)
/* Update the base state data with the updated state data store */
modelBaseStateData.copy(
stateDataStore = updatedStateDataStore
)
} else
// Empty arrivals means that there is no data for this EVCS at the current tick,
// thus we just return and wait for the next activation
modelBaseStateData
}

// We're only here if we're not flex-controlled, thus sending a Completion is always right
goToIdleReplyCompletionAndScheduleTriggerForNextAction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{
ProvisionMessage,
ServiceRegistrationMessage,
}
import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey
import org.apache.pekko.actor.ActorRef

import java.util.UUID
Expand Down Expand Up @@ -48,8 +47,7 @@ object EvMessage {
override val tick: Long,
override val serviceRef: ActorRef,
override val data: EvData,
override val nextDataTick: Option[Long] = None,
override val unlockKey: Option[ScheduleKey] = None,
override val nextDataTick: Option[Long],
) extends EvMessage
with ProvisionMessage[EvData]

Expand All @@ -74,7 +72,7 @@ object EvMessage {
* @param arrivals
* EVs arriving at the charging station
*/
final case class ArrivingEvsData(
final case class ArrivingEvs(
arrivals: Seq[EvModelWrapper]
) extends EvData {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package edu.ie3.simona.ontology.messages.services

import edu.ie3.simona.agent.participant.data.Data.PrimaryData.ApparentPower
import edu.ie3.simona.ontology.messages.services.ServiceMessage.ProvisionMessage
import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey
import org.apache.pekko.actor.ActorRef

sealed trait PrimaryDataMessage
Expand All @@ -30,7 +29,6 @@ object PrimaryDataMessage {
override val serviceRef: ActorRef,
override val data: ApparentPower,
override val nextDataTick: Option[Long],
override val unlockKey: Option[ScheduleKey] = None,
) extends ProvisionMessage[ApparentPower]
with PrimaryDataMessage
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey
*/
sealed trait ServiceMessage

case object ServiceMessage {
object ServiceMessage {

/** Message used to register for a service
*/
Expand Down Expand Up @@ -75,7 +75,10 @@ case object ServiceMessage {
val tick: Long
val serviceRef: ActorRef
val data: D

/** Next tick at which data could arrive. If None, no data is expected for
* the rest of the simulation
*/
val nextDataTick: Option[Long]
val unlockKey: Option[ScheduleKey]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import edu.ie3.simona.ontology.messages.services.ServiceMessage.{
ProvisionMessage,
ServiceRegistrationMessage,
}
import edu.ie3.simona.scheduler.ScheduleLock.ScheduleKey
import edu.ie3.util.scala.quantities.Irradiance
import org.apache.pekko.actor.ActorRef
import squants.{Temperature, Velocity}
Expand Down Expand Up @@ -54,7 +53,6 @@ object WeatherMessage {
override val serviceRef: ActorRef,
override val data: WeatherData,
override val nextDataTick: Option[Long],
override val unlockKey: Option[ScheduleKey] = None,
) extends WeatherMessage
with ProvisionMessage[WeatherData]

Expand Down
Loading