Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d0b6fe2
rename classes: *Process* => *Session*
syntron Nov 23, 2025
e4fd725
[ModelicaSystem*] omc_process => session
syntron Nov 23, 2025
fa448ea
[OMCSession*] fix docstrings
syntron Nov 23, 2025
fc04903
[ModelicaSystem*] remove dependency on depreciated OMCSessionZMQ
syntron Nov 23, 2025
6313dd6
[OMCSessionCmd] use OMCSession (old OMCProcess)
syntron Nov 23, 2025
3ccb5fd
[ModelicaSystem] fix initialisation of default OMCSession - use *Local
syntron Nov 26, 2025
fa97850
[unittests] use new definitions / remove OMCSessionZMQ
syntron Nov 23, 2025
8b19a46
[OMCSessionPort] add missing function / catch possible errors
syntron Nov 23, 2025
dd67406
[OMCSessionPort] fix exception message
syntron Nov 26, 2025
331e0a3
[OMCSession] improve logging
syntron Nov 23, 2025
73a38e5
[OMCSession*] define set_timeout()
syntron Nov 26, 2025
fe1775e
[OMCSession*] align all usages of timeout to the same structure
syntron Nov 25, 2025
938a124
[OMCSession*] simplify code for timeout loops
syntron Nov 26, 2025
9ad6f7c
add OMCPath to the public interface
syntron Nov 27, 2025
97e8333
[OMCSession] fix definiton of _timeout variable - use set_timeout() c…
syntron Nov 27, 2025
033e3a8
use keyword arguments if possible (FKA100 - flake8-force-keyword-argu…
syntron Nov 27, 2025
cbb6e56
[OMCSession*] some additional cleanup (mypy / flake8)
syntron Nov 27, 2025
223c895
[OMCSession] move call to set_timeout() to __post_init__
syntron Nov 27, 2025
fc43bdf
update README.md - replace OMCSessionZMQ with OMCSessionLocal
syntron Nov 27, 2025
589b17e
Merge branch 'OMCSessionPort' into v4.1.0-syntron
syntron Nov 28, 2025
b2499f1
Merge branch 'OMCSession_logging' into v4.1.0-syntron
syntron Nov 28, 2025
0ff9630
Merge branch 'linter_fix' into v4.1.0-syntron
syntron Nov 28, 2025
304e117
Merge branch 'OMCPath_to_init' into v4.1.0-syntron
syntron Nov 28, 2025
b1aba64
Merge branch 'ModelicaSystem_timeout' into v4.1.0-syntron
syntron Nov 28, 2025
2918597
[OMCSessionZMQ] cleanup / remove OMCSessionZMQ compatibility class
syntron Nov 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 31 additions & 30 deletions OMPython/ModelicaSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@
from OMPython.OMCSession import (
OMCSessionException,
OMCSessionRunData,
OMCSessionZMQ,
OMCProcess,
OMCProcessLocal,
OMCSession,
OMCSessionLocal,
OMCPath,
)

Expand Down Expand Up @@ -127,7 +126,7 @@ class ModelicaSystemCmd:

def __init__(
self,
session: OMCSessionZMQ,
session: OMCSession,
runpath: OMCPath,
modelname: Optional[str] = None,
) -> None:
Expand Down Expand Up @@ -291,8 +290,10 @@ def parse_simflags(simflags: str) -> dict[str, Optional[str | dict[str, Any] | n

The return data can be used as input for self.args_set().
"""
warnings.warn("The argument 'simflags' is depreciated and will be removed in future versions; "
"please use 'simargs' instead", DeprecationWarning, stacklevel=2)
warnings.warn(message="The argument 'simflags' is depreciated and will be removed in future versions; "
"please use 'simargs' instead",
category=DeprecationWarning,
stacklevel=2)

simargs: dict[str, Optional[str | dict[str, Any] | numbers.Number]] = {}

Expand Down Expand Up @@ -325,15 +326,15 @@ def parse_simflags(simflags: str) -> dict[str, Optional[str | dict[str, Any] | n

class ModelicaSystem:
"""
Class to simulate a Modelica model using OpenModelica via OMCSessionZMQ.
Class to simulate a Modelica model using OpenModelica via OMCSession.
"""

def __init__(
self,
command_line_options: Optional[list[str]] = None,
work_directory: Optional[str | os.PathLike] = None,
omhome: Optional[str] = None,
omc_process: Optional[OMCProcess] = None,
session: Optional[OMCSession] = None,
) -> None:
"""Create a ModelicaSystem instance. To define the model use model() or convertFmu2Mo().

Expand All @@ -344,8 +345,8 @@ def __init__(
work_directory: Path to a directory to be used for temporary
files like the model executable. If left unspecified, a tmp
directory will be created.
omhome: path to OMC to be used when creating the OMC session (see OMCSessionZMQ).
omc_process: definition of a (local) OMC process to be used. If
omhome: path to OMC to be used when creating the OMC session (see OMCSession).
session: definition of a (local) OMC session to be used. If
unspecified, a new local session will be created.
"""

Expand Down Expand Up @@ -373,10 +374,10 @@ def __init__(
self._linearized_outputs: list[str] = [] # linearization output list
self._linearized_states: list[str] = [] # linearization states list

if omc_process is not None:
self._session = OMCSessionZMQ(omc_process=omc_process)
if session is not None:
self._session = session
else:
self._session = OMCSessionZMQ(omhome=omhome)
self._session = OMCSessionLocal(omhome=omhome)

# set commandLineOptions using default values or the user defined list
if command_line_options is None:
Expand Down Expand Up @@ -461,13 +462,13 @@ def model(
if model_file is not None:
file_path = pathlib.Path(model_file)
# special handling for OMCProcessLocal - consider a relative path
if isinstance(self._session.omc_process, OMCProcessLocal) and not file_path.is_absolute():
if isinstance(self._session, OMCSessionLocal) and not file_path.is_absolute():
file_path = pathlib.Path.cwd() / file_path
if not file_path.is_file():
raise IOError(f"Model file {file_path} does not exist!")

self._file_name = self.getWorkDirectory() / file_path.name
if (isinstance(self._session.omc_process, OMCProcessLocal)
if (isinstance(self._session, OMCSessionLocal)
and file_path.as_posix() == self._file_name.as_posix()):
pass
elif self._file_name.is_file():
Expand All @@ -482,7 +483,7 @@ def model(
if build:
self.buildModel(variable_filter)

def session(self) -> OMCSessionZMQ:
def get_session(self) -> OMCSession:
"""
Return the OMC session used for this class.
"""
Expand Down Expand Up @@ -585,7 +586,7 @@ def buildModel(self, variableFilter: Optional[str] = None):

def sendExpression(self, expr: str, parsed: bool = True) -> Any:
try:
retval = self._session.sendExpression(expr, parsed)
retval = self._session.sendExpression(command=expr, parsed=parsed)
except OMCSessionException as ex:
raise ModelicaSystemError(f"Error executing {repr(expr)}: {ex}") from ex

Expand Down Expand Up @@ -1197,7 +1198,7 @@ def plot(
plot is created by OMC which needs access to the local display. This is not the case for docker and WSL.
"""

if not isinstance(self._session.omc_process, OMCProcessLocal):
if not isinstance(self._session, OMCSessionLocal):
raise ModelicaSystemError("Plot is using the OMC plot functionality; "
"thus, it is only working if OMC is running locally!")

Expand Down Expand Up @@ -1612,9 +1613,9 @@ def _createCSVData(self, csvfile: Optional[OMCPath] = None) -> OMCPath:
for signal_name, signal_values in inputs.items():
signal = np.array(signal_values)
interpolated_inputs[signal_name] = np.interp(
all_times,
signal[:, 0], # times
signal[:, 1], # values
x=all_times,
xp=signal[:, 0], # times
fp=signal[:, 1], # values
)

# Write CSV file
Expand Down Expand Up @@ -1954,7 +1955,7 @@ def __init__(
variable_filter: Optional[str] = None,
work_directory: Optional[str | os.PathLike] = None,
omhome: Optional[str] = None,
omc_process: Optional[OMCProcess] = None,
session: Optional[OMCSession] = None,
# simulation specific input
# TODO: add more settings (simulation options, input options, ...)
simargs: Optional[dict[str, Optional[str | dict[str, str] | numbers.Number]]] = None,
Expand All @@ -1974,7 +1975,7 @@ def __init__(
command_line_options=command_line_options,
work_directory=work_directory,
omhome=omhome,
omc_process=omc_process,
session=session,
)
self._mod.model(
model_file=model_file,
Expand All @@ -1988,9 +1989,9 @@ def __init__(
self._simargs = simargs

if resultpath is None:
self._resultpath = self.session().omcpath_tempdir()
self._resultpath = self.get_session().omcpath_tempdir()
else:
self._resultpath = self.session().omcpath(resultpath)
self._resultpath = self.get_session().omcpath(resultpath)
if not self._resultpath.is_dir():
raise ModelicaSystemError("Argument resultpath must be set to a valid path within the environment used "
f"for the OpenModelica session: {resultpath}!")
Expand All @@ -2003,11 +2004,11 @@ def __init__(
self._doe_def: Optional[dict[str, dict[str, Any]]] = None
self._doe_cmd: Optional[dict[str, OMCSessionRunData]] = None

def session(self) -> OMCSessionZMQ:
def get_session(self) -> OMCSession:
"""
Return the OMC session used for this class.
"""
return self._mod.session()
return self._mod.get_session()

def prepare(self) -> int:
"""
Expand Down Expand Up @@ -2046,7 +2047,7 @@ def prepare(self) -> int:

pk_value = pc_structure[idx_structure]
if isinstance(pk_value, str):
pk_value_str = self.session().escape_str(pk_value)
pk_value_str = self.get_session().escape_str(pk_value)
expression = f"setParameterValue({self._model_name}, {pk_structure}, \"{pk_value_str}\")"
elif isinstance(pk_value, bool):
pk_value_bool_str = "true" if pk_value else "false"
Expand Down Expand Up @@ -2167,12 +2168,12 @@ def worker(worker_id, task_queue):
raise ModelicaSystemError("Missing simulation definition!")

resultfile = cmd_definition.cmd_result_path
resultpath = self.session().omcpath(resultfile)
resultpath = self.get_session().omcpath(resultfile)

logger.info(f"[Worker {worker_id}] Performing task: {resultpath.name}")

try:
returncode = self.session().run_model_executable(cmd_run_data=cmd_definition)
returncode = self.get_session().run_model_executable(cmd_run_data=cmd_definition)
logger.info(f"[Worker {worker_id}] Simulation {resultpath.name} "
f"finished with return code: {returncode}")
except ModelicaSystemError as ex:
Expand Down
Loading