Exemple #1
0
    def test_validate_derivatives(self):

        message = None

        try:
            read_model_description('CoupledClutches.fmu', validate=True, validate_variable_names=False)
        except Exception as e:
            message = str(e)

        self.assertEqual(message, 'The unit "" of variable "inputs" (line 183) is not defined.')
Exemple #2
0
    def test_validate_variable_name(self):

        message = None

        try:
            read_model_description('CoupledClutches.fmu', validate=False, validate_variable_names=True)
        except Exception as e:
            message = str(e)

        self.assertTrue(message.startswith('"CoupledClutches_r(19)" (line 192) is not a legal variable name for naming convention "structured".'))
Exemple #3
0
    def test_validate_variable_names(self):

        problems = []

        try:
            read_model_description('CoupledClutches.fmu',
                                   validate=True,
                                   validate_variable_names=True)
        except ValidationError as e:
            problems = e.problems

        self.assertEqual(len(problems), 124)
Exemple #4
0
    def test_validate_derivatives(self):

        problems = []

        try:
            read_model_description('CoupledClutches.fmu',
                                   validate=True,
                                   validate_variable_names=False)
        except ValidationError as e:
            problems = e.problems

        self.assertEqual(
            problems[0],
            'The unit "" of variable "inputs" (line 183) is not defined.')
Exemple #5
0
    def test_validate_derivatives(self):

        message = None

        try:
            read_model_description('CoupledClutches.fmu',
                                   validate=True,
                                   validate_variable_names=False)
        except Exception as e:
            message = str(e)

        self.assertEquals(
            'Failed to validate model description. 1 problems were found:\n\n- The unit "" of variable "inputs" (line 183) is not defined.',
            message)
Exemple #6
0
    def test_validate_variable_names(self):

        message = ""

        try:
            read_model_description('CoupledClutches.fmu',
                                   validate=True,
                                   validate_variable_names=True)
        except Exception as e:
            message = str(e)

        self.assertTrue(
            message.startswith(
                'Failed to validate model description. 124 problems were found:'
            ))
Exemple #7
0
def validate_fmu(filename):
    """ Validate an FMU

    Returns:
        a list of the problems found
    """

    from . import read_model_description

    try:
        read_model_description(filename, validate=True)
    except Exception as e:
        return [str(e)]

    return []
Exemple #8
0
def add_cswrapper2(filename, outfilename=None):

    from fmpy.fmucontainer import Variable, Configuration, Component, create_fmu_container

    model_description = read_model_description(filename)

    model_identifier = model_description.modelExchange.modelIdentifier

    variables = []

    for variable in model_description.modelVariables:
        variables.append(
            Variable(type=variable.type,
                     variability=variable.variability,
                     causality=variable.causality,
                     initial=variable.initial,
                     name=variable.name,
                     start=variable.start,
                     description=variable.description,
                     mapping=[(model_identifier, variable.name)]))

    configuration = Configuration(variables=variables,
                                  components=[
                                      Component(filename=filename,
                                                interfaceType='ModelExchange',
                                                name=model_identifier)
                                  ])

    create_fmu_container(configuration, outfilename)
Exemple #9
0
def instantiate_fmu(component, ssp_unzipdir, start_time, parameters={}):

    fmu_filename = os.path.join(ssp_unzipdir, component.source)

    component.unzipdir = extract(fmu_filename)

    # read the model description
    model_description = read_model_description(fmu_filename, validate=False)

    # collect the value references
    component.variables = {}
    for variable in model_description.modelVariables:
        # component.vrs[variable.name] = variable.valueReference
        component.variables[variable.name] = variable

    fmu_kwargs = {
        'guid': model_description.guid,
        'unzipDirectory': component.unzipdir,
        'modelIdentifier': model_description.coSimulation.modelIdentifier,
        'instanceName': component.name
    }

    if model_description.fmiVersion == '1.0':
        component.fmu = FMU1Slave(**fmu_kwargs)
        component.fmu.instantiate()
        set_parameters(component, parameters)
        component.fmu.initialize()
    else:
        component.fmu = FMU2Slave(**fmu_kwargs)
        component.fmu.instantiate()
        component.fmu.setupExperiment(startTime=start_time)
        set_parameters(component, parameters)
        component.fmu.enterInitializationMode()
        component.fmu.exitInitializationMode()
