Simulator Objects
Simulator objects structure observer behavior and manage state variables during scenario execution.
Observer Objects
Observer objects are base classes that implement the observer pattern to loosely couple an observable and observer.
Observer and Observable classes implement the observer pattern using the observer pattern for loose coupling of behavior between objects. They are primarily building-blocks for other classes within the library.
The Entity class is a base simulation component that maintains stateful properties such as a simulation clock (i.e., the time). As an Observable, an Entity object notifies any bound Observers when its time property changes. The Entity class has stub methods to manage simulation state including initialize (before start of a new execution), tick (compute the next state variables during a time step interval), and tock (commit the next state variables at the time step boundary). Typically, users will create a custom Entity subclass to specialize behavior for a particular simulation entity.
The Simulation class manages scenario time advancement for an execution consisting of member Entity objects. As an Observable, a Simulation object notifies any bound Observers when any of its properties change including time, mode, time_scale_factor, duration, or time_step. The Simulator class has methods to manage simulation execution including initialize (prepares a new execution), execute (runs a new execution), and terminate (prematurely end an execution). When intitialized, a Simulator will initialize all member Entity objects. When executed, a Simulator will sequentially compute the next time step boundary, call tick on all member Entity objects to compute the next state, wait until the appropriate wallclock time, and finally call tock on all member Entity objects to process the state change. Timing options during initialization and execution specify the starting and ending scenario time, starting wallclock time, scenario time step duration (i.e., time interval between state updates), time scale factor (i.e., number of scenario seconds per wallclock second).
- class Observer
Bases:
ABCAbstract base class that can be notified of property changes from an associated
Observable.
- class Observable
Bases:
objectBase class that can register (add/remove) and notify observers of property changes.
- __init__()
Initializes a new observable.
- add_observer(observer: Observer) None
Adds an observer to this observable.
- Parameters:
observer (
Observer) – observer to be added
- class MessageObserver
Bases:
ABCAbstract base class for message observers that can receive RabbitMQ messages.
- class MessageObservable
Bases:
ObservableObservable that can notify observers of received messages.
- __init__()
Initialize message observable
- add_message_observer(observer: MessageObserver) None
Add a message observer.
- Parameters:
observer (MessageObserver) – The observer to add
- notify_message_observers(ch, method, properties, body) None
Notify all message observers about a received message.
- Parameters:
ch – Channel object
method – Method frame
properties – Message properties
body – Message body
- remove_message_observer(observer: MessageObserver) None
Remove a message observer.
- Parameters:
observer (MessageObserver) – The observer to remove
- class PropertyChangeCallback(property_name: str, callback: Callable[[object, object], None])
Bases:
ObserverTriggers a provided callback basedwhen a named property changes.
- class ScenarioTimeIntervalCallback(callback: Callable[[object, datetime], None], time_inteval: timedelta, time_init: timedelta | None = None)
Bases:
ObserverTriggers a provided callback at a fixed interval in scenario time.
- class WallclockTimeIntervalCallback(simulator: Simulator, callback: Callable[[datetime], None], time_inteval: timedelta, time_init: timedelta = None)
Bases:
ObserverTriggers a provided callback at a fixed interval in wallclock time.
- class Entity(name: str = None)
Bases:
ObservableA base entity that maintains its own clock (time) during scenario execution.
- Notifies observers of changes to one observable property
time: current scenario time
- __init__(name: str = None)
Initializes a new entity.
- Parameters:
name (str) – name of the entity (default: None)
- get_time() datetime
Retrieves the current scenario time.
- Returns:
current scenario time
- Return type:
- initialize(init_time: datetime) None
Initializes the entity at a designated initial scenario time.
- Parameters:
init_time (
datetime) – initial scenario time
- tick(time_step: timedelta) None
Computes the next state transition following an elapsed scenario duration (time step). If the entity hasn’t been initialized yet, the time_step will be stored but no time advancement will occur until the entity is initialized.
- Parameters:
time_step (
timedelta) – elapsed scenario duration
Scenario Objects
Scenario objects define states and methods for executing a simulation.
- class Mode(value)
-
Enumeration of simulation modes.
- The six simulation modes include
- UNDEFINED: Simulation is in an undefined state that is not one of the other modes.
For example, the simulation reverts to UNDEFINED after adding a new entity and must be re-initialized before execution.
INITIALIZING: Simulation is in the process of initialization.
INITIALIZED: Simulation has finished initialization and is ready to execute.
EXECUTING: Simulation is in the process of execution.
TERMINATING: Simulation is in the process of termination.
TERMINATED: Simulation has finished termination and is ready for initialization.
- class Simulator(wallclock_offset: timedelta = datetime.timedelta(0))
Bases:
ObservableObject that manages simulation of entities in a scenario.
- Notifies observers of changes to observable properties
time: current scenario time
mode: current execution mode
duration: scenario execution duration
time_step: scenario time step duration
- __init__(wallclock_offset: timedelta = datetime.timedelta(0))
Initializes a new simulator.
- Parameters:
wallclock_offset (
timedelta) – difference between the system clock and trusted wallclock source (default: zero)
- add_entity(entity: Entity) None
Adds an entity the the simulation.
- Parameters:
entity (
Entity) – entity to be added
- execute(init_time: datetime, duration: timedelta, time_step: timedelta, wallclock_epoch: datetime = None, time_scale_factor: float = 1) None
Executes a simulation for a specified duration with uniform time steps. Requires that the simulator is in UNDEFINED, INITIALIZED, or TERMINATED mode.
Initializes the simulation (if not already in the INITIALIZED mode), waits for the specified wallclock epoch, and transitions to the EXECUTING mode. During execution, incrementally performs state transitions for each entity. At the end of the simulation, transitions to the TERMINATING and, finally, TERMINATED mode.
- Parameters:
init_time (
datetime) – initial scenario timeduration (
timedelta) – scenario execution durationtime_step (
timedelta) – scenario time step durationwallclock_epoch (
datetime) – wallclock time corresponding to the initial scenario time, None uses the current wallclock time (default: None)time_scale_factor (float) – number of scenario seconds per wallclock second (default value: 1)
- get_duration() timedelta
Gets the scenario duration.
- Returns:
current scenario duration
- Return type:
timedelta
- get_entities() List[Entity]
Retrieves a list of all entities in the simulation.
- Returns:
list of entities in the simulation
- Return type:
List(Entity)
- get_entities_by_type(type: Type) List[Entity]
Retrieves a list of entities by type (class).
- Parameters:
type (Type) – type (class) of entity
- Returns:
list of entities with a matching type
- Return type:
List(Entity)
- get_init_time() datetime
Gets the initial scenario time.
- Returns:
initial scenario time
- Return type:
- get_simulation_epoch() datetime
Gets the scenario epoch.
- Returns:
current scenario epoch
- Return type:
- get_time_scale_factor() float
Gets the time scale factor in scenario seconds per wall clock second (>1 is faster-than-real-time).
- Returns:
current time scale factor
- Return type:
- get_time_step() timedelta
Gets the scenario time step duration.
- Returns:
time step duration
- Return type:
timedelta
- get_wallclock_epoch() datetime
Gets the wallclock epoch.
- Returns:
current wallclock epoch
- Return type:
- get_wallclock_time() datetime
Gets the current wallclock time.
- Returns:
current wallclock time
- Return type:
- get_wallclock_time_at_simulation_time(time: datetime) datetime
Gets the wallclock time corresponding to the designated scenario time.
- get_wallclock_time_step() timedelta
Gets the wallclock time step duration.
- Returns:
time step duration
- Return type:
timedelta
- initialize(init_time: datetime, wallclock_epoch: datetime = None, time_scale_factor: float = 1) None
Initializes the simulation to an initial scenario time. Requires that the simulator is in UNDEFINED, INITIALIZED, or TERMINATED mode.
Transitions to the INITIALIZING mode, initializes all entities to the initial scenario time, sets the wallclock epoch (wallclock time corresponding with the initial scenario time), and finally transitions to the INITIALIZED mode.
- remove_entity(entity: Entity) Entity
Removes an entity from the simulation.
- Parameters:
entity (
Entity) – entity to be removed- Returns:
removed entity
- Return type:
Entity
- resume() None
Resumes the scenario execution. Requires that the simulator is in PAUSING or PAUSED mode.
- set_duration(duration: timedelta) None
Sets the scenario duration. Requires that the simulator is in EXECUTING mode.
- Parameters:
duration (
timedelta) – scenario duration
- set_end_time(end_time: datetime) None
Sets the scenario end time. Requires that the simulator is in EXECUTING mode.
- Parameters:
end_time (
datetime) – scenario end time
- set_time_scale_factor(time_scale_factor: float, simulation_epoch: datetime = None) None
Sets the time scale factor in scenario seconds per wallclock second (>1 is faster-than-real-time). Requires that the simulator is in EXECUTING mode.
- set_time_step(time_step: timedelta) None
Set the scenario time step duration. Requires that the simulator is in EXECUTING mode.
- Parameters:
time_step (
timedelta) – scenario time step duration
- set_wallclock_offset(wallclock_offset: timedelta) None
Set the wallclock offset (difference between system clock and trusted wallclock source). Requires that the simulator is in UNDEFINED, INITIALIZING, INITIALIZED, or TERMINATED mode.
- Parameters:
wallclock_offset (
timedelta) – difference between system clock and trusted wallclock source