Skip to content

FMU Wrappers

FMU wrapper classes for FMI 2.0 and FMI 3.0.

This module contains the FMU handler classes for FMI 2.0 and FMI 3.0. These classes are used to load FMU files and interact with loaded FMUs.

Fmu2Handler

Fmu2Handler(path, fmu_slave)

Bases: FmuXHandler

Handler class for FMU in FMI version 2.0.

Source code in cofmpy/wrappers.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def __init__(self, path: str, fmu_slave):
    """Initializes the FMU handler with the given path and FMU slave class.

    Args:
        path (str): The path of .fmu file to open
        fmu_slave (class): The FMU slave class of FMPy to use to open the fmu
    """
    # read the model description
    self.description = read_model_description(path)

    self.default_step_size = (
        self.description.defaultExperiment.stepSize
        if self.description.defaultExperiment
        else None
    )

    # Create a dictionary to map variable names to attributes
    self.var_name2attr = {}
    for variable in self.description.modelVariables:
        self.var_name2attr[variable.name] = variable

    # extract the FMU and instantiate the slave
    unzipdir = extract(path)
    fmu_name = os.path.basename(path)

    self.fmu = fmu_slave(
        guid=self.description.guid,
        unzipDirectory=unzipdir,
        modelIdentifier=self.description.coSimulation.modelIdentifier,
        instanceName=fmu_name,
    )

    # Get the output variable names
    self.output_var_names = []
    self.output_var_names = list(self.get_output_names())

    # Instantiate the FMU
    self.fmu.instantiate(loggingOn=False)

reset

reset()

Resets the FMU to its initial state and sets up the experiment.

Source code in cofmpy/wrappers.py
477
478
479
480
481
def reset(self):
    """Resets the FMU to its initial state and sets up the experiment."""
    self.fmu.setupExperiment(startTime=0.0)
    self.fmu.enterInitializationMode()
    self.fmu.exitInitializationMode()

step

step(current_time, step_size, input_dict)

Performs a simulation step with the given current time, step size, and input values.

PARAMETER DESCRIPTION
current_time

the current simulation time.

TYPE: float

step_size

the size of the simulation step.

TYPE: float

input_dict

dictionary containing input variable names and their corresponding values.

TYPE: dict

RETURNS DESCRIPTION
dict

Dictionary containing output variable names and their corresponding values after the simulation step.

Source code in cofmpy/wrappers.py
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
def step(self, current_time: float, step_size: float, input_dict: dict) -> dict:
    """
    Performs a simulation step with the given current time, step size, and input
    values.

    Args:
        current_time (float): the current simulation time.
        step_size (float): the size of the simulation step.
        input_dict (dict): dictionary containing input variable names and their
            corresponding values.

    Returns:
        Dictionary containing output variable names and their corresponding values
            after the simulation step.
    """
    # Set all the input variable that are given
    for name, value in input_dict.items():
        self.fmu.setReal([self.var_name2attr[name].valueReference], value)
        # print(f"{name} : {value}")

    self.fmu.doStep(
        currentCommunicationPoint=current_time, communicationStepSize=step_size
    )
    result = {
        name: self.fmu.getReal([self.var_name2attr[name].valueReference])
        for name in self.get_output_names()
    }
    return result

Fmu3Handler

Fmu3Handler(path, fmu_slave)

Bases: FmuXHandler

Handler class for FMU in FMI version 3.0.

Source code in cofmpy/wrappers.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def __init__(self, path: str, fmu_slave):
    """Initializes the FMU handler with the given path and FMU slave class.

    Args:
        path (str): The path of .fmu file to open
        fmu_slave (class): The FMU slave class of FMPy to use to open the fmu
    """
    # read the model description
    self.description = read_model_description(path)

    self.default_step_size = (
        self.description.defaultExperiment.stepSize
        if self.description.defaultExperiment
        else None
    )

    # Create a dictionary to map variable names to attributes
    self.var_name2attr = {}
    for variable in self.description.modelVariables:
        self.var_name2attr[variable.name] = variable

    # extract the FMU and instantiate the slave
    unzipdir = extract(path)
    fmu_name = os.path.basename(path)

    self.fmu = fmu_slave(
        guid=self.description.guid,
        unzipDirectory=unzipdir,
        modelIdentifier=self.description.coSimulation.modelIdentifier,
        instanceName=fmu_name,
    )

    # Get the output variable names
    self.output_var_names = []
    self.output_var_names = list(self.get_output_names())

    # Instantiate the FMU
    self.fmu.instantiate(loggingOn=False)

