Wattson’s Co-Simulation Coordination

The Co-Simulation Controller in Wattson manages the Co-Simulation and coordination of multiple simulators as well as their individual components. For a unified interface, Wattson relies on Queries that are sent to the Co-Simulation Controller and that are then handled either directly by it or passed to other simulators to handle. Queries can have a side-effect, e.g., they can change the topology of the network. After the Query has been implemented, a Response is returned to the querying entity.

Queries & Responses

A Query (WattsonQuery) is an object that has a type (string) and some data (usually a dictionary).

Queries are sent by entities, e.g., simulators, network nodes or the user of Wattson, and forwarded to the Co-Simulation Controller. Every component, e.g., the WattsonNetworkEmulator or the PhysicalSimulator, register to the Co-Simulation Controller as a Query Handler. This allows the Controller to forward queries to these handlers.

The type serves as an identifier for the desired functionality and also allows the Co-Simulation Controller to correctly route the Query to the respective component. Each Query Handler states whether they are willing to handle the respective type. Each handler can use arbitrary types, e.g., the NetworkEmulator supports the get-nodes query type which is used to return a list of all network nodes to the querying entity. For further routing refinements, the WattsonQuery can be used as a parent class to define own query classes, e.g., the WattsonNetworkQuery.

The data allows to pass options to the query handler to specify what exactly should be done or returned. The data is not standardized but follows the convention that it should be a dictionary with fixed key names. For instance, the NetworkEmulator supports the query of type remove-node to remove a network node from the emulated network. Each node is identified by a unique entityId. Hence, to specify which node to remove, the data of the query is a dictionary with {"entity_id": $ENTITY_ID_OF_NODE}.

To each Query, a respective Response (WattsonResponse) is returned. It indicates whether the query has been handled successfully and can contain additional data, e.g., the list of nodes following the get-nodes example from above.

The overall flow is visualized in the following diagram.

Sometimes, the implementation of a query can take longer than a few milliseconds. To avoid the simulation from blocking and the client from waiting indefinitely, the QueryHandler can return an Response Promise (WattsonResponsePromise). Such a promise is still a response, but it does not contain a success status nor data yet. It just informs the querying entity that the query is being handled (asynchronously). The querying entity can wait for the promise to be resolved, i.e., to turn into a “real” Response, by polling the resolved status of the Response Promise (is_resolved()), by waiting for the promise to resolve (resolve(timeout)) or by setting a Callback to be called once the response is ready (on_resolve(callback)).

For instance, the network emulator could be instructed to create several new network nodes which might take a few seconds. Hence, the NetworkEmulator receives the Query, decides to handle it asynchronously in a separate thread, and immediately returns the Response Promise. As soon as the thread finishes the task, it resolves the pending promise which is sent to the querying entity. I.e., the ResponsePromise returns a usual Response which has the success status as well as any additional data.

Notifications

Similar to Queries, Notifications allow entities to communicate with each other. They can be sent by every component (e.g., a Network Node, the NetworkEmulator and PhysicalSimulator, the Co-Simulation Controller or the User). Each notification has a topic and optional data as well as a list of recipients. When a notification is sent by an entity, all other entities receive this notification and can either use it or discard the information. I.e., entities can filter Notifications by the recipient list and the topic. In contrast to a Query, a Notification has no Response.

The topic indicates the content of the notification. It can be related to the simulation as such as well as to aspects of the system under test.
E.g., the Co-Simulation Controller sends a simulation-start notification to all clients when the simulation starts, i.e., it informs about the simulation as such.

In contrast, the NetworkEmulator issues a Notification when the emulated network topology changes, i.e., it informs about an event in the system under test. Similarly, the PowerGridSimulator informs all subscribed clients about changed measurements as well as the state of the simulation itself.

Events

Events are “stateful” notifications. Each event has a name and a state (i.e., it occurred or it did not yet occur). Wattson Events can be seen as a multi-entity implementation of the default threading.Event in Python.

Events are centrally managed by the Co-Simulation Controller and dynamically created when needed. By default, no event occured.
Each entity can query the state of an event and change it, i.e., an Event can be set or cleared. Each entity is informed about the change of the event state. In contrast to Notifications, events are persistent. When Entity A sets an Event before Entity B even joins the Co-Simulation, Entity B is still synchronized to the Event. By default, Notifications are not persisted (although topics can be marked to be kept).

Scroll to Top