2 Copyright (C) 2012 Modelon AB
\r
4 This program is free software: you can redistribute it and/or modify
\r
5 it under the terms of the BSD style license.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
10 FMILIB_License.txt file for more details.
\r
12 You should have received a copy of the FMILIB_License.txt file
\r
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
\r
22 #include "config_test.h"
\r
24 #include <FMI/fmi_import_context.h>
\r
26 #include <FMI2/fmi2_import.h>
\r
30 int annotation_start_handle(void *context, const char *parentName, void *parent, const char *elm, const char **attr) {
\r
32 printf("Annotation element %s start (tool: %s, parent:%s)\n", elm, parentName,
\r
33 parent?fmi2_import_get_variable_name((fmi2_import_variable_t*)parent):"model");
\r
35 printf("Attribute %s = %s\n", attr[i], attr[i+1]);
\r
38 printf("Annotation data:\n");
\r
42 int annotation_data_handle(void* context, const char *s, int len) {
\r
44 for(i = 0; i < len; i++)
\r
49 int annotation_end_handle(void *context, const char *elm) {
\r
50 printf("\nAnnotation element %s end\n", elm);
\r
54 /** \brief XML callbacks are used to process parts of XML that are not handled by the library */
\r
55 fmi2_xml_callbacks_t annotation_callbacks = {
\r
56 annotation_start_handle,
\r
57 annotation_data_handle,
\r
58 annotation_end_handle, NULL};
\r
61 void do_exit(int code)
\r
63 printf("Press 'Enter' to exit\n");
\r
68 void mylogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
\r
70 printf("[%s][%s] %s\n", module, jm_log_level_to_string(log_level), message);
\r
71 if (!expect_error && log_level == jm_log_level_error) {
\r
76 void print_int(int i,void* data) {
\r
80 void print_dbl(double d,void* data) {
\r
84 void printTypeInfo(fmi2_import_variable_typedef_t* vt) {
\r
88 printf("No type definition\n");
\r
92 quan = fmi2_import_get_type_quantity(vt);
\r
94 printf("Type %s\n description: %s\n", fmi2_import_get_type_name(vt), fmi2_import_get_type_description(vt));
\r
96 printf("Base type: %s\n", fmi2_base_type_to_string(fmi2_import_get_base_type(vt)));
\r
99 printf("Quantity: %s\n", quan);
\r
101 switch(fmi2_import_get_base_type(vt)) {
\r
102 case fmi2_base_type_real: {
\r
103 fmi2_import_real_typedef_t* rt = fmi2_import_get_type_as_real(vt);
\r
104 fmi2_real_t min = fmi2_import_get_real_type_min(rt);
\r
105 fmi2_real_t max = fmi2_import_get_real_type_max(rt);
\r
106 fmi2_real_t nom = fmi2_import_get_real_type_nominal(rt);
\r
107 fmi2_import_unit_t* u = fmi2_import_get_real_type_unit(rt);
\r
108 fmi2_import_display_unit_t* du = fmi2_import_get_type_display_unit(rt);
\r
110 printf("Min %g, max %g, nominal %g\n", min, max, nom);
\r
114 fmi2_SI_base_unit_exp_to_string(fmi2_import_get_SI_unit_exponents(u), 1000, buf);
\r
115 printf("Unit: %s, base unit %s, factor %g, offset %g\n",
\r
116 fmi2_import_get_unit_name(u),
\r
118 fmi2_import_get_SI_unit_factor(u),
\r
119 fmi2_import_get_SI_unit_offset(u));
\r
122 printf("Display unit: %s, factor: %g, offset: %g, is relative: %s\n",
\r
123 fmi2_import_get_display_unit_name(du),
\r
124 fmi2_import_get_display_unit_factor(du),
\r
125 fmi2_import_get_display_unit_offset(du),
\r
126 fmi2_import_get_real_type_is_relative_quantity(rt)?"yes":"no"
\r
132 case fmi2_base_type_int:{
\r
133 fmi2_import_integer_typedef_t* it = fmi2_import_get_type_as_int(vt);
\r
134 int min = fmi2_import_get_integer_type_min(it);
\r
135 int max = fmi2_import_get_integer_type_max(it);
\r
136 printf("Min %d, max %d\n", min, max);
\r
139 case fmi2_base_type_bool:{
\r
142 case fmi2_base_type_str:{
\r
145 case fmi2_base_type_enum:{
\r
146 fmi2_import_enumeration_typedef_t* et = fmi2_import_get_type_as_enum(vt);
\r
147 int min = fmi2_import_get_enum_type_min(et);
\r
148 int max = fmi2_import_get_enum_type_max(et);
\r
149 printf("Min %d, max %d\n", min, max);
\r
152 ni = fmi2_import_get_enum_type_size(et);
\r
153 printf("There are %d items \n",ni);
\r
154 for(i = 1; i <= ni; i++) {
\r
155 int val = fmi2_import_get_enum_type_item_value(et, i);
\r
156 const char* str = fmi2_import_get_enum_type_value_name(et, val);
\r
157 const char* itnm = fmi2_import_get_enum_type_item_name(et, i);
\r
158 assert(strcmp(itnm, str)==0);
\r
159 printf("[%d] %s=%d (%s) \n", i,
\r
162 fmi2_import_get_enum_type_item_description(et, i));
\r
168 printf("Error in fmiGetBaseType()\n");
\r
173 void testVariableSearch(fmi2_import_t* fmu,
\r
174 fmi2_import_variable_t* v) {
\r
176 const char * a_name = fmi2_import_get_variable_name(v);
\r
177 fmi2_import_variable_t* found = fmi2_import_get_variable_by_name(fmu, a_name);
\r
179 printf("Searching by name %s found var %s\n", a_name, found?fmi2_import_get_variable_name(found):"nothing");
\r
183 printf("Searching by name worked fine\n");
\r
185 found = fmi2_import_get_variable_by_vr(fmu, fmi2_import_get_variable_base_type(v),fmi2_import_get_variable_vr(v));
\r
187 printf("Searching by vr failed for variable '%s'\n", a_name);
\r
190 else if(fmi2_import_get_variable_base_type(v) != fmi2_import_get_variable_base_type(found)) {
\r
191 printf("Searching %s found var %s", a_name, fmi2_import_get_variable_name(found));
\r
194 else if(fmi2_import_get_variable_vr(v) != fmi2_import_get_variable_vr(found)) {
\r
195 printf("Searching %s found var %s", a_name, fmi2_import_get_variable_name(found));
\r
199 printf("Searching by vr worked fine\n");
\r
203 void printVariableInfo(fmi2_import_t* fmu,
\r
204 fmi2_import_variable_t* v) {
\r
205 fmi2_base_type_enu_t bt;
\r
206 size_t vr = fmi2_import_get_variable_vr(v);
\r
207 assert(vr == (unsigned)vr);
\r
208 printf("Variable name: %s\n", fmi2_import_get_variable_name(v));
\r
209 printf("Description: %s\n", fmi2_import_get_variable_description(v));
\r
210 printf("VR: %u\n", (unsigned)vr);
\r
211 printf("Variability: %s\n", fmi2_variability_to_string(fmi2_import_get_variability(v)));
\r
212 printf("Causality: %s\n", fmi2_causality_to_string(fmi2_import_get_causality(v)));
\r
213 printf("Initial: %s\n", fmi2_initial_to_string(fmi2_import_get_initial(v)));
\r
215 bt = fmi2_import_get_variable_base_type(v);
\r
216 printf("Base type: %s\n", fmi2_base_type_to_string(bt));
\r
218 printTypeInfo(fmi2_import_get_variable_declared_type(v));
\r
219 if(bt == fmi2_base_type_real) {
\r
220 fmi2_import_real_variable_t *rv = fmi2_import_get_variable_as_real(v);
\r
221 fmi2_import_unit_t * u = fmi2_import_get_real_variable_unit(rv);
\r
222 fmi2_import_display_unit_t * du = fmi2_import_get_real_variable_display_unit(rv);
\r
223 printf("Unit: %s, display unit: %s\n", u ? fmi2_import_get_unit_name(u):0, du?fmi2_import_get_display_unit_name(du):"not provided");
\r
226 if(fmi2_import_get_variable_has_start(v)) {
\r
227 printf("There is a start value\n");
\r
229 switch(fmi2_import_get_variable_base_type(v)) {
\r
230 case fmi2_base_type_real: {
\r
231 fmi2_import_real_variable_t *rv = fmi2_import_get_variable_as_real(v);
\r
232 printf("start =%g\n", fmi2_import_get_real_variable_start(rv));
\r
235 case fmi2_base_type_int:{
\r
236 printf("start =%d\n", fmi2_import_get_integer_variable_start(fmi2_import_get_variable_as_integer(v)));
\r
239 case fmi2_base_type_bool:{
\r
240 printf("start = %d\n", fmi2_import_get_boolean_variable_start(fmi2_import_get_variable_as_boolean(v)));
\r
243 case fmi2_base_type_str:{
\r
244 printf("start = '%s'\n", fmi2_import_get_string_variable_start(fmi2_import_get_variable_as_string(v)));
\r
247 case fmi2_base_type_enum:{
\r
248 printf("start = %d\n", fmi2_import_get_enum_variable_start(fmi2_import_get_variable_as_enum(v)));
\r
252 printf("Error in fmiGetBaseType()\n");
\r
255 if(fmi2_import_get_variable_alias_kind(v) != fmi2_variable_is_not_alias) {
\r
256 printf("The variable is aliased to %s\n",
\r
257 fmi2_import_get_variable_name( fmi2_import_get_variable_alias_base(fmu, v)));
\r
260 printf("The variable is not an alias\n");
\r
263 fmi2_import_variable_list_t* vl = fmi2_import_get_variable_aliases(fmu, v);
\r
264 size_t i, n = fmi2_import_get_variable_list_size(vl);
\r
266 printf("Listing aliases: \n");
\r
268 printf("\t%s\n",fmi2_import_get_variable_name(fmi2_import_get_variable(vl, i)));
\r
270 fmi2_import_free_variable_list(vl);
\r
274 void printCapabilitiesInfo(fmi2_import_t* fmu) {
\r
277 for( i = 0; i < fmi2_capabilities_Num; ++i) {
\r
278 printf("%s = %u\n",
\r
279 fmi2_capability_to_string((fmi2_capabilities_enu_t)i),
\r
280 fmi2_import_get_capability(fmu, (fmi2_capabilities_enu_t)i));
\r
284 void printDependenciesInfo( fmi2_import_t* fmu, fmi2_import_variable_list_t* rows, fmi2_import_variable_list_t* cols, size_t* start, size_t *dep, char* factor) {
\r
286 if(!rows || !cols || !start) {
\r
287 printf("Dependencies are not available\n");
\r
289 nr = fmi2_import_get_variable_list_size(rows);
\r
290 for(i = 0; i < nr; i++) {
\r
291 printf("\t%s\n",fmi2_import_get_variable_name(fmi2_import_get_variable(rows, i)));
\r
296 nr = fmi2_import_get_variable_list_size(rows);
\r
297 for(i = 0; i < nr; i++) {
\r
298 if(start[i] == start[i+1]) {
\r
299 printf("\t%s has no dependencies\n",fmi2_import_get_variable_name(fmi2_import_get_variable(rows, i)));
\r
301 else if((start[i] + 1 == start[i+1]) && (dep[start[i]] == 0)) {
\r
302 printf("\t%s depends on all\n",fmi2_import_get_variable_name(fmi2_import_get_variable(rows, i)));
\r
305 printf("\t%s depends on:\n",fmi2_import_get_variable_name(fmi2_import_get_variable(rows, i)));
\r
306 for(j = start[i]; j < start[i+1]; j++) {
\r
307 printf("\t\t%s (factor kind: %s)\n",fmi2_import_get_variable_name(fmi2_import_get_variable(cols, dep[j]-1)),
\r
308 fmi2_dependency_factor_kind_to_string((fmi2_dependency_factor_kind_enu_t)factor[j]));
\r
314 int main(int argc, char *argv[])
\r
316 clock_t start, stop;
\r
318 const char* tmpPath;
\r
319 jm_callbacks callbacks;
\r
320 fmi_import_context_t* context;
\r
322 fmi2_import_t* fmu;
\r
325 printf("Usage: %s <path to a dir with modelDescription.xml>\n", argv[0]);
\r
330 expect_error = argc > 2;
\r
332 callbacks.malloc = malloc;
\r
333 callbacks.calloc = calloc;
\r
334 callbacks.realloc = realloc;
\r
335 callbacks.free = free;
\r
336 callbacks.logger = mylogger;
\r
337 callbacks.context = 0;
\r
338 callbacks.log_level = jm_log_level_debug;
\r
340 #ifdef FMILIB_GENERATE_BUILD_STAMP
\r
341 printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());
\r
344 context = fmi_import_allocate_context(&callbacks);
\r
347 fmu = fmi2_import_parse_xml(context, tmpPath, &annotation_callbacks);
\r
351 t = (double) (stop-start)/CLOCKS_PER_SEC;
\r
352 printf("Parsing took %g seconds\n", t);
\r
354 printf("Error parsing XML, exiting\n");
\r
355 fmi_import_free_context(context);
\r
359 printf("Model name: %s\n", fmi2_import_get_model_name(fmu));
\r
360 printf("Model GUID: %s\n", fmi2_import_get_GUID(fmu));
\r
361 printf("FMU kind: %s\n", fmi2_fmu_kind_to_string(fmi2_import_get_fmu_kind(fmu)));
\r
362 printf("Description: %s\n", fmi2_import_get_description(fmu));
\r
363 printf("Author: %s\n", fmi2_import_get_author(fmu));
\r
364 printf("FMI Version: %s\n", fmi2_import_get_model_standard_version(fmu));
\r
365 printf("Generation tool: %s\n", fmi2_import_get_generation_tool(fmu));
\r
366 printf("Generation date and time: %s\n", fmi2_import_get_generation_date_and_time(fmu));
\r
367 printf("Version: %s\n", fmi2_import_get_model_version(fmu));
\r
368 printf("Naming : %s\n", fmi2_naming_convention_to_string(fmi2_import_get_naming_convention(fmu)));
\r
370 if(fmi2_import_get_fmu_kind(fmu) != fmi2_fmu_kind_cs)
\r
371 printf("Model identifier ME: %s\n", fmi2_import_get_model_identifier_ME(fmu));
\r
372 if(fmi2_import_get_fmu_kind(fmu) != fmi2_fmu_kind_me)
\r
373 printf("Model identifier CS: %s\n", fmi2_import_get_model_identifier_CS(fmu));
\r
374 printCapabilitiesInfo(fmu);
\r
376 printf("NumberOfContinuousStates = " FMILIB_SIZET_FORMAT "\n", fmi2_import_get_number_of_continuous_states(fmu));
\r
377 printf("NumberOfEventIndicators = " FMILIB_SIZET_FORMAT "\n", fmi2_import_get_number_of_event_indicators(fmu));
\r
379 printf("Default experiment start = %g, end = %g, tolerance = %g, step = %g\n",
\r
380 fmi2_import_get_default_experiment_start(fmu),
\r
381 fmi2_import_get_default_experiment_stop(fmu),
\r
382 fmi2_import_get_default_experiment_tolerance(fmu),
\r
383 fmi2_import_get_default_experiment_step(fmu));
\r
386 int n_sources = fmi2_import_get_source_files_me_num(fmu);
\r
388 printf("There are %d source files for ME\n", n_sources);
\r
389 for (k=0; k < n_sources; k++) {
\r
390 printf("\t%s\n", fmi2_import_get_source_file_me(fmu, k));
\r
394 int n_sources = fmi2_import_get_source_files_cs_num(fmu);
\r
396 printf("There are %d source files for CS\n", n_sources);
\r
397 for (k=0; k < n_sources; k++) {
\r
398 printf("\t%s\n", fmi2_import_get_source_file_cs(fmu, k));
\r
404 size_t i, nv = fmi2_import_get_vendors_num(fmu);
\r
405 printf("There are %u tool annotation records \n", (unsigned)nv);
\r
406 for( i = 0; i < nv; i++) {
\r
407 printf("Vendor name [%u] %s", (unsigned)i, fmi2_import_get_vendor_name(fmu, i));
\r
411 fmi2_import_unit_definitions_t* ud = fmi2_import_get_unit_definitions(fmu);
\r
413 unsigned i, nu = fmi2_import_get_unit_definitions_number(ud);
\r
414 printf("There are %d different units used \n", nu);
\r
416 for(i = 0; i < nu; i++) {
\r
417 fmi2_import_unit_t* u = fmi2_import_get_unit(ud, i);
\r
420 printf("Error getting unit for index %d (%s)\n", i, fmi2_import_get_last_error(fmu));
\r
423 fmi2_SI_base_unit_exp_to_string(fmi2_import_get_SI_unit_exponents(u), 1000, buf);
\r
424 printf("Unit [%d] is %s, base unit %s, factor %g, offset %g, it has %d display units\n",
\r
425 i, fmi2_import_get_unit_name(u),
\r
427 fmi2_import_get_SI_unit_factor(u),
\r
428 fmi2_import_get_SI_unit_offset(u),
\r
429 fmi2_import_get_unit_display_unit_number(u));
\r
433 printf("Error getting unit definitions (%s)\n", fmi2_import_get_last_error(fmu));
\r
436 fmi2_import_type_definitions_t* td = fmi2_import_get_type_definitions(fmu);
\r
439 unsigned i, ntd = fmi2_import_get_type_definition_number(td);
\r
440 printf("There are %d defs\n", ntd);
\r
441 for(i = 0; i < ntd; i++) {
\r
442 fmi2_import_variable_typedef_t* vt = fmi2_import_get_typedef(td, i);
\r
444 printf("Error getting vartype for index %d (%s)\n", i, fmi2_import_get_last_error(fmu));
\r
452 printf("Error getting type definitions (%s)\n", fmi2_import_get_last_error(fmu));
\r
456 fmi2_import_variable_list_t* vl = fmi2_import_get_variable_list(fmu, 0);
\r
457 /* fmi2_import_variable_list_t* ders = fmi2_import_get_derivatives_list( fmu); */
\r
458 const fmi2_value_reference_t* vrl = fmi2_import_get_value_referece_list(vl);
\r
463 nv = fmi2_import_get_variable_list_size(vl);
\r
464 printf("There are %u variables in total \n",(unsigned)nv);
\r
465 for(i = 0; i < nv; i++) {
\r
466 fmi2_import_variable_t* var = fmi2_import_get_variable(vl, i);
\r
467 assert(vrl[i] == fmi2_import_get_variable_vr(var));
\r
469 printf("Something wrong with variable %u \n",(unsigned)i);
\r
473 printVariableInfo(fmu, var);
\r
474 /* size_t stateIndex = fmi2_import_get_state_index(var);
\r
476 printf("This variable is a state. Its derivative: %s\n",
\r
477 fmi2_import_get_variable_name(fmi2_import_get_variable(ders, stateIndex-1)));
\r
479 testVariableSearch(fmu, var);
\r
482 fmi2_import_free_variable_list(vl);
\r
483 /* fmi2_import_free_variable_list(ders); */
\r
486 fmi2_import_variable_list_t* vl = fmi2_import_get_inputs_list( fmu);
\r
489 n = fmi2_import_get_variable_list_size(vl);
\r
491 printf("Listing inputs: \n");
\r
492 for(i = 0;i<n;i++)
\r
493 printf("\t%s\n",fmi2_import_get_variable_name(fmi2_import_get_variable(vl, i)));
\r
496 printf("There are no inputs\n");
\r
498 fmi2_import_free_variable_list(vl);
\r
501 fmi2_import_variable_list_t* states = fmi2_import_get_states_list( fmu);
\r
502 fmi2_import_variable_list_t* inputs = fmi2_import_get_inputs_list( fmu);
\r
505 n = fmi2_import_get_variable_list_size(states);
\r
507 size_t *start, *dep;
\r
509 printf("Listing states and dependencies on inputs: \n");
\r
510 fmi2_import_get_dependencies_derivatives_on_inputs(fmu, &start, &dep, &factor);
\r
511 printDependenciesInfo( fmu, states, inputs, start, dep, factor);
\r
513 fmi2_import_get_dependencies_derivatives_on_states(fmu, &start, &dep, &factor);
\r
515 printf("Listing states and dependencies on other states: \n");
\r
516 printDependenciesInfo( fmu, states, states, start, dep, factor);
\r
519 printf("No dependencies on states available\n");
\r
523 printf("There are no states\n");
\r
525 fmi2_import_free_variable_list(inputs);
\r
526 fmi2_import_free_variable_list(states);
\r
529 fmi2_import_variable_list_t* states = fmi2_import_get_states_list( fmu);
\r
530 fmi2_import_variable_list_t* inputs = fmi2_import_get_inputs_list( fmu);
\r
531 fmi2_import_variable_list_t* outputs = fmi2_import_get_outputs_list( fmu);
\r
534 n = fmi2_import_get_variable_list_size(outputs);
\r
536 size_t *start, *dep;
\r
538 printf("Listing outputs and dependencies on inputs: \n");
\r
539 fmi2_import_get_dependencies_outputs_on_inputs(fmu, &start, &dep, &factor);
\r
540 printDependenciesInfo( fmu, outputs, inputs, start, dep, factor);
\r
542 fmi2_import_get_dependencies_outputs_on_states(fmu, &start, &dep, &factor);
\r
544 printf("Listing outputs and dependencies on states: \n");
\r
545 printDependenciesInfo( fmu, outputs, states, start, dep, factor);
\r
548 printf("No dependencies on states available\n");
\r
552 printf("There are no outputs\n");
\r
554 fmi2_import_free_variable_list(outputs);
\r
555 fmi2_import_free_variable_list(inputs);
\r
556 fmi2_import_free_variable_list(states);
\r
559 fmi2_import_free(fmu);
\r
560 fmi_import_free_context(context);
\r
562 printf("Everything seems to be OK since you got this far=)!\n");
\r