reset

reset()

Resets the FMU to its initial state

Source code in cofmpy/wrappers.py
536
537
538
539
def reset(self):
    """Resets the FMU to its initial state"""
    self.fmu.enterInitializationMode()
    self.fmu.exitInitializationMode()

step

step(current_time, step_size, input_dict)

Performs a simulation step with the given current time, step size, and input values.

PARAMETER DESCRIPTION
current_time

the current simulation time.

TYPE: float

step_size

the size of the simulation step.

TYPE: float

input_dict

dictionary containing input variable names and their corresponding values.

TYPE: dict

RETURNS DESCRIPTION
dict

Dictionary containing output variable names and their corresponding values after the simulation step.

Source code in cofmpy/wrappers.py
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
def step(self, current_time: float, step_size: float, input_dict: dict) -> dict:
    """
    Performs a simulation step with the given current time, step size, and input
    values.

    Args:
        current_time (float): the current simulation time.
        step_size (float): the size of the simulation step.
        input_dict (dict): dictionary containing input variable names and their
            corresponding values.

    Returns:
        Dictionary containing output variable names and their corresponding values
            after the simulation step.
    """
    # Set all the input variable that are given
    for name, value in input_dict.items():
        if self.var_name2attr[name].type == "Boolean":
            self.fmu.setBoolean([self.var_name2attr[name].valueReference], value)
        else:
            self.fmu.setFloat64([self.var_name2attr[name].valueReference], value)
        # print(f"{name} : {value}")

    self.fmu.doStep(
        currentCommunicationPoint=current_time, communicationStepSize=step_size
    )
    result = {
        name: self.fmu.getFloat64([self.var_name2attr[name].valueReference])
        for name in self.output_var_names
    }
    return result

FmuHandlerFactory

FmuHandlerFactory(path)

Factory class to create FMU handlers based on the FMI version.

ATTRIBUTE DESCRIPTION
path

The file path to the FMU.

TYPE: str

description

The model description of the FMU.

METHOD DESCRIPTION
__call__

Creates and returns an FMU handler based on the FMI version.

Initializes the FmuHandlerFactory with the given path and reads the model description.

PARAMETER DESCRIPTION
path

The file path to the FMU.

TYPE: str

RETURNS DESCRIPTION
FmuXHandler

The appropriate FMU handler based on the FMI version.

TYPE: FmuXHandler

RAISES DESCRIPTION
ValueError

If the FMI version is not recognized.

Source code in cofmpy/wrappers.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def __init__(self, path: str) -> "FmuXHandler":
    """
    Initializes the FmuHandlerFactory with the given path and reads the model
    description.

    Args:
        path (str): The file path to the FMU.

    Returns:
        FmuXHandler: The appropriate FMU handler based on the FMI version.

    Raises:
        ValueError: If the FMI version is not recognized.
    """
    self.path = path

    # case of .py file or .py::<class_name>
    if self.path.endswith(".py") or "::" in self.path:
        self.description = ProxyModelDescription()
    else:
        self.description = read_model_description(path)

FmuProxyHandler

FmuProxyHandler(path)

Bases: FmuXHandler

A handler class that acts as a proxy for an FMU by delegating operations to a dynamically loaded proxy object. This class provides FMI-like behaviors and interfaces for interacting with the proxy. Attributes: _proxy: The dynamically loaded proxy object. fmu: Alias for the proxy object for compatibility with FmuXHandler. _time (float): Internal simulation time. description (ProxyModelDescription): A proxy model description compatible with FmuXHandler helpers. default_step_size (float): Default step size for the simulation. var_name2attr (Dict[str, ProxyVarAttr]): A mapping of variable names to their attributes. output_var_names (List[str]): A list of output variable names. Methods: reset(): Resets the internal simulation time to 0.0. get_variable(name: str) -> list: Retrieves the value of a variable by name as a single-element list. set_variables(input_dict: Dict[str, Any]): Sets multiple variables based on the provided dictionary of variable names and values. step(current_time: float, step_size: float, input_dict: Dict[str, Any]) -> Dict[str, Any]: Advances the simulation by a given step size, applying inputs before stepping and returning the output variables. get_state() -> Dict[str, Any]: Retrieves the current state of the simulation, including time and variable values, in a JSON-serializable format. set_state(state: Dict[str, Any]): Restores the simulation state from a given dictionary.