Exemple #10
0
    def get_fmu(self):

        import shutil
        from fmpy import read_model_description, extract
        from fmpy.fmi2 import FMU2Slave

        shutil.copyfile(self.orig_fmu_path, self.dest_fmu_path)

        # read the model description
        self.model_description = read_model_description(self.dest_fmu_path)

        # collect the value references
        self.vrs = {}
        for variable in self.model_description.modelVariables:
            self.vrs[variable.name] = variable.valueReference

        #print(variable)

        # extract the FMU
        self.unzipdir = extract(self.dest_fmu_path)

        self.contr_sys = FMU2Slave(guid=self.model_description.guid,
                                   unzipDirectory=self.unzipdir,
                                   modelIdentifier=self.model_description.
                                   coSimulation.modelIdentifier,
                                   instanceName='instance1')

        #print(self.contr_sys)

        self.contr_sys.instantiate()
        self.contr_sys.setupExperiment(startTime=0.0)
        self.contr_sys.enterInitializationMode()
        self.contr_sys.exitInitializationMode()
Exemple #11
0
    def __init__(self, path_fmu):
        # define the model name and simulation parameters
        start_time = 0.0
        stop_time = 10.0
        self.step_size = 1e-2

        # read the model description
        model_description = read_model_description(path_fmu)

        # collect the value references
        vrs = {}
        for variable in model_description.modelVariables:
            vrs[variable.name] = variable.valueReference

        # get the value references for the variables we want to get/set
        self.vr_inputs = vrs['u']
        self.vr_output = vrs['Out1']

        # extract the FMU
        unzipdir = extract(path_fmu)
        self.fmu = FMU2Slave(
            guid=model_description.guid,
            unzipDirectory=unzipdir,
            modelIdentifier=model_description.coSimulation.modelIdentifier,
            instanceName='instance1')

        # initialize
        self.fmu.instantiate()
        self.fmu.setupExperiment(startTime=start_time)
        self.fmu.enterInitializationMode()
        self.fmu.exitInitializationMode()

        self.time = start_time
Exemple #12
0
    def test_type_definitions(self):
        """ Read the Type Definitions from the modelDescription.xml """

        for fmi_version in ['1.0', '2.0']:

            filename = download_file(
                'https://github.com/modelica/fmi-cross-check/raw/master/fmus/'
                + fmi_version + '/cs/win64/Dymola/2017/DFFREG/DFFREG.fmu')

            model_description = read_model_description(filename)

            real = model_description.typeDefinitions[0]

            self.assertEqual('Real', real.type)
            self.assertEqual('Modelica.SIunits.Time', real.name)
            self.assertEqual('Time', real.quantity)
            self.assertEqual('s', real.unit)

            logic = model_description.typeDefinitions[1]

            self.assertEqual('Enumeration', logic.type)
            self.assertEqual('Modelica.Electrical.Digital.Interfaces.Logic',
                             logic.name)
            self.assertEqual(9, len(logic.items))

            high_impedance = logic.items[4]

            self.assertEqual("'Z'", high_impedance.name)
            self.assertEqual(5, int(high_impedance.value))
            self.assertEqual("Z  High Impedance", high_impedance.description)
Exemple #13
0
    def __init__(self, fmu="testrig.fmu"):
        """
        Prepares the FMU for start and retrieves the available the inputs, outputs and output matrices from it

        :param fmu: the name of the fmu that will be used
        """
        file = os.path.realpath(os.path.join('../../fmus',
                                             fmu))  # TODO: validate file path
        self.model_description = fmpy.read_model_description(file)
        self.dt = 0
        self.t = 0
        self.inputs = []
        self.time_step_input_ref = -1
        for variable in self.model_description.modelVariables:
            if variable.causality == 'input':
                if not variable.name == "Input_time_step":
                    self.inputs.append(variable)
                else:
                    self.time_step_input_ref = variable.valueReference
        self.matrix_outputs = defaultdict(list)
        self.outputs = []
        for variable in self.model_description.modelVariables:
            if variable.causality == 'output':
                self.outputs.append(variable)
                if cell_regex.match(variable.name):
                    self.matrix_outputs[variable.name[:-4]].append(
                        len(self.outputs) - 1)
        self.file = file
        self.fmu = None
