diff --git a/CHANGELOG.md b/CHANGELOG.md
index e5d3914..c88fc55 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,13 @@
All notable changes to the [mlfmu] project will be documented in this file.
The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+## Unreleased
+
+### Changed
+
+* Generation of modelDescription.xml file to correctly generate tags for each output with 1-indexed indexes and InitialUnknowns tags
+* Generation of modelDescription.xml adds the variables (inputs, parameters and outputs) in the orderer of their valueReference. This is for the indexing to work correctly
+
## [1.0.2]
### Changed
diff --git a/src/mlfmu/utils/fmi_builder.py b/src/mlfmu/utils/fmi_builder.py
index b418f8c..cdb3595 100644
--- a/src/mlfmu/utils/fmi_builder.py
+++ b/src/mlfmu/utils/fmi_builder.py
@@ -76,8 +76,16 @@ def generate_model_description(fmu_model: FmiModel) -> ElementTree:
# tag with tab inside --> Append all outputs
model_structure = SubElement(root, "ModelStructure")
outputs = SubElement(model_structure, "Outputs")
+ initial_unknowns = SubElement(model_structure, "InitialUnknowns")
- for var in fmu_model.get_fmi_model_variables():
+ # Get all variables to add them inside the tag
+ model_variables = fmu_model.get_fmi_model_variables()
+
+ # The variables needs to be added in the order of their valueReference
+ sorted_model_variables = sorted(model_variables, key=lambda x: x.variable_reference)
+
+ # Add each variable inside the tag
+ for var in sorted_model_variables:
# XML variable attributes
var_attrs = {
"name": var.name,
@@ -95,9 +103,13 @@ def generate_model_description(fmu_model: FmiModel) -> ElementTree:
# FMI variable type element
_ = SubElement(var_elem, var.type.value.capitalize(), var_type_attrs)
- # Appending output to inside
+ # Adding outputs inside
if var.causality == FmiCausality.OUTPUT:
- _ = SubElement(outputs, "Unknown", {"index": str(var.variable_reference)})
+ # Index is 1-indexed for tag
+ unknown_attributes = {"index": str(var.variable_reference + 1)}
+ # For each output create an tag inside both and
+ _ = SubElement(outputs, "Unknown", unknown_attributes)
+ _ = SubElement(initial_unknowns, "Unknown", unknown_attributes)
# Create XML tree containing root element and pretty format its contents
xml_tree = ElementTree(root)
diff --git a/tests/utils/test_modelDescription_builder.py b/tests/utils/test_modelDescription_builder.py
index 7af8308..2ba348f 100644
--- a/tests/utils/test_modelDescription_builder.py
+++ b/tests/utils/test_modelDescription_builder.py
@@ -56,13 +56,14 @@ def test_generate_model_description_with_internal_state_params():
variables = xml_structure.findall(".//ScalarVariable")
assert xml_structure.getroot().tag == "fmiModelDescription"
- assert variables[0].attrib["name"] == "state1"
- assert variables[0].attrib["causality"] == "parameter"
- assert variables[0][0].tag == "Real"
- assert variables[0][0].attrib["start"] == "0.0"
- assert variables[1].attrib["name"] == "output1"
- assert variables[1].attrib["causality"] == "output"
+ assert variables[0].attrib["name"] == "output1"
+ assert variables[0].attrib["causality"] == "output"
+
+ assert variables[1].attrib["name"] == "state1"
+ assert variables[1].attrib["causality"] == "parameter"
+ assert variables[1][0].tag == "Real"
+ assert variables[1][0].attrib["start"] == "0.0"
def test_generate_vector_ports():
@@ -193,5 +194,6 @@ def test_generate_model_description_output():
output_variables = [var for var in variables if var.attrib.get("causality") == "output"]
outputs_registered = xml_structure.findall(".//Outputs/Unknown")
- assert output_variables[0].attrib["valueReference"] == outputs_registered[0].attrib["index"]
- assert output_variables[1].attrib["valueReference"] == outputs_registered[1].attrib["index"]
+ # The index should be the valueReference + 1
+ assert int(output_variables[0].attrib["valueReference"]) + 1 == int(outputs_registered[0].attrib["index"])
+ assert int(output_variables[1].attrib["valueReference"]) + 1 == int(outputs_registered[1].attrib["index"])