Initialize the wrapper class with a given proxy model file path. Args: path (str): The file path to the proxy model. This should be in the format .py or .py::. Attributes: _proxy: The proxy instance loaded from the file. fmu: Alias for the proxy instance for compatibility with FmuXHandler. _time (float): The current simulation time, initialized to 0.0. description (ProxyModelDescription): A model description object compatible with FmuXHandler helpers, containing metadata about the proxy model. default_step_size (Optional[float]): The default step size for the simulation, extracted from the proxy model description. var_name2attr (Dict[str, ProxyVarAttr]): A mapping of variable names to their attributes for quick lookup. output_var_names: A list of output variable names extracted from the proxy model. Raises: Any exceptions raised by load_proxy_class_from_file or other operations during initialization.

Source code in cofmpy/wrappers.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
def __init__(self, path: str):  # pylint: disable=super-init-not-called
    """
    Initialize the wrapper class with a given proxy model file path.
    Args:
        path (str): The file path to the proxy model. This should be in the
            format <model_name>.py or <model_name>.py::<class_name>.
    Attributes:
        _proxy: The proxy instance loaded from the file.
        fmu: Alias for the proxy instance for compatibility with FmuXHandler.
        _time (float): The current simulation time, initialized to 0.0.
        description (ProxyModelDescription): A model description object
            compatible with FmuXHandler helpers, containing metadata about
            the proxy model.
        default_step_size (Optional[float]): The default step size for the
            simulation, extracted from the proxy model description.
        var_name2attr (Dict[str, ProxyVarAttr]): A mapping of variable names
            to their attributes for quick lookup.
        output_var_names: A list of output variable names extracted from the
            proxy model.
    Raises:
        Any exceptions raised by `load_proxy_class_from_file` or other
        operations during initialization.
    """
    # extract proxy from path
    self._proxy = load_proxy_class_from_file(path)()
    self.fmu = self._proxy  # compatibility with FmuXHandler
    self._time: float = 0.0

    # Build a proxy model description compatible with FmuXHandler helpers
    pv: List[ProxyVarAttr] = []
    for vr, v in enumerate(self._proxy.variables()):
        pv.append(
            ProxyVarAttr(
                name=v.name,
                type=v.type,
                causality=v.causality,
                variability=v.variability,
                valueReference=vr,
                start=v.start,
            )
        )

    self.description = ProxyModelDescription(
        fmiVersion="proxy",
        guid=f"proxy-{self._proxy.model_identifier}",
        coSimulation=ProxyCoSimulation(
            modelIdentifier=self._proxy.model_identifier
        ),
        defaultExperiment=ProxyDefaultExperiment(
            stepSize=self._proxy.default_step_size
        ),
        modelVariables=pv,
    )

    self.default_step_size = (
        self.description.defaultExperiment.stepSize
        if self.description.defaultExperiment
        else None
    )

    self.var_name2attr: Dict[str, ProxyVarAttr] = {
        v.name: v for v in self.description.modelVariables
    }
    self.output_var_names = self.get_output_names()

FmuXHandler

FmuXHandler(path, fmu_slave)

Bases: ABC

Abstract base class for handling FMU Slave objects (FMI 2.0 or FMI 3.0).

ATTRIBUTE DESCRIPTION
description

The model description of the FMU.

TYPE: ModelDescription

var_name2attr

A dictionary mapping variable names to their attributes.

TYPE: dict

fmu

The FMU instance.

TYPE: FMU

output_var_names

A list of output variable names.

TYPE: list

METHOD DESCRIPTION
reset

Abstract method to reset the FMU. Must be implemented by subclasses.

step

Abstract method to perform a simulation step. Must be implemented by subclasses.

cancel_step

Cancels the current step of the FMU.

get_state

Retrieves the current state of the FMU.

set_state

Sets the state of the FMU to the given state.

get_output_names

Retrieves the names of the FMU output variables.

get_input_names

Retrieves the names of the FMU input variables.

get_parameter_names

