Recently I came across a problem statement where we have to initialize the parameters of the FMU from a PAR file. There are straightforward solutions using the FMPy, where I can run a python routine to assign the values. But somehow this workflow does not work for us since we aim for an off the shelf FMU with already its parameters updated from PAR file. The idea we thought was to keep the PAR file in a folder location and assign the FMU parameters value by calling a setter function inside FMU's instantiation routine. I would like to know if there is straightforward solution agreeing FMI standards to perform the above. Thanks in advance.
1 Answer
You can achieve this by following these general steps:
Unpack the FMU – FMUs are just ZIP files. First, extract the contents of the FMU to access its internal files, including the
.par
file.Read the
.par
file – Assuming the.par
file is a plain text or XML/JSON file, parse it using your preferred method (depending on its format).Set the parameter values – Use the FMU API (such as
fmi2SetReal
,fmi2SetInteger
, etc.) to set the parameter values after instantiating the FMU but before callingfmi2EnterInitializationMode
.
Example in Python using fmpy
Here’s how you might do it using FMPy:
import zipfile
import os
import fmpy
from fmpy import read_model_description, instantiate_fmu
import json # or xml.etree.ElementTree for XML files
fmu_path = 'MyModel.fmu'
unzipdir = fmu_path + '_unpacked'
# Step 1: Unpack the FMU
with zipfile.ZipFile(fmu_path, 'r') as z:
z.extractall(unzipdir)
# Step 2: Read the .par file
par_file_path = os.path.join(unzipdir, 'resources', 'parameters.par')
with open(par_file_path, 'r') as file:
parameters = json.load(file) # Or parse as needed
# Step 3: Read model description and instantiate FMU
model_description = read_model_description(fmu_path)
fmu = instantiate_fmu(model_description, unzipdir, fmi_type='CoSimulation')
# Set parameter values before initialization
fmu.setupExperiment()
fmu.enterInitializationMode()
for name, value in parameters.items():
vr = [v.valueReference for v in model_description.modelVariables if v.name == name]
if vr:
fmu.setReal(vr, [value]) # or setInteger, setBoolean, etc.
fmu.exitInitializationMode()
# Now the FMU is initialized with your parameter values
Notes:
Ensure the
.par
file is located inside the FMU’sresources/
folder.The file format (e.g. JSON, XML, INI) dictates how you parse it.
Always set parameters before entering initialization mode (
fmi2EnterInitializationMode
).
-
Thanks a lot for your reply. But, I am mostly looking for an accepted approach to do this within the FMU. Using FMPy, anyway we have a solution to set the parameter values. Also, can you please check the code since in the notes it is mentioned that the setters need to be called before fmu.eneterInitializationMode. Commented 3 hours ago