Exemple #14
0
def simulate_with_input():
    # os.chdir(r"C:\arash\PHD\IEA Projects\Annex\common exercise\ajab")
    os.chdir(path="C:/Users/gerar/PycharmProjects/untitled1/venv/Scripts")
    fmuf = 'TwinHouses71_new.fmu'
    start_time = 30463200
    # stop_time = 31676400
    # step_size = 3600
    #dump(fmuf)
    model_description = read_model_description(fmuf)
    vrs = {}
    for variable in model_description.modelVariables:
        vrs[variable.name] = variable.valueReference
        # print(variable)

    vr_output1 = vrs['Tav']  # temperature
    vr_output2 = vrs['hp_el']  # heat pump consumption
    vr_input1 = vrs['hp_s']  # heat pump status
    vr_input2 = vrs['hp_wt']  # heat water temperature
    #vr_outputs2 =vrs['lagtemp'] #hourly lagged temperature
    unzipdir = extract(fmuf)
    fmu = FMU2Slave(
        guid=model_description.guid,
        modelIdentifier=model_description.coSimulation.modelIdentifier,
        unzipDirectory=unzipdir,
        instanceName='instance1')
    fmu.instantiate()
    fmu.setupExperiment(startTime=start_time)
    fmu.enterInitializationMode()
    fmu.exitInitializationMode()
    # fmu.callbacks
    # output1=20

    return fmu, vr_input1, vr_input2, vr_output1, vr_output2
    def test_type_definitions(self):
        """ Read the Type Definitions from the modelDescription.xml """

        for fmi_version in ['1.0', '2.0']:

            download_file(
                'https://trac.fmi-standard.org/export/HEAD/branches/public/Test_FMUs/FMI_'
                + fmi_version +
                '/CoSimulation/win64/Dymola/2017/DFFREG/DFFREG.fmu')

            model_description = read_model_description('DFFREG.fmu')

            real = model_description.typeDefinitions[0]

            self.assertEqual('Real', real.type)
            self.assertEqual('Modelica.SIunits.Time', real.name)
            self.assertEqual('Time', real.quantity)
            self.assertEqual('s', real.unit)

            logic = model_description.typeDefinitions[1]

            self.assertEqual('Enumeration', logic.type)
            self.assertEqual('Modelica.Electrical.Digital.Interfaces.Logic',
                             logic.name)
            self.assertEqual(9, len(logic.items))

            high_impedance = logic.items[4]

            self.assertEqual("'Z'", high_impedance.name)
            self.assertEqual(5, int(high_impedance.value))
            self.assertEqual("Z  High Impedance", high_impedance.description)
    def validate(self,
                 build_dir,
                 fmi_types=['ModelExchange', 'CoSimulation'],
                 models=models,
                 compile=False):

        from fmpy.util import read_csv, validate_result

        for model in models:

            print(model)

            fmu_filename = os.path.join(build_dir, 'dist', model + '.fmu')

            if model == 'Feedthrough':
                start_values = {
                    'real_fixed_param': 1,
                    'string_param': "FMI is awesome!"
                }
                in_csv = os.path.join(test_fmus_dir, model, model + '_in.csv')
                input = read_csv(in_csv)
            else:
                start_values = {}
                input = None

            ref_csv = os.path.join(test_fmus_dir, model, model + '_ref.csv')

            for fmi_type in fmi_types:

                ref = read_csv(ref_csv)

                if compile:
                    compile_platform_binary(fmu_filename)

                read_model_description(fmu_filename,
                                       validate_variable_names=True,
                                       validate_model_structure=True)

                result = simulate_fmu(fmu_filename,
                                      fmi_type=fmi_type,
                                      start_values=start_values,
                                      input=input,
                                      solver='Euler')

                dev = validate_result(result, ref)

                self.assertLess(dev, 0.2, "Failed to validate " + model)
