Getting Started

This page presents a getting started guide using the command-line interface of Maestro.

Additional information is available at API.

0. Environment

Maestro is built with Java 11, but it is expected that Java 8 will work as well.

1. Downloads

Download the latest coe jar from releases: https://github.com/INTO-CPS-Association/maestro/releases/latest

We will be running a co-simulation of the MassSpringDamper case study, described in https://github.com/INTO-CPS-Association/example-mass_spring_damper.

Download the two Mass Spring Damper FMUs exported from 20-sim: https://github.com/INTO-CPS-Association/example-mass_spring_damper/tree/master/FMUs/20-Sim

Place both jar and FMUs in the same folder.

2. Describe FMU Connections

Create the following scenario.json file in the same folder as the jar file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
    "fmus":{
        "{msd1}":"MassSpringDamper1.fmu",
        "{msd2}":"MassSpringDamper2.fmu"
    },
    "connections":{
        "{msd1}.msd1i.x1":[
            "{msd2}.msd2i.x1"
        ],
        "{msd1}.msd1i.v1":[
            "{msd2}.msd2i.v1"
        ],
        "{msd2}.msd2i.fk":[
            "{msd1}.msd1i.fk"
        ]
    },
    "logVariables":{
        "{msd2}.msd2i":[
            "x2",
            "v2"
        ]
    },
    "parameters":{
        "{msd2}.msd2i.c2":1.0,
        "{msd2}.msd2i.cc":1.0,
        "{msd2}.msd2i.d2":1.0,
        "{msd2}.msd2i.dc":1.0,
        "{msd2}.msd2i.m2":1.0
    },
    "algorithm":{
        "type":"fixed-step",
        "size":0.001
    },
    "loggingOn":false,
    "overrideLogLevel":"INFO"
}

4a. Running a Co-simulation using CLI

Open a terminal in the same folder and execute java -jar coe-1.0.10-jar-with-dependencies.jar --configuration scenario.json  --oneshot --starttime 0.0 --endtime 10.0

Afterwards an outputs.csv file is available with the co-simulation results.

4b. Running a Co-simulation with Master Web Interface for Co-Simulation

This requires a bit more than execting a co-simulation using the CLI.

For this reason, a Python scrpt will be used as reference and explained in bits. Full Python Script

4b.1 Launch the COE

Launch the COE with a single argument, which makes it start up as a web server on port 8082: java -jar coe-1.0.10-jar-with-dependencies.jar -p 8082.

conn = http.client.HTTPConnection('localhost:' + str(port))

4b.2 Create a Session

It is necessary to create a session before conducting a co-simulation.

Example response: {'sessionId': '5f439916-23f8-4609-9ff8-5f81408b9046'}.

Python code:

print("Create session")
conn.request('GET', '/createSession')
response = conn.getresponse()
if not response.status == 200:
    print("Could not create session")
    sys.exit()

status = json.loads(response.read().decode())
print ("Session '%s', data=%s'" % (status["sessionId"], status))

4b.3 Initialize the co-simulation

Send the scenario.json to the server.

Example response: [{"status":"Initialized","sessionId":"5f439916-23f8-4609-9ff8-5f81408b9046","lastExecTime":0,"avaliableLogLevels":{"{msd2}.msd2i":[],"{msd1}.msd1i":[]}}].

Python code:

response = post(conn, '/initialize/' + status["sessionId"], "scenario.json")
if not response.status == 200:
    print("Could not initialize")
    sys.exit()

print ("Initialize response code '%d, data=%s'" % (response.status, response.read().decode()))

4b.4 Optional: Connect Web Socket

At this stage, one can connect a web socket if so desired. This is currently not part of the scenario. See the API for more information.

4b.5 Run the Co-Simulation

The information passed as CLI arguments are now part of a simulate.json file:

1
2
3
4
{
  "startTime": 0,
  "endTime": 10
}

Send the simulate.json file to the server.

Example response: {"status":"Finished","sessionId":"5f439916-23f8-4609-9ff8-5f81408b9046","lastExecTime":1752}'.

Python code:

def post(c, location, data_path):
    headers = {'Content-type': 'application/json'}
    foo = json.load(open(data_path))
    json_data = json.dumps(foo)
    c.request('POST', location, json_data, headers)
    res = c.getresponse()
    return res

response = post(conn, '/simulate/' + status["sessionId"], "simulate.json")
if not response.status == 200:
    print("Could not simulate")
    sys.exit()

print ("Simulate response code '%d, data=%s'" % (response.status, response.read().decode()))

4b.6 Get the results

Retrieve the csv results and store in result.csv

Example response: CSV content (too large to show).

Python code:

conn.request('GET', '/result/' + status["sessionId"] + "/plain")
response = conn.getresponse()
if not response.status == 200:
    print("Could not receive results")
    sys.exit()

result_csv_path = "result.csv"
csv = response.read().decode()
print ("Result response code '%d" % (response.status))
f = open(result_csv_path, "w")
f.write(csv)
f.close()

4b.7 Destroy the session

Destroy the session and allow Maestro to clean up session data

Example reponse: ‘Session 5f439916-23f8-4609-9ff8-5f81408b9046 destroyed’

Python code:

conn.request('GET', '/destroy/' + status['sessionId'])
response = conn.getresponse()
if not response.status == 200:
    print("Could not destroy session")
    sys.exit()

print ("Destroy response code '%d, data='%s'" % (response.status, response.read().decode()))