EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { PROPERTYTYPE p; if(sizeof(void *) == sizeof(int32)) p = PT_int32; if(sizeof(void *) == sizeof(int64)) p = PT_int64; // set the GridLAB core API callback table callback = fntable; gl_global_create("glmjava::classpath",PT_char256,get_classpath(),NULL); gl_global_create("glmjava::libpath",PT_char256,get_libpath(),NULL); gl_global_create("glmjava::jcallback",p,get_jcb(),PT_ACCESS,PA_REFERENCE,NULL); // default values strcpy(get_classpath(), "Win32/Debug/"); strcpy(get_libpath(), "Win32/Debug/"); // if(get_jvm() == NULL){ // gl_error("Unable to initialize JVM in java->init()"); // return NULL; // } // very nonstandard. return new_holder(module); }
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { if (set_callback(fntable)==NULL) { errno = EINVAL; return NULL; } pGlobalClock = fntable->global_clock; gl_global_getvar("execdir",libpath,sizeof(libpath)); strcat(libpath,"/plc/lib"); gl_global_create("plc::libpath",PT_char1024,libpath,NULL); gl_global_getvar("execdir",incpath,sizeof(incpath)); strcat(incpath,"/plc/include"); gl_global_create("plc::incpath",PT_char1024,incpath,NULL); new plc(module); new comm(module); /* always return the first class registered */ return plc::oclass; }
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { if (set_callback(fntable)==NULL) { errno = EINVAL; return NULL; } Socket::init(); gl_global_create("connection::security",PT_enumeration,&connection_security, PT_DESCRIPTION, "default connection security level", PT_KEYWORD, "NONE", (enumeration)CS_NONE, PT_KEYWORD, "LOW", (enumeration)CS_LOW, PT_KEYWORD, "STANDARD", (enumeration)CS_STANDARD, PT_KEYWORD, "HIGH", (enumeration)CS_HIGH, PT_KEYWORD, "EXTREME", (enumeration)CS_EXTREME, PT_KEYWORD, "PARANOID", (enumeration)CS_PARANOID, NULL); gl_global_create("connection::lockout",PT_double,&connection_lockout, PT_UNITS, "s", PT_DESCRIPTION, "default connection security lockout time", NULL); gl_global_create("connection::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the connection module",NULL); new native(module); // new xml(module); // TODO finish XML implementation new json(module); #if HAVE_FNCS new fncs_msg(module); #endif // TODO add new classes before this line /* always return the first class registered */ return native::oclass; }
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { if (set_callback(fntable)==NULL) { errno = EINVAL; return NULL; } gl_global_create("residential::default_line_voltage",PT_complex,&default_line_voltage,PT_SIZE,3,PT_UNITS,"V",PT_DESCRIPTION,"line voltage to use when no circuit is attached",NULL); gl_global_create("residential::default_line_current",PT_complex,&default_line_current,PT_SIZE,3,PT_UNITS,"A",PT_DESCRIPTION,"line current calculated when no circuit is attached",NULL); gl_global_create("residential::default_outdoor_temperature",PT_double,&default_outdoor_temperature,PT_UNITS,"degF",PT_DESCRIPTION,"outdoor air temperature when no climate data is found",NULL); gl_global_create("residential::default_humidity",PT_double,&default_humidity,PT_UNITS,"%",PT_DESCRIPTION,"humidity when no climate data is found",NULL); gl_global_create("residential::default_solar",PT_double,&default_solar,PT_SIZE,9,PT_UNITS,"Btu/sf",PT_DESCRIPTION,"solar gains when no climate data is found",NULL); gl_global_create("residential::default_etp_iterations",PT_int64,&default_etp_iterations,PT_DESCRIPTION,"number of iterations ETP solver will run",NULL); gl_global_create("residential::ANSI_voltage_check",PT_bool,&ANSI_voltage_check,PT_DESCRIPTION,"enable or disable messages about ANSI voltage limit violations in the house",NULL); new residential_enduse(module); new appliance(module); // obsolete as of 3.0: new house(module); new house_e(module); new waterheater(module); new lights(module); new refrigerator(module); new clotheswasher(module); new dishwasher(module); new occupantload(module); new plugload(module); new microwave(module); new range(module); new freezer(module); new dryer(module); new evcharger(module); new ZIPload(module); new thermal_storage(module); new evcharger_det(module); new soil_sensor(module); /* always return the first class registered */ return residential_enduse::oclass; }
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { if (!set_callback(fntable)) { errno = EINVAL; return NULL; } /* exported globals */ gl_global_create("powerflow::show_matrix_values",PT_bool,&show_matrix_values,NULL); gl_global_create("powerflow::primary_voltage_ratio",PT_double,&primary_voltage_ratio,NULL); gl_global_create("powerflow::nominal_frequency",PT_double,&nominal_frequency,NULL); gl_global_create("powerflow::require_voltage_control", PT_bool,&require_voltage_control,NULL); gl_global_create("powerflow::geographic_degree",PT_double,&geographic_degree,NULL); gl_global_create("powerflow::fault_impedance",PT_complex,&fault_Z,NULL); gl_global_create("powerflow::warning_underfrequency",PT_double,&warning_underfrequency,NULL); gl_global_create("powerflow::warning_overfrequency",PT_double,&warning_overfrequency,NULL); gl_global_create("powerflow::warning_undervoltage",PT_double,&warning_undervoltage,NULL); gl_global_create("powerflow::warning_overvoltage",PT_double,&warning_overvoltage,NULL); gl_global_create("powerflow::warning_voltageangle",PT_double,&warning_voltageangle,NULL); gl_global_create("powerflow::maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL); gl_global_create("powerflow::solver_method",PT_enumeration,&solver_method, PT_KEYWORD,"FBS",SM_FBS, PT_KEYWORD,"GS",SM_GS, PT_KEYWORD,"NR",SM_NR, NULL); gl_global_create("powerflow::lu_solver",PT_char256,&LUSolverName,NULL); gl_global_create("powerflow::acceleration_factor",PT_double,&acceleration_factor,NULL); gl_global_create("powerflow::NR_iteration_limit",PT_int64,&NR_iteration_limit,NULL); gl_global_create("powerflow::NR_superLU_procs",PT_int32,&NR_superLU_procs,NULL); gl_global_create("powerflow::default_maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL); // register each object class by creating the default instance new powerflow_object(module); new powerflow_library(module); new node(module); new link(module); new capacitor(module); new fuse(module); new meter(module); new line(module); new line_spacing(module); new overhead_line(module); new underground_line(module); new overhead_line_conductor(module); new underground_line_conductor(module); new line_configuration(module); new relay(module); new transformer_configuration(module); new transformer(module); new load(module); new regulator_configuration(module); new regulator(module); new triplex_node(module); new triplex_meter(module); new triplex_line(module); new triplex_line_configuration(module); new triplex_line_conductor(module); new switch_object(module); new substation(module); new pqload(module); new voltdump(module); new series_reactor(module); new restoration(module); new frequency_gen(module); new volt_var_control(module); new fault_check(module); new motor(module); new billdump(module); new power_metrics(module); new currdump(module); new recloser(module); new sectionalizer(module); new emissions(module); /* always return the first class registered */ return node::oclass; }
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[]) { if (!set_callback(fntable)) { errno = EINVAL; return NULL; } /* exported globals */ gl_global_create("powerflow::show_matrix_values",PT_bool,&show_matrix_values,NULL); gl_global_create("powerflow::primary_voltage_ratio",PT_double,&primary_voltage_ratio,NULL); gl_global_create("powerflow::nominal_frequency",PT_double,&nominal_frequency,NULL); gl_global_create("powerflow::require_voltage_control", PT_bool,&require_voltage_control,NULL); gl_global_create("powerflow::geographic_degree",PT_double,&geographic_degree,NULL); gl_global_create("powerflow::fault_impedance",PT_complex,&fault_Z,NULL); gl_global_create("powerflow::warning_underfrequency",PT_double,&warning_underfrequency,NULL); gl_global_create("powerflow::warning_overfrequency",PT_double,&warning_overfrequency,NULL); gl_global_create("powerflow::warning_undervoltage",PT_double,&warning_undervoltage,NULL); gl_global_create("powerflow::warning_overvoltage",PT_double,&warning_overvoltage,NULL); gl_global_create("powerflow::warning_voltageangle",PT_double,&warning_voltageangle,NULL); gl_global_create("powerflow::maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL); gl_global_create("powerflow::solver_method",PT_enumeration,&solver_method, PT_KEYWORD,"FBS",SM_FBS, PT_KEYWORD,"GS",SM_GS, PT_KEYWORD,"NR",SM_NR, NULL); gl_global_create("powerflow::line_capacitance",PT_bool,&use_line_cap,NULL); gl_global_create("powerflow::line_limits",PT_bool,&use_link_limits,NULL); gl_global_create("powerflow::lu_solver",PT_char256,&LUSolverName,NULL); gl_global_create("powerflow::NR_iteration_limit",PT_int64,&NR_iteration_limit,NULL); gl_global_create("powerflow::NR_superLU_procs",PT_int32,&NR_superLU_procs,NULL); gl_global_create("powerflow::default_maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL); gl_global_create("powerflow::default_maximum_power_error",PT_double,&default_maximum_power_error,NULL); gl_global_create("powerflow::NR_admit_change",PT_bool,&NR_admit_change,NULL); gl_global_create("powerflow::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the powerflow module",NULL); gl_global_create("powerflow::all_powerflow_delta", PT_bool, &all_powerflow_delta,PT_DESCRIPTION,"Forces all powerflow objects that are capable to participate in deltamode",NULL); gl_global_create("powerflow::deltamode_timestep", PT_double, &deltamode_timestep_publish,PT_UNITS,"ns",PT_DESCRIPTION,"Desired minimum timestep for deltamode-related simulations",NULL); gl_global_create("powerflow::deltamode_extra_function", PT_int64, &deltamode_extra_function,NULL); gl_global_create("powerflow::current_frequency",PT_double,¤t_frequency,PT_UNITS,"Hz",PT_DESCRIPTION,"Current system-level frequency of the powerflow system",NULL); gl_global_create("powerflow::master_frequency_update",PT_bool,&master_frequency_update,PT_DESCRIPTION,"Tracking variable to see if an object has become the system frequency updater",NULL); gl_global_create("powerflow::enable_frequency_dependence",PT_bool,&enable_frequency_dependence,PT_DESCRIPTION,"Flag to enable frequency-based variations in impedance values of lines and loads",NULL); gl_global_create("powerflow::default_resistance",PT_double,&default_resistance,NULL); // register each object class by creating the default instance new powerflow_object(module); new powerflow_library(module); new node(module); new link_object(module); new capacitor(module); new fuse(module); new meter(module); new line(module); new line_spacing(module); new overhead_line(module); new underground_line(module); new overhead_line_conductor(module); new underground_line_conductor(module); new line_configuration(module); new transformer_configuration(module); new transformer(module); new load(module); new regulator_configuration(module); new regulator(module); new triplex_node(module); new triplex_meter(module); new triplex_line(module); new triplex_line_configuration(module); new triplex_line_conductor(module); new switch_object(module); new substation(module); new pqload(module); new voltdump(module); new series_reactor(module); new restoration(module); new frequency_gen(module); new volt_var_control(module); new fault_check(module); new motor(module); new billdump(module); new power_metrics(module); new currdump(module); new recloser(module); new sectionalizer(module); new emissions(module); new load_tracker(module); new triplex_load(module); /* always return the first class registered */ return node::oclass; }
// the constructor registers the class and properties and sets the defaults triplex_meter::triplex_meter(MODULE *mod) : triplex_node(mod) { // first time init if (oclass==NULL) { // link to parent class (used by isa) pclass = triplex_node::oclass; // register the class definition oclass = gl_register_class(mod,"triplex_meter",sizeof(triplex_meter),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK); if (oclass==NULL) throw "unable to register class triplex_meter"; else oclass->trl = TRL_PROVEN; // publish the class properties if (gl_publish_variable(oclass, PT_INHERIT, "triplex_node", PT_double, "measured_real_energy[Wh]", PADDR(measured_real_energy),PT_DESCRIPTION,"metered real energy consumption", PT_double, "measured_reactive_energy[VAh]",PADDR(measured_reactive_energy),PT_DESCRIPTION,"metered reactive energy consumption", PT_complex, "measured_power[VA]", PADDR(measured_power),PT_DESCRIPTION,"metered power", PT_complex, "indiv_measured_power_1[VA]", PADDR(indiv_measured_power[0]),PT_DESCRIPTION,"metered power, phase 1", PT_complex, "indiv_measured_power_2[VA]", PADDR(indiv_measured_power[1]),PT_DESCRIPTION,"metered power, phase 2", PT_complex, "indiv_measured_power_N[VA]", PADDR(indiv_measured_power[2]),PT_DESCRIPTION,"metered power, phase N", PT_double, "measured_demand[W]", PADDR(measured_demand),PT_DESCRIPTION,"metered demand (peak of power)", PT_double, "measured_real_power[W]", PADDR(measured_real_power),PT_DESCRIPTION,"metered real power", PT_double, "measured_reactive_power[VAr]", PADDR(measured_reactive_power),PT_DESCRIPTION,"metered reactive power", PT_complex, "meter_power_consumption[VA]", PADDR(tpmeter_power_consumption),PT_DESCRIPTION,"power consumed by meter operation", // added to record last voltage/current PT_complex, "measured_voltage_1[V]", PADDR(measured_voltage[0]),PT_DESCRIPTION,"measured voltage, phase 1 to ground", PT_complex, "measured_voltage_2[V]", PADDR(measured_voltage[1]),PT_DESCRIPTION,"measured voltage, phase 2 to ground", PT_complex, "measured_voltage_N[V]", PADDR(measured_voltage[2]),PT_DESCRIPTION,"measured voltage, phase N to ground", PT_complex, "measured_current_1[A]", PADDR(measured_current[0]),PT_DESCRIPTION,"measured current, phase 1", PT_complex, "measured_current_2[A]", PADDR(measured_current[1]),PT_DESCRIPTION,"measured current, phase 2", PT_complex, "measured_current_N[A]", PADDR(measured_current[2]),PT_DESCRIPTION,"measured current, phase N", PT_bool, "customer_interrupted", PADDR(tpmeter_interrupted),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in an interrupted state", PT_bool, "customer_interrupted_secondary", PADDR(tpmeter_interrupted_secondary),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in a secondary interrupted state - i.e., momentary", #ifdef SUPPORT_OUTAGES PT_int16, "sustained_count", PADDR(sustained_count),PT_DESCRIPTION,"reliability sustained event counter", PT_int16, "momentary_count", PADDR(momentary_count),PT_DESCRIPTION,"reliability momentary event counter", PT_int16, "total_count", PADDR(total_count),PT_DESCRIPTION,"reliability total event counter", PT_int16, "s_flag", PADDR(s_flag),PT_DESCRIPTION,"reliability flag that gets set if the meter experienced more than n sustained interruptions", PT_int16, "t_flag", PADDR(t_flag),PT_DESCRIPTION,"reliability flage that gets set if the meter experienced more than n events total", PT_complex, "pre_load", PADDR(pre_load),PT_DESCRIPTION,"the load prior to being interrupted", #endif PT_double, "monthly_bill[$]", PADDR(monthly_bill),PT_DESCRIPTION,"Accumulator for the current month's bill", PT_double, "previous_monthly_bill[$]", PADDR(previous_monthly_bill),PT_DESCRIPTION,"Total monthly bill for the previous month", PT_double, "previous_monthly_energy[kWh]", PADDR(previous_monthly_energy),PT_DESCRIPTION,"", PT_double, "monthly_fee[$]", PADDR(monthly_fee),PT_DESCRIPTION,"Total monthly energy for the previous month", PT_double, "monthly_energy[kWh]", PADDR(monthly_energy),PT_DESCRIPTION,"Accumulator for the current month's energy", PT_enumeration, "bill_mode", PADDR(bill_mode),PT_DESCRIPTION,"Designates the bill mode to be used", PT_KEYWORD,"NONE",(enumeration)BM_NONE, PT_KEYWORD,"UNIFORM",(enumeration)BM_UNIFORM, PT_KEYWORD,"TIERED",(enumeration)BM_TIERED, PT_KEYWORD,"HOURLY",(enumeration)BM_HOURLY, PT_KEYWORD,"TIERED_RTP",(enumeration)BM_TIERED_RTP, PT_object, "power_market", PADDR(power_market),PT_DESCRIPTION,"Designates the auction object where prices are read from for bill mode", PT_int32, "bill_day", PADDR(bill_day),PT_DESCRIPTION,"Day bill is to be processed (assumed to occur at midnight of that day)", PT_double, "price[$/kWh]", PADDR(price),PT_DESCRIPTION,"Standard uniform pricing", PT_double, "price_base[$/kWh]", PADDR(price_base), PT_DESCRIPTION, "Used only in TIERED_RTP mode to describe the price before the first tier", PT_double, "first_tier_price[$/kWh]", PADDR(tier_price[0]),PT_DESCRIPTION,"first tier price of energy between first and second tier energy", PT_double, "first_tier_energy[kWh]", PADDR(tier_energy[0]),PT_DESCRIPTION,"price of energy on tier above price or price base", PT_double, "second_tier_price[$/kWh]", PADDR(tier_price[1]),PT_DESCRIPTION,"first tier price of energy between second and third tier energy", PT_double, "second_tier_energy[kWh]", PADDR(tier_energy[1]),PT_DESCRIPTION,"price of energy on tier above first tier", PT_double, "third_tier_price[$/kWh]", PADDR(tier_price[2]),PT_DESCRIPTION,"first tier price of energy greater than third tier energy", PT_double, "third_tier_energy[kWh]", PADDR(tier_energy[2]),PT_DESCRIPTION,"price of energy on tier above second tier", NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__); //Deltamode functions if (gl_publish_function(oclass, "delta_linkage_node", (FUNCTIONADDR)delta_linkage)==NULL) GL_THROW("Unable to publish triplex_meter delta_linkage function"); if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_triplex_meter)==NULL) GL_THROW("Unable to publish triplex_meter deltamode function"); if (gl_publish_function(oclass, "delta_freq_pwr_object", (FUNCTIONADDR)delta_frequency_node)==NULL) GL_THROW("Unable to publish triplex_meter deltamode function"); // market price name gl_global_create("powerflow::market_price_name",PT_char1024,&market_price_name,NULL); } }
EXPORT bool glx_init(glxlink *mod) { gl_verbose("initializing matlab link"); gl_verbose("PATH=%s", getenv("PATH")); // initialize matlab engine MATLABLINK *matlab = (MATLABLINK*)mod->get_data(); matlab->status = 0; #ifdef WIN32 if ( matlab->command ) matlab->engine = engOpen(matlab->command); else matlab->engine = engOpenSingleUse(NULL,NULL,&matlab->status); if ( matlab->engine==NULL ) { gl_error("matlab engine start failed, status code is '%d'", matlab->status); return false; } #else matlab->engine = engOpen(matlab->command); if ( matlab->engine==NULL ) { gl_error("matlab engine start failed"); return false; } #endif // set the output buffer if ( matlab->output_buffer!=NULL ) engOutputBuffer(matlab->engine,matlab->output_buffer,(int)matlab->output_size); // setup matlab engine engSetVisible(matlab->engine,window_show(matlab)); gl_debug("matlab link is open"); // special values needed by matlab mxArray *ts_never = mxCreateDoubleScalar((double)(TIMESTAMP)TS_NEVER); engPutVariable(matlab->engine,"TS_NEVER",ts_never); mxArray *ts_error = mxCreateDoubleScalar((double)(TIMESTAMP)TS_INVALID); engPutVariable(matlab->engine,"TS_ERROR",ts_error); mxArray *gld_ok = mxCreateDoubleScalar((double)(bool)true); engPutVariable(matlab->engine,"GLD_OK",gld_ok); mxArray *gld_err = mxCreateDoubleScalar((double)(bool)false); engPutVariable(matlab->engine,"GLD_ERROR",gld_err); // set the workdir if ( strcmp(matlab->workdir,"")!=0 ) { #ifdef WIN32 _mkdir(matlab->workdir); #else mkdir(matlab->workdir,0750); #endif if ( matlab->workdir[0]=='/' ) matlab_exec(matlab,"cd '%s'", matlab->workdir); else matlab_exec(matlab,"cd '%s/%s'", getcwd(NULL,0),matlab->workdir); } // run the initialization command(s) if ( matlab->init ) { mxArray *ans = matlab_exec(matlab,"%s",matlab->init); if ( ans && mxIsDouble(ans) && (bool)*mxGetPr(ans)==false ) { gl_error("matlab init failed"); return false; } else if ( ans && mxIsChar(ans) ) { int buflen = (mxGetM(ans) * mxGetN(ans)) + 1; char *string =(char*)malloc(buflen); int status_error = mxGetString(ans, string, buflen); if (status_error == 0) { gl_error("'%s'",string); return false; } else { gl_error("Did not catch Matlab error"); return false; } } } if ( matlab->rootname!=NULL ) { // build gridlabd data mwSize dims[] = {1,1}; mxArray *gridlabd_struct = mxCreateStructArray(2,dims,0,NULL); /////////////////////////////////////////////////////////////////////////// // build global data LINKLIST *item; mxArray *global_struct = mxCreateStructArray(2,dims,0,NULL); for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) ) { char *name = mod->get_name(item); GLOBALVAR *var = mod->get_globalvar(item); mxArray *var_struct = NULL; mwIndex var_index; if ( var==NULL ) continue; // do not map module or structured globals if ( strchr(var->prop->name,':')!=NULL ) { // ignore module globals here } else if ( strchr(var->prop->name,'.')!=NULL ) { char struct_name[256]; if ( sscanf(var->prop->name,"%[^.]",struct_name)==0 ) { gld_property prop(var); var_index = mxAddField(global_struct,prop.get_name()); var_struct = matlab_create_value(&prop); if ( var_struct!=NULL ) { //mod->add_copyto(var->prop->addr,mxGetData(var_struct)); mxSetFieldByNumber(global_struct,0,var_index,var_struct); } } } else // simple data { gld_property prop(var); var_index = mxAddField(global_struct,prop.get_name()); var_struct = matlab_create_value(&prop); if ( var_struct!=NULL ) { //mod->add_copyto(var->prop->addr,mxGetData(var_struct)); mxSetFieldByNumber(global_struct,0,var_index,var_struct); } } // update export list if ( var_struct!=NULL ) { mod->set_addr(item,(void*)var_struct); mod->set_index(item,(size_t)var_index); } } // add globals structure to gridlabd structure mwIndex gridlabd_index = mxAddField(gridlabd_struct,"global"); mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,global_struct); /////////////////////////////////////////////////////////////////////////// // build module data dims[0] = dims[1] = 1; mxArray *module_struct = mxCreateStructArray(2,dims,0,NULL); // add modules for ( MODULE *module = callback->module.getfirst() ; module!=NULL ; module=module->next ) { // create module info struct mwIndex dims[] = {1,1}; mxArray *module_data = mxCreateStructArray(2,dims,0,NULL); mwIndex module_index = mxAddField(module_struct,module->name); mxSetFieldByNumber(module_struct,0,module_index,module_data); // create version info struct const char *version_fields[] = {"major","minor"}; mxArray *version_data = mxCreateStructArray(2,dims,sizeof(version_fields)/sizeof(version_fields[0]),version_fields); mxArray *major_data = mxCreateDoubleScalar((double)module->major); mxArray *minor_data = mxCreateDoubleScalar((double)module->minor); mxSetFieldByNumber(version_data,0,0,major_data); mxSetFieldByNumber(version_data,0,1,minor_data); // attach version info to module info mwIndex version_index = mxAddField(module_data,"version"); mxSetFieldByNumber(module_data,0,version_index,version_data); } gridlabd_index = mxAddField(gridlabd_struct,"module"); mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,module_struct); /////////////////////////////////////////////////////////////////////////// // build class data dims[0] = dims[1] = 1; mxArray *class_struct = mxCreateStructArray(2,dims,0,NULL); gridlabd_index = mxAddField(gridlabd_struct,"class"); mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,class_struct); mwIndex class_id[1024]; // index into class struct memset(class_id,0,sizeof(class_id)); // add classes for ( CLASS *oclass = callback->class_getfirst() ; oclass!=NULL ; oclass=oclass->next ) { // count objects in this class mwIndex dims[] = {0,1}; for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { OBJECT *obj = mod->get_object(item); if ( obj==NULL || obj->oclass!=oclass ) continue; dims[0]++; } if ( dims[0]==0 ) continue; mxArray *runtime_struct = mxCreateStructArray(2,dims,0,NULL); // add class mwIndex class_index = mxAddField(class_struct,oclass->name); mxSetFieldByNumber(class_struct,0,class_index,runtime_struct); // add properties to class for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next ) { mwIndex dims[] = {1,1}; mxArray *property_struct = mxCreateStructArray(2,dims,0,NULL); mwIndex runtime_index = mxAddField(runtime_struct,prop->name); mxSetFieldByNumber(runtime_struct,0,runtime_index,property_struct); } // add objects to class for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { OBJECT *obj = mod->get_object(item); if ( obj==NULL || obj->oclass!=oclass ) continue; mwIndex index = class_id[obj->oclass->id]++; // add properties to class for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next ) { gld_property p(obj,prop); mxArray *data = matlab_create_value(&p); mxSetField(runtime_struct,index,prop->name,data); } // update export list mod->set_addr(item,(void*)runtime_struct); mod->set_index(item,(size_t)index); } } /////////////////////////////////////////////////////////////////////////// // build the object data dims[0] = 0; for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { if ( mod->get_object(item)!=NULL ) dims[0]++; } dims[1] = 1; memset(class_id,0,sizeof(class_id)); const char *objfields[] = {"name","class","id","parent","rank","clock","valid_to","schedule_skew", "latitude","longitude","in","out","rng_state","heartbeat","lock","flags"}; mxArray *object_struct = mxCreateStructArray(2,dims,sizeof(objfields)/sizeof(objfields[0]),objfields); mwIndex n=0; for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) ) { OBJECT *obj = mod->get_object(item); if ( obj==NULL ) continue; class_id[obj->oclass->id]++; // index into class struct const char *objname[] = {obj->name&&isdigit(obj->name[0])?NULL:obj->name}; const char *oclassname[] = {obj->oclass->name}; if (obj->name) mxSetFieldByNumber(object_struct,n,0,mxCreateCharMatrixFromStrings(mwSize(1),objname)); mxSetFieldByNumber(object_struct,n,1,mxCreateCharMatrixFromStrings(mwSize(1),oclassname)); mxSetFieldByNumber(object_struct,n,2,mxCreateDoubleScalar((double)class_id[obj->oclass->id])); if (obj->parent) mxSetFieldByNumber(object_struct,n,3,mxCreateDoubleScalar((double)obj->parent->id+1)); mxSetFieldByNumber(object_struct,n,4,mxCreateDoubleScalar((double)obj->rank)); mxSetFieldByNumber(object_struct,n,5,mxCreateDoubleScalar((double)obj->clock)); mxSetFieldByNumber(object_struct,n,6,mxCreateDoubleScalar((double)obj->valid_to)); mxSetFieldByNumber(object_struct,n,7,mxCreateDoubleScalar((double)obj->schedule_skew)); if ( isfinite(obj->latitude) ) mxSetFieldByNumber(object_struct,n,8,mxCreateDoubleScalar((double)obj->latitude)); if ( isfinite(obj->longitude) ) mxSetFieldByNumber(object_struct,n,9,mxCreateDoubleScalar((double)obj->longitude)); mxSetFieldByNumber(object_struct,n,10,mxCreateDoubleScalar((double)obj->in_svc)); mxSetFieldByNumber(object_struct,n,11,mxCreateDoubleScalar((double)obj->out_svc)); mxSetFieldByNumber(object_struct,n,12,mxCreateDoubleScalar((double)obj->rng_state)); mxSetFieldByNumber(object_struct,n,13,mxCreateDoubleScalar((double)obj->heartbeat)); mxSetFieldByNumber(object_struct,n,14,mxCreateDoubleScalar((double)obj->lock)); mxSetFieldByNumber(object_struct,n,15,mxCreateDoubleScalar((double)obj->flags)); n++; } gridlabd_index = mxAddField(gridlabd_struct,"object"); mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,object_struct); /////////////////////////////////////////////////////////////////////////// // post the gridlabd structure matlab->root = gridlabd_struct; engPutVariable(matlab->engine,matlab->rootname,matlab->root); } /////////////////////////////////////////////////////////////////////////// // build the import/export data for ( LINKLIST *item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) ) { OBJECTPROPERTY *objprop = mod->get_export(item); if ( objprop==NULL ) continue; // add to published items gld_property prop(objprop->obj,objprop->prop); item->addr = (mxArray*)matlab_create_value(&prop); engPutVariable(matlab->engine,item->name,(mxArray*)item->addr); } for ( LINKLIST *item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) ) { OBJECTPROPERTY *objprop = mod->get_import(item); if ( objprop==NULL ) continue; // check that not already in export list LINKLIST *export_item; bool found=false; for ( export_item=mod->get_exports() ; export_item!=NULL ; export_item=mod->get_next(export_item) ) { OBJECTPROPERTY *other = mod->get_export(item); if ( memcmp(objprop,other,sizeof(OBJECTPROPERTY)) ) found=true; } if ( !found ) { gld_property prop(objprop->obj,objprop->prop); item->addr = (mxArray*)matlab_create_value(&prop); engPutVariable(matlab->engine,item->name,(mxArray*)item->addr); } } static int32 matlab_flag = 1; gl_global_create("MATLAB",PT_int32,&matlab_flag,PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"indicates that MATLAB is available",NULL); mod->last_t = gl_globalclock; return true; }