Exemple #17
0
def runSimulation():
    # extract the FMU to a temporary directory
    unzipdir = fmpy.extract(fmu)
    # read the model description
    model_description = fmpy.read_model_description(unzipdir)
    # instantiate the FMU
    fmu_instance = fmpy.instantiate_fmu(unzipdir, model_description, 'CoSimulation')

    cf = fun_lib.importCostFunction(dir = 'Combined\\')

    params = readInitParams()
    cost = 1e300
    # shuffledParams = copy.

    for iter in range(niter):
    # todo paralelize this

        
        cur_params = shuffleParams(params)

        # reset the FMU instance instead of creating a new one
        fmu_instance.reset()
        
        result = fmpy.simulate_fmu(unzipdir,
                                    stop_time=1,
                                    start_values=cur_params,
                                    model_description=model_description,
                                    fmu_instance=fmu_instance,
                                    fmi_call_logger=lambda s: print('[FMI] ' + s) )

        var_set = {}
        for name in result.dtype.names:
            var_set[name] = result[name]
            
        if DRAW_PLOTS:
            var_set['__draw_plots'] = True
            var_set['__plot_title'] = "Run %i" % (fun_lib.getRunNumber())
            var_set['__saveFig_path'] = "%sFitFig_%03d.png" % (fun_lib.getSafeLogDir('Schedules'), fun_lib.getRunNumber())

        objectives = cf.getObjectives(var_set, targetsFolder = r"../data/Valsalva/")
        cur_cost = fun_lib.countTotalSumCost(objectives)

        if cur_cost < cost:
            # woohoo, better costs!
            cost = cur_cost
            params = cur_params
            writeSchedule(params, cost, iter)

        print(result)
    

    # free the FMU instance and unload the shared library
    fmu_instance.freeInstance()

    # delete the temporary directory
    shutil.rmtree(unzipdir, ignore_errors=True)

    print('that is all, folks')
    pass
Exemple #18
0
    def __init__(self, name, options):
        super().__init__(name, options)

        if (options['tool'] == "IPSL") or (options['tool'] == "FMU"):
            if 'inputs' not in options:
                raise Exception("DynamicSimulation.init(): Inputs must be provided.")
            if 'outputs' not in options:
                raise Exception("DynamicSimulation.init(): Outputs must be provided.")

            if 'fmu' in options:
                myFMUid = options['fmu']
            else:
                myFMUid = options['model_path'] + '\\' + options['model'] + '.fmu'
            modelDescription = read_model_description(myFMUid, validate=True)

            if options['tool'] == "IPSL":
                tIPSL = IPSLtranslator(modelDescription.modelVariables)
            else:
                tIPSL = FMPYtranslator(modelDescription.modelVariables)

            import copy
            DSnoInitopt = copy.deepcopy(options)

            self.inElemList = []
            for i in options['inputs']:
                tranIn = tIPSL.translate(i)
                if len(tranIn)>1:
                    ind = DSnoInitopt['inputs'].index(i)
                    DSnoInitopt['inputs'].pop(ind)
                    for j in reversed(tranIn):
                        DSnoInitopt['inputs'].insert(ind,j)
                    #pom = Demux(name + '->' + i, len(tranIn))

                    if i.find("Pg")>=0 or i.find("Qg")>=0:
                        pom = Demux(name + '->' + i, len(tranIn))
                    elif i.find("Pd")>=0 or i.find("Qd")>=0:
                        ind = tIPSL.getIndex(tranIn)
                        pom = Demux(name + '->' + i, len(tranIn), VALUETYPES.REAL, {'ind' : ind})

                    self.add_element(pom)
                    self.inElemList.append(pom)
                else:
                    pom = Reflector(name + '->' + i)
                    self.add_element(pom)
                    self.inElemList.append(pom)
                    if tIPSL.isSignal(i):
                        self.setInputCondition("edge{" + i + "}", 'init')

            actualOutputs = DSnoInitopt['inputs'].copy()


            self.myTool = DynamicSimulationNoInit(name + '->DSnoInit', DSnoInitopt)
            self.add_element(self.myTool)

            cnt = 0
            for i in range(0,len(self.inElemList)):
                for j in range(0,len(self.inElemList[i].output)):
                    self.inElemList[i].connect(self.myTool,j+1,actualOutputs[cnt])
                    cnt += 1
