Skip to content

Commit

Permalink
Merge branch 'release/v0.3.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
t-sommer committed Dec 10, 2021
2 parents b069b92 + 99e9a6a commit 178af24
Show file tree
Hide file tree
Showing 27 changed files with 1,607 additions and 374 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dist/
MANIFEST
rpclib-*/
*.egg-info
.pytest_cache/

# test artifacts
tests/IntegerNetwork1/
Expand Down
67 changes: 35 additions & 32 deletions build_remoting.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,24 @@
from fmpy.util import download_file


url = 'https://github.com/rpclib/rpclib/archive/refs/tags/v2.3.0.tar.gz'
checksum = 'eb9e6fa65e1a79b37097397f60599b93cb443d304fbc0447c50851bc3452fdef'

# build configuration
config = 'Release'

download_file(url, checksum)

filename = os.path.basename(url)
config = 'Debug'

basedir = os.path.abspath(os.path.dirname(__file__))

source_dir = 'rpclib-2.3.0'
rpclib_dir = os.path.join(basedir, 'rpclib-2.3.0').replace('\\', '/')

rpclib_dir = os.path.join(basedir, source_dir).replace('\\', '/')
if not os.path.isdir(rpclib_dir):

# clean up
shutil.rmtree(source_dir, ignore_errors=True)
filename = download_file(url='https://github.com/rpclib/rpclib/archive/refs/tags/v2.3.0.tar.gz',
checksum='eb9e6fa65e1a79b37097397f60599b93cb443d304fbc0447c50851bc3452fdef')

print("Extracting %s" % filename)
with tarfile.open(filename, 'r:gz') as tar:
tar.extractall()

if os.name == 'nt':
print("Extracting %s" % filename)
with tarfile.open(filename, 'r:gz') as tar:
tar.extractall()

# patch the CMake project to link static against the MSVC runtime
with open(os.path.join(source_dir, 'CMakeLists.txt'), 'a') as file:
# Append 'hello' at the end of file
with open(os.path.join(rpclib_dir, 'CMakeLists.txt'), 'a') as file:
file.write('''
message(${CMAKE_CXX_FLAGS_RELEASE})
Expand All @@ -54,32 +44,40 @@
message(${CMAKE_CXX_FLAGS_DEBUG})
''')

if os.name == 'nt':

for bitness, generator in [('win32', 'Visual Studio 15 2017'), ('win64', 'Visual Studio 15 2017 Win64')]:

# clean up
shutil.rmtree(os.path.join(basedir, 'remoting', bitness), ignore_errors=True)

print("Building rpclib...")
print(f"Building rpclib for {bitness}...")

check_call(args=[
'cmake',
'-B', source_dir + '/' + bitness,
'-B', rpclib_dir + '/' + bitness,
'-D', 'RPCLIB_MSVC_STATIC_RUNTIME=ON',
'-D', 'CMAKE_INSTALL_PREFIX=' + source_dir + '/' + bitness + '/install',
'-D', 'CMAKE_INSTALL_PREFIX=' + os.path.join(rpclib_dir, bitness, 'install'),
'-G', generator,
source_dir
rpclib_dir
])

check_call(args=['cmake', '--build', source_dir + '/' + bitness, '--target', 'install', '--config', config])
check_call(args=[
'cmake',
'--build', os.path.join(rpclib_dir, bitness),
'--target', 'install',
'--config', config
])

print("Building remoting binaries...")
print(f"Building remoting binaries for {bitness}...")

check_call(args=[
'cmake',
'-B', 'remoting/' + bitness,
'-G', generator,
'-D', 'RPCLIB=' + rpclib_dir + '/' + bitness + '/install',
'-B', 'remoting/' + bitness, 'remoting'
'-D', 'RPCLIB=' + os.path.join(rpclib_dir, bitness, 'install'),
'-B', 'remoting/' + bitness,
'remoting'
])

check_call(['cmake', '--build', 'remoting/' + bitness, '--config', config])
Expand All @@ -93,22 +91,27 @@

check_call(args=[
'cmake',
'-B', source_dir + '/linux64',
'-D', 'CMAKE_INSTALL_PREFIX=' + source_dir + '/linux64' + '/install',
'-B', os.path.join(rpclib_dir, 'linux64'),
'-D', 'CMAKE_INSTALL_PREFIX=' + os.path.join(rpclib_dir, 'linux64', 'install'),
'-D', 'CMAKE_POSITION_INDEPENDENT_CODE=ON',
'-G', 'Unix Makefiles',
source_dir
rpclib_dir
])

