11# Feel++ mo2fmu converter
22
3- Modelica to FMU converter based on dymola
3+ Modelica to FMU converter with Dymola and OpenModelica support.
4+
5+ ## Features
6+
7+ - ** Multiple backends** : Supports both Dymola and OpenModelica compilers
8+ - ** Automatic backend selection** : Automatically detects available compilers
9+ - ** FMI 1.0, 2.0, and 3.0 support** : Generate Co-Simulation and Model Exchange FMUs
10+ - ** Python API** : Programmatic access for integration into workflows
11+ - ** Command-line interface** : Simple CLI with ` compile ` and ` check ` subcommands
412
513## Installation
614
715### From PyPI (Recommended)
816
9- Install the latest stable release from PyPI:
17+ Install the latest stable release from PyPI using [ uv ] ( https://docs.astral.sh/uv/ ) :
1018
1119``` console
12- pip install feelpp-mo2fmu
20+ uv pip install feelpp-mo2fmu
1321```
1422
15- Or using uv (faster):
23+ ### With OpenModelica Support
24+
25+ To use OpenModelica as a backend, install with the optional dependency:
1626
1727``` console
18- uv pip install feelpp-mo2fmu
28+ uv pip install "feelpp-mo2fmu[openmodelica]"
29+ ```
30+
31+ This will install [ OMPython] ( https://github.com/OpenModelica/OMPython ) for Python integration with OpenModelica.
32+
33+ ### With Simulation Support
34+
35+ To run simulations and validate FMUs (useful for testing):
36+
37+ ``` console
38+ uv pip install "feelpp-mo2fmu[simulation]"
1939```
2040
41+ This will install [ FMPy] ( https://github.com/CATIA-Systems/FMPy ) for FMU simulation and validation.
42+
2143### From Source
2244
2345For development or to use the latest unreleased features:
@@ -42,44 +64,204 @@ export DYMOLA_EXECUTABLE=/usr/local/bin/dymola
4264export DYMOLA_WHL=Modelica/Library/python_interface/dymola-2025.1-py3-none-any.whl
4365```
4466
45- These environment variables are used by:
46- - Tests (avoiding hardcoded paths)
47- - CI/CD workflows
48- - Command-line interface defaults
49-
5067** Environment Variables:**
5168- ` DYMOLA_ROOT ` : Path to Dymola installation root directory (default: ` /opt/dymola-2025xRefresh1-x86_64/ ` )
5269- ` DYMOLA_EXECUTABLE ` : Path to Dymola executable binary (default: ` /usr/local/bin/dymola ` )
5370- ` DYMOLA_WHL ` : Relative path to Dymola Python wheel from DYMOLA_ROOT (default: ` Modelica/Library/python_interface/dymola-2025.1-py3-none-any.whl ` )
5471
55- ## Usage in command line
72+ ### OpenModelica Location
73+
74+ OpenModelica can be configured via environment variables:
75+
76+ ``` bash
77+ export OPENMODELICA_HOME=/usr/lib/omc
78+ ```
79+
80+ ** Environment Variables:**
81+ - ` OPENMODELICA_HOME ` : Path to OpenModelica installation (default: auto-detected)
82+
83+ ## Command Line Interface
84+
85+ The mo2fmu CLI provides two subcommands: ` compile ` and ` check ` .
86+
87+ ### Main Help
5688
5789``` console
5890$ mo2fmu --help
59- Usage: mo2fmu [OPTIONS] MO OUTDIR
91+ Usage: mo2fmu [OPTIONS] COMMAND [ARGS]...
92+
93+ mo2fmu - Convert Modelica models to Functional Mock-up Units (FMUs).
94+
95+ Use 'mo2fmu compile' to generate FMUs or 'mo2fmu check' to verify compilers.
96+
97+ Options:
98+ -v, --version Show version information.
99+ --help Show this message and exit.
100+
101+ Commands:
102+ check Check availability of Modelica compilers and their FMI support.
103+ compile Compile a Modelica model to FMU.
104+ ```
105+
106+ ### Compile Command
107+
108+ Generate FMUs from Modelica models:
109+
110+ ``` console
111+ $ mo2fmu compile --help
112+ Usage: mo2fmu compile [OPTIONS] MO OUTDIR
113+
114+ Compile a Modelica model to FMU.
115+
116+ Options:
117+ --name TEXT Custom name for the FMU (default: .mo file stem).
118+ -l, --load TEXT Load one or more Modelica packages.
119+ --flags TEXT Compiler-specific flags for FMU translation.
120+ -t, --type [all|cs|me|csSolver] FMI type: cs (Co-Simulation), me (Model Exchange),
121+ all, or csSolver.
122+ --fmi-version [1|2|3] FMI version. FMI 3.0 requires Dymola 2024+
123+ or OpenModelica 1.21+.
124+ -b, --backend [dymola|openmodelica|auto]
125+ Modelica compiler backend (default: auto-detect).
126+ --dymola PATH Path to Dymola root directory.
127+ --dymola-exec PATH Path to Dymola executable.
128+ --dymola-whl PATH Path to Dymola wheel file (relative to Dymola root).
129+ -v, --verbose Enable verbose output.
130+ -f, --force Overwrite existing FMU.
131+ --help Show this message and exit.
132+ ```
133+
134+ ** Compile Examples:**
135+
136+ ``` console
137+ # Basic compilation (auto-detect backend)
138+ mo2fmu compile model.mo ./output
139+
140+ # Compile with OpenModelica backend
141+ mo2fmu compile --backend openmodelica model.mo ./output
142+
143+ # Compile FMI 3.0 Co-Simulation FMU with verbose output
144+ mo2fmu compile -v --fmi-version 3 --type cs model.mo ./output
145+
146+ # Force overwrite existing FMU
147+ mo2fmu compile -f model.mo ./output
148+
149+ # Load additional Modelica packages
150+ mo2fmu compile --load package1.mo --load package2.mo model.mo ./output
151+ ```
152+
153+ ### Check Command
154+
155+ Verify compiler availability and FMI support:
156+
157+ ``` console
158+ $ mo2fmu check --help
159+ Usage: mo2fmu check [OPTIONS]
160+
161+ Check availability of Modelica compilers and their FMI support.
60162
61163Options:
62- --fmumodelname TEXT change the model name of the FMU (default: .mo
63- file stem)
64- --load TEXT load one or more Modelica packages.
65- --flags TEXT one or more Dymola flags for FMU translation.
66- --type [all|cs|me|csSolver] the FMI type: cs, me, all, or csSolver.
67- --version TEXT the FMI version.
68- --dymola PATH path to Dymola root.
69- --dymolapath PATH path to Dymola executable.
70- --dymolawhl PATH path to Dymola whl file, relative to Dymola
71- root.
72- -v, --verbose verbose mode.
73- -f, --force force FMU generation even if file exists.
74- --help Show this message and exit.----
164+ --dymola PATH Path to Dymola root directory.
165+ --dymola-exec PATH Path to Dymola executable.
166+ --dymola-whl PATH Path to Dymola wheel file (relative to Dymola root).
167+ --json Output results as JSON.
168+ --help Show this message and exit.
75169```
76170
77- ## Usage in Python
171+ ** Check Examples: **
78172
79- Here is an example of how to use the ` mo2fmu ` function in Python that would convert a Modelica file to an FMU:
173+ ``` console
174+ # Check all available compilers
175+ mo2fmu check
176+
177+ # Output as JSON (for scripting)
178+ mo2fmu check --json
179+
180+ # Check with custom Dymola path
181+ mo2fmu check --dymola /opt/dymola-2024x
182+ ```
183+
184+ ## Python API
185+
186+ ### Recommended API
187+
188+ The recommended API provides a clean interface with automatic backend selection:
189+
190+ ``` python
191+ from feelpp.mo2fmu import compileFmu, getCompiler, checkCompilers
192+
193+ # Auto-detect and use available compiler
194+ result = compileFmu(" path/to/model.mo" , " ./output" )
195+ if result.success:
196+ print (f " FMU created at { result.fmu_path} " )
197+ else :
198+ print (f " Error: { result.error_message} " )
199+
200+ # Explicitly use OpenModelica
201+ result = compileFmu(" path/to/model.mo" , " ./output" , backend = " openmodelica" )
202+
203+ # Compile FMI 3.0 Model Exchange FMU
204+ result = compileFmu(
205+ " path/to/model.mo" ,
206+ " ./output" ,
207+ fmiType = " me" ,
208+ fmiVersion = " 3" ,
209+ verbose = True ,
210+ )
211+
212+ # Check available compilers
213+ available = checkCompilers()
214+ for name, info in available.items():
215+ print (f " { name} : available= { info[' available' ]} , versions= { info.get(' fmi_versions' , [])} " )
216+
217+ # Get a specific compiler instance for more control
218+ compiler = getCompiler(" openmodelica" )
219+ if compiler.is_available:
220+ print (f " Using { compiler.name} " )
221+ ```
222+
223+ ### Using Compiler Classes Directly
224+
225+ For full control, use the compiler classes directly:
226+
227+ ``` python
228+ from feelpp.mo2fmu import (
229+ DymolaCompiler,
230+ OpenModelicaCompiler,
231+ ModelicaModel,
232+ CompilationConfig,
233+ )
234+ from pathlib import Path
235+
236+ # Using OpenModelica
237+ compiler = OpenModelicaCompiler()
238+ if compiler.is_available:
239+ model = ModelicaModel(Path(" path/to/model.mo" ))
240+ config = CompilationConfig(
241+ fmi_type = " cs" , # Co-Simulation
242+ fmi_version = " 3" , # FMI 3.0
243+ verbose = True ,
244+ )
245+ result = compiler.compile(model, Path(" ./output" ), config)
246+
247+ if result.success:
248+ print (f " FMU created: { result.fmu_path} " )
249+ else :
250+ print (f " Compilation failed: { result.error_message} " )
251+
252+ # Using Dymola
253+ compiler = DymolaCompiler()
254+ if compiler.is_available:
255+ result = compiler.compile(model, Path(" ./output" ), config)
256+ ```
257+
258+ ### Legacy API
259+
260+ The original API is still available for backward compatibility:
80261
81262``` python
82263from feelpp.mo2fmu import mo2fmu
264+
83265mo2fmu(
84266 mo_file = " path/to/model.mo" ,
85267 outdir = " path/to/output/dir" ,
@@ -92,10 +274,44 @@ mo2fmu(
92274 dymola_executable = " /path/to/dymola/executable" ,
93275 dymola_whl = " /path/to/dymola.whl" ,
94276 verbose = True ,
95- force = False
277+ force = False ,
278+ backend = " dymola" , # or "openmodelica", "auto"
96279)
97280```
98281
282+ ## Backend Comparison
283+
284+ | Feature | Dymola | OpenModelica |
285+ | ---------| --------| --------------|
286+ | License | Commercial | Open Source (GPL) |
287+ | FMI 1.0 | ✓ | ✓ |
288+ | FMI 2.0 | ✓ | ✓ |
289+ | FMI 3.0 | ✓ (2024+) | ✓ (v1.21+) |
290+ | Co-Simulation | ✓ | ✓ |
291+ | Model Exchange | ✓ | ✓ |
292+ | csSolver type | ✓ | ✗ |
293+ | Modelica Standard Library | ✓ | ✓ |
294+ | BuildingSystems | ✓ | Partial |
295+ | Buildings Library | ✓ | ✓ |
296+
297+ ## Running Tests
298+
299+ The test suite includes unit tests and FMU simulation tests:
300+
301+ ``` console
302+ # Run all tests
303+ uv run pytest
304+
305+ # Run with verbose output
306+ uv run pytest -v
307+
308+ # Run only unit tests (no simulation)
309+ uv run pytest tests/test_compilers.py tests/test_mo2fmu.py
310+
311+ # Run simulation tests (requires FMPy)
312+ uv run pytest tests/test_fmu_simulation.py
313+ ```
314+
99315## Continuous Integration
100316
101317Our GitHub Actions workflow (` .github/workflows/ci.yml ` ) includes:
0 commit comments