Azrael_DD
Azrael_DD

Reputation: 271

How to modify a component's value within a redeclare statement via OMPython

I need to be able to modify the contents of a Modelica package/model via Python, for automated simulation etc. Mostly this works fine with OMPython, but there is a special problem I cannot solve:

Consider these two files: 1) example.mo (A Modelica package)

package Example "Example Package"
  model Component "A component with some settings"
    parameter Real value=100 "Some value";
    replaceable BasicSensor sensor "Replaceable sensor" annotation (
        Placement(transformation(extent={{-10,-10},{10,10}})),
        __Dymola_choicesAllMatching=true);
    annotation (Icon(graphics={Rectangle(extent={{-40,40},{40,-40}}, lineColor={28,
                108,200})}));
  end Component;

  model System "A system with a component"
    Component component(value=50, redeclare SpecialSensor sensor(sensitivity=10))
      "Modified component"
      annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
    annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
          coordinateSystem(preserveAspectRatio=false)));
  end System;

  model BasicSensor
    parameter Real sensitivity=1 "Some value";
    annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Ellipse(extent={{-40,40},{40,-40}}, lineColor={28,108,200})}),
        Diagram(coordinateSystem(preserveAspectRatio=false)));
  end BasicSensor;

  model SpecialSensor
    extends BasicSensor;
    annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
          coordinateSystem(preserveAspectRatio=false)));
  end SpecialSensor;
end Example;

2) test.py (A Python script)

"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
    'loadFile("example.mo")',
    'setComponentModifierValue(Example.System, component.value, $Code(=200))',
    # 'setComponentModifierValue(Example.System, component.sensor.sensitivity, $Code(=20))',
    'saveModel("example_edit.mo", Example)',
    ]
for cmd in cmds:
    answer = omc.sendExpression(cmd)
    print(cmd, answer)

In Modelica, we have a "System" that contains a "Component" which in turn contains a replaceable "sensor". With the Python script I can properly modify "component.value". Running the script yields the following result file example_edit.mo (only showing the part with changes):

model System "A system with a component"
    Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 10)) "Modified component" annotation(
      Placement(transformation(extent = {{-10, -10}, {10, 10}})));
    annotation(
      Icon(coordinateSystem(preserveAspectRatio = false)),
      Diagram(coordinateSystem(preserveAspectRatio = false)));
  end System;

"component.value" has been changed from 50 to 200, as desired.

However, I do not know how to change the "sensitivity" of the redeclared sensor. The naive approach is the commented line in the python script. If we include that line, the replaced sensor simply vanishes from the resulting model

model System "A system with a component"
    Component component(value = 200) "Modified component" annotation(
      Placement(transformation(extent = {{-10, -10}, {10, 10}})));
    annotation(
      Icon(coordinateSystem(preserveAspectRatio = false)),
      Diagram(coordinateSystem(preserveAspectRatio = false)));
  end System;

Finally, the actual question: How can I achieve the following desired result with the "sensitivity" changed to 20? (Through the OMPython interface, not with with regex or similar hacks.)

model System "A system with a component"
    Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 20)) "Modified component" annotation(
      Placement(transformation(extent = {{-10, -10}, {10, 10}})));
    annotation(
      Icon(coordinateSystem(preserveAspectRatio = false)),
      Diagram(coordinateSystem(preserveAspectRatio = false)));
  end System;

Regards and many thanks!

Upvotes: 2

Views: 314

Answers (1)

Azrael_DD
Azrael_DD

Reputation: 271

With feedback from openmodelica.org I realized that OpenModelica currently (1.14.1) does not fully support those redeclare statements. Thus the desired result is plainly not possible yet. It seems to be planned for 1.16.0.

See a question on openmodelica.org and the roadmap for future reference. Also this might be the correct ticket to track.

Edit:

With the current dev build of OpenModelica v1.17.0-dev-326-g94acb25482 (64-bit), the following Python code allows setting redeclare statements and answers the original question:

"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
    'loadFile("example.mo")',   
    'removeElementModifiers(Example.System, "component", false)',
    'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
    'setElementModifierValue(Example.System, component.value, $Code(=200))',
    'saveModel("example_edit.mo", Example)',
    ]
for cmd in cmds:
    answer = omc.sendExpression(cmd)
    print(cmd, ':', answer)

This creates the desired output:

  model System "A system with a component"
    Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 20)) "Modified component" annotation(
      Placement(transformation(extent = {{-10, -10}, {10, 10}})));
    annotation(
      Icon(coordinateSystem(preserveAspectRatio = false)),
      Diagram(coordinateSystem(preserveAspectRatio = false)));
  end System;

However, it seems like the command removeElementModifiers() is currently required, because without it...

"""Python test script for replacing information in modelica models."""
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
    'loadFile("example.mo")',   
    # 'removeElementModifiers(Example.System, "component", false)',
    'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
    'setElementModifierValue(Example.System, component.value, $Code(=200))',
    'saveModel("example_edit.mo", Example)',
    ]
for cmd in cmds:
    answer = omc.sendExpression(cmd)
    print(cmd, ':', answer)

... the redeclare SpecialSensor part is missing in the output:

  model System "A system with a component"
    Component component(value = 200) "Modified component" annotation(
      Placement(transformation(extent = {{-10, -10}, {10, 10}})));
    annotation(
      Icon(coordinateSystem(preserveAspectRatio = false)),
      Diagram(coordinateSystem(preserveAspectRatio = false)));
  end System;

Upvotes: 1

Related Questions