void fmi1_default_callback_logger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...) { va_list args; char buf[500], *curp; va_start (args, message); curp = buf; *curp = 0; if(instanceName) { sprintf(curp, "[%s]", instanceName); curp += strlen(instanceName)+2; } if(category) { sprintf(curp, "[%s]", category); curp += strlen(category)+2; } fprintf(stdout, "%s[status=%s]", buf, fmi1_status_to_string(status)); vfprintf (stdout, message, args); fprintf(stdout, "\n"); va_end (args); }
void* FMI2ModelExchangeConstructor_OMC(int fmi_log_level, char* working_directory, char* instanceName, int debugLogging) { FMI2ModelExchange* FMI2ME = malloc(sizeof(FMI2ModelExchange)); jm_status_enu_t status, instantiateModelStatus; FMI2ME->FMILogLevel = fmi_log_level; /* JM callbacks */ FMI2ME->JMCallbacks.malloc = malloc; FMI2ME->JMCallbacks.calloc = calloc; FMI2ME->JMCallbacks.realloc = realloc; FMI2ME->JMCallbacks.free = free; FMI2ME->JMCallbacks.logger = importlogger; FMI2ME->JMCallbacks.log_level = FMI2ME->FMILogLevel; FMI2ME->JMCallbacks.context = 0; FMI2ME->FMIImportContext = fmi_import_allocate_context(&FMI2ME->JMCallbacks); /* parse the xml file */ FMI2ME->FMIWorkingDirectory = (char*) malloc(strlen(working_directory)+1); strcpy(FMI2ME->FMIWorkingDirectory, working_directory); FMI2ME->FMIImportInstance = fmi2_import_parse_xml(FMI2ME->FMIImportContext, FMI2ME->FMIWorkingDirectory, NULL); if(!FMI2ME->FMIImportInstance) { FMI2ME->FMISolvingMode = fmi2_none_mode; ModelicaFormatError("Error parsing the XML file contained in %s\n", FMI2ME->FMIWorkingDirectory); return 0; } /* FMI callback functions */ FMI2ME->FMICallbackFunctions.logger = fmi2logger; FMI2ME->FMICallbackFunctions.allocateMemory = calloc; FMI2ME->FMICallbackFunctions.freeMemory = free; FMI2ME->FMICallbackFunctions.componentEnvironment = FMI2ME->FMIImportInstance; /* Load the binary (dll/so) */ status = fmi2_import_create_dllfmu(FMI2ME->FMIImportInstance, fmi2_import_get_fmu_kind(FMI2ME->FMIImportInstance), &FMI2ME->FMICallbackFunctions); if (status == jm_status_error) { FMI2ME->FMISolvingMode = fmi2_none_mode; ModelicaFormatError("Loading of FMU dynamic link library failed with status : %s\n", jm_log_level_to_string(status)); return 0; } FMI2ME->FMIInstanceName = (char*) malloc(strlen(instanceName)+1); strcpy(FMI2ME->FMIInstanceName, instanceName); FMI2ME->FMIDebugLogging = debugLogging; instantiateModelStatus = fmi2_import_instantiate(FMI2ME->FMIImportInstance, FMI2ME->FMIInstanceName, fmi2_model_exchange, NULL, fmi2_false); if (instantiateModelStatus == jm_status_error) { FMI2ME->FMISolvingMode = fmi2_none_mode; ModelicaFormatError("fmi2InstantiateModel failed with status : %s\n", jm_log_level_to_string(instantiateModelStatus)); return 0; } /* Only call fmi2SetDebugLogging if debugLogging is true */ if (FMI2ME->FMIDebugLogging) { int i; size_t categoriesSize = 0; fmi2_status_t debugLoggingStatus; fmi2_string_t *categories; /* Read the log categories size */ categoriesSize = fmi2_import_get_log_categories_num(FMI2ME->FMIImportInstance); categories = (fmi2_string_t*)malloc(categoriesSize*sizeof(fmi2_string_t)); for (i = 0 ; i < categoriesSize ; i++) { categories[i] = fmi2_import_get_log_category(FMI2ME->FMIImportInstance, i); } debugLoggingStatus = fmi2_import_set_debug_logging(FMI2ME->FMIImportInstance, FMI2ME->FMIDebugLogging, categoriesSize, categories); if (debugLoggingStatus != fmi2_status_ok && debugLoggingStatus != fmi2_status_warning) { ModelicaFormatMessage("fmi2SetDebugLogging failed with status : %s\n", fmi1_status_to_string(debugLoggingStatus)); } } FMI2ME->FMIToleranceControlled = fmi2_true; FMI2ME->FMIRelativeTolerance = 0.001; FMI2ME->FMIEventInfo = malloc(sizeof(fmi2_event_info_t)); FMI2ME->FMISolvingMode = fmi2_instantiated_mode; return FMI2ME; }
jm_status_enu_t fmi1_cs_simulate(fmu_check_data_t* cdata) { fmi1_status_t fmistatus; jm_status_enu_t jmstatus = jm_status_success; jm_callbacks* cb = &cdata->callbacks; fmi1_import_t* fmu = cdata->fmu1; fmi1_string_t fmuGUID = fmi1_import_get_GUID(fmu); fmi1_string_t mimeType; fmi1_real_t timeout = 0.0; fmi1_boolean_t visible = fmi1_false; fmi1_boolean_t interactive = fmi1_false; fmi1_real_t tstart = fmi1_import_get_default_experiment_start(fmu); fmi1_real_t tcur = tstart; fmi1_real_t hstep; fmi1_real_t tend = fmi1_import_get_default_experiment_stop(fmu); fmi1_boolean_t StopTimeDefined = fmi1_true; mimeType = fmi1_import_get_mime_type(fmu); if( (cdata->fmu1_kind == fmi1_fmu_kind_enu_cs_standalone) || !mimeType || !mimeType[0]) { mimeType = "application/x-fmu-sharedlibrary"; } else { if( strcmp(mimeType, "application/x-fmu-sharedlibrary") != 0 ) { jm_log_info(cb, fmu_checker_module,"The FMU requests simulator with MIME type '%s'.", mimeType); printf("\nPlease, start a simulator program for MIME type '%s'\nPress enter to continue.\n", mimeType); getchar(); } } if(cdata->stopTime > 0) { tend = cdata->stopTime; } if(cdata->stepSize > 0) { hstep = cdata->stepSize; } else { hstep = (tend - tstart) / cdata->numSteps; } cdata->instanceName = "Test FMI 1.0 CS"; jm_log_verbose(cb, fmu_checker_module, "Checker will instantiate the slave with \n" "\tFMU location ='%s'\n\tMIME type = '%s'", cdata->fmuLocation, mimeType); jmstatus = fmi1_import_instantiate_slave(fmu, cdata->instanceName, cdata->fmuLocation, mimeType, timeout, visible, interactive); if (jmstatus == jm_status_error) { jm_log_fatal(cb, fmu_checker_module, "Could not instantiate the model"); return jm_status_error; } fmistatus = fmi1_import_initialize_slave(fmu, tstart, StopTimeDefined, tend); if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) { jm_log_info(cb, fmu_checker_module, "Initialized FMU for simulation starting at time %g", tstart); fmistatus = fmi1_status_ok; } else { jm_log_fatal(cb, fmu_checker_module, "Failed to initialize FMU for simulation (FMU status: %s)", fmi1_status_to_string(fmistatus)); jmstatus = jm_status_error; } if(jmstatus != jm_status_error) { jm_log_verbose(cb, fmu_checker_module, "Writing simulation output for start time"); if(fmi1_write_csv_data(cdata, tstart) != jm_status_success){ jmstatus = jm_status_error; } } while ((tcur < tend) && (jmstatus != jm_status_error)) { fmi1_boolean_t newStep = fmi1_true; fmi1_real_t tnext = tcur + hstep; if(tnext > tend - 1e-3*hstep) { /* last step should be on tend */ hstep = tend - tcur; tnext = tend; } jm_log_verbose(cb, fmu_checker_module, "Simulation step from time: %g until: %g", tcur, tnext); fmistatus = fmi1_import_do_step(fmu, tcur, hstep, newStep); tcur = tnext; if(fmi1_write_csv_data(cdata, tcur) != jm_status_success){ jmstatus = jm_status_error; } if((fmistatus == fmi1_status_ok) || (fmistatus == fmi1_status_warning)) { fmistatus = fmi1_status_ok; } else jmstatus = jm_status_error; } if((fmistatus != fmi1_status_ok) && (fmistatus != fmi1_status_warning)) { jm_log_fatal(cb, fmu_checker_module, "Simulation loop terminated at time %g since FMU returned status: %s", tcur, fmi1_status_to_string(fmistatus)); jmstatus = jm_status_error; } else if(jmstatus != jm_status_error) { jm_log_info(cb, fmu_checker_module, "Simulation finished successfully at time %g", tcur); } fmistatus = fmi1_import_terminate_slave(fmu); if( fmistatus != fmi1_status_ok) { jm_log_error(cb, fmu_checker_module, "fmiTerminateSlave returned status: %s", fmi1_status_to_string(fmistatus)); } fmi1_import_free_slave_instance(fmu); return jmstatus; }
void fmi1_log_forwarding_v(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, va_list args) { char buf[50000], *curp; const char* statusStr; fmi1_import_t* fmu = 0; jm_callbacks* cb = jm_get_default_callbacks(); jm_log_level_enu_t logLevel = jm_log_level_error; if(fmi1_import_active_fmu) { size_t n = jm_vector_get_size(jm_voidp)(fmi1_import_active_fmu); size_t i; for(i= 0; i < n; i++) { fmu = (fmi1_import_t*)jm_vector_get_item(jm_voidp)(fmi1_import_active_fmu, i); if(fmu->capi->c == c) { cb = fmu->callbacks; break; } } if(i >= n) { /* Could not find matching FMU -> use default callbacks */ fmu = 0; cb = jm_get_default_callbacks(); } } switch(status) { case fmi1_status_discard: case fmi1_status_pending: case fmi1_status_ok: logLevel = jm_log_level_info; break; case fmi1_status_warning: logLevel = jm_log_level_warning; break; case fmi1_status_error: logLevel = jm_log_level_error; break; case fmi1_status_fatal: default: logLevel = jm_log_level_fatal; } if(logLevel > cb->log_level) return; curp = buf; *curp = 0; if(category) { sprintf(curp, "[%s]", category); curp += strlen(category)+2; } statusStr = fmi1_status_to_string(status); sprintf(curp, "[FMU status:%s] ", statusStr); curp += strlen(statusStr) + strlen("[FMU status:] "); vsprintf(curp, message, args); if(fmu) { fmi1_import_expand_variable_references(fmu, buf, cb->errMessageBuffer,JM_MAX_ERROR_MESSAGE_SIZE); } else { strncpy(cb->errMessageBuffer, buf, JM_MAX_ERROR_MESSAGE_SIZE); cb->errMessageBuffer[JM_MAX_ERROR_MESSAGE_SIZE - 1] = '\0'; } if(cb->logger) { cb->logger(cb, instanceName, logLevel, cb->errMessageBuffer); } }