From f10e4e0c5bf42b61baeefd4927c6266a04b96ed2 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 9 Jul 2025 20:26:04 +0200 Subject: [PATCH 1/4] [ModelicaSystem] update handling of xml_file --- OMPython/ModelicaSystem.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index d0178cf2..5167d79e 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -481,8 +481,10 @@ def buildModel(self, variableFilter: Optional[str] = None): buildModelResult = self._requestApi("buildModel", self._model_name, properties=varFilter) logger.debug("OM model build result: %s", buildModelResult) - self._xml_file = pathlib.Path(buildModelResult[0]).parent / buildModelResult[1] - self._xmlparse() + xml_file = pathlib.Path(buildModelResult[0]).parent / buildModelResult[1] + self._xmlparse(xml_file=xml_file) + # TODO: remove _xml_file?! + self._xml_file = xml_file def sendExpression(self, expr: str, parsed: bool = True): try: @@ -508,11 +510,11 @@ def _requestApi(self, apiName, entity=None, properties=None): # 2 return self.sendExpression(exp) - def _xmlparse(self): - if not self._xml_file.is_file(): - raise ModelicaSystemError(f"XML file not generated: {self._xml_file}") + def _xmlparse(self, xml_file: pathlib.Path): + if not xml_file.is_file(): + raise ModelicaSystemError(f"XML file not generated: {xml_file}") - tree = ET.parse(self._xml_file) + tree = ET.parse(xml_file) rootCQ = tree.getroot() for attr in rootCQ.iter('DefaultExperiment'): for key in ("startTime", "stopTime", "stepSize", "tolerance", From 4ed4bc9961687fcc95a24770a5631190523a6d90 Mon Sep 17 00:00:00 2001 From: syntron Date: Wed, 9 Jul 2025 20:26:42 +0200 Subject: [PATCH 2/4] [ModelicaSystem] replace ET.parse() with ET.ElementTree(ET.fromstring()) read the file content and work on this string see: https://stackoverflow.com/questions/647071/python-xml-elementtree-from-a-string-source --- OMPython/ModelicaSystem.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index 5167d79e..c8476a25 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -514,7 +514,8 @@ def _xmlparse(self, xml_file: pathlib.Path): if not xml_file.is_file(): raise ModelicaSystemError(f"XML file not generated: {xml_file}") - tree = ET.parse(xml_file) + xml_content = xml_file.read_text() + tree = ET.ElementTree(ET.fromstring(xml_content)) rootCQ = tree.getroot() for attr in rootCQ.iter('DefaultExperiment'): for key in ("startTime", "stopTime", "stepSize", "tolerance", From 111326fb15516de280d766ee6a0886f16682a64e Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 10 Jul 2025 09:59:04 +0200 Subject: [PATCH 3/4] [ModelicaSystem._xmlparse] mypy fixes & cleanup --- OMPython/ModelicaSystem.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index c8476a25..e7238d66 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -520,14 +520,24 @@ def _xmlparse(self, xml_file: pathlib.Path): for attr in rootCQ.iter('DefaultExperiment'): for key in ("startTime", "stopTime", "stepSize", "tolerance", "solver", "outputFormat"): - self._simulate_options[key] = attr.get(key) + self._simulate_options[key] = str(attr.get(key)) for sv in rootCQ.iter('ScalarVariable'): - scalar = {} - for key in ("name", "description", "variability", "causality", "alias"): - scalar[key] = sv.get(key) - scalar["changeable"] = sv.get('isValueChangeable') - scalar["aliasvariable"] = sv.get('aliasVariable') + translations = { + "alias": "alias", + "aliasvariable": "aliasVariable", + "causality": "causality", + "changeable": "isValueChangeable", + "description": "description", + "name": "name", + "variability": "variability", + } + + scalar: dict[str, Any] = {} + for key_dst, key_src in translations.items(): + val = sv.get(key_src) + scalar[key_dst] = None if val is None else str(val) + ch = list(sv) for att in ch: scalar["start"] = att.get('start') @@ -535,6 +545,7 @@ def _xmlparse(self, xml_file: pathlib.Path): scalar["max"] = att.get('max') scalar["unit"] = att.get('unit') + # save parameters in the corresponding class variables if scalar["variability"] == "parameter": if scalar["name"] in self._override_variables: self._params[scalar["name"]] = self._override_variables[scalar["name"]] From f958964b754a496ef4042006133785999d7f38f8 Mon Sep 17 00:00:00 2001 From: syntron Date: Thu, 10 Jul 2025 10:03:53 +0200 Subject: [PATCH 4/4] [ModelicaSystem] remove class variable _xml_file --- OMPython/ModelicaSystem.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OMPython/ModelicaSystem.py b/OMPython/ModelicaSystem.py index e7238d66..cc4a7c8b 100644 --- a/OMPython/ModelicaSystem.py +++ b/OMPython/ModelicaSystem.py @@ -383,7 +383,6 @@ def __init__( if not isinstance(lmodel, list): raise ModelicaSystemError(f"Invalid input type for lmodel: {type(lmodel)} - list expected!") - self._xml_file = None self._lmodel = lmodel # may be needed if model is derived from other model self._model_name = modelName # Model class name self._file_name = pathlib.Path(fileName).resolve() if fileName is not None else None # Model file/package name @@ -483,8 +482,6 @@ def buildModel(self, variableFilter: Optional[str] = None): xml_file = pathlib.Path(buildModelResult[0]).parent / buildModelResult[1] self._xmlparse(xml_file=xml_file) - # TODO: remove _xml_file?! - self._xml_file = xml_file def sendExpression(self, expr: str, parsed: bool = True): try: @@ -1460,7 +1457,8 @@ def load_module_from_path(module_name, file_path): return module_def - if self._xml_file is None: + if len(self._quantities) == 0: + # if self._quantities has no content, the xml file was not parsed; see self._xmlparse() raise ModelicaSystemError( "Linearization cannot be performed as the model is not build, " "use ModelicaSystem() to build the model first"