Retrieves the names of the FMU tunable parameters.

Initializes the FMU handler with the given path and FMU slave class.

PARAMETER DESCRIPTION
path

The path of .fmu file to open

TYPE: str

fmu_slave

The FMU slave class of FMPy to use to open the fmu

TYPE: class

Source code in cofmpy/wrappers.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def __init__(self, path: str, fmu_slave):
    """Initializes the FMU handler with the given path and FMU slave class.

    Args:
        path (str): The path of .fmu file to open
        fmu_slave (class): The FMU slave class of FMPy to use to open the fmu
    """
    # read the model description
    self.description = read_model_description(path)

    self.default_step_size = (
        self.description.defaultExperiment.stepSize
        if self.description.defaultExperiment
        else None
    )

    # Create a dictionary to map variable names to attributes
    self.var_name2attr = {}
    for variable in self.description.modelVariables:
        self.var_name2attr[variable.name] = variable

    # extract the FMU and instantiate the slave
    unzipdir = extract(path)
    fmu_name = os.path.basename(path)

    self.fmu = fmu_slave(
        guid=self.description.guid,
        unzipDirectory=unzipdir,
        modelIdentifier=self.description.coSimulation.modelIdentifier,
        instanceName=fmu_name,
    )

    # Get the output variable names
    self.output_var_names = []
    self.output_var_names = list(self.get_output_names())

    # Instantiate the FMU
    self.fmu.instantiate(loggingOn=False)

cancel_step

cancel_step()

Cancels the current step of the FMU.

Source code in cofmpy/wrappers.py
254
255
256
def cancel_step(self):
    """Cancels the current step of the FMU."""
    self.fmu.cancelStep()

get_causality

get_causality(name)

Retrieves the causality of a variable.

PARAMETER DESCRIPTION
name

The name of the variable to get

TYPE: str

RETURNS DESCRIPTION
str

The causality of the variable

TYPE: str

Source code in cofmpy/wrappers.py
232
233
234
235
236
237
238
239
240
241
def get_causality(self, name: str) -> str:
    """Retrieves the causality of a variable.

    Args:
        name (str): The name of the variable to get

    Returns:
        str: The causality of the variable
    """
    return self.var_name2attr[name].causality

get_input_names

get_input_names()

Retrieves the list of names of the FMU's input variables.

RETURNS DESCRIPTION
list

A list containing the name of each input variable

TYPE: list[str]

Source code in cofmpy/wrappers.py
197
198
199
200
201
202
203
204
205
206
207
def get_input_names(self) -> list[str]:
    """Retrieves the list of names of the FMU's input variables.

    Returns:
        list: A list containing the name of each input variable
    """
    input_names = []
    for variable in self.description.modelVariables:
        if variable.causality == "input":
            input_names.append(variable.name)
    return input_names

get_output_names

get_output_names()

Retrieves the list of names of the FMU's output variables.

RETURNS DESCRIPTION
list

A list containing the name of each output variable

TYPE: list[str]

Source code in cofmpy/wrappers.py
220
221
222
223
224
225
226
227
228
229
230
def get_output_names(self) -> list[str]:
    """Retrieves the list of names of the FMU's output variables.

    Returns:
        list: A list containing the name of each output variable
    """
    output_names = []
    for variable in self.description.modelVariables:
        if variable.causality == "output":
            output_names.append(variable.name)
    return output_names

get_parameter_names

get_parameter_names()

Retrieves the names of the FMU tunable parameters. Returns: list: A list containing the name of each tunable parameter

Source code in cofmpy/wrappers.py
209
210
211
212
213
214
215
216
217
218
def get_parameter_names(self) -> list[str]:
    """Retrieves the names of the FMU tunable parameters.
    Returns:
        list: A list containing the name of each tunable parameter
    """
    parameter_names = []
    for variable in self.description.modelVariables:
        if variable.causality == "parameter":
            parameter_names.append(variable.name)
    return parameter_names

get_state

get_state()

Retrieves the current state of the FMU.

RETURNS DESCRIPTION
fmiXFMUState

The current of state of the FMU, X is the version of FMI used (ie. fmi3FMUState for FMI3.0)