Exemple #19
0
def compile_platform_binary(filename, output_filename=None, target_platform=None, compiler_options=None):
    """ Compile the binary of an FMU for the current platform and add it to the FMU

    Parameters:
        filename:          filename of the source code FMU
        output_filename:   filename of the FMU with the compiled binary (None: overwrite existing FMU)
        compiler_options:  custom compiler options
    """

    from . import read_model_description, extract, platform, platform_tuple
    import zipfile
    from shutil import copyfile, rmtree
    from os.path import join, basename, relpath, exists, normpath, isfile, splitext

    unzipdir = extract(filename)

    model_description = read_model_description(filename)

    if target_platform is None:
        target_platform = platform if model_description.fmiVersion in ['1.0', '2.0'] else platform_tuple

    binary = compile_dll(model_description=model_description,
                         sources_dir=join(unzipdir, 'sources'),
                         target_platform=target_platform,
                         compiler_options=compiler_options)

    unzipdir2 = extract(filename)

    target_platform_dir = join(unzipdir2, 'binaries', target_platform)

    if not exists(target_platform_dir):
        os.makedirs(target_platform_dir)

    copyfile(src=binary, dst=join(target_platform_dir, basename(binary)))

    debug_database = splitext(binary)[0] + '.pdb'

    if isfile(debug_database):
        copyfile(src=debug_database, dst=join(target_platform_dir, basename(debug_database)))

    if output_filename is None:
        output_filename = filename  # overwrite the existing archive

    # create a new archive from the existing files + compiled binary
    with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zf:
        base_path = normpath(unzipdir2)
        for dirpath, dirnames, filenames in os.walk(unzipdir2):
            for name in sorted(dirnames):
                path = normpath(join(dirpath, name))
                zf.write(path, relpath(path, base_path))
            for name in filenames:
                path = normpath(join(dirpath, name))
                if isfile(path):
                    zf.write(path, relpath(path, base_path))

    # clean up
    rmtree(unzipdir, ignore_errors=True)
    rmtree(unzipdir2, ignore_errors=True)
    def test_get_directional_derivative(self):

        fmu_filename = 'Rectifier.fmu'

        download_test_file('2.0', 'CoSimulation', 'Dymola', '2017',
                           'Rectifier', fmu_filename)

        model_description = read_model_description(filename=fmu_filename)

        unzipdir = extract(fmu_filename)

        fmu = FMU2Slave(
            guid=model_description.guid,
            unzipDirectory=unzipdir,
            modelIdentifier=model_description.coSimulation.modelIdentifier)

        fmu.instantiate()
        fmu.setupExperiment()
        fmu.enterInitializationMode()

        # get the partial derivative for an initial unknown
        unknown = model_description.initialUnknowns[1]

        self.assertEqual('iAC[1]', unknown.variable.name)

        vrs_unknown = [unknown.variable.valueReference]
        vrs_known = [v.valueReference for v in unknown.dependencies]
        dv_known = [1.0] * len(unknown.dependencies)

        partial_der = fmu.getDirectionalDerivative(vUnknown_ref=vrs_unknown,
                                                   vKnown_ref=vrs_known,
                                                   dvKnown=dv_known)

        self.assertEqual([-2.0], partial_der)

        fmu.exitInitializationMode()

        # get the partial derivative for three output variables
        unknowns = model_description.outputs[4:7]

        self.assertEqual(['uAC[1]', 'uAC[2]', 'uAC[3]'],
                         [u.variable.name for u in unknowns])

        vrs_unknown = [u.variable.valueReference for u in unknowns]
        vrs_known = [v.valueReference for v in unknowns[0].dependencies]
        dv_known = [1.0] * len(vrs_known)

        partial_der = fmu.getDirectionalDerivative(vUnknown_ref=vrs_unknown,
                                                   vKnown_ref=vrs_known,
                                                   dvKnown=dv_known)

        self.assertAlmostEqual(-1500, partial_der[0])
        self.assertAlmostEqual(0, partial_der[1])
        self.assertAlmostEqual(1500, partial_der[2])

        fmu.terminate()
        fmu.freeInstance()
        rmtree(unzipdir)
Exemple #21
0
async def fmu_detail(request: web.Request):
    """
    Get detailed information for the FMU with the given id

    Append /models to get the 3d models if any
    """
    file = await find_in_dir(request.match_info['id'], request.app['settings'].FMU_DIR)
    model_description = read_model_description(file)
    return web.json_response(model_description, dumps=dumps)
Exemple #22
0
    def test_validate_variable_names(self):

        filename = download_file(
            url=
            'https://github.com/modelica/fmi-cross-check/raw/master/fmus/2.0/me/win64/MapleSim/2015.1/CoupledClutches/CoupledClutches.fmu',
            checksum=
            'af8f8ca4d7073b2d6207d8eea4a3257e3a23a69089f03181236ee3ecf13ff77f')

        problems = []

        try:
            read_model_description(filename,
                                   validate=True,
                                   validate_variable_names=True)
        except ValidationError as e:
            problems = e.problems

        self.assertEqual(len(problems), 124)
