Title: How to modify a component's value within a redeclare statement via OMPython
Tags: python;modelica;openmodelica
Question: 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!

Here is the accepted answer: 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.
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:
&quot;&quot;&quot;Python test script for replacing information in modelica models.&quot;&quot;&quot;
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
'loadFile(&quot;example.mo&quot;)',
'removeElementModifiers(Example.System, &quot;component&quot;, false)',
'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
'setElementModifierValue(Example.System, component.value, $Code(=200))',
'saveModel(&quot;example_edit.mo&quot;, Example)',
for cmd in cmds:
answer = omc.sendExpression(cmd)
print(cmd, ':', answer)
This creates the desired output:
model System &quot;A system with a component&quot;
Component component(value = 200, redeclare SpecialSensor sensor(sensitivity = 20)) &quot;Modified component&quot; 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...
&quot;&quot;&quot;Python test script for replacing information in modelica models.&quot;&quot;&quot;
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
cmds = [
'loadFile(&quot;example.mo&quot;)',
# 'removeElementModifiers(Example.System, &quot;component&quot;, false)',
'setElementModifierValue(Example.System, component.sensor, $Code((redeclare SpecialSensor sensor(sensitivity = 20))))',
'setElementModifierValue(Example.System, component.value, $Code(=200))',
'saveModel(&quot;example_edit.mo&quot;, Example)',
for cmd in cmds:
answer = omc.sendExpression(cmd)
print(cmd, ':', answer)
... the redeclare SpecialSensor part is missing in the output:
model System &quot;A system with a component&quot;
Component component(value = 200) &quot;Modified component&quot; annotation(
Placement(transformation(extent = {{-10, -10}, {10, 10}})));
annotation(
Icon(coordinateSystem(preserveAspectRatio = false)),
Diagram(coordinateSystem(preserveAspectRatio = false)));
end System;
Comment for this answer: Just a quick note: the redeclares are supported if you want to compile the model. What we we are talking here is about the API to get/set the information about redeclares in the Modelica code via scripts or from OMEdit.
Comment for this answer: If you don't remove anything and call setElementModifierValue I think it should update it.
Comment for this answer: @AdrianPop I don't know if you will read this, but is there a way to use ``setElementModifierValue()`` with redeclare code without first using ``removeElementModifiers()``? Maybe I am still missing something... first reading all existing values, saving them, and then reapplying them is quite tedious, when all I want to do is change a single value.
Comment for this answer: @AdrianPop Thanks for getting back to me, much appreciated.I expanded my answer to show the output when I don't use ``removeElementModifiers()``: The redeclare part is missing. The order of setting component.sensor and component.value also does not matter in that case, only ``value`` survives the process. Is this unintended behaviour? Should I create an issue on GitHub?
Comment for this answer: I created an issue here: https://github.com/OpenModelica/OpenModelica/issues/7182


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2020:00:06/03/20', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<python><modelica><openmodelica>', 'Title': "How to modify a component's value within a redeclare statement via OMPython", 'ViewCount': 239, 'id': 62168453, 'user_AboutMe': '<p>Mostly using Python</p>\n', 'user_AccountId': 12453632.0, 'user_DisplayName': 'Azrael_DD', 'user_Reputation': 130.0, 'user_Views': 11.0, 'user_id': 9067534.0}}