Skip to content

Commit

Permalink
Merge branch 'release/v0.2.26'
Browse files Browse the repository at this point in the history
  • Loading branch information
t-sommer committed Nov 27, 2020
2 parents 2d569cc + aaf8c73 commit a2c6236
Show file tree
Hide file tree
Showing 37 changed files with 16,199 additions and 752 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ The FMPy Web App is built with [Dash](https://plotly.com/dash/) and a great way
To start it run

```
python -m fmpy.webapp Rectfier.fmu
python -m fmpy.webapp Rectifier.fmu
```

on the command line or use `--help` for more options.
Expand Down
15 changes: 15 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ jobs:
python build_cvode.py
displayName: Build CVode binaries
- bash: |
source activate myEnvironment
python build_fmucontainer.py
displayName: Build FMU Container
- bash: |
source activate myEnvironment
python setup.py bdist_wheel --universal
Expand Down Expand Up @@ -93,6 +98,11 @@ jobs:
python build_cvode.py
displayName: Build CVode binaries
- bash: |
source activate myEnvironment
python build_fmucontainer.py
displayName: Build FMU Container
- bash: |
source activate myEnvironment
python setup.py bdist_wheel --universal
Expand Down Expand Up @@ -151,6 +161,11 @@ jobs:
python build_cvode.py
displayName: Build CVode binaries
- bash: |
source activate myEnvironment
python build_fmucontainer.py
displayName: Build FMU Container
- script: |
call activate myEnvironment
python build_remoting.py
Expand Down
30 changes: 30 additions & 0 deletions build_fmucontainer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import shutil

from fmpy import platform, sharedLibraryExtension
import os
from subprocess import check_call


if os.name == 'nt':
generators = [
('win32', 'Visual Studio 15 2017'),
('win64', 'Visual Studio 15 2017 Win64')
]
else:
generators = [(platform, 'Unix Makefiles')]

for p, generator in generators:

build_dir = 'fmpy/fmucontainer/%s' % p

shutil.rmtree(build_dir, ignore_errors=True)
os.mkdir(build_dir)

check_call([
'cmake',
'-G', generator,
'-S', 'fmpy/fmucontainer',
'-B', build_dir
])

check_call(['cmake', '--build', build_dir, '--config', 'Release'])
13 changes: 13 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## v0.2.26 (2020-11-27)

### Enhancements

- Create "FMU Containers" with nested FMUs (experimental) (#193)
- Handle Scheduled Execution in instantiate_fmu() (#200)
- Add "create-jupyter-notebook" command to CLI (#192)
- Add all parameters to start_values in Jupyter Notebook (#190)
- Fix Boolean start values in Jupyter Notebooks (#188)
- Validate FMI 3 model description (#181)
- Remove assert statements from fmpy.sundials (#202)
- Update SSP schema to v1.0 and remove ssp.examples

## v0.2.25 (2020-11-04)

### Enhancements
Expand Down
2 changes: 1 addition & 1 deletion fmpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ctypes import *
import _ctypes

__version__ = '0.2.25'
__version__ = '0.2.26'

# experimental
plot_library = 'matplotlib' # 'plotly'
Expand Down
16 changes: 9 additions & 7 deletions fmpy/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def main():
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(description))

parser.add_argument('command', choices=['info', 'validate', 'simulate', 'compile', 'add-cswrapper', 'add-remoting', 'create-cmake-project'],
parser.add_argument('command', choices=['info', 'validate', 'simulate', 'compile', 'add-cswrapper', 'add-remoting',
'create-cmake-project', 'create-jupyter-notebook'],
help="Command to execute")
parser.add_argument('fmu_filename', help="filename of the FMU")

Expand Down Expand Up @@ -65,18 +66,19 @@ def main():
elif args.command == 'validate':

import sys
from fmpy.util import validate_fmu
from fmpy.validation import validate_fmu

messages = validate_fmu(args.fmu_filename)
problems = validate_fmu(args.fmu_filename)

if len(messages) == 0:
if len(problems) == 0:
print('No problems found.')
else:
print('The following problems were found:')
for message in messages:
print('%d problems were found:' % len(problems))
for message in problems:
print()
print(message)
sys.exit(1)

sys.exit(len(problems))

elif args.command == 'compile':

Expand Down
5 changes: 5 additions & 0 deletions fmpy/fmucontainer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# build artifacts
darwin64/
linux64/
win32/
win64/
51 changes: 51 additions & 0 deletions fmpy/fmucontainer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
cmake_minimum_required (VERSION 3.2)

project (FMUContainer)

if (WIN32)
set(FMI_PLATFORM win)
elseif (APPLE)
set(FMI_PLATFORM darwin)
else ()
set(FMI_PLATFORM linux)
endif ()

if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set (FMI_PLATFORM ${FMI_PLATFORM}64)
else ()
set (FMI_PLATFORM ${FMI_PLATFORM}32)
endif ()

if (MSVC)
# link statically against the the Visual C runtime
string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")

# disable compiler warnings
add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
endif ()

add_library(FMUContainer SHARED
../c-code/fmi2Functions.h
../c-code/fmi2FunctionTypes.h
../c-code/fmi2TypesPlatform.h
sources/FMUContainer.c
sources/mpack.h
sources/mpack.c
)

SET_TARGET_PROPERTIES(FMUContainer PROPERTIES PREFIX "")

target_include_directories(FMUContainer PUBLIC
sources
../c-code
)

target_link_libraries(FMUContainer
${CMAKE_DL_LIBS}
)

add_custom_command(TARGET FMUContainer POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_FILE:FMUContainer>"
"${CMAKE_CURRENT_SOURCE_DIR}/binaries/${FMI_PLATFORM}"
)
115 changes: 115 additions & 0 deletions fmpy/fmucontainer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
from tempfile import mkdtemp


def create_fmu_container(configuration, output_filename):
""" Create an FMU from nested FMUs (experimental)
see tests/test_fmu_container.py for an example
"""

import os
import shutil
import fmpy
from fmpy import read_model_description, extract
import msgpack
from datetime import datetime
import pytz

base_filename, _ = os.path.splitext(output_filename)
model_name = os.path.basename(base_filename)

unzipdir = mkdtemp()

basedir = os.path.dirname(__file__)

for directory in ['binaries', 'documentation', 'sources']:
shutil.copytree(os.path.join(basedir, directory), os.path.join(unzipdir, directory))

os.mkdir(os.path.join(unzipdir, 'resources'))

data = {
'components': [],
'variables': [],
'connections': []
}

l = []

component_map = {}
vi = 0 # variable index

l.append('<?xml version="1.0" encoding="UTF-8"?>')
l.append('<fmiModelDescription')
l.append(' fmiVersion="2.0"')
l.append(' modelName="%s"' % model_name)
l.append(' guid=""')
if 'description' in configuration:
l.append(' description="%s"' % configuration['description'])
l.append(' generationTool="FMPy %s FMU Container"' % fmpy.__version__)
l.append(' generationDateAndTime="%s">' % datetime.now(pytz.utc).isoformat())
l.append('')
l.append(' <CoSimulation modelIdentifier="FMUContainer">')
l.append(' <SourceFiles>')
l.append(' <File name="FMUContainer.c"/>')
l.append(' <File name="mpack.c"/>')
l.append(' </SourceFiles>')
l.append(' </CoSimulation>')
l.append('')
l.append(' <ModelVariables>')
for i, component in enumerate(configuration['components']):
model_description = read_model_description(component['filename'])
model_identifier = model_description.coSimulation.modelIdentifier
extract(component['filename'], os.path.join(unzipdir, 'resources', model_identifier))
variables = dict((v.name, v) for v in model_description.modelVariables)
component_map[component['name']] = (i, variables)
data['components'].append({
'name': component['name'],
'guid': model_description.guid,
'modelIdentifier': model_identifier,
})
for name in component['variables']:
v = variables[name]
data['variables'].append({'component': i, 'valueReference': v.valueReference})
name = component['name'] + '.' + v.name
description = v.description
if name in configuration['variables']:
mapping = configuration['variables'][name]
if 'name' in mapping:
name = mapping['name']
if 'description' in mapping:
description = mapping['description']
description = ' description="%s"' % description if description else ''
l.append(' <ScalarVariable name="%s" valueReference="%d" causality="%s" variability="%s"%s>' % (name, vi, v.causality, v.variability, description))
l.append(' <%s%s/>' % (v.type, ' start="%s"' % v.start if v.start else ''))
l.append(' </ScalarVariable>')
vi += 1
l.append(' </ModelVariables>')
l.append('')
l.append(' <ModelStructure/>')
l.append('')
l.append('</fmiModelDescription>')

for sc, sv, ec, ev in configuration['connections']:
data['connections'].append({
'type': component_map[sc][1][sv].type,
'startComponent': component_map[sc][0],
'endComponent': component_map[ec][0],
'startValueReference': component_map[sc][1][sv].valueReference,
'endValueReference': component_map[ec][1][ev].valueReference,
})

with open(os.path.join(unzipdir, 'modelDescription.xml'), 'w') as f:
f.write('\n'.join(l) + '\n')

with open(os.path.join(unzipdir, 'resources', 'config.mp'), 'wb') as f:
packed = msgpack.packb(data)
f.write(packed)

shutil.make_archive(base_filename, 'zip', unzipdir)

if os.path.isfile(output_filename):
os.remove(output_filename)

os.rename(base_filename + '.zip', output_filename)

shutil.rmtree(unzipdir, ignore_errors=True)
1 change: 1 addition & 0 deletions fmpy/fmucontainer/binaries/darwin64/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.dylib
1 change: 1 addition & 0 deletions fmpy/fmucontainer/binaries/linux64/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.so
1 change: 1 addition & 0 deletions fmpy/fmucontainer/binaries/win32/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.dll
1 change: 1 addition & 0 deletions fmpy/fmucontainer/binaries/win64/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.dll
53 changes: 53 additions & 0 deletions fmpy/fmucontainer/documentation/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
This FMU is part of FMPy and is released under the 2-Clause BSD license.
Any contained FMUs and resources are subject to their respective licenses.

Copyright (c) 2017-2020 Dassault Systemes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


This FMU contains a copy of MPack (https://github.com/ludocode/mpack) in
both binary and source form. It is license under the

The MIT License (MIT)

Copyright (c) 2015-2018 Nicholas Fraser

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading

0 comments on commit a2c6236

Please sign in to comment.