Innoslate Scripting Guide

Mastering Simulation Scripting in Innoslate: A Comprehensive Guide to Automating and Customizing Simulations

Sections Available in the Scripting Guide

Function Description
Innoslate Simulators Discover the capabilities of Innoslate Simulators, empowering you to simulate and analyze complex systems and other applicable utilities.
JavaScript Basics Learn how to utilize JavaScript basics in the Innoslate Scripting Guides, enabling automation and customization of simulations.
Pre-Built  Scripts Discover pre-built scripts in the Innoslate Scripting Guides to quickly apply common simulation functionalities and save development time.
OR Decisions Learn how to implement OR decisions in your simulation scripts to create conditional branching and decision-making scenarios.
API Advanced Simulation Explore advanced simulation capabilities through the Innoslate API in the Scripting Guides.
'Inno' API Advanced Sim. Unlock advanced simulation features with the 'Inno' API in the Innoslate Scripting Guides, providing you with powerful tools on Innoslate.
Using I/Os Master the usage of inputs and outputs (I/Os) in the Innoslate Scripting Guides, between simulation scripts and external systems.

1  Innoslate Simulators

Innoslate’s discrete event and Monte Carlo simulators require little scripting for most applications. The logic execution uses the decision points and Input/Output (I/O) triggers for basic problems, but for more complex simulations you will want to learn how to add scripts, which will range from minimal to complex.

2  JavaScript Basics

JavaScript was initially created to “make web pages alive”. The programs in this language are called scripts. They can be written right in a web page’s HTML and run automatically as the page loads. Scripts are provided and executed as plain text. They don’t need special preparation or compilation to run. The syntax for JavaScript is shown.

JS Picture1-1

 

