从 python 脚本重现 Dymola 信息层
reproduce Dymola info layer from python script
我想编写一个 Python 脚本来提取有关 Modelica 函数输入和输出的相同信息,如 Dymola 信息层中所示,例如对于正弦函数:
我想展示一个最小的例子,但我什至不知道从哪里开始。
Dymola 为模型文档即时生成此信息,但我不知道检索它的方法。
ModelManagement
库(随 Dymola 一起提供并包含在标准许可证中)允许从加载的 classes 中提取此类信息。
但是,使用起来有点痛苦。问题是这个库中的大多数函数只分析 class 的确切代码 - 不考虑扩展的 classes。因此你必须自己循环扩展classes。
下面是一个示例,它试图获取 class 的所有组件定义,包括从扩展 classes 继承的组件定义。对于每个组件,都会返回一个具有多个属性的字典,这对应于 Dymola 中的记录 ModelManagement.Structure.AST.ComponentAttributes
。
它包含组件名称、描述、可变性、前缀 input
和 output
等信息。
因此对于您的示例 class Modelica.Math.sin
输入和输出可以使用字典键 isOutput
和 isInput
.
轻松识别
但请注意,这不适用于 Modelica.Blocks.Interfaces.RealInput
等块的输入和输出连接器 - 以及电针等因果连接器。你必须自己实施一些东西来识别那些。
下面的代码简单地使用固定的 class 路径来列出 Modelica.Blocks.Continuous.Integrator
的所有输入和输出连接器。此外,它还输出所有参数。
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)
我想编写一个 Python 脚本来提取有关 Modelica 函数输入和输出的相同信息,如 Dymola 信息层中所示,例如对于正弦函数:
我想展示一个最小的例子,但我什至不知道从哪里开始。
Dymola 为模型文档即时生成此信息,但我不知道检索它的方法。
ModelManagement
库(随 Dymola 一起提供并包含在标准许可证中)允许从加载的 classes 中提取此类信息。
但是,使用起来有点痛苦。问题是这个库中的大多数函数只分析 class 的确切代码 - 不考虑扩展的 classes。因此你必须自己循环扩展classes。
下面是一个示例,它试图获取 class 的所有组件定义,包括从扩展 classes 继承的组件定义。对于每个组件,都会返回一个具有多个属性的字典,这对应于 Dymola 中的记录 ModelManagement.Structure.AST.ComponentAttributes
。
它包含组件名称、描述、可变性、前缀 input
和 output
等信息。
因此对于您的示例 class Modelica.Math.sin
输入和输出可以使用字典键 isOutput
和 isInput
.
但请注意,这不适用于 Modelica.Blocks.Interfaces.RealInput
等块的输入和输出连接器 - 以及电针等因果连接器。你必须自己实施一些东西来识别那些。
下面的代码简单地使用固定的 class 路径来列出 Modelica.Blocks.Continuous.Integrator
的所有输入和输出连接器。此外,它还输出所有参数。
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)