3939import numpy as np
4040import os
4141import pathlib
42- import platform
43- import re
4442import subprocess
4543import textwrap
4644from typing import Optional , Any
4745import warnings
4846import xml .etree .ElementTree as ET
4947
50- from OMPython .OMCSession import OMCSessionException , OMCSessionZMQ , OMCProcessLocal , OMCPath
48+ from OMPython .OMCSession import OMCSessionException , OMCSessionZMQ , OMCProcessLocal , OMCPath , OMCSessionRunData
5149
5250# define logger using the current module name as ID
5351logger = logging .getLogger (__name__ )
@@ -113,7 +111,14 @@ def __getitem__(self, index: int):
113111class ModelicaSystemCmd :
114112 """A compiled model executable."""
115113
116- def __init__ (self , runpath : pathlib .Path , modelname : str , timeout : Optional [float ] = None ) -> None :
114+ def __init__ (
115+ self ,
116+ session : OMCSessionZMQ ,
117+ runpath : OMCPath ,
118+ modelname : str ,
119+ timeout : Optional [float ] = None ,
120+ ) -> None :
121+ self ._session = session
117122 self ._runpath = pathlib .Path (runpath ).resolve ().absolute ()
118123 self ._model_name = modelname
119124 self ._timeout = timeout
@@ -174,27 +179,12 @@ def args_set(self, args: dict[str, Optional[str | dict[str, str]]]) -> None:
174179 for arg in args :
175180 self .arg_set (key = arg , val = args [arg ])
176181
177- def get_exe (self ) -> pathlib .Path :
178- """Get the path to the compiled model executable."""
179- if platform .system () == "Windows" :
180- path_exe = self ._runpath / f"{ self ._model_name } .exe"
181- else :
182- path_exe = self ._runpath / self ._model_name
183-
184- if not path_exe .exists ():
185- raise ModelicaSystemError (f"Application file path not found: { path_exe } " )
186-
187- return path_exe
188-
189- def get_cmd (self ) -> list :
190- """Get a list with the path to the executable and all command line args.
191-
192- This can later be used as an argument for subprocess.run().
182+ def get_cmd_args (self ) -> list :
183+ """
184+ Get a list with the command arguments for the model executable.
193185 """
194186
195- path_exe = self .get_exe ()
196-
197- cmdl = [path_exe .as_posix ()]
187+ cmdl = []
198188 for key in self ._args :
199189 if self ._args [key ] is None :
200190 cmdl .append (f"-{ key } " )
@@ -203,40 +193,49 @@ def get_cmd(self) -> list:
203193
204194 return cmdl
205195
206- def run (self ) -> int :
207- """Run the requested simulation.
208-
209- Returns
210- -------
211- Subprocess return code (0 on success).
196+ def run_def (self ) -> OMCSessionRunData :
212197 """
198+ Define all needed data to run the model executable. The data is stored in an OMCSessionRunData object.
199+ """
200+ # ensure that a result filename is provided
201+ result_file = self .arg_get ('r' )
202+ if not isinstance (result_file , str ):
203+ result_file = (self ._runpath / f"{ self ._model_name } .mat" ).as_posix ()
204+
205+ omc_run_data = OMCSessionRunData (
206+ cmd_path = self ._runpath .as_posix (),
207+ cmd_model_name = self ._model_name ,
208+ cmd_args = self .get_cmd_args (),
209+ cmd_result_path = result_file ,
210+ cmd_timeout = self ._timeout ,
211+ )
213212
214- cmdl : list = self .get_cmd ()
215-
216- logger .debug ("Run OM command %s in %s" , repr (cmdl ), self ._runpath .as_posix ())
213+ return omc_run_data
217214
218- if platform .system () == "Windows" :
219- path_dll = ""
215+ @staticmethod
216+ def run_cmd (cmd_run_data : OMCSessionRunData ) -> int :
217+ """
218+ Run the command defined in cmd_run_data. This class is defined as static method such that there is no need to
219+ keep instances of over classes around.
220+ """
220221
221- # set the process environment from the generated .bat file in windows which should have all the dependencies
222- path_bat = self ._runpath / f"{ self ._model_name } .bat"
223- if not path_bat .exists ():
224- raise ModelicaSystemError ("Batch file (*.bat) does not exist " + str (path_bat ))
222+ my_env = os .environ .copy ()
223+ if isinstance (cmd_run_data .cmd_library_path , str ):
224+ my_env ["PATH" ] = cmd_run_data .cmd_library_path + os .pathsep + my_env ["PATH" ]
225225
226- with open (file = path_bat , mode = 'r' , encoding = 'utf-8' ) as fh :
227- for line in fh :
228- match = re .match (r"^SET PATH=([^%]*)" , line , re .IGNORECASE )
229- if match :
230- path_dll = match .group (1 ).strip (';' ) # Remove any trailing semicolons
231- my_env = os .environ .copy ()
232- my_env ["PATH" ] = path_dll + os .pathsep + my_env ["PATH" ]
233- else :
234- # TODO: how to handle path to resources of external libraries for any system not Windows?
235- my_env = None
226+ cmdl = cmd_run_data .get_cmd ()
236227
228+ logger .debug ("Run OM command %s in %s" , repr (cmdl ), cmd_run_data .cmd_path )
237229 try :
238- cmdres = subprocess .run (cmdl , capture_output = True , text = True , env = my_env , cwd = self ._runpath ,
239- timeout = self ._timeout , check = True )
230+ cmdres = subprocess .run (
231+ cmdl ,
232+ capture_output = True ,
233+ text = True ,
234+ env = my_env ,
235+ cwd = cmd_run_data .cmd_path ,
236+ timeout = cmd_run_data .cmd_timeout ,
237+ check = True ,
238+ )
240239 stdout = cmdres .stdout .strip ()
241240 stderr = cmdres .stderr .strip ()
242241 returncode = cmdres .returncode
@@ -252,6 +251,17 @@ def run(self) -> int:
252251
253252 return returncode
254253
254+ def run (self ) -> int :
255+ """Run the requested simulation.
256+
257+ Returns
258+ -------
259+ Subprocess return code (0 on success).
260+ """
261+ cmd_run_data = self .run_def ()
262+ cmd_run_data = self ._session .omc_run_data_update (cmd_run_data , session = self ._session )
263+ return self .run_cmd (cmd_run_data = cmd_run_data )
264+
255265 @staticmethod
256266 def parse_simflags (simflags : str ) -> dict [str , Optional [str | dict [str , str ]]]:
257267 """
@@ -952,7 +962,8 @@ def simulate_cmd(
952962 """
953963
954964 om_cmd = ModelicaSystemCmd (
955- runpath = pathlib .Path (self .getWorkDirectory ()),
965+ session = self ._getconn ,
966+ runpath = self .getWorkDirectory (),
956967 modelname = self ._model_name ,
957968 timeout = timeout ,
958969 )
@@ -1562,7 +1573,8 @@ def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = N
15621573 )
15631574
15641575 om_cmd = ModelicaSystemCmd (
1565- runpath = pathlib .Path (self .getWorkDirectory ()),
1576+ session = self ._getconn ,
1577+ runpath = self .getWorkDirectory (),
15661578 modelname = self ._model_name ,
15671579 timeout = timeout ,
15681580 )
0 commit comments