Skip to content

Commit fbca54d

Browse files
committed
[ModelicaSystemCmd] cleanup / docstrings
1 parent d663b1f commit fbca54d

File tree

1 file changed

+98
-36
lines changed

1 file changed

+98
-36
lines changed

OMPython/ModelicaSystem.py

Lines changed: 98 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -109,28 +109,69 @@ def __getitem__(self, index: int):
109109

110110

111111
class 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

Comments
 (0)