FMI Interface support
Applications that communicate with external devices are inherently difficult to test in isolation. A large number of simulation tools is available, that allow interfacing such applications with a simulated device. This enables application development, testing and evaluation in absence of an actual device. In addition simulation can easily provide information on current device state, and simulate conditions that are rare and difficult to achieve on request in a physical device (i.e., specific malfunctions). Squish supports communication to such tools using the FMI interface.
The Functional Mockup Interface is an industry standard for model exchange and co-simulation of dynamic models. It describes interface between exporters and importers of simulation units called Functional Mockup Units (FMUs). Squish has the capability to import FMUs that support FMI 2.0 CoSimulation mode. As an FMU importer, Squish has access to all variables exposed by a FMU, and is responsible for driving the simulation process. The following section introduces APIs that Squish provides to import and execute FMUs.
Full FMI 2.0 specification text can be obtained at https://www.fmi-standard.org. Squish support of FMI interface is based upon the FMI library from the JModelica platform.
FMI Overview
Note: The interface described here is not considered the final version. The details of the described API can change in the release version of the feature.
The FMI standard specifies that a FMU can contain either compiled executable code in form of a platform-specific shared object file, or a set of source code files that can be compiled by an FMI importer. Squish supports only the former.
It is not recommended to load a FMU in the same context as the AUT. To separate the FMU from any other processes, Squish provides a utility executable fmiutil
. FMI functionality is available only in the application context of the fmiutil
tool. It is located in Squish binary installation directory. To launch fmiutil
, use the ApplicationContext startFMI() function.
ApplicationContext startFMI()
ApplicationContext startFMI(host)
ApplicationContext startFMI(host, port)
ApplicationContext startFMI(host, port, timeoutSecs)
Starts a new fmiutil
instance and returns a handle to its application context.
Optionally, as first and second parameters a host
and port
can be specified. If these parameters are used, instead of connecting to the default host and port (as specified in the squishide
's settings or on squishrunner's command line), a connection to the squishserver on the specified host and listening to the specified port will be established.
The third parameter, timeoutSecs
(an integer number of seconds) can also be specified. This tells Squish how long it should be prepared to wait for the application to start before throwing an error. If specified, this value overrides squishrunner's default AUT timeout. If not specified the squishserver's default is used—this is 20 seconds, unless it has been changed. See Squish Server Settings dialog.
If you want to specify a timeout, but don't want to change the host or port, you can do so by passing an empty string as the host (which will make Squish use the configured host—localhost
by default), and by passing -1 as the port.
Fmi2Import class
The Fmi2Import
class is the core of the Squish FMI Interface support. It represents an FMU imported by Squish.
Fmi2Import Fmi2Import.create(filename, workingDirectory)
Fmi2Import Fmi2Import.create(filename)
This static method opens a specified FMU using the specified directory as a working directory, and returns a Fmi2Import
object. If workingDirectory
is not specified, a temporary directory is created in %TEMP% directory on each invocation of the method.
Fmi2Import.lastError
This read-only property holds a string describing the last error a FMU has encountered. It is set by Fmi2Import
methods when returning an error.
Fmi2Import.name
Fmi2Import.identifierME
Fmi2Import.identifierCS
Fmi2Import.guid
Fmi2Import.description
Fmi2Import.author
Fmi2Import.copyright
Fmi2Import.license
Fmi2Import.version
Fmi2Import.standardVersion
Fmi2Import.generationTool
Fmi2Import.generationDate
Fmi2Import.namingConvetion
Fmi2Import.continuousStates
Fmi2Import.eventIndicators
Fmi2Import.defaultExperimentStart
Fmi2Import.defaultExperimentStop
Fmi2Import.defaultExperimentTolerance
Fmi2Import.defaultExperimentStep
These read-only properties hold meatadata for a FMU object as specified by FMI 2.0 standard.
Fmi2Import.fmuKind
This read-only property holds a value that indicates the FMI modes supported by a FMU. It can be one of:
Fmi2Import.KindUnknown
— An unknkown FMU kindFmi2Import.KindME
— A FMU that supports only ModelExchange modeFmi2Import.KindCS
— A FMU that supports only CoSimulation modeFmi2Import.KindMECS
— A FMU that supports both ModelExchange and CoSimulation mode
Fmi2Import.state
This read-only property holds the current state of a FMU. It can be one of:
Fmi2Import.Preloaded
— The XML file describing the FMU was parsed, but binary model executable was not loaded yet.Fmi2Import.Instantiated
— The binary model executable was successfully loaded and the model was instantiated.Fmi2Import.Init
— The FMU has entered the initialization mode.Fmi2Import.Event
— The FMU is in event state. This state is only available for ModelExchange FMUs.Fmi2Import.Continous
— The FMU is in continous state. This state is only available for ModelExchange FMUs.Fmi2Import.StepComplete
— The last simulation step was successfully completed. This state is only available for CoSimulation FMUs.Fmi2Import.StepFailed
— The last simulation step has failed. This state is only available for CoSimulation FMUs.Fmi2Import.Terminated
— The simulation process was terminated.Fmi2Import.Error
— A simulation error has occured. The simulation should be either terminated or restored to a prevoiously saved state.Fmi2Import.Fatal
— A fatal error has occured within the FMU. The FMU should be abandoned in its current state.
Fmi2Import.type
Read-only property that describes the type of the FMU that was instantiated. The value of this property before the FMU is instantiated is indeterminate. It can be one of:
Fmi2Import.TypeME
— The FMU was instantiated in ModelExchange mode.Fmi2Import.TypeCS
— The FMU was instantiated in CoSimulation mode.
Fmi2Import.time
This read-only property holds the current simulation time of the FMU.
Fmi2Import.typesPlatform
This read-only property holds a string identifier that corresponds to a basic set of primitive types that are used on the current platform by FMI applications. Attempts to use a FMU that was compiled with different typesPlatform than the one used to compile Squish will cause an error, as mandated by the FMI 2.0 standard.
Fmi2Import.types
This read-only property holds an array of Fmi2Type objects that describe type definitions for a FMU.
Fmi2Import.units
This read-only property holds an array of Fmi2Unit
objects that describe units used by a FMU.
Fmi2Import.variables
This read-only property holds an array of Fmi2Variable
objects that describe variables used by a FMU.
Fmi2Import.vendors
This read-only property holds an array of strings - each describing a software vendor that contributed to the loaded FMU.
Fmi2Import.logCategories
This read-only property holds an array of string identifiers describing log categories that a FMU uses.
Fmi2Import.logCategoriesDescriptions
This read-only property holds an array of string descriptions for log categories that a FMU uses.
Fmi2Import.sourceFilesME
This read-only property holds an array of file names. If a FMU delivers source code for a ModelExchange binary, this array contains the names of those source files.
Fmi2Import.sourceFilesCS
This read-only property holds an array of file names. If a FMU delivers source code for a CoSimulation binary, this array contains the names of those source files.
Fmi2Import.outputs
This read-only property holds a Fmi2VariableArray
object that lists output variables defined for a FMU.
Fmi2Import.derivatives
This read-only property holds a Fmi2VariableArray
object that lists derivative variables defined for a FMU.
Fmi2Import.discreteStates
This read-only property holds a Fmi2VariableArray
object that lists discrete-state variables defined for a FMU.
Fmi2Import initialUnknowns
This read-only property holds a Fmi2VariableArray
object that lists variables of initially unknown value defined for a FMU.
Fmi2Import.instantiate(name, type, visible)
This method loads the dynamic library bundled with the FMU and instantiates a FMU object. type
must be either Fmi2Import.TypeME
or Fmi2Import.TypeCS
. The Chosen type must be supported by FMU as indicated by the Fmi2Import.fmuKind property. The default value for this parameter is Fmi2Import.TypeCS
if supported by the FMU, and Fmi2Import.TypeME
otherwise.
name
should be a short string. It is used in error messages as model identifier. Default value for this parameter is the value of the Fmi2Import.name property.
visible
should be a boolean value. In case the FMU shows its own GUI, either directly or by an external and possibly pre-existing application. This parameter indicates whether such GUI should be brought to the foreground immediately. If the FMU shows no GUI of any kind, this parameter is ignored.
Note: If any non-static method of a Fmi2Import
object is called, this method is called implicitly with default parameter values.
Fmi2Import.setupExperiment(startTime, stopTime, tolerance)
This method informs a FMU to setup the experiment and causes the FMU to enter the initialization mode. This method requires the FMU to be instantiated. If this method is called after the initialization mode has been entered, an error is reported. Default values for parameters are Fmi2Import.defaultExperimentStart, Fmi2Import.defaultExperimentStop and Fmi2Import.defaultExperimentTolerance respectively.
Note: If any method of a Fmi2Import
object that requires it to set up is called, this method is called implicitly with default parameter values.
Fmi2Import.exitInitializationMode()
This method causes a FMU to exit initialization mode and enter Fmi2Import.StepComplete
(for CoSimulation FMUs) or Fmi2Import.Event
(for ModelExchange FMUs) state. This method requires FMU to be in the initialization state.
Note: If any method of a Fmi2Import
object that requires it to initialize is called, this method is called implicitly.
Fmi2Import.getCapability(capability)
This method returns an integer that describes the requested capability
of a FMU. capablity
can be one of:
Fmi2Import.ME_needsExecutionTool
— If the value of this capability is 1, the FMU doesn't contain the full ModelExchange model implementation and requires additional software to be available.Fmi2Import.ME_canBeInstantiatedOnlyOncePerProcess
— If the value of this capability is 1, the FMU can only be instantiated once in ModelExchange mode. This has only informational value, as Squish allows only a single instance of any FMU.Fmi2Import.ME_canGetAndSetFMUstate
— If the value of this capability is 1, the ModelExchange FMU can use Fmi2State Fmi2Import.getState() and Fmi2Import.setState(state) to save and restore the current FMU state.Fmi2Import.ME_canSerializeFMUstate
— If the value of this capability is 1, the ModelExchange FMU state can be serialized.Fmi2Import.CS_needsExecutionTool
— If the value of this capability is 1, the FMU doesn't contain the full CoSimulation model implementation and requires additional software to be available.Fmi2Import.CS_canHandleVariableCommunicationStepSize
— If the value of this capability is 0, using different step size values with a CoSimulation FMU may cause an error.Fmi2Import.CS_canBeInstantiatedOnlyOncePerProcess
— If the value of this capability is 1, the FMU can only be instantiated once in CoSimulation mode. This has only informational value, as Squish allows only a single instance of any FMU.Fmi2Import.CS_canGetAndSetFMUstate
— If the value of this capability is 1, the CoSimulation FMU can utilize Fmi2State Fmi2Import.getState() and Fmi2Import.setState(state) to save and restore the current FMU state.Fmi2Import.CS_canSerializeFMUstate
— If the value of this capability is 1, the CoSimulation FMU state can be serialized.
Fmi2Import.getAliasBase(var)
If var
is an alias variable, it returns the non-alias variable that var
aliases. If var
is a non-alias variable, it returns var
.
Fmi2Import.getAliases(var)
This method returns a Fmi2VariableArray
object that contains all known aliases for the var
variable. The array includes the base (non-alias) variable.
Fmi2Import.getVariable(name)
This method returns a Fmi2Variable object that describes a variable of a given name
. If no variable named name
is found in a FMU, an error is reported.
Fmi2Import.getVariables(names)
This method returns a Fmi2VariableArray
object that contains variables of the names in names
array. If any of the names in the names
array is not found in a FMU, an error is reported.
Fmi2Import.getVariableByName(name)
This method returns a Fmi2Variable
object that describes a variable of a given name
. If no variable named name
is found in a FMU, it returns null
.
Fmi2Import.getVariableByReference(vref)
This method returns a Fmi2Variable
object that describes a variable of a given vref
variable reference. If no variable with vref
variable reference is found in a FMU, it returns null
.
Fmi2Import.setDebugLogging(loggingOn, categories)
This method sets debug logging on a FMU. If loggingOn
is true
, logging is enabled. categories
is an array that specifies which log categories are to be logged. Entries of this array can be any of the identifiers found in Fmi2Import.logCategories array.
Fmi2Import.setReal(variables, values)
This method sets the values of the FMU variables to the specified values. It returns true
in case of success, or false
in case the values were rejected by FMU. This usually happens for numerical reasons: value outside bounds was set, integrator could not converge, etc.
variables
should be a Fmi2VariableArray
object or an array of either variable names or Fmi2Variable class objects. The specified variables must be exclusively real variables.
values
should be an array of numeric values for corresponding variables. The length of variables
and values
must be the same. This method requires the FMU to be instantiated.
Fmi2Import.setInteger(variables, values)
This method sets the values of the FMU variables to the specified values. It returns true
in case of success, or false
in case the values were rejected by FMU. This usually happens for numerical reasons: value outside bounds was set, integrator could not converge, etc.
variables
should be a Fmi2VariableArray object or an array of either variable names or Fmi2Variable class objects. The specified variables must be either integer or enumeration variables.
values
should be an array of numeric values for the corresponding variables. The length of variables
and values
must be the same. This method requires the FMU to be instantiated.
Fmi2Import.setBoolean(variables, values)
This method sets the values of the FMU variables to the specified values. It returns true
in case of success, or false
in case the values were rejected by FMU. This usually happens for numerical reasons: value outside bounds was set, integrator could not converge, etc.
variables
should be a Fmi2VariableArray
object or an array of either variable names or Fmi2Variable class objects. The specified variables must be exclusively boolean variables.
values
should be an array of boolean values for corresponding variables. The length of variables
and values
must be the same. This method requires the FMU to be instantiated.
Fmi2Import.setString(variables, values)
This method sets the values of the FMU variables to the specified values. It returns true
in case of success, or false
in case the values were rejected by FMU. This usually happens for numerical reasons: value outside bounds was set, integrator could not converge, etc.
variables
should be a Fmi2VariableArray
object or an array of either variable names or Fmi2Variable class objects. The specified variables must be exclusively string variables.
values
should be an array of string values for corresponding variables. The length of variables
and values
must be the same. This method requires the FMU to be instantiated.
Fmi2Import.setValue(variables, values)
This method sets the values of the FMU variables to the specified values. It returns true
in case of success, or false
in case the values were rejected by FMU. This usually happens for numerical reasons: value outside bounds was set, integrator could not converge, etc.
variables
should be a Fmi2VariableArray
object or an array of either variable names or Fmi2Variable class objects. The specified variables can be of any type. values
should be an array of values for corresponding variables. The length of variables
and values
must be the same, and the types of values must match corresponding variable definition. This method requires the FMU to be instantiated.
Fmi2Import.getReal(variables)
This method returns an array containing the values of specified FMU variables. variables
should be an array of variable names, an array of Fmi2Variable class objects or a Fmi2VariableArray
object. The specified variables must be exclusively real variables. This method requires the FMU to be set up.
Fmi2Import.getInteger(variables)
This method returns an array containing the values of specified FMU variables. variables
should be an array of variable names, an array of Fmi2Variable class objects or a Fmi2VariableArray
object. The specified variables must be either integer or enumeration variables. This method requires the FMU to be set up.
Fmi2Import.getBoolean(variables)
This method returns an array containing the values of specified FMU variables. variables
should be an array of variable names, an array of Fmi2Variable class objects or a Fmi2VariableArray
object. The specified variables must be exclusively boolean variables. This method requires the FMU to be set up.
Fmi2Import.getString(variables)
This method returns an array containing the values of specified FMU variables. variables
should be an array of variable names, an array of Fmi2Variable class objects or a Fmi2VariableArray
object. The specified variables must be exclusively string variables. This method requires the FMU to be set up.
Fmi2State Fmi2Import.getState()
This method returns a Fmi2State
object that represents the current FMU state. It can be used as an argument to Fmi2Import.setState(state) to restore an FMU from a previously saved state. This method requires a FMU to be instantiated.
Fmi2Import.setState(state)
This method restores the FMU state to state saved in Fmi2State class object state
. This method requires a FMU to be instantiated.
Fmi2Import.terminate()
This method terminates the current simulation and changes the current FMU state to Fmi2Import.Terminated
. This method requires a FMU to be initialized, and not to be in Fmi2Import.Error
state.
Fmi2Import.reset()
This method restores a FMU to the Fmi2Import.Instantiated
state. This method requires a FMU to be instantiated.
Fmi2Import.doStep(stepSize, noPriorState)
This method performs a simulation step in CoSimulation mode. It increases internal FMU simulation time Fmi2Import.time by stepSize
. It returns true
if a simulation step was performed correctly, or false
if a simulation step could not be completed. This usually happens for numerical reasons; i.e., the internal FMU integrator did not converge. Returning to a previously saved state and retrying the simulation step with modified inputs may succeed. This method requires a FMU to be initialized.
An optional parameter noPriorState
can be specified, it informs the FMU that it will no longer be restored to a state with time before current FMU time. It can be used by a FMU as hint to flush cache buffers. Default value for this parameter is true
.
Fmi2Import.run(runtime, stepSize, timeFactor)
Fmi2Import.run(runtime, stepSize)
This method performs a series of simulation steps of stepSize
. The simulation is continued until internal FMU time is increased by runtime
or until a simulation step could not be performed, in which case this method returns false
. This method requires a FMU to be initialized.
An optional argument timeFactor
controls speed at which simulation steps are performed. It provides the relation between the simulation time and the simulation execution time. For example if time factor equals 0.5
, two seconds of simulation time should be excuted in one second of execution time. In case of simulation of real systems interacting with external software the timeFactor
of 1
is probably most useful. Default value for this parameter is 0
- simulation steps are performed as quickly as the environment and the FMU allows.
Note: Squish cannot execute the simulation quicker than an FMU and execution environment allow. If the simulation runs slower than requested, consider increasing stepSize to reduce FMU interaction frequency.
Fmi2Import.runDetached(stepSize, timeFactor)
Fmi2Import.runDetached(stepSize)
This method performs a series of simulation steps of stepSize
just as Fmi2Import.run(runtime, stepSize, timeFactor). The difference is, that this method returns immediateley and performs simulation in background, parallel to further test script execution. Any errors encountered during the simulation are reported by Fmi2Import.sync() method. This method requires a FMU to be initialized.
Fmi2Import.sync()
If FMU runs a detached simulation started by Fmi2Import.runDetached(stepSize, timeFactor) it waits until requested simulation steps are performed and returns false
if the simulation was interrupted prematurely. If any errors were encountered during the simulation, an exception is thrown.
Fmi2Variable class
The Fmi2Variable
class represents a variable exposed by a FMU.
Fmi2Variable.name
This read-only property holds a variable name.
Fmi2Variable.value
This property holds the current value of the variable. If a FMU is not ready to provide variable values (i.e., it wasn't fully initialized), the result is the default empty value - zero for numeric and enumeration types, false
for boolean variables and an empty string for string variables.
This property is read-only. to change values of input variables use Fmi2Import.setValue(variables, values) or type-specific Fmi2Import.set*
methods.
Fmi2Variable.description
This read-only property holds a human-readable variable description.
Fmi2Variable.valueReference
This read-only property holds the value reference for a variable. Value reference is an integer that is used internally by an FMU to identify the variable. Alias variables use the same valueReference as their base variable, and therefore always have the same value.
Fmi2Variable.declaredType
This read-only property holds an object of the Fmi2Type class type in case the variable has a declared type, null
otherwise.
Fmi2Variable.baseType
This read-only property holds a value that describes the basic data type of a variable. It can be one of:
Fmi2Import.Real
— a real variableFmi2Import.Integer
— an integer variableFmi2Import.Boolean
— a boolean variableFmi2Import.String
— a string variableFmi2Import.Enum
— an enumeration variable
Fmi2Variable.hasStart
This read-only property holds a boolean that indicates whether a variable has a defined startup value.
Fmi2Variable.variability
This read-only property holds a value that describes when changes in value of a variable are allowed. It can be one of:
Fmi2Variable.Constant
— the value of a variable never changesFmi2Variable.Fixed
— the value of a variable remains constant after a FMU has been initializedFmi2Variable.Tunable
— The value cannot change between events (ModelExchange) or between simulation steps (CoSimulation)Fmi2Variable.Discrete
— The value cannot change between events (ModelExchange) or between simulation steps (CoSimulation)Fmi2Variable.Continuous
— no restrictions on value changesFmi2Variable.UnknownVariability
— unknown variablity
Fmi2Variable.causality
This read-only property indicates how the value for a variable is obtained. It can be one of:
Fmi2Variable.Parameter
— an independent parameter; can be set by a test script.Fmi2Variable.CalculatedParameter
— calculated within the FMU model during initialization or after a parameter is changed.Fmi2Variable.Input
— an input variable; can be set by a test script.Fmi2Variable.Output
— an output variable;Fmi2Variable.Local
— internal FMU variable;Fmi2Variable.Independent
— an independent variable for a simulation. All other variables are defined as functions of the independent variable. Default independent variable is 'time'. There can be at most one independent variable in a FMU;Fmi2Variable.UnknownCausaility
— unknown causality.
Fmi2Variable.initial
This read-only property holds a value that indicates how the initial value for a variable is obtained. It can be one of:
Fmi2Variable.Exact
— astart
attribute is used as initial value;Fmi2Variable.Approx
— an initial value is computed iteratively. Astart
attribute is used as initial value for computation;Fmi2Variable.Calculated
— an initial value is calculated from values of other variables during initialization.
Fmi2Variable.previous
This read-only property holds a Fmi2Variable
that holds the previous value of the variable, or null
if no such variable was defined.
Fmi2Variable.isAlias
This read-only property holds a boolean that is true
if the variable is an alias for another variable.
Fmi2RealVariable Fmi2Variable.asReal()
This method casts a variable to Fmi2RealVariable
object if its baseType
is Real
, or null
otherwise.
Fmi2IntegerVariable Fmi2Variable.asInteger()
This method casts a variable to Fmi2IntegerVariable
object if its baseType
is Integer
, or null
otherwise.
Fmi2EnumVariable Fmi2Variable.asEnum()
This method casts a variable to Fmi2EnumVariable
object if its baseType
is Enum
, or null
otherwise.
Fmi2StringVariable Fmi2Variable.asString()
This method casts a variable to Fmi2StringVariable
object if its baseType
is String
, or null
otherwise.
Fmi2BooleanVariable Fmi2Variable.asBoolean()
This method casts a variable to Fmi2BooleanVariable
object if its baseType
is Boolean
, or null
otherwise.
Fmi2RealVariable.start
Fmi2IntegerVariable.start
Fmi2EnumVariable.start
Fmi2StringVariable.start
Fmi2BooleanVariable.start
These read-only properties hold start values of appropriate type for a variable.
Fmi2RealVariable.min
Fmi2RealVariable.max
Fmi2IntegerVariable.min
Fmi2IntegerVariable.max
Fmi2EnumVariable.min
Fmi2EnumVariable.max
These read-only properties hold minmal and maximal values for a variable.
Fmi2RealVariable.derivativeOf
This read-only property holds an Fmi2RealVariable
object for which the variable is a derivative, or null
if none.
Fmi2RealVariable.unit
This read-only property holds an Fmi2Unit
object if defined for a variable or null
otherwise.
Fmi2RealVariable.displayUnit
This read-only property holds an Fmi2DisplayUnit
object if defined for a variable or null
otherwise.
Fmi2Type class
The Fmi2Type
class contains information about an FMI type definition. It serves purely informational role.
Fmi2Type.name
This read-only property holds a name for the type definition.
Fmi2Type.description
This read-only property holds a description for the type definition.
Fmi2Type.baseType
This read-only property holds a base type for the type definition. The meaning of this value is the same as Fmi2Variable.baseType.
Fmi2Type.quantity
This read-only property holds a string that describes quantity of the type definition.
Fmi2RealType Fmi2Type.asReal()
This method casts a type definition to the Fmi2RealType object if its baseType
is Real
, or null
otherwise.
Fmi2IntegerType Fmi2Type.asInteger()
This method casts a type definition to the Fmi2ItegerType object if its baseType
is Real
, or null
otherwise.
Fmi2EnumType Fmi2Type.asEnum()
This method casts a type definition to the Fmi2EnumType object if its baseType
is Enum
, or null
otherwise.
Fmi2Unit class
The Fmi2Unit
class contains information about an FMI unit definition. Each Fmi2Unit
class can have a number of associated Fmi2DisplayUnit
objects. Display units are used to display values in a user-friendly format. Both classes serve purely informational role.
Fmi2Unit.name
This read-only property holds a name for the unit definition.
Fmi2Unit.displayUnits
This read-only property holds an array of Fmi2DisplayUnit
objects that correspond to the unit definition.
Fmi2Unit.SIexponents
This read-only property holds an array of integers that describe SI exponents for the unit definition.
Fmi2Unit.SIfactor
Fmi2Unit.SIoffset
These read-only properties hold a factor and an offset to a corresponding SI unit.
Fmi2Unit.fromSI(value)
This method converts a value expressed in a corresponding SI unit to a value in the specified unit.
Fmi2Unit.toSI(value)
This method converts a value expressed in the specified unit to a value in a corresponding SI unit.
Fmi2DisplayUnit.name
This read-only property holds a name for the display unit definition.
Fmi2DisplayUnit.baseUnit
This read-only property holds an associated Fmi2Unit
object.
Fmi2DisplayUnit.factor
Fmi2DisplayUnit.offset
These read-only properties hold a factor and an offset to a corresponding Fmi2Unit
.
Fmi2DisplayUnit.fromDisplayUnit(value)
This method converts a value expressed in a corresponding Fmi2Unit
to a value in the display unit.
Fmi2DisplayUnit.toDisplayUnit(value)
This method converts a value expressed in the display unit to a value in a corresponding Fmi2Unit
unit.
Fmi2State class
Some FMUs have the ability to store their current state and to restore from a previously saved state. Fmi2State
represents a stored FMU state.
You can query ability to save and restore the state of an FMU using Fmi2Import.getCapability(capability) method with the Fmi2Import.CS_canGetAndSetFMUstate
flag. Additionally, FMUs with the Fmi2Import.CS_canSerializeFMUstate
capability flag set can serialize such a state into a sequence of bytes that can be transfered between FMU instances.
Fmi2DisplayUnit.size
This read-only property holds a size of a byte array that can hold serialized state data.
Fmi2State.serialize()
This method serializes the represented state and returns it as an array of bytes.
Examples
Running a simulation
The following snippet shows an example of loading a FMU object, accessing its variables and running the simulation process.
function main() { startFMI(); var fmu = Fmi2Import.create( '/data/deviceModel.fmu' ); // Retrieves model variable called 'varX' var variableX = fmu.getVariable( "varX" ); // An alternative approach var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); // Set the values of the variables fmu.setValue( [ variableX, variableY, "varZ" ], [ 1, 2, 4 ] ); // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ); // Run the simulation for specific time snooze(5); // Compare the value of a variable with expected value test.compare( variableX.value, 1 ); // Destroys the FMI object and terminates 'fmiutil' fmu.destroy(); }
sub main() { startFMI(); my $fmu = Fmi2Import::create( '/data/deviceModel.fmu' ); # Retrieves model variable called 'varX' my $variableX = $fmu->getVariable( "varX" ); # An alternative approach my $variableY = findObject( "{name='varY' type='Fmi2Variable'}" ); # Set the values of the variables @variables = ( "varX", "varY", "varZ" ); @values = ( 1, 2, 4 ); $fmu->setValue( \@variables, \@values ); # Run the simulation in the background at real-time pace. $fmu->runDetached( 0.01, 1 ); # Run the simulation for specific time snooze(5); # Compare the value of a variable with expected value test::compare( $variableX->value, 1 ); # Destroys the FMI object and terminates 'fmiutil' $fmu->destroy(); }
def main(): startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Retrieves model variable called 'varX' variableX = fmu.getVariable( "varX" ) # An alternative approach variableY = findObject( "{name='varY' type='Fmi2Variable'}" ) # Set the values of the variables fmu.setValue( [ variableX, variableY, "varZ" ], [ 1, 2, 4 ] ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) # Run the simulation for specific time snooze(5) # Compare the value of a variable with expected value test.compare( variableX.value, 1 ) # Destroys the FMI object and terminates 'fmiutil' fmu.destroy()
require 'squish' include Squish def main startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Retrieves model variable called 'varX' variableX = fmu.getVariable( "varX" ) # An alternative approach variableY = findObject( "{name='varY' type='Fmi2Variable'}" ) # Set the values of the variables fmu.setValue( [ "varX", "varY", "varZ" ], [ 1, 2, 4 ] ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) # Run the simulation for specific time snooze(5) # Compare the value of a variable with expected value Test.compare( variableX.value, 1 ) # Destroys the FMI object and terminates 'fmiutil' fmu.destroy() end
proc main {} { startFMI set fmu [ invoke Fmi2Import create "/data/deviceModel.fmu" ] # Retrieves model variable called 'varX' set variableX [ invoke $fmu getVariable "varX" ]; # An alternative approach set variableY [ findObject "{name='varY' type='Fmi2Variable'}" ] # Set the values of the variables property set $variableX value 1 property set $variableY value 2 property set [ findObject "{name='varZ' type='Fmi2Variable'}" ] value 4 # Run the simulation in the background at real-time pace. invoke $fmu runDetached 0.01 1 # Run the simulation for specific time snooze 5 # Compare the value of a variable with expected value test compare [ property get $variableX value ] 1 # Destroys the FMI object and terminates 'fmiutil' invoke $fmu destroy }
Running a simulation in parallel to the AUT
An FMU object is created in the utility process. If the test script accesses FMU and AUT, the current context must be changed to match currently accessed object, as described in How to Start and Access Multiple Applications Under Test.
function main() { var fmictx = startFMI(); var fmu = Fmi2Import.create( '/data/deviceModel.fmu' ); // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ); var autctx = startApplication( "/an/aut" ); activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ); activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ); setApplicationContext( fmictx ); test.compare( fmu.getVariable( "isStarted" ).value, True ); fmu.setValue( [ "isRunning" ], [ 1 ] ); setApplicationContext( autctx ); test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ); setApplicationContext( fmictx ); fmu.destroy(); }
sub main() { my $fmictx = startFMI(); my $fmu = Fmi2Import::create( '/data/deviceModel.fmu' ); # Run the simulation in the background at real-time pace. $fmu->runDetached( 0.01, 1 ); my $autctx = startApplication( "/an/aut" ); activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ); activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ); setApplicationContext( $fmictx ); test::compare( $fmu->getVariable( "isStarted" )->value, True ); @variables = ( "isRunning" ); @values = ( 1 ); $fmu->setValue( \@variables, \@values ); setApplicationContext( $autctx ); test::compare( waitForObject( ":Status_QLabel" )->text, "Running" ); setApplicationContext( $fmictx ); $fmu.destroy(); }
def main(): fmictx = startFMI() fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) // Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) autctx = startApplication( "/an/aut" ) activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ) activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ) setApplicationContext( fmictx ) test.compare( fmu.getVariable( "isStarted" ).value, 1 ) fmu.setValue( [ "isRunning" ], [ 1 ] ) setApplicationContext( autctx ) test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ) setApplicationContext( fmictx ) fmu.destroy()
require 'squish' include Squish def main() { fmictx = startApplication( "fmiutil" ) fmu = Fmi2Import.create( '/data/deviceModel.fmu' ) # Run the simulation in the background at real-time pace. fmu.runDetached( 0.01, 1 ) var autctx = startApplication( "/an/aut" ) activateItem( waitForObjectItem( ":_QMenuBar", "Device" ) ) activateItem( waitForObjectItem( ":Device_QMenu", "Start" ) ) setApplicationContext( fmictx ) test.compare( fmu.getVariable( "isStarted" ).value, True ) fmu.setValue( [ "isRunning" ], [ 1 ] ) setApplicationContext( autctx ) test.compare( waitForObject( ":Status_QLabel" ).text, "Running" ) setApplicationContext( fmictx ) fmu.destroy() }
proc main {} { set fmictx [ startFMI ] set fmu [ invoke Fmi2Import create "/data/deviceModel.fmu" ] # Run the simulation in the background at real-time pace. invoke $fmu runDetached 0.01 1 set autctx [ startApplication "/an/aut" ] invoke activateItem [waitForObjectItem ":_QMenuBar" "Device" ] invoke activateItem [waitForObjectItem ":Device_QMenu" "Start" ] setApplicationContext $fmictx test compare [ property get [ invoke $fmu getVariable "isStarted" ] value ] 1 set isRunning [ invoke $fmu getVariable "isRunning" ]; property set $isRunning value 1 setApplicationContext $autctx test compare [ property get [ waitForObject ":Status_QLabel" ] text ] "Running" setApplicationContext $fmictx invoke $fmu destroy
Waiting for simulation results
To wait for a simulation variable to take a specific value, use Object waitForObject(objectOrName). If the value
property is specified, it will find only the variable of specified value, and wait if no such variable exists.
// will wait until variable 'varY' has a value of 1. var variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. my $variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" )
// will wait until variable 'varY' has a value of 1. variableY = waitForObject( "{type='Fmi2Variable' name='varY' value='1'}" );
// will wait until variable 'varY' has a value of 1. set variableY [ waitForObject "{type='Fmi2Variable' name='varY' value='1'}" ]
If the condition to wait for is more complex, a Boolean waitFor(condition) function can be used.
var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); waitFor( function() { return variableY.value < 1; } );
my $variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); waitFor( function() { return $variableY->value < 1; } );
variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) waitFor( lambda: variableY.value < 1 )
var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) waitFor( lambda { return variableY.value < 1 } )
set variableY [ findObject "{type='Fmi2Variable' name='varY'}" ] waitFor [ proc "" {} { expr [ property get $variableY value ] < 1 } ]
In case a variable of interest has the expected value for a relatively short period of time, it is possible - due to parallel nature of test script execution - that the above functions miss that value entirely. To gain fine control over the simulation process, run the variable directly from the test script.
setApplicationContext( fmictx ); // Stops background execution of the simulation process (if started). fmu.sync(); var variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); for ( var i=0; i<1000; ++i ) { fmu.doStep( 0.01 ); if ( variableY.value < 1 ) break; } test.verify( variableY.value < 1 ); // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 );
setApplicationContext( $fmictx ); // Stops background execution of the simulation process (if started). $fmu->sync(); my $variableY = findObject( "{type='Fmi2Variable' name='varY'}" ); for ( my $i=0; $i<1000; $i++ ) { $fmu->doStep( 0.01 ); if ( $variableY->value < 1 ) { last; } } test::verify( $variableY->value < 1 ); // Re-start detahed execution ( if required ) $fmu->runDetached( 0.01, 1 );
setApplicationContext( fmictx ) // Stops background execution of the simulation process (if started). fmu.sync() variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) for x in range(0, 1000): fmu.doStep( 0.01 ) if variableY.value < 1: break test.verify( variableY.value < 1 ) // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 )
setApplicationContext( fmictx ) // Stops background execution of the simulation process (if started). fmu.sync() variableY = findObject( "{type='Fmi2Variable' name='varY'}" ) for x in 1..1000: fmu.doStep( 0.01 ) if variableY.value < 1 then break end end test.verify( variableY.value < 1 ) // Re-start detahed execution ( if required ) fmu.runDetached( 0.01, 1 )
setApplicationContext $fmictx # Stops background execution of the simulation process (if started). invoke fmu sync set variableY [ findObject "{type='Fmi2Variable' name='varY'}" ] for {set i 0} {$i < 1000} {incr i} { invoke $fmu doStep 0.01 if { expr [ property get $variableY value ] < 1 } { break } } invoke test verify [ expr [ property get $variableY value ] < 1 ] # Re-start detached execution ( if required ) invoke fmu runDetached 0.01 1
© 2024 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.
The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation.
Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners.