00001
00002
00003
00004
00005
00006
00007
00008 #include "metrics_collector.h"
00009
00010 #include <iostream>
00011 #include <fstream>
00012 #include <string.h>
00013 #include <algorithm>
00014 #include <cmath>
00015 #include <vector>
00016 #include <assert.h>
00017 using namespace std;
00018
00019 CLASS *metrics_collector::oclass = NULL;
00020 CLASS *metrics_collector::pclass = NULL;
00021 metrics_collector *metrics_collector::defaults = NULL;
00022 PROPERTY *metrics_collector::propTriplexNomV = NULL;
00023 PROPERTY *metrics_collector::propTriplexV1 = NULL;
00024 PROPERTY *metrics_collector::propTriplexV2 = NULL;
00025 PROPERTY *metrics_collector::propTriplexV12 = NULL;
00026 PROPERTY *metrics_collector::propTriplexPrice = NULL;
00027 PROPERTY *metrics_collector::propTriplexBill = NULL;
00028 PROPERTY *metrics_collector::propTriplexP = NULL;
00029 PROPERTY *metrics_collector::propTriplexQ = NULL;
00030 PROPERTY *metrics_collector::propMeterNomV = NULL;
00031 PROPERTY *metrics_collector::propMeterVa = NULL;
00032 PROPERTY *metrics_collector::propMeterVb = NULL;
00033 PROPERTY *metrics_collector::propMeterVc = NULL;
00034 PROPERTY *metrics_collector::propMeterVab = NULL;
00035 PROPERTY *metrics_collector::propMeterVbc = NULL;
00036 PROPERTY *metrics_collector::propMeterVca = NULL;
00037 PROPERTY *metrics_collector::propMeterPrice = NULL;
00038 PROPERTY *metrics_collector::propMeterBill = NULL;
00039 PROPERTY *metrics_collector::propMeterP = NULL;
00040 PROPERTY *metrics_collector::propMeterQ = NULL;
00041 PROPERTY *metrics_collector::propHouseLoad = NULL;
00042 PROPERTY *metrics_collector::propHouseHVAC = NULL;
00043 PROPERTY *metrics_collector::propHouseAirTemp = NULL;
00044 PROPERTY *metrics_collector::propHouseCoolSet = NULL;
00045 PROPERTY *metrics_collector::propHouseHeatSet = NULL;
00046 PROPERTY *metrics_collector::propWaterLoad = NULL;
00047 PROPERTY *metrics_collector::propInverterS = NULL;
00048 PROPERTY *metrics_collector::propCapCountA = NULL;
00049 PROPERTY *metrics_collector::propCapCountB = NULL;
00050 PROPERTY *metrics_collector::propCapCountC = NULL;
00051 PROPERTY *metrics_collector::propRegCountA = NULL;
00052 PROPERTY *metrics_collector::propRegCountB = NULL;
00053 PROPERTY *metrics_collector::propRegCountC = NULL;
00054 PROPERTY *metrics_collector::propSwingSubLoad = NULL;
00055 PROPERTY *metrics_collector::propSwingMeterS = NULL;
00056
00057 bool metrics_collector::log_set = true;
00058
00059 void new_metrics_collector(MODULE *mod){
00060 new metrics_collector(mod);
00061 }
00062
00063 metrics_collector::metrics_collector(MODULE *mod){
00064 if(oclass == NULL)
00065 {
00066 #ifdef _DEBUG
00067 gl_debug("construction metrics_collector class");
00068 #endif
00069 oclass = gl_register_class(mod,"metrics_collector",sizeof(metrics_collector), PC_POSTTOPDOWN);
00070 if(oclass == NULL)
00071 GL_THROW("unable to register object class implemented by %s",__FILE__);
00072
00073 if(gl_publish_variable(oclass,
00074 PT_double, "interval[s]", PADDR(interval_length_dbl), PT_DESCRIPTION, "Interval at which the metrics_collector output is stored in JSON format",NULL) < 1)
00075 GL_THROW("unable to publish properties in %s",__FILE__);
00076
00077 defaults = this;
00078 memset(this, 0, sizeof(metrics_collector));
00079 }
00080 }
00081
00082 int metrics_collector::isa(char *classname){
00083 return (strcmp(classname, oclass->name) == 0);
00084 }
00085
00086 int metrics_collector::create(){
00087
00088 memcpy(this, defaults, sizeof(metrics_collector));
00089
00090 time_array = NULL;
00091 real_power_array = NULL;
00092 reactive_power_array = NULL;
00093 voltage_vll_array = NULL;
00094 voltage_vln_array = NULL;
00095 voltage_unbalance_array = NULL;
00096 total_load_array = NULL;
00097 hvac_load_array = NULL;
00098 wh_load_array = NULL;
00099 air_temperature_array = NULL;
00100 dev_cooling_array = NULL;
00101 dev_heating_array = NULL;
00102 count_array = NULL;
00103 real_power_loss_array = NULL;
00104 reactive_power_loss_array = NULL;
00105
00106 metrics = NULL;
00107
00108
00109 interval_length = -1;
00110 curr_index = 0;
00111 interval_length_dbl=-1.0;
00112
00113 strcpy (parent_name, "No name given");
00114
00115 log_me = false;
00116 first_write = true;
00117 return 1;
00118 }
00119
00120 int metrics_collector::init(OBJECT *parent){
00121
00122 OBJECT *obj = OBJECTHDR(this);
00123
00124
00125 if (parent == NULL)
00126 {
00127 gl_error("metrics_collector must have a parent (triplex meter, house, waterheater, inverter, substation, or meter)");
00128
00129
00130
00131 return 0;
00132 }
00133 parent_string = "";
00134
00135 if (gl_object_isa(parent,"triplex_meter")) {
00136 parent_string = "triplex_meter";
00137 if (propTriplexNomV == NULL) propTriplexNomV = gl_get_property (parent, "nominal_voltage");
00138 if (propTriplexPrice == NULL) propTriplexPrice = gl_get_property (parent, "price");
00139 if (propTriplexBill == NULL) propTriplexBill = gl_get_property (parent, "monthly_bill");
00140 if (propTriplexP == NULL) propTriplexP = gl_get_property (parent, "measured_real_power");
00141 if (propTriplexQ == NULL) propTriplexQ = gl_get_property (parent, "measured_reactive_power");
00142 if (propTriplexV1 == NULL) propTriplexV1 = gl_get_property (parent, "voltage_1");
00143 if (propTriplexV2 == NULL) propTriplexV2 = gl_get_property (parent, "voltage_2");
00144 if (propTriplexV12 == NULL) propTriplexV12 = gl_get_property (parent, "voltage_12");
00145 if (!log_set) {
00146 log_set = log_me = true;
00147 }
00148 } else if (gl_object_isa(parent, "house")) {
00149 parent_string = "house";
00150 if (propHouseLoad == NULL) propHouseLoad = gl_get_property (parent, "total_load");
00151 if (propHouseHVAC == NULL) propHouseHVAC = gl_get_property (parent, "hvac_load");
00152 if (propHouseAirTemp == NULL) propHouseAirTemp = gl_get_property (parent, "air_temperature");
00153 if (propHouseCoolSet == NULL) propHouseCoolSet = gl_get_property (parent, "cooling_setpoint");
00154 if (propHouseHeatSet == NULL) propHouseHeatSet = gl_get_property (parent, "heating_setpoint");
00155 } else if (gl_object_isa(parent,"waterheater")) {
00156 parent_string = "waterheater";
00157 if (propWaterLoad == NULL) propWaterLoad = gl_get_property (parent, "actual_load");
00158 } else if (gl_object_isa(parent,"inverter")) {
00159 parent_string = "inverter";
00160 if (propInverterS == NULL) propInverterS = gl_get_property (parent, "VA_Out");
00161 } else if (gl_object_isa(parent,"capacitor")) {
00162 parent_string = "capacitor";
00163 if (propCapCountA == NULL) propCapCountA = gl_get_property (parent, "cap_A_switch_count");
00164 if (propCapCountB == NULL) propCapCountB = gl_get_property (parent, "cap_B_switch_count");
00165 if (propCapCountC == NULL) propCapCountC = gl_get_property (parent, "cap_C_switch_count");
00166 } else if (gl_object_isa(parent,"regulator")) {
00167 parent_string = "regulator";
00168 if (propRegCountA == NULL) propRegCountA = gl_get_property (parent, "tap_A_change_count");
00169 if (propRegCountB == NULL) propRegCountB = gl_get_property (parent, "tap_B_change_count");
00170 if (propRegCountC == NULL) propRegCountC = gl_get_property (parent, "tap_C_change_count");
00171 } else if (gl_object_isa(parent,"substation")) {
00172 PROPERTY *pval = gl_get_property(parent,"bustype");
00173 if ((pval==NULL) || (pval->ptype!=PT_enumeration))
00174 {
00175 GL_THROW("metrics_collector:%s failed to map bustype variable from %s",obj->name?obj->name:"unnamed",parent->name?parent->name:"unnamed");
00176
00177
00178
00179
00180 }
00181
00182 enumeration *meter_bustype = (enumeration*)GETADDR(parent,pval);
00183
00184 if (*meter_bustype != 2) {
00185 gl_error("If a metrics_collector is attached to a substation, it must be a SWING bus");
00186 return 0;
00187 }
00188 parent_string = "swingbus";
00189 if (propSwingSubLoad == NULL) propSwingSubLoad = gl_get_property (parent, "distribution_load");
00190 } else if (gl_object_isa(parent,"meter")) {
00191 parent_string = "meter";
00192 if (propMeterNomV == NULL) propMeterNomV = gl_get_property (parent, "nominal_voltage");
00193 if (propMeterPrice == NULL) propMeterPrice = gl_get_property (parent, "price");
00194 if (propMeterBill == NULL) propMeterBill = gl_get_property (parent, "monthly_bill");
00195 if (propMeterP == NULL) propMeterP = gl_get_property (parent, "measured_real_power");
00196 if (propMeterQ == NULL) propMeterQ = gl_get_property (parent, "measured_reactive_power");
00197 if (propMeterVa == NULL) propMeterVa = gl_get_property (parent, "voltage_A");
00198 if (propMeterVb == NULL) propMeterVb = gl_get_property (parent, "voltage_B");
00199 if (propMeterVc == NULL) propMeterVc = gl_get_property (parent, "voltage_C");
00200 if (propMeterVab == NULL) propMeterVab = gl_get_property (parent, "voltage_AB");
00201 if (propMeterVbc == NULL) propMeterVbc = gl_get_property (parent, "voltage_BC");
00202 if (propMeterVca == NULL) propMeterVca = gl_get_property (parent, "voltage_CA");
00203 PROPERTY *pval = gl_get_property(parent,"bustype");
00204 if ((pval!=NULL) && (pval->ptype==PT_enumeration))
00205 {
00206 enumeration *meter_bustype = (enumeration*)GETADDR(parent,pval);
00207 if (*meter_bustype == 2) {
00208 parent_string = "swingbus";
00209 if (propSwingMeterS == NULL) propSwingMeterS = gl_get_property (parent, "measured_power");
00210 }
00211 }
00212 } else {
00213 gl_error("metrics_collector allows only these parents: triplex meter, house, waterheater, inverter, substation, meter, capacitor, regulator");
00214
00215
00216
00217 return 0;
00218 }
00219
00220
00221 if (strcmp(parent_string, "triplex_meter") == 0)
00222 {
00223 if (parent->name != NULL) {
00224 strcpy (parent_name, parent->name);
00225 }
00226 metrics = (double *)gl_malloc(MTR_ARRAY_SIZE*sizeof(double));
00227 if (metrics == NULL)
00228 {
00229 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00230 }
00231 }
00232 else if (strcmp(parent_string, "meter") == 0)
00233 {
00234 if (parent->name != NULL) {
00235 strcpy (parent_name, parent->name);
00236 }
00237 metrics = (double *)gl_malloc(MTR_ARRAY_SIZE*sizeof(double));
00238 if (metrics == NULL)
00239 {
00240 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00241 }
00242 }
00243 else if (strcmp(parent_string, "house") == 0)
00244 {
00245 if (parent->name != NULL) {
00246 strcpy (parent_name, parent->name);
00247 }
00248 metrics = (double *)gl_malloc(HSE_ARRAY_SIZE*sizeof(double));
00249 if (metrics == NULL)
00250 {
00251 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00252 }
00253 }
00254 else if (strcmp(parent_string, "waterheater") == 0)
00255 {
00256 if (parent->parent->name != NULL) {
00257 strcpy (parent_name, parent->parent->name);
00258 }
00259 metrics = (double *)gl_malloc(WH_ARRAY_SIZE*sizeof(double));
00260 if (metrics == NULL)
00261 {
00262 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00263 }
00264
00265 char tname[32];
00266 sprintf(tname, "%i", parent->id);
00267 char *namestr = (parent->name ? parent->name : tname);
00268 sprintf(waterheaterName, "waterheater_%s_actual_load", namestr);
00269 }
00270 else if (strcmp(parent_string, "inverter") == 0)
00271 {
00272 if (parent->name != NULL) {
00273 strcpy (parent_name, parent->name);
00274 }
00275 metrics = (double *)gl_malloc(INV_ARRAY_SIZE*sizeof(double));
00276 if (metrics == NULL)
00277 {
00278 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00279 }
00280 }
00281 else if (strcmp(parent_string, "capacitor") == 0)
00282 {
00283 if (parent->name != NULL) {
00284 strcpy (parent_name, parent->name);
00285 }
00286 metrics = (double *)gl_malloc(CAP_ARRAY_SIZE*sizeof(double));
00287 if (metrics == NULL)
00288 {
00289 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00290 }
00291 }
00292 else if (strcmp(parent_string, "regulator") == 0)
00293 {
00294 if (parent->name != NULL) {
00295 strcpy (parent_name, parent->name);
00296 }
00297 metrics = (double *)gl_malloc(REG_ARRAY_SIZE*sizeof(double));
00298 if (metrics == NULL)
00299 {
00300 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00301 }
00302 }
00303 else if (strcmp(parent_string, "swingbus") == 0)
00304 {
00305
00306
00307 link_objects = gl_find_objects(FL_NEW,FT_MODULE,SAME,"powerflow",FT_END);
00308 if(link_objects == NULL){
00309 gl_warning("No link objects were found.");
00310
00311
00312
00313 }
00314 if (parent->name != NULL) {
00315 strcpy (parent_name, parent->name);
00316 }
00317 else {
00318 strcpy (parent_name, "Swing Bus Metrics");
00319 }
00320 metrics = (double *)gl_malloc(FDR_ARRAY_SIZE*sizeof(double));
00321 if (metrics == NULL)
00322 {
00323 GL_THROW("metrics_collector %d::init(): Failed to allocate JSON metrics array",obj->id);
00324 }
00325 }
00326
00327
00328 interval_length = (TIMESTAMP)(interval_length_dbl);
00329 vector_length = interval_length + 1;
00330 if(interval_length <= 0){
00331 gl_error("metrics_collector::init(): invalid interval of %i, must be greater than 0", interval_length);
00332
00333
00334
00335 return 0;
00336 }
00337
00338
00339 time_array = (TIMESTAMP *)gl_malloc(vector_length*sizeof(TIMESTAMP));
00340 if (time_array == NULL)
00341 {
00342 GL_THROW("metrics_collector %d::init(): Failed to allocate time array",obj->id);
00343
00344
00345
00346
00347 }
00348
00349
00350 if ((strcmp(parent_string, "triplex_meter") == 0) || (strcmp(parent_string, "meter") == 0)) {
00351
00352 real_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00353
00354 if (real_power_array == NULL)
00355 {
00356 GL_THROW("metrics_collector %d::init(): Failed to allocate real power array",obj->id);
00357
00358
00359
00360
00361 }
00362
00363
00364 reactive_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00365
00366 if (reactive_power_array == NULL)
00367 {
00368 GL_THROW("metrics_collector %d::init(): Failed to allocate reactive power array",obj->id);
00369
00370
00371
00372
00373 }
00374
00375
00376 voltage_vll_array = (double *)gl_malloc(vector_length*sizeof(double));
00377
00378 if (voltage_vll_array == NULL)
00379 {
00380 GL_THROW("metrics_collector %d::init(): Failed to allocate phase 1-2 voltage array",obj->id);
00381
00382
00383
00384
00385 }
00386
00387
00388 voltage_vln_array = (double *)gl_malloc(vector_length*sizeof(double));
00389
00390 if (voltage_vln_array == NULL)
00391 {
00392 GL_THROW("metrics_collector %d::init(): Failed to allocate average vln voltage array",obj->id);
00393
00394
00395
00396
00397 }
00398
00399
00400 voltage_unbalance_array = (double *)gl_malloc(vector_length*sizeof(double));
00401
00402 if (voltage_unbalance_array == NULL)
00403 {
00404 GL_THROW("metrics_collector %d::init(): Failed to allocate voltage unbalance array",obj->id);
00405
00406
00407
00408
00409 }
00410
00411
00412 for (curr_index=0; curr_index<vector_length; curr_index++)
00413 {
00414 real_power_array[curr_index] = 0.0;
00415 reactive_power_array[curr_index] = 0.0;
00416 voltage_vll_array[curr_index] = 0.0;
00417 voltage_vln_array[curr_index] = 0.0;
00418 voltage_unbalance_array[curr_index] = 0.0;
00419 }
00420
00421 }
00422
00423 else if (strcmp(parent_string, "house") == 0) {
00424
00425 total_load_array = (double *)gl_malloc(vector_length*sizeof(double));
00426
00427 if (total_load_array == NULL)
00428 {
00429 GL_THROW("metrics_collector %d::init(): Failed to allocate total_load array",obj->id);
00430
00431
00432
00433
00434 }
00435
00436
00437 hvac_load_array = (double *)gl_malloc(vector_length*sizeof(double));
00438
00439 if (hvac_load_array == NULL)
00440 {
00441 GL_THROW("metrics_collector %d::init(): Failed to allocate hvac_load array",obj->id);
00442
00443
00444
00445
00446 }
00447
00448
00449 air_temperature_array = (double *)gl_malloc(vector_length*sizeof(double));
00450
00451 if (air_temperature_array == NULL)
00452 {
00453 GL_THROW("metrics_collector %d::init(): Failed to allocate air_temperature array",obj->id);
00454
00455
00456
00457
00458 }
00459
00460
00461 dev_cooling_array = (double *)gl_malloc(vector_length*sizeof(double));
00462
00463 if (dev_cooling_array == NULL)
00464 {
00465 GL_THROW("metrics_collector %d::init(): Failed to allocate dev_cooling_array array",obj->id);
00466
00467
00468
00469
00470 }
00471
00472
00473 dev_heating_array = (double *)gl_malloc(vector_length*sizeof(double));
00474
00475 if (dev_heating_array == NULL)
00476 {
00477 GL_THROW("metrics_collector %d::init(): Failed to allocate dev_heating_array array",obj->id);
00478
00479
00480
00481
00482 }
00483
00484
00485 for (curr_index=0; curr_index<vector_length; curr_index++)
00486 {
00487 total_load_array[curr_index] = 0.0;
00488 hvac_load_array[curr_index] = 0.0;
00489 air_temperature_array[curr_index] = 0.0;
00490 dev_cooling_array[curr_index] = 0.0;
00491 dev_heating_array[curr_index] = 0.0;
00492 }
00493 }
00494
00495 else if (strcmp(parent_string, "waterheater") == 0) {
00496
00497 wh_load_array = (double *)gl_malloc(vector_length*sizeof(double));
00498
00499 if (wh_load_array == NULL)
00500 {
00501 GL_THROW("metrics_collector %d::init(): Failed to allocate wh_load array",obj->id);
00502
00503
00504
00505
00506 }
00507 }
00508
00509 else if (strcmp(parent_string, "inverter") == 0) {
00510
00511 real_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00512
00513 if (real_power_array == NULL)
00514 {
00515 GL_THROW("metrics_collector %d::init(): Failed to allocate real power array",obj->id);
00516
00517
00518
00519
00520 }
00521
00522
00523 reactive_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00524
00525 if (reactive_power_array == NULL)
00526 {
00527 GL_THROW("metrics_collector %d::init(): Failed to allocate reactive power array",obj->id);
00528
00529
00530
00531
00532 }
00533 }
00534
00535 else if (strcmp(parent_string, "swingbus") == 0) {
00536
00537 real_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00538
00539 if (real_power_array == NULL)
00540 {
00541 GL_THROW("metrics_collector %d::init(): Failed to allocate real power array",obj->id);
00542
00543
00544
00545
00546 }
00547
00548
00549 reactive_power_array = (double *)gl_malloc(vector_length*sizeof(double));
00550
00551 if (reactive_power_array == NULL)
00552 {
00553 GL_THROW("metrics_collector %d::init(): Failed to allocate reactive power array",obj->id);
00554
00555
00556
00557
00558 }
00559
00560 real_power_loss_array = (double *)gl_malloc(vector_length*sizeof(double));
00561
00562 if (real_power_loss_array == NULL)
00563 {
00564 GL_THROW("metrics_collector %d::init(): Failed to allocate real power loss array",obj->id);
00565
00566
00567
00568
00569 }
00570
00571
00572 reactive_power_loss_array = (double *)gl_malloc(vector_length*sizeof(double));
00573
00574 if (reactive_power_loss_array == NULL)
00575 {
00576 GL_THROW("metrics_collector %d::init(): Failed to allocate reactive power loss array",obj->id);
00577
00578
00579
00580
00581 }
00582 }
00583 else if ((strcmp(parent_string, "capacitor") == 0) || (strcmp(parent_string, "regulator") == 0)) {
00584 count_array = (double *)gl_malloc(vector_length*sizeof(double));
00585
00586 if (count_array == NULL)
00587 {
00588 GL_THROW("metrics_collector %d::init(): Failed to allocate operation count array",obj->id);
00589
00590
00591
00592
00593 }
00594 for (int i = 0; i < vector_length; i++) count_array[i] = 0.0;
00595 }
00596
00597 else {
00598 gl_error("metrics_collector must have a triplex meter, meter, house, waterheater, inverter or swing-bus as its parent");
00599
00600
00601
00602
00603 return 0;
00604 }
00605
00606
00607
00608 curr_index = 0;
00609
00610
00611 start_time = gl_globalclock;
00612 next_write = start_time + interval_length;
00613
00614 return 1;
00615 }
00616
00617 TIMESTAMP metrics_collector::postsync(TIMESTAMP t0, TIMESTAMP t1) {
00618
00619 if (next_write <= t1) {
00620 write_now = true;
00621 }
00622 return t1 + interval_length;
00623 }
00624
00625 int metrics_collector::commit(TIMESTAMP t1){
00626 OBJECT *obj = OBJECTHDR(this);
00627
00628 if(0 == read_line(obj)){
00629 gl_error("metrics_collector::commit(): error when reading the values");
00630 return 0;
00631 }
00632
00633
00634 if (write_now) {
00635 if (0 == write_line(t1, obj)) {
00636 gl_error("metrics_collector::commit(): error when aggregating values over the interval");
00637 return 0;
00638 }
00639 write_now = false;
00640 }
00641 return 1;
00642 }
00643
00647 int metrics_collector::read_line(OBJECT *obj){
00648
00649
00650 time_array[curr_index] = gl_globalclock;
00651
00652 if (strcmp(parent_string, "triplex_meter") == 0) {
00653 real_power_array[curr_index] = *gl_get_double(obj->parent, propTriplexP);
00654 reactive_power_array[curr_index] = *gl_get_double(obj->parent, propTriplexQ);
00655
00656
00657 price_parent = *gl_get_double(obj->parent, propTriplexPrice);
00658 bill_parent = *gl_get_double(obj->parent, propTriplexBill);
00659
00660
00661 double v1 = (*gl_get_complex(obj->parent, propTriplexV1)).Mag();
00662 double v2 = (*gl_get_complex(obj->parent, propTriplexV2)).Mag();
00663 double v12 = (*gl_get_complex(obj->parent, propTriplexV12)).Mag();
00664
00665
00666 double vavg = 0.5 * (v1 + v2);
00667
00668 voltage_vll_array[curr_index] = fabs(v12);
00669 voltage_vln_array[curr_index] = vavg;
00670 voltage_unbalance_array[curr_index] = 0.5 * fabs(v1 - v2)/vavg;
00671 }
00672 else if (strcmp(parent_string, "meter") == 0)
00673 {
00674 real_power_array[curr_index] = *gl_get_double(obj->parent, propMeterP);
00675 reactive_power_array[curr_index] = *gl_get_double(obj->parent, propMeterQ);
00676
00677
00678 price_parent = *gl_get_double(obj->parent, propMeterPrice);
00679 bill_parent = *gl_get_double(obj->parent, propMeterBill);
00680
00681
00682 double va = (*gl_get_complex(obj->parent, propMeterVa)).Mag();
00683 double vb = (*gl_get_complex(obj->parent, propMeterVb)).Mag();
00684 double vc = (*gl_get_complex(obj->parent, propMeterVc)).Mag();
00685 double vavg = (va + vb + vc) / 3.0;
00686 double vmin = va;
00687 double vmax = va;
00688 if (vb < vmin) vmin = vb;
00689 if (vb > vmax) vmax = vb;
00690 if (vc < vmin) vmin = vc;
00691 if (vc > vmax) vmax = vc;
00692 double vab = (*gl_get_complex(obj->parent, propMeterVab)).Mag();
00693 double vbc = (*gl_get_complex(obj->parent, propMeterVbc)).Mag();
00694 double vca = (*gl_get_complex(obj->parent, propMeterVca)).Mag();
00695 double vll = (vab + vbc + vca) / 3.0;
00696
00697 double vdev = fabs(vab - vll);
00698 double vdev2 = fabs(vbc - vll);
00699 double vdev3 = fabs(vca - vll);
00700 if (vdev2 > vdev) vdev = vdev2;
00701 if (vdev3 > vdev) vdev = vdev3;
00702
00703 voltage_vll_array[curr_index] = vll;
00704 voltage_vln_array[curr_index] = vavg;
00705 voltage_unbalance_array[curr_index] = vdev / vll;
00706 }
00707 else if (strcmp(parent_string, "house") == 0)
00708 {
00709 total_load_array[curr_index] = *gl_get_double(obj->parent, propHouseLoad);
00710 hvac_load_array[curr_index] = *gl_get_double(obj->parent, propHouseHVAC);
00711 air_temperature_array[curr_index] = *gl_get_double(obj->parent, propHouseAirTemp);
00712 dev_cooling_array[curr_index] = *gl_get_double(obj->parent, propHouseCoolSet);
00713 dev_heating_array[curr_index] = *gl_get_double(obj->parent, propHouseHeatSet);
00714 }
00715 else if (strcmp(parent_string, "waterheater") == 0) {
00716 wh_load_array[curr_index] = *gl_get_double(obj->parent, propWaterLoad);
00717 }
00718 else if (strcmp(parent_string, "inverter") == 0) {
00719 complex VAOut = *gl_get_complex(obj->parent, propInverterS);
00720 real_power_array[curr_index] = (double)VAOut.Re();
00721 reactive_power_array[curr_index] = (double)VAOut.Im();
00722 }
00723 else if (strcmp(parent_string, "capacitor") == 0) {
00724 double opcount = *gl_get_double(obj->parent, propCapCountA)
00725 + *gl_get_double(obj->parent, propCapCountB) + *gl_get_double(obj->parent, propCapCountC);
00726 count_array[curr_index] = opcount;
00727 }
00728 else if (strcmp(parent_string, "regulator") == 0) {
00729 double opcount = *gl_get_double(obj->parent, propRegCountA)
00730 + *gl_get_double(obj->parent, propRegCountB) + *gl_get_double(obj->parent, propRegCountC);
00731 count_array[curr_index] = opcount;
00732 }
00733 else if (strcmp(parent_string, "swingbus") == 0) {
00734
00735 complex VAfeeder;
00736 if (gl_object_isa(obj->parent,"substation")) {
00737 VAfeeder = *gl_get_complex(obj->parent, propSwingSubLoad);
00738 } else {
00739 VAfeeder = *gl_get_complex(obj->parent, propSwingMeterS);
00740 }
00741 real_power_array[curr_index] = (double)VAfeeder.Re();
00742 reactive_power_array[curr_index] = (double)VAfeeder.Im();
00743
00744 int index = 0;
00745 obj = NULL;
00746 complex lossesSum = 0.0;
00747 while(obj = gl_find_next(link_objects,obj)){
00748 if(index >= link_objects->hit_count){
00749 break;
00750 }
00751 char * oclassName = obj->oclass->name;
00752 if (strcmp(oclassName, "overhead_line") == 0 || strcmp(oclassName, "underground_line") == 0 ||
00753 strcmp(oclassName, "triplex_line") == 0 || strcmp(oclassName, "transformer") == 0 ||
00754 strcmp(oclassName, "regulator") == 0 || strcmp(oclassName, "switch") == 0 || strcmp(oclassName, "fuse") == 0) {
00755
00756 link_object *one_link = OBJECTDATA(obj,link_object);
00757 if(one_link == NULL){
00758 gl_error("Unable to map the object as link.");
00759 return 0;
00760 }
00761 complex loss = one_link->power_loss;
00762
00763 if (loss.Re() < 0) {
00764 loss.Re() = -loss.Re();
00765 }
00766 lossesSum += loss;
00767 }
00768 index++;
00769 }
00770
00771 real_power_loss_array[curr_index] = (double)lossesSum.Re();
00772 reactive_power_loss_array[curr_index] = (double)lossesSum.Im();
00773 }
00774
00775 else {
00776 gl_error("metrics_collector must have a triplex meter, house, waterheater, inverter, swing-bus, capacitor or regulator as its parent");
00777
00778
00779
00780
00781 return 0;
00782 }
00783
00784
00785
00786 ++curr_index;
00787 if (curr_index == vector_length) {
00788 gl_error ("metrics_collector wrapped its buffer for aggregating data, %d %d %ld\n",
00789 curr_index, vector_length, gl_globalclock);
00790
00791
00792
00793
00794 }
00795 return 1;
00796 }
00797
00798 void metrics_collector::log_to_console(char *msg, TIMESTAMP t) {
00799 if (log_me) {
00800 printf("** %s: t = %i, next_write = %i, curr_index = %i\n",
00801 msg, t - start_time, next_write - start_time, curr_index);
00802 for (int j = 0; j < curr_index; j++) {
00803 printf(" %i", time_array[j] - start_time);
00804 }
00805 printf("\n");
00806 for (int j = 0; j < curr_index; j++) {
00807
00808 printf(" %g", voltage_vll_array[j]);
00809 }
00810 printf("\n");
00811 }
00812 }
00813
00818 int metrics_collector::write_line(TIMESTAMP t1, OBJECT *obj){
00819
00820 bool bOverran = false;
00821 if (t1 > next_write) {
00822 bOverran = true;
00823 copyHistories (curr_index - 1, curr_index);
00824 interpolateHistories (curr_index - 1, next_write);
00825
00826 }
00827
00828 if ((strcmp(parent_string, "triplex_meter") == 0) || (strcmp(parent_string, "meter") == 0)) {
00829 metrics[MTR_MIN_REAL_POWER] = findMin(real_power_array, curr_index);
00830 metrics[MTR_MAX_REAL_POWER] = findMax(real_power_array, curr_index);
00831 metrics[MTR_AVG_REAL_POWER] = findAverage(real_power_array, curr_index);
00832
00833 metrics[MTR_MIN_REAC_POWER] = findMin(reactive_power_array, curr_index);
00834 metrics[MTR_MAX_REAC_POWER] = findMax(reactive_power_array, curr_index);
00835 metrics[MTR_AVG_REAC_POWER] = findAverage(reactive_power_array, curr_index);
00836
00837 metrics[MTR_REAL_ENERGY] = findAverage(real_power_array, curr_index) * interval_length / 3600;
00838 metrics[MTR_REAC_ENERGY] = findAverage(reactive_power_array, curr_index) * interval_length / 3600;
00839
00840
00841 metrics[MTR_BILL] = bill_parent;
00842
00843 metrics[MTR_MIN_VLL] = findMin(voltage_vll_array, curr_index);
00844 metrics[MTR_MAX_VLL] = findMax(voltage_vll_array, curr_index);
00845 metrics[MTR_AVG_VLL] = findAverage(voltage_vll_array, curr_index);
00846
00847 metrics[MTR_MIN_VLN] = findMin(voltage_vln_array, curr_index);
00848 metrics[MTR_MAX_VLN] = findMax(voltage_vln_array, curr_index);
00849 metrics[MTR_AVG_VLN] = findAverage(voltage_vln_array, curr_index);
00850
00851 metrics[MTR_MIN_VUNB] = findMin(voltage_unbalance_array, curr_index);
00852 metrics[MTR_MAX_VUNB] = findMax(voltage_unbalance_array, curr_index);
00853 metrics[MTR_AVG_VUNB] = findAverage(voltage_unbalance_array, curr_index);
00854
00855
00856 double normVol = 1.0, aboveRangeA, belowRangeA, aboveRangeB, belowRangeB, belowOutage;
00857 if (strcmp(parent_string, "triplex_meter") == 0) {
00858 normVol = *gl_get_double(obj->parent, propTriplexNomV);
00859 belowOutage = normVol * 0.10000 * 2.0;
00860 aboveRangeA = normVol * 1.05000 * 2.0;
00861 belowRangeA = normVol * 0.95000 * 2.0;
00862 aboveRangeB = normVol * 1.05833 * 2.0;
00863 belowRangeB = normVol * 0.91667 * 2.0;
00864 if (log_me) {
00865 log_to_console ("checking violations", t1);
00866 aboveRangeA = normVol * 1.040 * 2.0;
00867 aboveRangeB = normVol * 1.044 * 2.0;
00868 }
00869 } else {
00870 normVol = *gl_get_double(obj->parent, propMeterNomV);
00871 belowOutage = normVol * 0.10000 * (std::sqrt(3));
00872 aboveRangeA = normVol * 1.05000 * (std::sqrt(3));
00873 belowRangeA = normVol * 0.95000 * (std::sqrt(3));
00874 aboveRangeB = normVol * 1.05833 * (std::sqrt(3));
00875 belowRangeB = normVol * 0.91667 * (std::sqrt(3));
00876 }
00877
00878 struct vol_violation vol_Vio = findOutLimit(first_write, voltage_vll_array, true, aboveRangeA, curr_index);
00879 metrics[MTR_ABOVE_A_DUR] = vol_Vio.durationViolation;
00880 metrics[MTR_ABOVE_A_CNT] = vol_Vio.countViolation;
00881
00882 vol_Vio = findOutLimit(first_write, voltage_vll_array, false, belowRangeA, curr_index);
00883 metrics[MTR_BELOW_A_DUR] = vol_Vio.durationViolation;
00884 metrics[MTR_BELOW_A_CNT] = vol_Vio.countViolation;
00885
00886 vol_Vio = findOutLimit(first_write, voltage_vll_array, true, aboveRangeB, curr_index);
00887 metrics[MTR_ABOVE_B_DUR] = vol_Vio.durationViolation;
00888 metrics[MTR_ABOVE_B_CNT] = vol_Vio.countViolation;
00889
00890 vol_Vio = findOutLimit(first_write, voltage_vll_array, false, belowRangeB, curr_index);
00891 metrics[MTR_BELOW_B_DUR] = vol_Vio.durationViolation;
00892 metrics[MTR_BELOW_B_CNT] = vol_Vio.countViolation;
00893
00894 vol_Vio = findOutLimit(first_write, voltage_vll_array, false, belowOutage, curr_index);
00895 metrics[MTR_BELOW_10_DUR] = vol_Vio.durationViolation;
00896 metrics[MTR_BELOW_10_CNT] = vol_Vio.countViolation;
00897 }
00898
00899 else if (strcmp(parent_string, "house") == 0) {
00900 metrics[HSE_MIN_TOTAL_LOAD] = findMin(total_load_array, curr_index);
00901 metrics[HSE_MAX_TOTAL_LOAD] = findMax(total_load_array, curr_index);
00902 metrics[HSE_AVG_TOTAL_LOAD] = findAverage(total_load_array, curr_index);
00903
00904 metrics[HSE_MIN_HVAC_LOAD] = findMin(hvac_load_array, curr_index);
00905 metrics[HSE_MAX_HVAC_LOAD] = findMax(hvac_load_array, curr_index);
00906 metrics[HSE_AVG_HVAC_LOAD] = findAverage(hvac_load_array, curr_index);
00907
00908 metrics[HSE_MIN_AIR_TEMP] = findMin(air_temperature_array, curr_index);
00909 metrics[HSE_MAX_AIR_TEMP] = findMax(air_temperature_array, curr_index);
00910 metrics[HSE_AVG_AIR_TEMP] = findAverage(air_temperature_array, curr_index);
00911 metrics[HSE_AVG_DEV_COOLING] = findAverage(dev_cooling_array, curr_index);
00912 metrics[HSE_AVG_DEV_HEATING] = findAverage(dev_heating_array, curr_index);
00913 }
00914 else if (strcmp(parent_string, "waterheater") == 0) {
00915 metrics[WH_MIN_ACTUAL_LOAD] = findMin(wh_load_array, curr_index);
00916 metrics[WH_MAX_ACTUAL_LOAD] = findMax(wh_load_array, curr_index);
00917 metrics[WH_AVG_ACTUAL_LOAD] = findAverage(wh_load_array, curr_index);
00918 }
00919 else if (strcmp(parent_string, "inverter") == 0) {
00920 metrics[INV_MIN_REAL_POWER] = findMin(real_power_array, curr_index);
00921 metrics[INV_MAX_REAL_POWER] = findMax(real_power_array, curr_index);
00922 metrics[INV_AVG_REAL_POWER] = findAverage(real_power_array, curr_index);
00923
00924 metrics[INV_MIN_REAC_POWER] = findMin(reactive_power_array, curr_index);
00925 metrics[INV_MAX_REAC_POWER] = findMax(reactive_power_array, curr_index);
00926 metrics[INV_AVG_REAC_POWER] = findAverage(reactive_power_array, curr_index);
00927 }
00928 else if (strcmp(parent_string, "capacitor") == 0) {
00929 metrics[CAP_OPERATION_CNT] = findMax(count_array, curr_index);
00930 }
00931 else if (strcmp(parent_string, "regulator") == 0) {
00932 metrics[REG_OPERATION_CNT] = findMax(count_array, curr_index);
00933 }
00934 else if (strcmp(parent_string, "swingbus") == 0) {
00935
00936 metrics[FDR_MIN_REAL_POWER] = findMin(real_power_array, curr_index);
00937 metrics[FDR_MAX_REAL_POWER] = findMax(real_power_array, curr_index);
00938 metrics[FDR_AVG_REAL_POWER] = findAverage(real_power_array, curr_index);
00939 metrics[FDR_MED_REAL_POWER] = findMedian(real_power_array, curr_index);
00940
00941 metrics[FDR_MIN_REAC_POWER] = findMin(reactive_power_array, curr_index);
00942 metrics[FDR_MAX_REAC_POWER] = findMax(reactive_power_array, curr_index);
00943 metrics[FDR_AVG_REAC_POWER] = findAverage(reactive_power_array, curr_index);
00944 metrics[FDR_MED_REAC_POWER] = findMedian(reactive_power_array, curr_index);
00945
00946 metrics[FDR_REAL_ENERGY] = findAverage(real_power_array, curr_index) * interval_length / 3600;
00947 metrics[FDR_REAC_ENERGY] = findAverage(reactive_power_array, curr_index) * interval_length / 3600;
00948
00949 metrics[FDR_MIN_REAL_LOSS] = findMin(real_power_loss_array, curr_index);
00950 metrics[FDR_MAX_REAL_LOSS] = findMax(real_power_loss_array, curr_index);
00951 metrics[FDR_AVG_REAL_LOSS] = findAverage(real_power_loss_array, curr_index);
00952 metrics[FDR_MED_REAL_LOSS] = findMedian(real_power_loss_array, curr_index);
00953
00954 metrics[FDR_MIN_REAC_LOSS] = findMin(reactive_power_loss_array, curr_index);
00955 metrics[FDR_MAX_REAC_LOSS] = findMax(reactive_power_loss_array, curr_index);
00956 metrics[FDR_AVG_REAC_LOSS] = findAverage(reactive_power_loss_array, curr_index);
00957 metrics[FDR_MED_REAC_LOSS] = findMedian(reactive_power_loss_array, curr_index);
00958 }
00959
00960
00961 if (bOverran) {
00962 copyHistories(curr_index - 1, 0);
00963 copyHistories(curr_index, 1);
00964 curr_index = 2;
00965 } else {
00966 copyHistories(curr_index - 1, 0);
00967 curr_index = 1;
00968 }
00969
00970 next_write = min(next_write + interval_length, gl_globalstoptime);
00971 first_write = false;
00972
00973 return 1;
00974 }
00975
00976 void metrics_collector::copyHistories (int from, int to) {
00977 time_array[to] = time_array[from];
00978 if (voltage_vll_array) voltage_vll_array[to] = voltage_vll_array[from];
00979 if (voltage_vln_array) voltage_vln_array[to] = voltage_vln_array[from];
00980 if (voltage_unbalance_array) voltage_unbalance_array[to] = voltage_unbalance_array[from];
00981 if (total_load_array) total_load_array[to] = total_load_array[from];
00982 if (hvac_load_array) hvac_load_array[to] = hvac_load_array[from];
00983 if (air_temperature_array) air_temperature_array[to] = air_temperature_array[from];
00984 if (dev_cooling_array) dev_cooling_array[to] = dev_cooling_array[from];
00985 if (dev_heating_array) dev_heating_array[to] = dev_heating_array[from];
00986 if (wh_load_array) wh_load_array[to] = wh_load_array[from];
00987 if (count_array) count_array[to] = count_array[from];
00988 if (real_power_array) real_power_array[to] = real_power_array[from];
00989 if (reactive_power_array) reactive_power_array[to] = reactive_power_array[from];
00990 if (real_power_loss_array) real_power_loss_array[to] = real_power_loss_array[from];
00991 if (reactive_power_loss_array) reactive_power_loss_array[to] = reactive_power_loss_array[from];
00992 }
00993
00994 void metrics_collector::interpolate (double *a, int idx, double denom, double top) {
00995 a[idx] = a[idx-1] + (a[idx+1] - a[idx-1]) * top / denom;
00996 }
00997
00998 void metrics_collector::interpolateHistories (int idx, TIMESTAMP t) {
00999 time_array[idx] = t;
01000 double denom = time_array[idx+1] - time_array[idx-1];
01001 double top = t - time_array[idx-1];
01002 if (voltage_vll_array) interpolate (voltage_vll_array, idx, denom, top);
01003 if (voltage_vln_array) interpolate (voltage_vln_array, idx, denom, top);
01004 if (voltage_unbalance_array) interpolate (voltage_unbalance_array, idx, denom, top);
01005 if (total_load_array) interpolate (total_load_array, idx, denom, top);
01006 if (hvac_load_array) interpolate (hvac_load_array, idx, denom, top);
01007 if (air_temperature_array) interpolate (air_temperature_array, idx, denom, top);
01008 if (dev_cooling_array) interpolate (dev_cooling_array, idx, denom, top);
01009 if (dev_heating_array) interpolate (dev_heating_array, idx, denom, top);
01010 if (wh_load_array) interpolate (wh_load_array, idx, denom, top);
01011 if (count_array) interpolate (count_array, idx, denom, top);
01012 if (real_power_array) interpolate (real_power_array, idx, denom, top);
01013 if (reactive_power_array) interpolate (reactive_power_array, idx, denom, top);
01014 if (real_power_loss_array) interpolate (real_power_loss_array, idx, denom, top);
01015 if (reactive_power_loss_array) interpolate (reactive_power_loss_array, idx, denom, top);
01016 }
01017
01018 double metrics_collector::findMax(double array[], int length) {
01019 double max = array[0];
01020
01021 for (int i = 1; i < length; i++) {
01022 if (array[i] > max) {
01023 max = array[i];
01024 }
01025 }
01026 return max;
01027 }
01028
01029 double metrics_collector::findMin(double array[], int length) {
01030 double min = array[0];
01031
01032 for (int i = 1; i < length; i++) {
01033 if (array[i] < min) {
01034 min = array[i];
01035 }
01036 }
01037 return min;
01038 }
01039
01040 double metrics_collector::findAverage(double array[], int length) {
01041 if (length < 2) return array[0];
01042 double sum = 0;
01043 double tlen = time_array[length-1] - time_array[0];
01044 for (int i = 1; i < length; i++) {
01045 double dA = 0.5 * (array[i] + array[i-1]) * (time_array[i] - time_array[i-1]);
01046 sum += dA;
01047 }
01048 return sum / tlen;
01049 }
01050
01051
01052 struct HistBar {
01053 double height;
01054 double v1;
01055 double width;
01056 double avg;
01057 HistBar (TIMESTAMP t1, TIMESTAMP t2, double y1, double y2) {
01058 height = t2 - t1;
01059 v1 = y1;
01060 width = y2 - y1;
01061 avg = 0.5 * (y1 + y2);
01062 }
01063 bool operator < (const HistBar& bar) const {
01064 return avg < bar.avg;
01065 }
01066 };
01067
01068 double metrics_collector::findMedian(double array[], int length) {
01069 std::vector<HistBar> Histogram;
01070
01071 double nobs = 0.0;
01072 for (int i = 1; i < length; i++) {
01073 Histogram.push_back (HistBar (time_array[i-1], time_array[i], array[i-1], array[i]));
01074 nobs += Histogram[i-1].height;
01075 }
01076
01077 std::sort(Histogram.begin(), Histogram.end());
01078
01079
01080 double cume = 0.0;
01081 for (int i = 0; i < length - 1; i++) {
01082 if ((cume + Histogram[i].height) >= 0.5 * nobs) {
01083 return Histogram[i].v1 + (0.5 * nobs - cume) * Histogram[i].width / Histogram[i].height;
01084
01085 }
01086 cume += Histogram[i].height;
01087 }
01088 return 0.0;
01089 }
01090
01091 vol_violation metrics_collector::findOutLimit (bool firstCall, double array[], bool checkAbove, double limitVal, int length) {
01092 struct vol_violation result;
01093 double y1, y2, dt, t, slope;
01094 bool crossed;
01095 result.countViolation = 0;
01096 result.durationViolation = 0.0;
01097
01098 for (int i = 1; i < length; i++) {
01099 dt = time_array[i] - time_array[i-1];
01100 y2 = array[i] - limitVal;
01101 y1 = array[i-1] - limitVal;
01102 crossed = false;
01103 if (checkAbove) {
01104 if (y1 > 0.0 || y2 > 0.0) {
01105 if (y1 * y2 <= 0.0) crossed = true;
01106 if (firstCall) {
01107 result.countViolation += 1;
01108 } else if (y1 <= 0.0 && y2 > 0.0) {
01109 result.countViolation += 1;
01110 }
01111 if (crossed) {
01112 slope = (y2 - y1) / dt;
01113 t = -y1 / slope;
01114 assert (t >= 0.0 && t <= dt);
01115 if (y1 > 0.0) {
01116 result.durationViolation += t;
01117 } else {
01118 result.durationViolation += (dt - t);
01119 }
01120 } else {
01121 result.durationViolation += dt;
01122 }
01123 }
01124 } else {
01125 if (y1 < 0.0 || y2 < 0.0) {
01126 if (y1 * y2 <= 0.0) crossed = true;
01127 if (firstCall) {
01128 result.countViolation += 1;
01129 } else if (y1 >= 0.0 && y2 < 0.0) {
01130 result.countViolation += 1;
01131 }
01132 if (crossed) {
01133 slope = (y2 - y1) / dt;
01134 t = -y1 / slope;
01135 assert (t >= 0.0 && t <= dt);
01136 if (y1 < 0.0) {
01137 result.durationViolation += t;
01138 } else {
01139 result.durationViolation += (dt - t);
01140 }
01141 } else {
01142 result.durationViolation += dt;
01143 }
01144 }
01145 }
01146 firstCall = false;
01147 }
01148 if (log_me) {
01149 printf("limit %g count %i duration %g\n", limitVal, result.countViolation, result.durationViolation);
01150 }
01151 return result;
01152 }
01153
01154 EXPORT int create_metrics_collector(OBJECT **obj, OBJECT *parent){
01155 int rv = 0;
01156 try {
01157 *obj = gl_create_object(metrics_collector::oclass);
01158 if(*obj != NULL){
01159 metrics_collector *my = OBJECTDATA(*obj, metrics_collector);
01160 gl_set_parent(*obj, parent);
01161 rv = my->create();
01162 }
01163 }
01164 catch (char *msg){
01165 gl_error("create_metrics_collector: %s", msg);
01166 }
01167 catch (const char *msg){
01168 gl_error("create_metrics_collector: %s", msg);
01169 }
01170 catch (...){
01171 gl_error("create_metrics_collector: unexpected exception caught");
01172 }
01173 return rv;
01174 }
01175
01176 EXPORT int init_metrics_collector(OBJECT *obj){
01177 metrics_collector *my = OBJECTDATA(obj, metrics_collector);
01178 int rv = 0;
01179 try {
01180 rv = my->init(obj->parent);
01181 }
01182 catch (char *msg){
01183 gl_error("init_metrics_collector: %s", msg);
01184 }
01185 catch (const char *msg){
01186 gl_error("init_metrics_collector: %s", msg);
01187 }
01188 return rv;
01189 }
01190
01191 EXPORT TIMESTAMP sync_metrics_collector(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass){
01192 TIMESTAMP rv = 0;
01193 metrics_collector *my = OBJECTDATA(obj, metrics_collector);
01194 try {
01195 switch(pass){
01196 case PC_PRETOPDOWN:
01197 rv = TS_NEVER;
01198 break;
01199 case PC_BOTTOMUP:
01200 rv = TS_NEVER;
01201 break;
01202 case PC_POSTTOPDOWN:
01203 rv = my->postsync(obj->clock, t0);
01204 obj->clock = t0;
01205 break;
01206 default:
01207 throw "invalid pass request";
01208 }
01209 }
01210 catch(char *msg){
01211 gl_error("sync_metrics_collector: %s", msg);
01212 }
01213 catch(const char *msg){
01214 gl_error("sync_metrics_collector: %s", msg);
01215 }
01216 return rv;
01217 }
01218
01219 EXPORT int commit_metrics_collector(OBJECT *obj){
01220 int rv = 0;
01221 metrics_collector *my = OBJECTDATA(obj, metrics_collector);
01222 try {
01223 rv = my->commit(obj->clock);
01224 }
01225 catch (char *msg){
01226 gl_error("commit_metrics_collector: %s", msg);
01227 }
01228 catch (const char *msg){
01229 gl_error("commit_metrics_collector: %s", msg);
01230 }
01231 return rv;
01232 }
01233
01234 EXPORT int isa_metrics_collector(OBJECT *obj, char *classname)
01235 {
01236 return OBJECTDATA(obj, metrics_collector)->isa(classname);
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247