Exemple #23
0
def create_cmake_project(filename, project_dir):
    """ Create a CMake project from a C code FMU

    Parameters:

        filename     filename of the C code FMU
        project_dir  existing directory for the CMake project
    """

    from zipfile import ZipFile
    from fmpy import read_model_description, extract

    model_description = read_model_description(filename)

    extract(filename, unzipdir=project_dir)

    fmpy_dir = os.path.dirname(__file__)
    source_dir = os.path.join(fmpy_dir, 'c-code')

    with open(os.path.join(source_dir, 'CMakeLists.txt'), 'r') as cmake_file:
        txt = cmake_file.read()

    definitions = []

    if model_description.coSimulation is not None:
        definitions.append('CO_SIMULATION')

    if model_description.modelExchange is not None:
        definitions.append('MODEL_EXCHANGE')

    with ZipFile(filename, 'r') as archive:
        # don't add the current directory
        resources = list(
            filter(lambda n: not n.startswith('.'), archive.namelist()))

    # always add the binaries
    resources.append('binaries')

    # use the first source file set of the first build configuration
    build_configuration = model_description.buildConfigurations[0]
    source_file_set = build_configuration.sourceFileSets[0]

    sources = ['sources/' + file for file in source_file_set.sourceFiles]

    # substitute the variables
    txt = txt.replace('%MODEL_NAME%', model_description.modelName)
    txt = txt.replace('%MODEL_IDENTIFIER%',
                      build_configuration.modelIdentifier)
    txt = txt.replace('%DEFINITIONS%', ' '.join(definitions))
    txt = txt.replace('%INCLUDE_DIRS%',
                      '"' + source_dir.replace('\\', '/') + '"')
    txt = txt.replace('%SOURCES%', ' '.join(sources))
    txt = txt.replace('%RESOURCES%',
                      '\n    '.join('"' + r + '"' for r in resources))

    with open(os.path.join(project_dir, 'CMakeLists.txt'), 'w') as outfile:
        outfile.write(txt)
Exemple #24
0
def add_remoting(filename):

    from . import extract, read_model_description, supported_platforms
    from shutil import copyfile, rmtree
    import zipfile
    import os

    platforms = supported_platforms(filename)

    if 'win32' not in platforms:
        raise Exception("The FMU does not support the platform \"win32\".")

    if 'win64' in platforms:
        raise Exception("The FMU already supports \"win64\".")

    model_description = read_model_description(filename)

    current_dir = os.path.dirname(__file__)
    client = os.path.join(current_dir, 'remoting', 'client.dll')
    server = os.path.join(current_dir, 'remoting', 'server.exe')
    license = os.path.join(current_dir, 'remoting', 'license.txt')

    tempdir = extract(filename)

    if model_description.coSimulation is not None:
        model_identifier = model_description.coSimulation.modelIdentifier
    else:
        model_identifier = model_description.modelExchange.modelIdentifier

    # copy the binaries & license
    os.mkdir(os.path.join(tempdir, 'binaries', 'win64'))
    copyfile(
        client,
        os.path.join(tempdir, 'binaries', 'win64', model_identifier + '.dll'))
    copyfile(server, os.path.join(tempdir, 'binaries', 'win64', 'server.exe'))
    licenses_dir = os.path.join(tempdir, 'documentation', 'licenses')
    if not os.path.isdir(licenses_dir):
        os.mkdir(licenses_dir)
    copyfile(
        license,
        os.path.join(tempdir, 'documentation', 'licenses',
                     'fmpy-remoting-binaries.txt'))

    # create a new archive from the existing files + remoting binaries
    with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zf:
        base_path = os.path.normpath(tempdir)
        for dirpath, dirnames, filenames in os.walk(tempdir):
            for name in sorted(dirnames):
                path = os.path.normpath(os.path.join(dirpath, name))
                zf.write(path, os.path.relpath(path, base_path))
            for name in filenames:
                path = os.path.normpath(os.path.join(dirpath, name))
                if os.path.isfile(path):
                    zf.write(path, os.path.relpath(path, base_path))

    # clean up
    rmtree(tempdir, ignore_errors=True)
