Reputation: 581
I would like to write a Python script to extract the same information about the inputs and outputs of a Modelica function as shown in the Dymola info layer, e.g. for the sine function:
I would like to show a minimal example but I don't even know where to start.
Upvotes: 1
Views: 144
Reputation: 6645
Dymola generates this information on the fly for the model documentation, but I am not aware of a way to retrieve it.
The ModelManagement
library (shipped with Dymola and included in the standard license) allows to extract such information from loaded classes.
However, it is a bit painful to use. The problem is that most functions in this library only analyze the exact code of the class - extended classes are not considered. Hence you have to loop over extended classes by yourself.
Below is an example which tries to get all component definitions of a class, including the ones inherited from extended classes. For every component a dict with several properties is returned, which corresponds to the record ModelManagement.Structure.AST.ComponentAttributes
in Dymola.
It contains information like the component name, its description, its variability, the presence of the prefixes input
and output
etc.
So for your example class Modelica.Math.sin
inputs and outputs can be identified easily using the dict keys isOutput
and isInput
.
But beware that this does not work for input and output connectors of blocks like Modelica.Blocks.Interfaces.RealInput
- and a-causal connectors like electric pins. You will have to implement something by yourself to identify those.
The code below simply uses fixed class paths to list all input and output connectors of Modelica.Blocks.Continuous.Integrator
. Additionally it outputs all its parameters.
import pprint
from dymola.dymola_interface import DymolaInterface
def get_extends(dym, c):
""" return a list with all extended classes (including inherited extends) """
extends = dym.ExecuteCommand(f'ModelManagement.Structure.AST.ExtendsInClassAttributes("{c}")')
for e in extends.copy():
sub_extends = get_extends(dym, e['fullTypeName'])
# only add sub-extends if they are not already in the list
for s in sub_extends:
if not any(s['fullTypeName'] == tmp_e['fullTypeName'] for tmp_e in extends):
extends.append(s)
return extends
def get_components(dym, c):
""" return a list with all components in a class (including inherited ones )"""
# get components defined in the class itself
comp = dym.ExecuteCommand(f'ModelManagement.Structure.AST.ComponentsInClassAttributes("{c}")')
# get components defined in extended classes itself
for e in get_extends(dym, c):
comp.extend(dym.ExecuteCommand(
f'ModelManagement.Structure.AST.ComponentsInClassAttributes("{e["fullTypeName"]}")'))
return comp
if __name__ == '__main__':
modelica_class = 'Modelica.Blocks.Continuous.Integrator'
# get all components in the model
dymola = DymolaInterface(showwindow=False)
components = get_components(dymola, modelica_class)
dymola.close()
# extract inputs and parameters
inputs = ['Modelica.Blocks.Interfaces.RealInput', 'Modelica.Blocks.Interfaces.BooleanInput',
'Modelica.Blocks.Interfaces.BooleanInput']
inputs = [c for c in components if c['fullTypeName'] in inputs]
parameters = [c for c in components if c['variability'] == 'parameter']
print('-------- inputs ------------')
pprint.pprint(inputs)
print('\n\n-------- parameters ------------')
pprint.pprint(parameters)
Upvotes: 3