For adding to Innoslate scripts, note the use of “let” to define a variable. Innoslate script allows either “let” or “var” to define variables. Comments can also be added using two backslashes (//). Also “print()” statements can easily be added. These statements print to the Innoslate simulator console.


The OR and LOOP decision points (special cases of the Action) already come with pre-built scripts (Probability and Resource for both and Iterations for the Loop). These can be used without any scripting on your part. Just select the script type you want, adjust the values, and submit the script, then we generate the script automatically. The code behind each decision point’s script type can be accessed by selecting ‘Script’ from the drop-down menu. An example of each is shown in the later sections below. 

3  Pre-Built Scripts

3.1  OR Script

3.1.1  OR Probability

The user selects “Or Probability” from the drop-down menu, as seen, then the user can adjust the branch probabilities, in this case making Yes is 70% of the time and No is 30%. 

JS Picture2

 

The script that is generated is shown. Note that the comment line at the top contains the information shown in the user interface above. The comment list each branch's ID number with its corresponding assigned percentages. If changes are made it is recommended to either update assigned percentages or delete it.

JS Picture3

3.1.2  OR Resource Script

The Or Resource script will use Resource entity attributes such as its Amount to be set and used as a condition for the Or Resource script. A Resource entity must be created first and available in the database. The branch options include logical constructs and values. This shows the user interface for the Or Resource script. 

JS Picture4

 

These options will be used to compare the Resource amount at the time the script is executed. This shows the resulting script from this selection. Note that the Global ID is used for getting the Resource from the database (using the Rest API: Sim.getAmountByGlobalId()). More on this is provided in the Advanced Simulator Scripting section.

JS Picture5

3.2  Loop Script

3.2.1  Loop Probability

Loop Probability will be based on the percentages set by the user. In this figure we changed the default probabilities from 50/50 to 80/20 between the Continue and Exit branches.

JS Picture6

 

This shows the generated script. The script allows the simulator to stay in the Continue branch because of the condition, “r <= 80”. If the condition is not met the simulator will leave on the Exit branch.

JS Picture7

3.2.2  Loop Resource

The Loop Resource is similar to the Or Resource, except the condition is based on the Resource’s amount value. Figure below shows the user interface for the Loop Resource. 

JS Picture8

 

This references the Resource construct in the script by using the REST API, “  Sim.getAmountByGlobalId()”, and Resource’s Global ID.

JS Picture9

3.2.3  Loop Iteration

The Loop Iteration script allows to user to tell the simulator amount of times the loop should run. Figure below shows the Loop Iterations user interface. We changed the number of iterations from the default value of 3 to 10. 

JS Picture10

 

Figure below shows the resulting script. Note that the “i” variable is initialized to zero outside the function and then “i” is incremented each time this function is called.

JS Picture11

 

It is recommended to start with these if you are building a new script, as it will often be easier to get the exit branch identifier automatically. Note that the branch identifier is not essential for the script and if you want to reuse (copy and paste) the script into other Actions/Decision Points, then you will want to eliminate them.

We also provide “stubs” for those needing to develop scripts from scratch for onStart(), onEnd(), and prompt(). At this point, you will need to know a little JavaScript to write executable programs. Note that prompting the user only works with the discrete event simulator and will throw an error in the Monte Carlo simulator.

One more common situation is the need to make sure that decision points are synchronized with other decision points. The next section discusses this situation.

4  Synchronizing OR Decision

Often we need to make sure that when a decision is made by one Asset that another Asset uses that decision to go down a particular path. We can see this in the example below. 

JS Picture12

 

In this diagram, the first asset makes a decision using a standard probability script. We want the second asset to respond to that decision and go down a similar path. For this to execute properly, we need to trigger the second decision point from the first, i.e. to ensure that the second decision point does not try to execute at the same time as the first one (which it would do without the “Decision” Input/Output entity.

But we also need to pass on to the second decision point what the decision was (yes or no in this case). This synchronizing of the decision can be accomplished by setting a JavaScript global variable or putting a “Yes” or “No” in the Input/Output attribute field. Let’s look at the first one.

Figure below shows the first decision point [Decide? (Asset #1)], where it starts with the standard probability script. Then we added the “globals.set” and “print” lines.

JS Picture13

 

For Asset #2’s OR script, then we get the global variable and use it instead of the probability to make the decision. We also added print statements to show it went down the correct path.

JS Picture14

The results for a yes decision are shown.

JS Picture15

 

The results for a no-decision are shown.

JS Picture16

5  Advance Simulator Script using API

The simulator has a scripting API (Sim) to allow users to gain access to data contained in the model being executed. To use many of these APIs, you need to provide the Global ID or project-level ID. These IDs can be found when selecting an entity in the Metadata tab on the sidebar.

Sim is a utility class that references methods used to access simulation objects during simulation. The figure identifies each of the functions available in the Sim API and what they return. 

JS Picture17

Note that the table below is missing two methods:

Sim.getResourceByGlobalId(GlobalID)

Sim.setResourceByGlobalId(GlobalId, amount)

These objects include:

  • Entities (Actions, Resources, I/Os, Conduits, Assets, Cost)
  • Current Time
  • HTTP Request

You can use these functions to get the names, numbers, descriptions, and any other related attributes of any of the entities available within the simulation. The entities are limited as the simulator only loads information on the entity classes listed above. The example below shows how to use these functions for Cost and Time. Figure below shows Actions that incur Costs. The picture shows a simple Action Diagram with two Actions. 

JS Picture18

 

The Action Diagram shows the incurs relationship and Cost entities for each Action. If you add the script into the Action diagram and then execute it, you will see the results in the final figure.

JS Picture19
JS Picture20

5.1  Using Resources in Simulators

Previous figures showed the predefined scripting capabilities in the OR and LOOP actions. These figures show how the pre-built scripts access the current amount of Resources identified by their GlobalIDs. These IDs are found in the Metadata tab of the entity view on the Action Diagram sidebar for the Resource, as seen. The scripts are able to be manipulated via user-defined scripts of an action and then plotted during the simulation.

JS Picture22

 

Important information about attributes of a Resource:

Resource Entity View 

Value of Resource not being between Minimum and Maximum Amount will cause the simulation to deadlock (break).

 Relationships created between Actions and Resources allow for Pre-Defined Scripting to: 

  • produces Resources
  • consumes Resources
  • seizes Resources 

Either the produces or seizes relationship can be selected when you drag from a green circle on a highlighted Resource onto an Action, an overlay of the two options will be provided. If you select seizes the Resource icon will turn a lighter purple and the lines will have a “seizes”. This example shows an example of the produces relationship. Click on each Action Entity and go to ‘Relationships’ on the side panel, find the ‘produces’ relationship, and define the amount to produce.

JS Picture23

 

JS Picture24

 

This figure shows the results of the simulation. The consumed amount of the Resource is permanently taken away from the Resource, while seized amount only takes away from the Resource during an Action’s duration.

JS Picture25

 

Scripts can also be developed to change resources, with or without the Resource being directly associated with the Action.

JS Picture26

For this example, we had the Action produce 20 units (remember units are arbitrary and must be consistently set) of the Resource using the attribute on the produces/produced by relationship. The scripts for the Actions are shown below:

JS Picture27

 

The resulting simulation output is shown. Note that the produces relationship incrementing of the Resource occurs before the execution of the onEnd() script. So the net effect of the first script is to reduce the amount to 10 units from the original 20. The second script reduces the amount of the Resource by another 5 units. 

JS Picture28

5.2  Using Scripts Prompts

The Innoslate simulator can help conduct tabletop exercises, and develop standard operating procedures, and Concepts of Operations. These applications simulate how users may respond to different events and how the system reacts to the user’s input. As such, scripts to prompt the user for input have also been provided. This table below shows the prompt script methods and their purpose.

JS Picture29

 

Note these prompts may only be used with the discrete event simulator. If these prompts are enabled during a Monte Carlo simulation the user will receive an error message.

An example of using this prompt is shown. The prompt method automatically returns the “response” variable to the script, so that the user only needs to use the onEnd(response) function call. 

JS Picture30

6  Advance Simulator Scripting Using ‘Inno’ API

The “Inno” APIs consist of the following methods: InnoObject, InnoEntity, InnoAttributes, InnoSimulation, InnoRelationships, and InnoLabels. These methods can only be used with the entity classes directly related to the instances included in the simulation. They cannot manipulate other classes within the database, such as Risk, Time, Measures, etc. Any changes to the attributes, relationships, and labels are only temporary and contained within the simulation. This limitation is a security feature that makes database corruption impossible. It also is essential for cyber security in a cloud environment. To make database changes, you can use the general JavaAPIs with the Enterprise version of Innoslate.

The following subsections discuss each of these methods and their usage.

6.1  InnoObject Methods

InnoObject methods enable the user to get and set most of the common attributes of any object (Name, Description, Created and Modified Dates, etc.). Table below shows these methods and their return values.

InnoObject Methods

Method Return 
getCreated() Creation time in milliseconds
getCreatedBy() The user that created the object
getDatabase() Database for the current entity
getDescription() Description text of the object
getDescriptionAsText() Strips out special characters and formatting
getGlobalID() The global ID of the entity
getId() The ID of the entity 
getModified() Modified time in milliseconds
getModifiedBy() The user that last modified the object
getName() Name of the object
isHidden() Determines if the object is a hidden object
isLocked() Determines if the object is locked
setDescription( text) Updated entity description 
setHidden( hidden ) Sets object as hidden
setLocked( locked ) Sets the locked state of the object
setName( name ) Updated entity name

 

An example of using some of these methods is shown. The results of the simulation are shown in the Console panel in the figure.

JS Picture31

6.2  InnoEntity Methods

InnoEntity methods enable the user to get and set most of the common attributes and properties of any class entity (Number). This table shows these methods and their return values.

InnoAttribute Methods

Method(s) Return
setInnoClass( name ),

setInnoClassByName(
 name )
Entity Object
setInnoClassById( id ) Entity Object
getInnoClassId() Id number
getNumber() Entity’s Number
hasChanged() Boolean: true || false
instanceOf( name ), 
instanceOfByName(
 name )
Boolean: true || false
instanceOfById( id )  
setNumber( number ) Entity 

 

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for the first three actions.

JS Picture32

6.3  InnoAttributes Methods

InnoAttributes methods enable the user to get and set any attributes of any object. This table shows these methods and their return values.

InnoAttribute Methods

Method Input Return
all()   id: attribute value of all attributes
get( name ),

getByName(
 name )
String id: attribute value
getById( id ) Integer id: attribute value
getByProperty( property ) InnoProperty id: attribute value
set( name,value ), 
setByName( name,value )
String, String InnoEntity 
setById( i d,value ) Integer, String InnoEntity 
setByProperty( property,value ) InnoProperty, String  

 

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions.

JS Picture33

6.4  InnoSimulation Methods

InnoSimulation methods enable the user to get and set simulation scripts. This capability would enable the user to create different scripts for execution within the simulation. This table shows these methods and their return values.

InnoSimulation Methods

Method Input Return
getScript()   The string of the script
getScript( script ) String  

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions.

JS Picture34

6.5  InnoRelationship Methods

InnoRelationship methods enable the user to get and set relationships between entities. This table shows these methods and their return values.

InnoRelationship Methods

Method Return
add( relationName, target ), addByName( relationName, target ) Entity
addById( relationId, target ) Entity
addByRelation( relation,target )  
allLazy() The array of all InnoEntity related to Entity
allTargetIds() all IDs of related Entities
allTargetIdsMap() Map of IDs
allTargets() The array of InnoEntity objects
get( name, target ),

getByName( name, target )
EntityRelationship object if exist, or false
getById( id,target ) EntityRelationship object if exist, or false
getAndRemove( name,target ) EntityRelationship object if exist, or false
remove( relationship ) True if successful
anyByIdLazy( id ) Array of InnoRelations

anyLazy( name ),


anyByNameLazy( name )

Array of InnoRelations
anyTargetIds( name )

IDs of related Entities
anyTargetIdsById( relationId )

IDs that have given a relationship with 
contains( relationship )

Boolean
containsAny(relationName),



containsAnyByName(relationName)
Boolean
containsAnyById( id ) Boolean
containsById( relationId, target ) Boolean
containsByName( relationName, target ) Boolean
countAny( relationName ),



countAnyByName( relationName )

Integer
countAnyById( id ) Integer

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions.

JS Picture34

6.6  InnoLabel Methods

InnoLabel methods enable the user to perform operations like add, remove, and check for labels. This table shows these methods and their return values.

InnoLabel Methods

Method Input Return
add( label ) InnoLabel InnoEntity
addByName( id ) Integer InnoEntity
addByName( name ) String InnoEntity
all()   label id: InnoLabel pairs
contains( label ) InnoLabel Boolean
containsById( id ) Integer Boolean

containsByName

( name )

String Boolean
ids()   the array of label IDs
remove( InnoLabel ) InnoLabel  

 

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions.

JS Picture36

7  Using I/Os

We have already seen how Input/Output entities are used to control the sequencing of the Actions as a trigger. With version 4.5, a “Value” attribute was added to act as a variable in the simulation. This attribute allows information transfer to be more visual in the simulation, instead of just using global variables in the script. The value attribute is a text string and can be encoded with any data type. To access the Value attribute, you can use the Sim.getIOValueByNumber(), Sim.getIOValueById(), and Sim.getIOValueByGlobalId() methods for the “Sim” API. To set the I/O value, you will still need to use the InnoEntity methods discussed above. An example is provided below.

7.1  Using Basic I/O API

I/O can be used to store and retrieve values using the I/O construct. The I/O construct uses the following “Sim” API found:

I/O Sim APIs

Method Input Value Input Type Return
Sim.getIOValueByNumber() Entity’s Number Attribute String Entity Attribute Value
Sim.getIOValueById() Entity’s ID Integer Entity Attribute Value
Sim.getIOValueBYGlobalId() Entity’s Global ID integer Entity Attribute  Value

There are two ways to retrieve the I/O value and it’s based on whether the entity has a trigger or not. 

If an I/O has the following relationship used:

  •  “generated by” 
  • received by” 

The I/O will be a trigger for the entity with the “received by” relationship. An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions. 

JS Picture37

 

If an I/O has only one relationship used :

  • received by” 

The I/O will need to be set to ‘optional’ and this can be done by going to I/O “received by” relationship and turning the trigger field into “No” as seen. Doing this will avoid a deadlock when the simulation runs. 

JS Picture38

 

An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions. 

JS Picture39

 

Another use of the I/O is to set value and retrieve it for later use. To set a value for an IO is to assign a variable using the API and store a new value using “attributes().set()”. An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions. 

JS Picture40

7.2  Using Advanced I/O API

Section 7.1 provides the basics for setting and getting the IO entity value. This section will show how a user can set and get IO values from a decomposed parent diagram. This is done by making the I/O entity traced to the action entity prior to decomposing that entity. It will ensure the same IO is passed to its child entity. 

To set the IO value, the user will need to handle that script in the child entity. An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions. 

JS Picture41

 

Once the IO value is set by the child entity that IO value can be passed and used in the parent diagram. The user will need to make sure the IO is a trigger in the parent diagram to allow the value to be used. An example of using some of these methods is shown. The Console panel shown in this diagram shows the simulation results for these actions. 

JS Picture42

 

To continue learning about Simulators, Click Here.

(Next Article: Simulator API)