check_call(args=['cmake', '--build', source_dir + '/linux64', '--target', 'install', '--config', config])
check_call(args=[
'cmake',
'--build', os.path.join(rpclib_dir, 'linux64'),
'--target', 'install',
'--config', config
])

print("Building remoting binaries...")

check_call(args=[
'cmake',
'-B', 'remoting/' + 'linux64',
'-G', 'Unix Makefiles',
'-D', 'RPCLIB=' + rpclib_dir + '/linux64/install',
'-D', 'RPCLIB=' + os.path.join(rpclib_dir, 'linux64', 'install'),
'-B', 'remoting/linux64', 'remoting'
])

Expand Down
15 changes: 15 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## v0.3.4 (2021-12-10)

### Bug fixes

- Fix links to FMI Specs (#349)
- Fix validation of quoted variable names (#347)
- Set start values of Container FMU's variables (#345)

### Enhancements

- Use Dash 2.0 and update dependencies (#339)
- Raise FMICallExeption when FMI calls fail (#346)
- Add shared memory implementation for remoting on Windows (#328)
- Check if start values can be set (#351)

## v0.3.3 (2021-11-29)

### Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion fmpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import _ctypes
from typing import Union, IO, List

__version__ = '0.3.3'
__version__ = '0.3.4'

# experimental
plot_library = 'matplotlib' # 'plotly'
Expand Down
21 changes: 20 additions & 1 deletion fmpy/fmi1.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,25 @@ def stepFinished(componentEnvironment, status):
pass


class FMICallException(Exception):
""" Raised when an FMI call fails """

def __init__(self, function: str, status: int):

if status in range(5):
label = ['ok', 'warning', 'discard', 'error', 'fatal', 'pending'][status]
else:
label = 'illegal return code'

super().__init__(f"{function} failed with status {status} ({label}).")

self.function = function
"The name of the FMI function"

self.status = status
"The status returned by the FMI function"


class _FMU(object):
""" Base class for all FMUs """

Expand Down Expand Up @@ -307,7 +326,7 @@ def w(*args):
if restype == fmi1Status:
# check the status code
if res > fmi1Warning:
raise Exception("fmi%s failed with status %d." % (fname, res))
raise FMICallException(function=fname, status=res)

return res

Expand Down
4 changes: 2 additions & 2 deletions fmpy/fmi2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pathlib
from ctypes import *
from . import free, calloc
from .fmi1 import _FMU, printLogMessage
from .fmi1 import _FMU, FMICallException, printLogMessage


fmi2Component = c_void_p
Expand Down Expand Up @@ -212,7 +212,7 @@ def w(*args):
if restype == fmi2Status: # status code
# check the status code
if res > fmi2Warning:
raise Exception("%s failed with status %d." % (fname, res))
raise FMICallException(function=fname, status=res)

return res

Expand Down
5 changes: 2 additions & 3 deletions fmpy/fmi3.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
""" FMI 3.0 interface """

import os
import pathlib
from ctypes import *
from typing import Tuple

from . import sharedLibraryExtension, platform_tuple
from .fmi1 import _FMU, printLogMessage
from .fmi1 import _FMU, FMICallException, printLogMessage


fmi3Instance = c_void_p
Expand Down Expand Up @@ -507,7 +506,7 @@ def w(*args):
if restype == fmi3Status: # status code
# check the status code
if res > fmi3Warning:
raise Exception("%s failed with status %d." % (fname, res))
raise FMICallException(function=fname, status=res)

return res

Expand Down
18 changes: 15 additions & 3 deletions fmpy/fmucontainer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,22 @@ def to_xml(o):
component_indices.append(component_index)
value_references.append(value_reference)

data['variables'].append({
variable = {
'components': component_indices,
'valueReferences': value_references
})
'valueReferences': value_references,
}

if v.start is not None:
if v.type == 'Real':
variable['start'] = float(v.start)
elif v.type in ['Enumeration', 'Integer']:
variable['start'] = int(v.start)
elif v.type == 'Boolean':
variable['start'] = bool(v.start)
elif v.type == 'String':
variable['start'] = v.start

data['variables'].append(variable)

# modelDescription.xml
start = f' start="{ v.start }"' if v.start else ''
Expand Down
49 changes: 48 additions & 1 deletion fmpy/fmucontainer/sources/FMUContainer.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ fmi2Component fmi2Instantiate(fmi2String instanceName,
mpack_node_t components = mpack_node_map_cstr(variable, "components");
mpack_node_t valueReferences = mpack_node_map_cstr(variable, "valueReferences");

bool hasStartValue = mpack_node_map_contains_cstr(variable, "start");

mpack_node_t start;
mpack_type_t variableType;

if (hasStartValue) {
start = mpack_node_map_cstr(variable, "start");
variableType = mpack_node_type(start);
}

s->variables[i].size = mpack_node_array_length(components);
s->variables[i].ci = calloc(s->variables[i].size, sizeof(size_t));
s->variables[i].vr = calloc(s->variables[i].size, sizeof(fmi2ValueReference));
Expand All @@ -265,9 +275,46 @@ fmi2Component fmi2Instantiate(fmi2String instanceName,

mpack_node_t component = mpack_node_array_at(components, j);
mpack_node_t valueReference = mpack_node_array_at(valueReferences, j);
fmi2ValueReference vr = mpack_node_u32(valueReference);

if (hasStartValue) {

fmi2Status status;
FMIInstance *m = s->components[j];

switch (variableType) {
case mpack_type_double: {
fmi2Real value = mpack_node_double(start);
status = FMI2SetReal(m, &vr, 1, &value);
break;
}
case mpack_type_int: {
fmi2Integer value = mpack_node_int(start);
status = FMI2SetInteger(m, &vr, 1, &value);
break;
}
case mpack_type_bool: {
fmi2Boolean value = mpack_node_bool(start);
status = FMI2SetBoolean(m, &vr, 1, &value);
break;
}
case mpack_type_str: {
fmi2String value = mpack_node_cstr_alloc(start, 2048);
status = FMI2SetString(m, &vr, 1, &value);
MPACK_FREE((void*)value);
break;
}
default:
break;
}

if (status > fmi2Warning) {
return NULL;
}
}

s->variables[i].ci[j] = mpack_node_u64(component);
s->variables[i].vr[j] = mpack_node_u32(valueReference);
s->variables[i].vr[j] = vr;
}

}
Expand Down
6 changes: 3 additions & 3 deletions fmpy/gui/MainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ def __init__(self, parent=None):
self.ui.actionAddCoSimulationWrapper.triggered.connect(self.addCoSimulationWrapper)

# help menu
self.ui.actionOpenFMI1SpecCS.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://svn.modelica.org/fmi/branches/public/specifications/v1.0/FMI_for_CoSimulation_v1.0.1.pdf')))
self.ui.actionOpenFMI1SpecME.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://svn.modelica.org/fmi/branches/public/specifications/v1.0/FMI_for_ModelExchange_v1.0.1.pdf')))
self.ui.actionOpenFMI2Spec.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://github.com/modelica/fmi-standard/releases/download/v2.0.2/FMI-Specification-2.0.2.pdf')))
self.ui.actionOpenFMI1SpecCS.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://fmi-standard.org/assets/releases/FMI_for_CoSimulation_v1.0.1.pdf')))
self.ui.actionOpenFMI1SpecME.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://fmi-standard.org/assets/releases/FMI_for_ModelExchange_v1.0.1.pdf')))
self.ui.actionOpenFMI2Spec.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://github.com/modelica/fmi-standard/releases/download/v2.0.3/FMI-Specification-2.0.3.pdf')))
self.ui.actionOpenTestFMUs.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://github.com/modelica/fmi-cross-check/tree/master/fmus')))
self.ui.actionOpenWebsite.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://github.com/CATIA-Systems/FMPy')))
self.ui.actionShowReleaseNotes.triggered.connect(lambda: QDesktopServices.openUrl(QUrl('https://fmpy.readthedocs.io/en/latest/changelog/')))
Expand Down
2 changes: 1 addition & 1 deletion fmpy/gui/forms/MainWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,7 @@ QToolButton::menu-button {
</action>
<action name="actionOpenFMI2Spec">
<property name="text">
<string>FMI 2.0.2</string>
<string>FMI 2.0.3</string>
</property>
<property name="toolTip">
<string>FMI 2.0.2</string>
Expand Down
Loading

0 comments on commit 178af24

Please sign in to comment.