Exemple #25
0
    def test_read_model_description(self):

        unzipdir = os.path.join(os.environ['FMI3_FMUS_DIR'],
                                'linearOperatorcs30')

        model_description = read_model_description(unzipdir)

        fmu = FMU3Slave(
            guid=model_description.guid,
            unzipDirectory=unzipdir,
            modelIdentifier=model_description.coSimulation.modelIdentifier)

        fmu.instantiate()
        fmu.setupExperiment()
        fmu.enterInitializationMode()
        fmu.exitInitializationMode()

        variables = dict((v.name, v) for v in model_description.modelVariables)

        def get_real(variable):
            vr = (fmi3ValueReference * 1)(variable.valueReference)
            value = np.zeros(variable.extent)
            status = fmu.fmi3GetReal(
                fmu.component, vr, len(vr),
                cast(value.ctypes.data, POINTER(fmi3Float64)), value.size)
            self.assertEqual(status, fmi3OK)
            return value

        def set_real(variable, data):
            vr = (fmi3ValueReference * 1)(variable.valueReference)
            status = fmu.fmi3SetReal(
                fmu.component, vr, len(vr),
                cast(data.ctypes.data, POINTER(fmi3Float64)), data.size)
            self.assertEqual(status, fmi3OK)

        # get "in"
        in_data = get_real(variables['in'])
        self.assertTrue(np.all(in_data == [1, 1, 1]))

        # get "operator"
        operator_data = get_real(variables['operator'])
        self.assertTrue(
            np.all(operator_data.flat == [1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1]))

        # set "in"
        in_data[:] = [1, 2, 3]
        set_real(variables['in'], in_data)

        # get "out"
        out_data = get_real(variables['out'])
        self.assertTrue(np.all(out_data == [1, 2, 3, 6]))

        # clean up
        fmu.terminate()
        fmu.freeInstance()
Exemple #26
0
def df_to_repr_jsonld(df, fmu, time_is_relative):
    """Render JSON-LD-representation of DataFrame."""

    logger.debug("df:\n{}".format(df))

    unit_map = {
        "W": UNIT.W,
        "kW.h": UNIT["KiloW-HR"],
        "deg": UNIT.DEG,
    }

    # Read model description
    desc = fmpy.read_model_description(fmu)

    # Iterate over columns of dataframe
    graph = graph_bind_prefixes(rdflib.Graph())
    for label, series in df.items():
        # Set unit to '1' if it is undefined
        # https://github.com/CATIA-Systems/FMPy/blob/master/fmpy/model_description.py#L154
        model_variable = py_.find(desc.modelVariables, lambda x: x.name == label)
        if model_variable.unit is not None:
            unit = model_variable.unit
        else:
            unit = "1"

        logger.debug(f"{model_variable.name} / {unit}")

        # Define `sosa:ObservableProperty` for each column
        observable_iri = f"#{label}"
        observable_uriref = rdflib.URIRef(observable_iri)
        graph.add((observable_uriref, RDF.type, SOSA.ObservableProperty))

        for index, value in series.items():
            # Define `sosa:Observation` for each row
            observation_id = f"#{nanoid.generate(size=8)}"
            observation_uriref = rdflib.URIRef(observation_id)
            graph.add((observation_uriref, RDF.type, SOSA.Observation))
            graph.add((observation_uriref, SOSA.observedProperty, observable_uriref))

            # Define `qudt:QuantityValue` for each value
            result_uriref = rdflib.URIRef(f"{observation_id}_result")
            graph.add((result_uriref, RDF.type, QUDT.QuantityValue))
            graph.add((result_uriref, QUDT.numericValue, rdflib.Literal(float(value))))
            graph.add((result_uriref, QUDT.unit, unit_map[unit]))
            graph.add((observation_uriref, SOSA.hasResult, result_uriref))

            # Define `time:Instant` for each index
            time_uriref = rdflib.URIRef(f"{observation_id}_time")
            time_literal = rdflib.Literal(index, datatype=XSD.dateTimeStamp)
            graph.add((time_uriref, RDF.type, TIME.Instant))
            graph.add((time_uriref, TIME.inXSDDateTimeStamp, time_literal))
            graph.add((observation_uriref, SOSA.phenomenonTime, time_uriref))

    return json.loads(graph.serialize(format="application/ld+json"))
Exemple #27
0
def load_fmu(instance_name, path):
    """A function to read an FMU and go through default initialization"""

    mdl_desc = fmpy.read_model_description(path)
    unzip_dir = fmpy.extract(path)

    fmu = FMU2Slave(instanceName=instance_name,
                    guid=mdl_desc.guid,
                    modelIdentifier=mdl_desc.coSimulation.modelIdentifier,
                    unzipDirectory=unzip_dir)
    return Slave(mdl_desc, fmu)
