16 const char *description;
17 const char *declaredType;
41 const char *description;
46 int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error);
48 int FMI1_CS_UNLOAD(void* fmu, const char **error);
49 FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
50 FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
51 int FMI1_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
52 int FMI1_CS_INITIALIZE(void* fmu, const char **error);
53 int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
54 int FMI1_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
55 double FMI1_CS_GET_REAL(void* fmu, int vr, const char **error);
56 int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
58 int FMI2_CS_UNLOAD(void* fmu, const char **error);
59 FMIL_Variable *FMI2_CS_GET_VARIABLES(void* fmu, int *count, const char **error);
60 FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void* fmu, int *count, const char **error);
61 int FMI2_CS_INSTANTIATE(void* fmu, const char *instanceName, const char **error);
62 int FMI2_CS_INITIALIZE(void* fmu, const char **error);
63 int FMI2_CS_STEP(void* fmu, double masterTime, double stepSize, const char **error);
64 int FMI2_CS_SET_REAL(void* fmu, int vr, double value, const char **error);
65 double FMI2_CS_GET_REAL(void* fmu, int vr, const char **error);
66 int FMI2_CS_GET_REALS(void* fmu, int *vrs, double *values, int count, const char **error);
74 /* Logger function used by the C-API */
75 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
77 printf("module = %s, log level = %d: %s\n", module, log_level, message);
80 /* Logger function used by the FMU internally */
81 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
86 va_start(argp, message);
87 /*len=jm_vsnprintf(msg, BUFFER, message, argp);
88 printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);
90 printf("Warning: message was trancated");
94 int FMI_CS_LOAD(const char *zipFilePath, const char *unzipFolder, void **fmuPointer, int *fmuVersion, const char **error) {
96 fmi1_callback_functions_t callBackFunctions;
97 fmi2_callback_functions_t callBackFunctions2;
98 fmi_import_context_t* context;
99 fmi_version_enu_t version;
100 jm_status_enu_t status;
103 jm_callbacks* callbacks;
105 callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));
107 callbacks->malloc = malloc;
108 callbacks->calloc = calloc;
109 callbacks->realloc = realloc;
110 callbacks->free = free;
111 callbacks->logger = importlogger;
113 callbacks->log_level = jm_log_level_debug;
115 callbacks->log_level = jm_log_level_warning;
117 callbacks->context = 0;
119 context = fmi_import_allocate_context(callbacks);
121 version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);
123 if (version == fmi_version_1_enu ) {
124 fmu = fmi1_import_parse_xml(context, unzipFolder);
125 if (fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_standalone && fmi1_import_get_fmu_kind(fmu) != fmi1_fmu_kind_enu_cs_tool) {
126 *error = "Provided FMU is version 1 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
127 return 2; /* wrong type, should be co-simulation */
130 callBackFunctions.logger = fmilogger;
131 callBackFunctions.allocateMemory = calloc;
132 callBackFunctions.freeMemory = free;
134 status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);
135 if (status == jm_status_error) {
136 *error = fmi1_import_get_last_error(fmu);
142 } else if (version == fmi_version_2_0_enu) {
143 fmu2 = fmi2_import_parse_xml(context, unzipFolder, 0);
145 if (fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_standalone && fmi2_import_get_fmu_kind(fmu2) != fmi1_fmu_kind_enu_cs_tool) {
146 *error = "Provided FMU is version 2.0 but wrong type me (Model Exchange) when it should be cs (Co-Simulation)";
147 return 2; /* wrong type, should be co-simulation */
150 callBackFunctions2.logger = fmi2_log_forwarding;
151 callBackFunctions2.allocateMemory = calloc;
152 callBackFunctions2.freeMemory = free;
153 callBackFunctions2.componentEnvironment = fmu2;
155 status = fmi2_import_create_dllfmu(fmu2, fmi2_fmu_kind_cs, &callBackFunctions2);
156 if (status == jm_status_error) {
157 *error = fmi2_import_get_last_error(fmu2);
164 *error = "Couldn't find version of FMU - possibly incorrect file!";
168 fmi_import_free_context(context);
170 return 0; /* success */
173 int FMI1_CS_UNLOAD(void *fmu_, const char **error) {
174 fmi1_import_t *fmu = (fmi1_import_t *)fmu_;
175 fmi1_import_destroy_dllfmu(fmu);
176 fmi1_import_free(fmu);
180 int FMI2_CS_UNLOAD(void *fmu_, const char **error) {
181 fmi2_import_t *fmu = (fmi2_import_t *)fmu_;
182 fmi2_import_destroy_dllfmu(fmu);
183 fmi2_import_free(fmu);
189 printf("No type definition\n");
193 quan = fmi1_import_get_type_quantity(vt);
195 printf("Type %s\n description: %s\n", fmi1_import_get_type_name(vt), fmi1_import_get_type_description(vt));
197 printf("Base type: %s\n", fmi1_base_type_to_string(fmi1_import_get_base_type(vt)));
200 printf("Quantity: %s\n", quan);
202 switch(fmi1_import_get_base_type(vt)) {
203 case fmi1_base_type_real: {
204 fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(vt);
205 fmi1_real_t min = fmi1_import_get_real_type_min(rt);
206 fmi1_real_t max = fmi1_import_get_real_type_max(rt);
207 fmi1_real_t nom = fmi1_import_get_real_type_nominal(rt);
208 fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
209 fmi1_import_display_unit_t* du = fmi1_import_get_type_display_unit(rt);
211 printf("Min %g, max %g, nominal %g\n", min, max, nom);
214 printf("Unit: %s\n", fmi1_import_get_unit_name(u));
217 printf("Display unit: %s, gain: %g, offset: %g, is relative: %s",
218 fmi1_import_get_display_unit_name(du),
219 fmi1_import_get_display_unit_gain(du),
220 fmi1_import_get_display_unit_offset(du),
221 fmi1_import_get_real_type_is_relative_quantity(rt)?"yes":"no"
227 case fmi1_base_type_int:{
228 fmi1_import_integer_typedef_t* it = fmi1_import_get_type_as_int(vt);
229 int min = fmi1_import_get_integer_type_min(it);
230 int max = fmi1_import_get_integer_type_max(it);
231 printf("Min %d, max %d\n", min, max);
234 case fmi1_base_type_bool:{
237 case fmi1_base_type_str:{
240 case fmi1_base_type_enum:{
241 fmi1_import_enumeration_typedef_t* et = fmi1_import_get_type_as_enum(vt);
242 int min = fmi1_import_get_enum_type_min(et);
243 int max = fmi1_import_get_enum_type_max(et);
244 printf("Min %d, max %d\n", min, max);
248 ni = fmi1_import_get_enum_type_size(et);
251 printf("There are %u items \n",(unsigned)ni);
252 for(i = 0; i < ni; i++) {
253 printf("[%u] %s (%s) \n", (unsigned)i+1, fmi1_import_get_enum_type_item_name(et, i), fmi1_import_get_enum_type_item_description(et, i));
259 printf("Error in fmiGetBaseType()\n");
264 FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
267 FMIL_Variable *result;
268 fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);
269 fmi1_import_variable_typedef_t* type;
271 count[0] = fmi1_import_get_variable_list_size(vl);
273 result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
275 for(i = 0; i < count[0]; i++) {
277 fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);
280 printf("Something wrong with variable %d \n",i);
285 result[i].name = fmi1_import_get_variable_name(var);
286 result[i].description = fmi1_import_get_variable_description(var);
288 switch (fmi1_import_get_variability(var)) {
289 case fmi1_variability_enu_constant:
290 result[i].variability = 0;
292 case fmi1_variability_enu_parameter:
293 result[i].variability = 1;
295 case fmi1_variability_enu_discrete:
296 result[i].variability = 2;
298 case fmi1_variability_enu_continuous:
299 result[i].variability = 3;
301 case fmi1_variability_enu_unknown:
302 result[i].variability = 4;
306 switch (fmi1_import_get_causality(var)) {
307 case fmi1_causality_enu_input:
308 result[i].causality = 0;
310 case fmi1_causality_enu_output:
311 result[i].causality = 1;
313 case fmi1_causality_enu_internal:
314 result[i].causality = 2;
316 case fmi1_causality_enu_none:
317 result[i].causality = 3;
319 case fmi1_causality_enu_unknown:
320 result[i].causality = 4;
324 switch (fmi1_import_get_variable_base_type(var)) {
325 case fmi1_base_type_real:
328 case fmi1_base_type_int:
331 case fmi1_base_type_bool:
334 case fmi1_base_type_str:
337 case fmi1_base_type_enum:
342 result[i].vr = fmi1_import_get_variable_vr(var);
344 type = fmi1_import_get_variable_declared_type(var);
346 result[i].declaredType = fmi1_import_get_type_name(type);
348 result[i].declaredType = 0;
355 fmi1_import_free_variable_list(vl);
361 FMIL_Variable *FMI2_CS_GET_VARIABLES(void *fmu, int *count, const char **error) {
364 FMIL_Variable *result;
365 fmi2_import_variable_list_t* vl = fmi2_import_get_variable_list((fmi2_import_t *)fmu, 0);
366 fmi2_import_variable_typedef_t* type;
368 count[0] = fmi2_import_get_variable_list_size(vl);
370 result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
372 for(i = 0; i < count[0]; i++) {
374 fmi2_import_variable_t* var = fmi2_import_get_variable(vl, i);
377 printf("Something wrong with variable %d \n",i);
382 result[i].name = fmi2_import_get_variable_name(var);
383 result[i].description = fmi2_import_get_variable_description(var);
385 switch (fmi2_import_get_variability(var)) {
386 case fmi2_variability_enu_constant:
387 result[i].variability = 0;
389 case fmi2_variability_enu_fixed:
390 case fmi2_variability_enu_tunable:
391 result[i].variability = 1;
393 case fmi2_variability_enu_discrete:
394 result[i].variability = 2;
396 case fmi2_variability_enu_continuous:
397 result[i].variability = 3;
399 case fmi2_variability_enu_unknown:
400 result[i].variability = 4;
404 switch (fmi2_import_get_causality(var)) {
405 case fmi2_causality_enu_input:
406 result[i].causality = 0;
408 case fmi2_causality_enu_output:
409 result[i].causality = 1;
411 case fmi2_causality_enu_local:
412 result[i].causality = 2;
414 case fmi2_causality_enu_independent:
415 result[i].causality = 3;
417 case fmi2_causality_enu_unknown:
418 result[i].causality = 4;
422 switch (fmi2_import_get_variable_base_type(var)) {
423 case fmi2_base_type_real:
426 case fmi2_base_type_int:
429 case fmi2_base_type_bool:
432 case fmi2_base_type_str:
435 case fmi2_base_type_enum:
440 result[i].vr = fmi2_import_get_variable_vr(var);
442 type = fmi2_import_get_variable_declared_type(var);
444 result[i].declaredType = fmi2_import_get_type_name(type);
446 result[i].declaredType = 0;
453 fmi2_import_free_variable_list(vl);
459 FMIL_DeclaredType *FMI1_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
461 FMIL_DeclaredType *result;
462 fmi1_import_type_definitions_t* td = fmi1_import_get_type_definitions((fmi1_import_t *)fmu);
463 fmi1_import_variable_typedef_t* type;
464 unsigned i, ntd = (unsigned)fmi1_import_get_type_definition_number(td);
468 result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
470 for(i = 0; i < ntd; i++) {
471 type = fmi1_import_get_typedef(td, i);
472 result[i].name = fmi1_import_get_type_name(type);
473 result[i].description = fmi1_import_get_type_description(type);
474 result[i].quantity = fmi1_import_get_type_quantity(type);
477 switch(fmi1_import_get_base_type(type)) {
478 case fmi1_base_type_real: {
479 fmi1_import_real_typedef_t* rt = fmi1_import_get_type_as_real(type);
480 fmi1_import_unit_t* u = fmi1_import_get_real_type_unit(rt);
481 if(u) result[i].unit = fmi1_import_get_unit_name(u);
491 FMIL_DeclaredType *FMI2_CS_GET_DECLARED_TYPES(void *fmu, int *count, const char **error) {
493 FMIL_DeclaredType *result;
494 fmi2_import_type_definitions_t* td = fmi2_import_get_type_definitions((fmi2_import_t *)fmu);
495 fmi2_import_variable_typedef_t* type;
496 unsigned i, ntd = (unsigned)fmi2_import_get_type_definition_number(td);
500 result = (FMIL_DeclaredType *)malloc(count[0]*sizeof(FMIL_DeclaredType));
502 for(i = 0; i < ntd; i++) {
503 type = fmi2_import_get_typedef(td, i);
504 result[i].name = fmi2_import_get_type_name(type);
505 result[i].description = fmi2_import_get_type_description(type);
506 result[i].quantity = fmi2_import_get_type_quantity(type);
509 switch(fmi2_import_get_base_type(type)) {
510 case fmi2_base_type_real: {
511 fmi2_import_real_typedef_t* rt = fmi2_import_get_type_as_real(type);
512 fmi2_import_unit_t* u = fmi2_import_get_real_type_unit(rt);
513 if(u) result[i].unit = fmi2_import_get_unit_name(u);
523 int FMI1_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
525 fmi1_string_t fmuLocation;
526 fmi1_string_t mimeType;
528 fmi1_boolean_t visible;
529 fmi1_boolean_t interactive;
530 fmi1_boolean_t loggingOn;
532 jm_status_enu_t jmstatus;
537 visible = fmi1_false;
538 interactive = fmi1_false;
539 loggingOn = fmi1_true;
541 jmstatus = fmi1_import_instantiate_slave((fmi1_import_t*)fmu, instanceName, NULL, NULL, timeout, fmi1_false, fmi1_false);
542 if (jmstatus == jm_status_error) {
543 *error = fmi1_import_get_last_error((fmi1_import_t*)fmu);
549 int FMI2_CS_INSTANTIATE(void *fmu, const char *instanceName, const char **error) {
551 fmi2_string_t fmuLocation;
552 fmi2_string_t mimeType;
554 fmi2_boolean_t visible;
555 fmi2_boolean_t interactive;
556 fmi2_boolean_t loggingOn;
557 jm_status_enu_t jmstatus;
562 visible = fmi2_false;
563 jmstatus = fmi2_import_instantiate((fmi2_import_t*)fmu, instanceName, fmi2_cosimulation, NULL, visible);
564 if (jmstatus == jm_status_error) {
565 *error = fmi2_import_get_last_error((fmi2_import_t*)fmu);
571 int FMI1_CS_INITIALIZE(void *fmu, const char **error) {
573 fmi1_status_t status;
576 fmi1_boolean_t StopTimeDefined;
580 StopTimeDefined = fmi1_false;
582 status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);
583 if (status == fmi1_status_error || status == fmi1_status_fatal) {
584 printf("fmi1_capi_initialize_slave: Failed\n");
587 printf("fmi1_capi_initialize_slave: Success\n");
593 int FMI2_CS_INITIALIZE(void *fmu, const char **error) {
597 fmi2_boolean_t StopTimeDefined;
598 fmi2_real_t relativeTol = 1e-4;
600 fmi2_status_t fmistatus;
604 StopTimeDefined = fmi1_false;
606 fmistatus = fmi2_import_setup_experiment((fmi2_import_t*)fmu, fmi2_true, relativeTol, tStart, StopTimeDefined, tStop);
607 if(fmistatus != fmi2_status_ok) {
608 *error = ("fmi2_import_setup_experiment failed\n");
612 fmistatus = fmi2_import_enter_initialization_mode((fmi2_import_t*)fmu);
613 if(fmistatus != fmi2_status_ok) {
614 *error = ("fmi2_import_enter_initialization_mode failed\n");
618 fmistatus = fmi2_import_exit_initialization_mode((fmi2_import_t*)fmu);
619 if(fmistatus != fmi2_status_ok) {
620 *error = ("fmi2_import_exit_initialization_mode failed\n");
627 int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
629 fmi1_status_t status;
631 status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);
632 if (status == fmi1_status_error || status == fmi1_status_fatal) {
633 *error = "Error happened during stepping!";
639 int FMI2_CS_STEP(void *fmu, double masterTime, double stepSize, const char **error) {
641 fmi2_status_t status;
643 status = fmi2_import_do_step((fmi2_import_t *)fmu, (fmi2_real_t)masterTime, (fmi2_real_t)stepSize, fmi2_true);
644 if (status == fmi2_status_error || status == fmi2_status_fatal) {
645 *error = "Error happened during stepping!";
651 int FMI1_CS_SET_REAL(void *fmu, int valueId, double value, const char **error) {
653 fmi1_status_t status;
655 fmi1_value_reference_t vr = valueId;
656 status = fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);
657 if (status == fmi1_status_error || status == fmi1_status_fatal) {
658 *error = "Error happened during setting real value!";
664 int FMI2_CS_SET_REAL(void *fmu, int valueId, double value, const char **error) {
666 fmi2_status_t status;
668 fmi2_value_reference_t vr = valueId;
669 status = fmi2_import_set_real((fmi2_import_t *)fmu, &vr, 1, &value);
670 if (status == fmi2_status_error || status == fmi2_status_fatal) {
671 *error = "Error happened during setting real value!";
677 double FMI1_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
679 fmi1_value_reference_t vr = valueReference;
682 fmi1_status_t status;
684 status = fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);
685 if (status == fmi1_status_error || status == fmi1_status_fatal) {
686 *error = "Error happened during getting real value!";
691 double FMI2_CS_GET_REAL(void *fmu, int valueReference, const char **error) {
693 fmi2_value_reference_t vr = valueReference;
696 fmi2_status_t status;
698 status = fmi2_import_get_real((fmi2_import_t *)fmu, &vr, 1, &value);
699 if (status == fmi2_status_error || status == fmi2_status_fatal) {
700 *error = "Error happened during setting real value!";
705 int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
707 fmi1_value_reference_t *vrs = (fmi1_value_reference_t*) valueReferences;
710 fmi1_status_t status;
712 status = fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);
713 if (status == fmi1_status_error || status == fmi1_status_fatal) {
714 *error = "Error happened during getting reals value!";
719 int FMI2_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count, const char **error) {
721 fmi2_value_reference_t *vrs = (fmi2_value_reference_t*) valueReferences;
724 fmi2_status_t status;
726 status = fmi2_import_get_real((fmi2_import_t *)fmu, vrs, count, result);
727 if (status == fmi2_status_error || status == fmi2_status_fatal) {
728 *error = "Error happened during getting reals value!";