Source code in cofmpy/wrappers.py
258
259
260
261
262
263
264
265
def get_state(self):
    """Retrieves the current state of the FMU.

    Returns:
        (fmiXFMUState): The current of state of the FMU, X is the version of FMI used
            (ie. fmi3FMUState for FMI3.0)
    """
    return self.fmu.getFMUState()

get_variable

get_variable(name)

Gets the variable matching the given name.

PARAMETER DESCRIPTION
name

The name of the variable to get

TYPE: str

RETURNS DESCRIPTION
list

The value of the variable, as a list.

TYPE: list

Source code in cofmpy/wrappers.py
281
282
283
284
285
286
287
288
289
290
291
292
def get_variable(self, name: str) -> list:
    """
    Gets the variable matching the given name.

    Args:
        name (str): The name of the variable to get

    Returns:
        list: The value of the variable, as a list.
    """
    var = self.var_name2attr[name]
    return getattr(self.fmu, f"get{var.type}")([var.valueReference])

get_variable_names

get_variable_names()

Retrieves the names of all variables in the FMU.

RETURNS DESCRIPTION
list

A list containing the name of each variable

TYPE: list[str]

Source code in cofmpy/wrappers.py
189
190
191
192
193
194
195
def get_variable_names(self) -> list[str]:
    """Retrieves the names of all variables in the FMU.

    Returns:
        list: A list containing the name of each variable
    """
    return [variable.name for variable in self.description.modelVariables]

get_variable_type

get_variable_type(name)

Retrieves the type of the variable with the given name.

PARAMETER DESCRIPTION
name

The name of the variable.

TYPE: str

RETURNS DESCRIPTION
str

The type of the variable.

TYPE: str

Source code in cofmpy/wrappers.py
243
244
245
246
247
248
249
250
251
252
def get_variable_type(self, name: str) -> str:
    """Retrieves the type of the variable with the given name.

    Args:
        name (str): The name of the variable.

    Returns:
        str: The type of the variable.
    """
    return self.var_name2attr[name].type

get_variables

get_variables(names)

Gets the values of the FMU variables matching the given names.

PARAMETER DESCRIPTION
names

A list of variable names to get

TYPE: list

RETURNS DESCRIPTION
dict

A dictionary containing the variable names and their corresponding values

TYPE: dict

Source code in cofmpy/wrappers.py
177
178
179
180
181
182
183
184
185
186
187
def get_variables(self, names: list[str]) -> dict:
    """Gets the values of the FMU variables matching the given names.

    Args:
        names (list): A list of variable names to get

    Returns:
        dict: A dictionary containing the variable names and their corresponding
              values
    """
    return {name: self.get_variable(name) for name in names}

reset abstractmethod

reset()

Resets the FMU to its initial state and sets up the experiment.

Source code in cofmpy/wrappers.py
294
295
296
297
@abstractmethod
def reset(self):
    """Resets the FMU to its initial state and sets up the experiment."""
    raise NotImplementedError

set_state

set_state(state)

Sets the state of the FMU to the given state.

PARAMETER DESCRIPTION
state

The state of the FMU to set, X is the version of FMI used (ie. fmi3FMUState for FMI3.0)

TYPE: fmiXFMUState

Source code in cofmpy/wrappers.py
267
268
269
270
271
272
273
274
def set_state(self, state):
    """Sets the state of the FMU to the given state.

    Args:
        state (fmiXFMUState): The state of the FMU to set, X is the version of FMI
            used (ie. fmi3FMUState for FMI3.0)
    """
    self.fmu.setFMUState(state)

set_variables

set_variables(input_dict)

Sets the FMU variables to the given values.

PARAMETER DESCRIPTION
input_dict

A dictionary containing variable names and their corresponding values.

TYPE: dict

Source code in cofmpy/wrappers.py
167
168
169
170
171
172
173
174
175
def set_variables(self, input_dict: dict):
    """Sets the FMU variables to the given values.

    Args:
        input_dict (dict): A dictionary containing variable names and their
            corresponding values.
    """
    for name, value in input_dict.items():
        self._set_variable(name, value)

step abstractmethod

step(current_time, step_size, input_dict)

Performs a simulation step with the given current time, step size, and input values.

Source code in cofmpy/wrappers.py
299
300
301
302
303
304
305
@abstractmethod
def step(self, current_time, step_size, input_dict):
    """
    Performs a simulation step with the given current time, step size, and input
    values.
    """
    raise NotImplementedError