Exemple #28
0
    def __init__(self,
                 fmu_path,
                 step_size,
                 stop_time,
                 timestamp_key,
                 start_time=None,
                 target_keys=None,
                 input_keys=None,
                 control_keys=None):
        """Loads and executes Functional Mockup Unit (FMU) modules

        Handles FMU archives adhering to the Functional Mockup Interface
        standard 2.0 as a part of a digital twin experiment. We make
        extensive use of FMPY library. The full FMI spec can be found at
        https://fmi-standard.org/

        Args:
            fmu_path (str): Path to the FMI-compliant zip-archive
            start_time (float): Value of time variable supplied to the
                FMU at the first timestep of the simulation. None (def)
                translates to 0.0
            stop_time (float): (Optional) final value of the time
                variable in the simulation. A valid FMU will report an
                error state if master tries to simulate past stop_time
            step_size (float): The default communication step size for
                the model. Can be be overridden in individual calls to
                step method to accommodate dynamical stepping
            timestamp_key: String identifier of the timestamp key
            target_keys (List(str)): Dependent variable names in the
                simulation
            input_keys (List(str)): Independent variable names in the
                simulation
            control_keys (List(str)): (Optional) Variable names e.g. for
                validating the simulation output, in meas-vs-sim style
        """
        super(FMUModelHandler, self).__init__(target_keys=target_keys,
                                              input_keys=input_keys,
                                              control_keys=control_keys)
        self.model_description = read_model_description(fmu_path)
        self.fmu_filename = fmu_path
        self.start_time = 0 if start_time is None else start_time
        # TODO parse default stop_time from model_description
        self.stop_time = stop_time
        # TODO parse default step_size from model_description
        self.step_size = step_size
        # TODO should make this work with datetimes as well as integers
        self.timestamp_key = timestamp_key
        self.unzipdir = extract(fmu_path)
        self.vrs = {}
        self._fmu = None
        self._vr_input = None
        self._vr_output = None
        self._get_value_references()
Exemple #29
0
def create_cmake_project(filename, project_dir):
    """ Create a CMake project from a C code FMU

    Parameters:

        filename     filename of the C code FMU
        project_dir  existing directory for the CMake project
    """

    from fmpy import read_model_description, extract
    import shutil

    model_description = read_model_description(filename)

    extract(filename, unzipdir=project_dir)

    fmpy_dir = os.path.dirname(__file__)
    source_dir = os.path.join(fmpy_dir, 'c-code', 'fmi2')

    # copy the FMI headers and the source FMU wrapper
    for source_file in [
            'fmi2_wrapper.c', 'fmi2Functions.h', 'fmi2FunctionTypes.h',
            'fmi2TypesPlatform.h'
    ]:
        shutil.copy(os.path.join(source_dir, source_file),
                    os.path.join(project_dir, 'sources'))

    with open(os.path.join(source_dir, 'CMakeLists.txt'), 'r') as cmake_file:
        txt = cmake_file.read()

    definitions = []

    if model_description.coSimulation is not None:
        implementation = model_description.coSimulation
        definitions.append('CO_SIMULATION')
    else:
        implementation = model_description.modelExchange

    if model_description.modelExchange is not None:
        definitions.append('MODEL_EXCHANGE')

    sources = ['modelDescription.xml', 'sources/fmi2_wrapper.c']
    sources += ['sources/' + file for file in implementation.sourceFiles]

    # substitute the variables
    txt = txt.replace('%MODEL_NAME%', model_description.modelName)
    txt = txt.replace('%MODEL_IDENTIFIER%', implementation.modelIdentifier)
    txt = txt.replace('%DEFINITIONS%', ' '.join(definitions))
    txt = txt.replace('%SOURCES%', ' '.join(sources))

    with open(os.path.join(project_dir, 'CMakeLists.txt'), 'w') as outfile:
        outfile.write(txt)
Exemple #30
0
    def test_cswrapper(self):

        filename = 'CoupledClutches.fmu'

        download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2', 'CoupledClutches', filename)

        model_description = read_model_description(filename)

        self.assertIsNone(model_description.coSimulation)

        add_cswrapper(filename)

        simulate_fmu(filename, fmi_type='CoSimulation')