@@ -109,28 +109,69 @@ def __getitem__(self, index: int):
109109
110110
111111class ModelicaSystemCmd :
112+ """
113+ Execute a simulation by running the comiled model.
114+ """
112115
113- def __init__ (self , cmdpath : pathlib .Path , modelname : str , timeout : Optional [int ] = None ):
114- self .tempdir = cmdpath
115- self .modelName = modelname
116- self ._exe_file = self .get_exe_file (tempdir = cmdpath , modelName = modelname )
117- if not self ._exe_file .exists ():
118- raise ModelicaSystemError (f"Application file path not found: { self ._exe_file } " )
116+ def __init__ (self , runpath : pathlib .Path , modelname : str , timeout : Optional [int ] = None ) -> None :
117+ """
118+ Initialisation
119119
120+ Parameters
121+ ----------
122+ runpath : pathlib.Path
123+ modelname : str
124+ timeout : Optional[int], None
125+ """
126+ self ._runpath = pathlib .Path (runpath ).resolve ().absolute ()
127+ self ._modelname = modelname
120128 self ._timeout = timeout
121129 self ._args = {}
122130
123- def arg_set (self , key , val = None ):
131+ self ._exe_file = self .get_exe_file (tempdir = runpath , modelname = modelname )
132+ if not self ._exe_file .exists ():
133+ raise ModelicaSystemError (f"Application file path not found: { self ._exe_file } " )
134+
135+ def arg_set (self , key : str , val : str = None ) -> None :
136+ """
137+ Set one argument for the executeable model.
138+
139+ Parameters
140+ ----------
141+ key : str
142+ val : str, None
143+ """
144+ if not isinstance (key , str ):
145+ raise ModelicaSystemError (f"Invalid argument key: { repr (key )} (type: { type (key )} )" )
124146 key = key .strip ()
125147 if val is not None :
148+ if not isinstance (val , str ):
149+ raise ModelicaSystemError (f"Invalid argument value for { repr (key )} : { repr (val )} (type: { type (val )} )" )
126150 val = val .strip ()
151+ if key in self ._args :
152+ logger .warning (f"Overwrite model executable argument: { repr (key )} = { repr (val )} "
153+ f"(was: { repr (self ._args [key ])} )" )
127154 self ._args [key ] = val
128155
129- def args_set (self , args : dict ):
156+ def args_set (self , args : dict ) -> None :
157+ """
158+ Define arguments for the model executable.
159+
160+ Parameters
161+ ----------
162+ args : dict
163+ """
130164 for arg in args :
131165 self .arg_set (key = arg , val = args [arg ])
132166
133- def run (self ):
167+ def run (self ) -> bool :
168+ """
169+ Run the requested simulation
170+
171+ Returns
172+ -------
173+ bool
174+ """
134175
135176 cmdl = [self ._exe_file .as_posix ()]
136177 for key in self ._args :
@@ -139,57 +180,78 @@ def run(self):
139180 else :
140181 cmdl .append (f"-{ key } ={ self ._args [key ]} " )
141182
142- self ._run_cmd (cmd = cmdl , timeout = self ._timeout )
143-
144- return True
145-
146- def _run_cmd (self , cmd : list , timeout : Optional [int ] = None ):
147- logger .debug ("Run OM command %s in %s" , cmd , self .tempdir )
183+ logger .debug ("Run OM command %s in %s" , repr (cmdl ), self ._runpath .as_posix ())
148184
149185 if platform .system () == "Windows" :
150- dllPath = ""
186+ path_dll = ""
151187
152188 # set the process environment from the generated .bat file in windows which should have all the dependencies
153- batFilePath = pathlib . Path ( self .tempdir ) / f"{ self .modelName } .bat"
154- if not batFilePath .exists ():
155- ModelicaSystemError ("Batch file (*.bat) does not exist " + str (batFilePath ))
189+ path_bat = self ._runpath / f"{ self ._modelname } .bat"
190+ if not path_bat .exists ():
191+ ModelicaSystemError ("Batch file (*.bat) does not exist " + str (path_bat ))
156192
157- with open (batFilePath , 'r' ) as file :
193+ with open (path_bat , 'r' ) as file :
158194 for line in file :
159195 match = re .match (r"^SET PATH=([^%]*)" , line , re .IGNORECASE )
160196 if match :
161- dllPath = match .group (1 ).strip (';' ) # Remove any trailing semicolons
197+ path_dll = match .group (1 ).strip (';' ) # Remove any trailing semicolons
162198 my_env = os .environ .copy ()
163- my_env ["PATH" ] = dllPath + os .pathsep + my_env ["PATH" ]
199+ my_env ["PATH" ] = path_dll + os .pathsep + my_env ["PATH" ]
164200 else :
165201 # TODO: how to handle path to resources of external libraries for any system not Windows?
166202 my_env = None
167203
168204 try :
169- cmdres = subprocess .run (cmd , capture_output = True , text = True , env = my_env , cwd = self .tempdir ,
170- timeout = timeout )
205+ cmdres = subprocess .run (cmdl , capture_output = True , text = True , env = my_env , cwd = self ._runpath ,
206+ timeout = self . _timeout )
171207 stdout = cmdres .stdout .strip ()
172208 stderr = cmdres .stderr .strip ()
173209
174- logger .debug ("OM output for command %s:\n %s" , cmd , stdout )
210+ logger .debug ("OM output for command %s:\n %s" , cmdl , stdout )
175211
176212 if cmdres .returncode != 0 :
177- raise ModelicaSystemError (f"Error running command { cmd } : return code = { cmdres .returncode } " )
213+ raise ModelicaSystemError (f"Error running command { cmdl } : return code = { cmdres .returncode } " )
178214 if stderr :
179- raise ModelicaSystemError (f"Error running command { cmd } : { stderr } " )
215+ raise ModelicaSystemError (f"Error running command { cmdl } : { stderr } " )
180216 except subprocess .TimeoutExpired :
181- raise ModelicaSystemError (f"Timeout running command { repr (cmd )} " )
217+ raise ModelicaSystemError (f"Timeout running command { repr (cmdl )} " )
182218 except Exception as ex :
183- raise ModelicaSystemError (f"Error running command { cmd } " ) from ex
219+ raise ModelicaSystemError (f"Error running command { cmdl } " ) from ex
220+
221+ return True
222+
223+ @staticmethod
224+ def get_exe_file (tempdir : pathlib .Path , modelname : str ) -> pathlib .Path :
225+ """
226+ Get path to model executable.
227+
228+ Parameters
229+ ----------
230+ tempdir : pathlib.Path
231+ modelname : str
184232
185- def get_exe_file (self , tempdir , modelName ) -> pathlib .Path :
186- """Get path to model executable."""
233+ Returns
234+ -------
235+ pathlib.Path
236+ """
187237 if platform .system () == "Windows" :
188- return pathlib .Path (tempdir ) / f"{ modelName } .exe"
238+ return pathlib .Path (tempdir ) / f"{ modelname } .exe"
189239 else :
190- return pathlib .Path (tempdir ) / modelName
240+ return pathlib .Path (tempdir ) / modelname
241+
242+ @staticmethod
243+ def parse_simflags (simflags : str ) -> dict :
244+ """
245+ Parse a simflag definition; this is depreciated!
191246
192- def parse_simflags (self , simflags : str ) -> dict :
247+ Parameters
248+ ----------
249+ simflags : str
250+
251+ Returns
252+ -------
253+ dict
254+ """
193255 # add old style simulation arguments
194256 warnings .warn ("The argument 'simflags' is depreciated and will be removed in future versions; "
195257 "please use 'simargs' instead" , DeprecationWarning , stacklevel = 2 )
@@ -721,7 +783,7 @@ def simulate(self, resultfile: Optional[str] = None, simflags: Optional[str] = N
721783 >>> simulate(simargs={"noEventEmit": None, "noRestart": None, "override": "e=0.3,g=10"}) # using simargs
722784 """
723785
724- om_cmd = ModelicaSystemCmd (cmdpath = pathlib .Path (self .tempdir ), modelname = self .modelName , timeout = timeout )
786+ om_cmd = ModelicaSystemCmd (runpath = pathlib .Path (self .tempdir ), modelname = self .modelName , timeout = timeout )
725787
726788 if resultfile is None :
727789 # default result file generated by OM
@@ -1107,7 +1169,7 @@ def linearize(self, lintime: Optional[float] = None, simflags: Optional[str] = N
11071169 raise IOError ("Linearization cannot be performed as the model is not build, "
11081170 "use ModelicaSystem() to build the model first" )
11091171
1110- om_cmd = ModelicaSystemCmd (cmdpath = pathlib .Path (self .tempdir ), modelname = self .modelName , timeout = timeout )
1172+ om_cmd = ModelicaSystemCmd (runpath = pathlib .Path (self .tempdir ), modelname = self .modelName , timeout = timeout )
11111173
11121174 overrideLinearFile = pathlib .Path (self .tempdir ) / f'{ self .modelName } _override_linear.txt'
11131175
0 commit comments