00001
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <errno.h>
00012
00013 #include "gridlabd.h"
00014 #include "metrics.h"
00015
00016 CLASS *metrics::oclass = NULL;
00017 metrics *metrics::defaults = NULL;
00018
00019 bool metrics::report_event_log = true;
00020
00021 static PASSCONFIG clockpass = PC_POSTTOPDOWN;
00022
00023
00024 metrics::metrics(MODULE *module)
00025 {
00026 if (oclass==NULL)
00027 {
00028 oclass = gl_register_class(module,"metrics",sizeof(metrics),PC_POSTTOPDOWN|PC_AUTOLOCK);
00029 if (oclass==NULL)
00030 throw "unable to register class metrics";
00031 else
00032 oclass->trl = TRL_DEMONSTRATED;
00033
00034 if (gl_publish_variable(oclass,
00035 PT_char1024, "report_file", PADDR(report_file),
00036 PT_char1024, "customer_group", PADDR(customer_group),
00037 PT_object, "module_metrics_object", PADDR(module_metrics_obj),
00038 PT_char1024, "metrics_of_interest", PADDR(metrics_oi),
00039 PT_double, "metric_interval[s]", PADDR(metric_interval_dbl),
00040 PT_double, "report_interval[s]", PADDR(report_interval_dbl),
00041 PT_bool,"perform_secondary_interruptions_count",PADDR(secondary_interruptions_count),PT_ACCESS,PA_HIDDEN,
00042 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00043
00044 if (gl_publish_function(oclass, "metrics_event_ended", (FUNCTIONADDR)metrics_event_ended)==NULL)
00045 GL_THROW("Unable to publish reliability external function");
00046 if (gl_publish_function(oclass, "metrics_event_ended_secondary", (FUNCTIONADDR)metrics_event_ended_secondary)==NULL)
00047 GL_THROW("Unable to publish reliability external function");
00048 if (gl_publish_function(oclass, "metrics_get_interrupted_count", (FUNCTIONADDR)metrics_get_interrupted_count)==NULL)
00049 GL_THROW("Unable to publish reliability external function");
00050 if (gl_publish_function(oclass, "metrics_get_interrupted_count_secondary", (FUNCTIONADDR)metrics_get_interrupted_count_secondary)==NULL)
00051 GL_THROW("Unable to publish reliability external function");
00052 }
00053 }
00054
00055
00056 int metrics::create(void)
00057 {
00058 customer_group[0] = '\0';
00059 module_metrics_obj = NULL;
00060 metrics_oi[0] = '\0';
00061 metric_interval_dbl = 0.0;
00062 report_interval_dbl = 31536000.0;
00063
00064
00065 num_indices = 0;
00066 CalcIndices = NULL;
00067 next_metric_interval = 0;
00068 next_report_interval = 0;
00069 next_annual_interval = 0;
00070
00071 metric_interval = 0;
00072 report_interval = 0;
00073 CustomerCount = 0;
00074 Customers = NULL;
00075 curr_time = TS_NEVER;
00076 metric_interval_event_count = 0;
00077 annual_interval_event_count = 0;
00078 metric_equal_annual = false;
00079
00080 reset_interval_func = NULL;
00081 reset_annual_func = NULL;
00082 compute_metrics = NULL;
00083
00084 secondary_interruptions_count = false;
00085
00086 return 1;
00087 }
00088
00089
00090 int metrics::init(OBJECT *parent)
00091 {
00092 OBJECT *hdr = OBJECTHDR(this);
00093 int index, indexa, indexb, returnval;
00094 char work_metrics[1025];
00095 char *startVal, *endVal, *workVal;
00096 char workbuffer[1025];
00097 char metricbuffer[257];
00098 FILE *FPVal;
00099 FINDLIST *CandidateObjs;
00100 OBJECT *temp_obj;
00101 bool *temp_bool;
00102 FUNCTIONADDR funadd = NULL;
00103 STATUS temp_return_status;
00104
00105
00106 if (module_metrics_obj == NULL)
00107 {
00108 GL_THROW("Please specify a module metrics object for metrics:%s",hdr->name);
00109
00110
00111
00112
00113
00114 }
00115
00116
00117 funadd = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"init_reliability"));
00118
00119
00120 if (funadd == NULL)
00121 {
00122 GL_THROW("Unable to map reliability init function on %s in %s",module_metrics_obj->name,hdr->name);
00123
00124
00125
00126
00127
00128 }
00129
00130 temp_return_status = ((STATUS (*)(OBJECT *, OBJECT *))(*funadd))(module_metrics_obj,hdr);
00131
00132
00133 if (temp_return_status==FAILED)
00134 {
00135 GL_THROW("Unable to map reliability init function on %s in %s",module_metrics_obj->name,hdr->name);
00136
00137 }
00138
00139
00140 index = 0;
00141
00142 while ((metrics_oi[index] != '\0') && (index < 1024))
00143 {
00144 if (metrics_oi[index] == ',')
00145 {
00146 num_indices++;
00147 }
00148
00149 index++;
00150 }
00151
00152
00153 if (index == 1024)
00154 {
00155 GL_THROW("Maximum length exceeded on metrics_of_interest in metrics:%s",hdr->name);
00156
00157
00158
00159
00160
00161
00162 }
00163
00164
00165 if (num_indices >= 1)
00166 num_indices++;
00167
00168
00169 if ((num_indices == 0) && (index > 1))
00170 num_indices = 1;
00171
00172
00173 if (num_indices == 0)
00174 {
00175 GL_THROW("No indices of interest specified for metrics:%s",hdr->name);
00176
00177
00178
00179 }
00180
00181
00182 CalcIndices = (INDEXARRAY*)gl_malloc(num_indices * sizeof(INDEXARRAY));
00183
00184
00185 if (CalcIndices == NULL)
00186 {
00187 GL_THROW("Failure to allocate indices memory in metrics:%s",hdr->name);
00188
00189
00190
00191
00192
00193 }
00194
00195
00196 for (index=0; index<num_indices; index++)
00197 {
00198 CalcIndices[index].MetricLoc = NULL;
00199
00200 for (indexa=0; indexa<257; indexa++)
00201 CalcIndices[index].MetricName[indexa]='\0';
00202 }
00203
00204
00205 metrics_oi.copy_to(work_metrics);
00206
00207
00208 startVal = work_metrics;
00209 endVal = work_metrics;
00210
00211
00212 for (index=0; index<num_indices; index++)
00213 {
00214
00215 while ((*endVal != ',') && (*endVal != '\0'))
00216 {
00217 endVal++;
00218 }
00219
00220
00221 *endVal='\0';
00222
00223
00224 workVal = startVal;
00225 indexa = 0;
00226 while ((workVal<=endVal) && (indexa < 256))
00227 {
00228
00229 CalcIndices[index].MetricName[indexa] = *workVal;
00230
00231
00232 metricbuffer[indexa] = *workVal;
00233
00234
00235 indexa++;
00236 workVal++;
00237 }
00238
00239
00240 indexb = indexa-1;
00241
00242
00243 endVal++;
00244 startVal = endVal;
00245
00246
00247 CalcIndices[index].MetricLoc = new gld_property(module_metrics_obj,CalcIndices[index].MetricName);
00248
00249
00250 if ((CalcIndices[index].MetricLoc->is_valid() != true) || (CalcIndices[index].MetricLoc->is_double() != true))
00251 {
00252 GL_THROW("Unable to find metric %s in object %s for metric:%s",CalcIndices[index].MetricName.get_string(),module_metrics_obj->name,hdr->name);
00253
00254
00255
00256
00257
00258 }
00259
00260
00261 if ((indexb+4) <= 256)
00262 {
00263 metricbuffer[indexb] = '_';
00264 metricbuffer[(indexb+1)] = 'i';
00265 metricbuffer[(indexb+2)] = 'n';
00266 metricbuffer[(indexb+3)] = 't';
00267 metricbuffer[(indexb+4)] = '\0';
00268
00269
00270 CalcIndices[index].MetricLocInterval = new gld_property(module_metrics_obj,metricbuffer);
00271
00272
00273 if ((CalcIndices[index].MetricLocInterval->is_valid() != true) || (CalcIndices[index].MetricLocInterval->is_double() != true))
00274 {
00275 GL_THROW("Unable to find metric interval in object %s for metric:%s",module_metrics_obj->name,hdr->name);
00276
00277
00278
00279
00280
00281 }
00282
00283
00284 }
00285 }
00286
00287
00288 reset_interval_func = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"reset_interval_metrics"));
00289
00290
00291 if (reset_interval_func == NULL)
00292 {
00293 GL_THROW("Failed to map interval reset in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
00294
00295
00296
00297
00298
00299 }
00300
00301 reset_annual_func = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"reset_annual_metrics"));
00302
00303
00304 if (reset_annual_func == NULL)
00305 {
00306 GL_THROW("Failed to map annual reset in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
00307
00308
00309
00310
00311
00312 }
00313
00314 compute_metrics = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"calc_metrics"));
00315
00316
00317 if (compute_metrics == NULL)
00318 {
00319 GL_THROW("Failed to map metric computation function in metrics object %s for metrics:%s",module_metrics_obj->name,hdr->name);
00320
00321
00322
00323
00324
00325 }
00326
00327
00328 returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_interval_func))(hdr,module_metrics_obj);
00329
00330 if (returnval != 1)
00331 {
00332 GL_THROW("Failed to reset interval metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
00333
00334
00335
00336
00337 }
00338
00339
00340 returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_annual_func))(hdr,module_metrics_obj);
00341
00342 if (returnval != 1)
00343 {
00344 GL_THROW("Failed to reset annual metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
00345
00346
00347
00348
00349 }
00350
00351
00352 metric_interval = (TIMESTAMP)metric_interval_dbl;
00353 report_interval = (TIMESTAMP)report_interval_dbl;
00354
00355
00356 if (metric_interval == 31536000)
00357 metric_equal_annual = true;
00358
00359
00360 if (report_file[0] == '\0')
00361 {
00362 GL_THROW("Please specify a proper report file name if you would like an output file from metrics:%s",hdr->name);
00363
00364
00365
00366
00367 }
00368
00369
00370 FPVal = fopen(report_file,"wt");
00371
00372
00373 if (FPVal == NULL)
00374 {
00375 GL_THROW("Unable to create the report file '%s' for metrics:%s",report_file,hdr->name);
00376
00377
00378
00379
00380
00381 }
00382
00383
00384 fprintf(FPVal,"Reliability report for %s\n", gl_global_getvar("modelname",workbuffer,(1025*sizeof(char))));
00385
00386
00387 CandidateObjs = gl_find_objects(FL_GROUP,customer_group.get_string());
00388 if (CandidateObjs==NULL)
00389 {
00390 GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,customer_group.get_string());
00391
00392
00393
00394
00395
00396 }
00397
00398
00399 if (CandidateObjs->hit_count == 0)
00400 {
00401 GL_THROW("Failure to find devices for %s specified as: %s",hdr->name,customer_group.get_string());
00402
00403 }
00404
00405
00406 CustomerCount = CandidateObjs->hit_count;
00407
00408
00409 Customers = (CUSTARRAY*)gl_malloc(CustomerCount*sizeof(CUSTARRAY));
00410
00411
00412 if (Customers == NULL)
00413 {
00414 GL_THROW("Failure to allocate customer list memory in metrics:%s",hdr->name);
00415
00416
00417
00418
00419
00420 }
00421
00422
00423 temp_obj = NULL;
00424 for (index=0; index<CustomerCount; index++)
00425 {
00426
00427 temp_obj = gl_find_next(CandidateObjs, temp_obj);
00428
00429 if (temp_obj == NULL)
00430 {
00431 GL_THROW("Failed to populate customer list in metrics: %s",hdr->name);
00432
00433
00434
00435
00436
00437 }
00438
00439 Customers[index].CustomerObj = temp_obj;
00440
00441
00442 Customers[index].CustInterrupted = new gld_property(temp_obj,"customer_interrupted");
00443
00444
00445 if ((Customers[index].CustInterrupted->is_valid() != true) || (Customers[index].CustInterrupted->is_bool() != true))
00446 {
00447 GL_THROW("Unable to find interrupted flag for customer object %s in metrics:%s",temp_obj->name,hdr->name);
00448
00449
00450
00451
00452
00453 }
00454
00455 if (index == 0)
00456 {
00457
00458
00459 Customers[index].CustInterrupted_Secondary = new gld_property(temp_obj, "customer_interrupted_secondary");
00460
00461
00462 if ((Customers[index].CustInterrupted_Secondary->is_valid() != true) || (Customers[index].CustInterrupted_Secondary->is_bool() != true))
00463 {
00464 gl_warning("Unable to find secondary interruption flag, no secondary interruptions recorded in metrics:%s",hdr->name);
00465
00466
00467
00468
00469
00470
00471
00472
00473 Customers[index].CustInterrupted_Secondary = NULL;
00474 }
00475 else
00476 {
00477 secondary_interruptions_count = true;
00478 }
00479 }
00480 else if (secondary_interruptions_count == true)
00481 {
00482
00483
00484 Customers[index].CustInterrupted_Secondary = new gld_property(temp_obj, "customer_interrupted_secondary");
00485
00486
00487 if ((Customers[index].CustInterrupted_Secondary->is_valid() != true) || (Customers[index].CustInterrupted_Secondary->is_bool() != true))
00488 {
00489 GL_THROW("Unable to find secondary interruption flag for customer object %s in metrics:%s",temp_obj->name,hdr->name);
00490
00491
00492
00493
00494
00495 }
00496 }
00497
00498
00499 }
00500
00501
00502 gl_free(CandidateObjs);
00503
00504
00505 fprintf(FPVal,"Number of customers = %d\n\n",CustomerCount);
00506
00507
00508 funadd = NULL;
00509
00510
00511 funadd = (FUNCTIONADDR)(gl_get_function(module_metrics_obj,"logfile_extra"));
00512
00513
00514 if (funadd != NULL)
00515 {
00516
00517 returnval = ((int (*)(OBJECT *, char *))(*funadd))(module_metrics_obj,workbuffer);
00518
00519
00520 if (returnval==0)
00521 {
00522 GL_THROW("Failed to write extra header material for %s in %s",module_metrics_obj->name,hdr->name);
00523
00524
00525
00526
00527 }
00528
00529
00530 fprintf(FPVal,"%s",workbuffer);
00531 }
00532
00533
00534 fclose(FPVal);
00535
00536 return 1;
00537 }
00538
00539 TIMESTAMP metrics::postsync(TIMESTAMP t0, TIMESTAMP t1)
00540 {
00541 DATETIME dt;
00542 int returnval;
00543 bool metrics_written;
00544 OBJECT *hdr = OBJECTHDR(this);
00545 FILE *FPVal;
00546
00547
00548 if (curr_time == TS_NEVER)
00549 {
00550
00551 if (metric_interval == 0)
00552 {
00553 next_metric_interval = TS_NEVER;
00554 }
00555 else
00556 {
00557 next_metric_interval = t1 + metric_interval;
00558 }
00559
00560 next_report_interval = t1 + report_interval;
00561 next_annual_interval = t1 + 31536000;
00562
00563
00564 if (report_event_log == true)
00565 {
00566
00567 FPVal = fopen(report_file,"at");
00568
00569
00570 gl_localtime(t1,&dt);
00571
00572
00573 fprintf(FPVal,"Events for year starting at %04d-%02d-%02d %02d:%02d:%02d\n",dt.year,dt.month,dt.day,dt.hour,dt.minute,dt.second);
00574
00575
00576 if (secondary_interruptions_count == true)
00577 {
00578 fprintf(FPVal,"Annual Event #,Metric Interval Event #,Starting DateTime (YYYY-MM-DD hh:mm:ss),Ending DateTime (YYYY-MM-DD hh:mm:ss),Object type,Object Name,Inducing Object,\"Protective\" Device,Desired Fault type,Implemented Fault Type,Number customers affected,Secondary number of customers affected\n");
00579 }
00580 else
00581 {
00582 fprintf(FPVal,"Annual Event #,Metric Interval Event #,Starting DateTime (YYYY-MM-DD hh:mm:ss),Ending DateTime (YYYY-MM-DD hh:mm:ss),Object type,Object Name,Inducing Object,\"Protective\" Device,Desired Fault type,Implemented Fault Type,Number customers affected\n");
00583 }
00584
00585
00586 fclose(FPVal);
00587 }
00588
00589
00590 curr_time = t1;
00591 }
00592
00593
00594 if (curr_time != t0)
00595 {
00596
00597 metrics_written = false;
00598
00599 if (t0 >= next_report_interval)
00600 {
00601
00602 write_metrics();
00603
00604
00605 metrics_written = true;
00606
00607
00608 next_report_interval = t0 + report_interval;
00609 }
00610
00611
00612 if (t0 >= next_metric_interval)
00613 {
00614
00615 if (metrics_written == false)
00616 write_metrics();
00617
00618
00619 next_metric_interval = t0 + metric_interval;
00620
00621
00622 wlock(module_metrics_obj);
00623
00624
00625 returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_interval_func))(hdr,module_metrics_obj);
00626
00627
00628 wunlock(module_metrics_obj);
00629
00630 if (returnval != 1)
00631 {
00632 GL_THROW("Failed to reset interval metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
00633
00634 }
00635
00636
00637 metric_interval_event_count = 0;
00638
00639
00640 if ((report_event_log == true) && (metric_equal_annual == false))
00641 {
00642
00643 FPVal = fopen(report_file,"at");
00644
00645
00646 gl_localtime(t0,&dt);
00647
00648
00649 fprintf(FPVal,"\nNew Metric Interval started at %04d-%02d-%02d %02d:%02d:%02d\n\n",dt.year,dt.month,dt.day,dt.hour,dt.minute,dt.second);
00650
00651
00652 fclose(FPVal);
00653 }
00654 }
00655
00656
00657 if (t0 >= next_annual_interval)
00658 {
00659
00660 if (metrics_written == false)
00661 write_metrics();
00662
00663
00664 next_annual_interval = t0 + 31536000;
00665
00666
00667 wlock(module_metrics_obj);
00668
00669
00670 returnval = ((int (*)(OBJECT *, OBJECT *))(*reset_annual_func))(hdr,module_metrics_obj);
00671
00672
00673 wunlock(module_metrics_obj);
00674
00675 if (returnval != 1)
00676 {
00677 GL_THROW("Failed to reset annual metrics for %s by metrics:%s",module_metrics_obj->name,hdr->name);
00678
00679 }
00680
00681
00682 annual_interval_event_count = 0;
00683
00684
00685 if (report_event_log == true)
00686 {
00687
00688 FPVal = fopen(report_file,"at");
00689
00690
00691 gl_localtime(t0,&dt);
00692
00693
00694 fprintf(FPVal,"\nNew Annual Interval started at %04d-%02d-%02d %02d:%02d:%02d\n\n",dt.year,dt.month,dt.day,dt.hour,dt.minute,dt.second);
00695
00696
00697 fclose(FPVal);
00698 }
00699 }
00700
00701
00702 curr_time = t0;
00703 }
00704
00705
00706 if (next_metric_interval < next_annual_interval)
00707 {
00708 if (next_metric_interval < next_report_interval)
00709 return -next_metric_interval;
00710 else
00711 return -next_report_interval;
00712 }
00713 else
00714 {
00715 if (next_annual_interval < next_report_interval)
00716 return -next_annual_interval;
00717 else
00718 return -next_report_interval;
00719 }
00720 }
00721
00722
00723 void metrics::event_ended(OBJECT *event_obj, OBJECT *fault_obj, OBJECT *faulting_obj, TIMESTAMP event_start_time, TIMESTAMP event_end_time, char *fault_type, char *impl_fault, int number_customers_int)
00724 {
00725 DATETIME start_dt, end_dt;
00726 TIMESTAMP outage_length;
00727 OBJECT *hdr = OBJECTHDR(this);
00728 int returnval;
00729 FILE *FPVal;
00730
00731
00732 outage_length = event_end_time - event_start_time;
00733
00734
00735 wlock(module_metrics_obj);
00736
00737
00738 returnval = ((int (*)(OBJECT *, OBJECT *, int, int, TIMESTAMP, TIMESTAMP))(*compute_metrics))(hdr,module_metrics_obj,number_customers_int,CustomerCount,outage_length,metric_interval);
00739
00740
00741 wunlock(module_metrics_obj);
00742
00743
00744 if (returnval != 1)
00745 {
00746 GL_THROW("Metrics:%s failed to perform a post-event metric update",hdr->name);
00747
00748
00749
00750
00751
00752 }
00753
00754
00755 metric_interval_event_count++;
00756 annual_interval_event_count++;
00757
00758
00759 if (report_event_log == true)
00760 {
00761
00762 gl_localtime(event_start_time,&start_dt);
00763 gl_localtime(event_end_time,&end_dt);
00764
00765
00766 FPVal = fopen(report_file,"at");
00767
00768
00769 if (faulting_obj==NULL)
00770 {
00771
00772 fprintf(FPVal,"%d,%d,%04d-%02d-%02d %02d:%02d:%02d,%04d-%02d-%02d %02d:%02d:%02d,%s,%s,%s,N/A,%s,%s,%d\n",annual_interval_event_count,metric_interval_event_count,start_dt.year,start_dt.month,start_dt.day,start_dt.hour,start_dt.minute,start_dt.second,end_dt.year,end_dt.month,end_dt.day,end_dt.hour,end_dt.minute,end_dt.second,fault_obj->oclass->name,fault_obj->name,event_obj->name,fault_type,impl_fault,number_customers_int);
00773 }
00774 else
00775 {
00776
00777 fprintf(FPVal,"%d,%d,%04d-%02d-%02d %02d:%02d:%02d,%04d-%02d-%02d %02d:%02d:%02d,%s,%s,%s,%s,%s,%s,%d\n",annual_interval_event_count,metric_interval_event_count,start_dt.year,start_dt.month,start_dt.day,start_dt.hour,start_dt.minute,start_dt.second,end_dt.year,end_dt.month,end_dt.day,end_dt.hour,end_dt.minute,end_dt.second,fault_obj->oclass->name,fault_obj->name,event_obj->name,faulting_obj->name,fault_type,impl_fault,number_customers_int);
00778 }
00779
00780
00781 fclose(FPVal);
00782 }
00783 }
00784
00785
00786 void metrics::event_ended_sec(OBJECT *event_obj, OBJECT *fault_obj, OBJECT *faulting_obj, TIMESTAMP event_start_time, TIMESTAMP event_end_time, char *fault_type, char *impl_fault, int number_customers_int, int number_customers_int_secondary)
00787 {
00788 DATETIME start_dt, end_dt;
00789 TIMESTAMP outage_length;
00790 OBJECT *hdr = OBJECTHDR(this);
00791 int returnval;
00792 FILE *FPVal;
00793
00794
00795 outage_length = event_end_time - event_start_time;
00796
00797
00798 wlock(module_metrics_obj);
00799
00800
00801 returnval = ((int (*)(OBJECT *, OBJECT *, int, int, int, TIMESTAMP, TIMESTAMP))(*compute_metrics))(hdr,module_metrics_obj,number_customers_int,number_customers_int_secondary,CustomerCount,outage_length,metric_interval);
00802
00803
00804 wunlock(module_metrics_obj);
00805
00806
00807 if (returnval != 1)
00808 {
00809 GL_THROW("Metrics:%s failed to perform a post-event metric update",hdr->name);
00810
00811
00812
00813
00814
00815 }
00816
00817
00818 metric_interval_event_count++;
00819 annual_interval_event_count++;
00820
00821
00822 if (report_event_log == true)
00823 {
00824
00825 gl_localtime(event_start_time,&start_dt);
00826 gl_localtime(event_end_time,&end_dt);
00827
00828
00829 FPVal = fopen(report_file,"at");
00830
00831
00832 if (faulting_obj==NULL)
00833 {
00834 fprintf(FPVal,"%d,%d,%04d-%02d-%02d %02d:%02d:%02d,%04d-%02d-%02d %02d:%02d:%02d,%s,%s,%s,N/A,%s,%s,%d,%d\n",annual_interval_event_count,metric_interval_event_count,start_dt.year,start_dt.month,start_dt.day,start_dt.hour,start_dt.minute,start_dt.second,end_dt.year,end_dt.month,end_dt.day,end_dt.hour,end_dt.minute,end_dt.second,fault_obj->oclass->name,fault_obj->name,event_obj->name,fault_type,impl_fault,number_customers_int,number_customers_int_secondary);
00835 }
00836 else
00837 {
00838 fprintf(FPVal,"%d,%d,%04d-%02d-%02d %02d:%02d:%02d,%04d-%02d-%02d %02d:%02d:%02d,%s,%s,%s,%s,%s,%s,%d,%d\n",annual_interval_event_count,metric_interval_event_count,start_dt.year,start_dt.month,start_dt.day,start_dt.hour,start_dt.minute,start_dt.second,end_dt.year,end_dt.month,end_dt.day,end_dt.hour,end_dt.minute,end_dt.second,fault_obj->oclass->name,fault_obj->name,event_obj->name,faulting_obj->name,fault_type,impl_fault,number_customers_int,number_customers_int_secondary);
00839 }
00840
00841
00842 fclose(FPVal);
00843 }
00844 }
00845
00846
00847 int metrics::get_interrupted_count(void)
00848 {
00849 int index, in_outage;
00850 gld_rlock *test_rlock;
00851 bool temp_bool;
00852
00853
00854 in_outage = 0;
00855
00856
00857 for (index=0; index<CustomerCount; index++)
00858 {
00859
00860 Customers[index].CustInterrupted->getp<bool>(temp_bool,*test_rlock);
00861
00862
00863 if (temp_bool == true)
00864 in_outage++;
00865 }
00866
00867
00868 return in_outage;
00869 }
00870
00871
00872 void metrics::get_interrupted_count_secondary(int *in_outage, int *in_outage_secondary)
00873 {
00874 int index, in_outage_temp, in_outage_temp_sec;
00875 gld_rlock *test_rlock;
00876 bool temp_bool;
00877
00878
00879 in_outage_temp = 0;
00880 in_outage_temp_sec = 0;
00881
00882
00883 for (index=0; index<CustomerCount; index++)
00884 {
00885
00886 Customers[index].CustInterrupted->getp<bool>(temp_bool,*test_rlock);
00887
00888
00889 if (temp_bool == true)
00890 in_outage_temp++;
00891
00892
00893 Customers[index].CustInterrupted_Secondary->getp<bool>(temp_bool,*test_rlock);
00894
00895
00896 if (temp_bool == true)
00897 in_outage_temp_sec++;
00898 }
00899
00900
00901 *in_outage = in_outage_temp;
00902 *in_outage_secondary = in_outage_temp_sec;
00903 }
00904
00905
00906
00907 void metrics::write_metrics(void)
00908 {
00909 FILE *FPVAL;
00910 int index;
00911 bool first_written;
00912
00913
00914 FPVAL = fopen(report_file,"at");
00915
00916
00917 fprintf(FPVAL,"\n");
00918
00919
00920 for (index=0; index<num_indices; index++)
00921 {
00922
00923 if (index==0)
00924 {
00925
00926 fprintf(FPVAL,"%s = %f",CalcIndices[index].MetricName.get_string(),CalcIndices[index].MetricLoc->get_double());
00927 }
00928 else
00929 {
00930
00931 fprintf(FPVAL,", %s = %f",CalcIndices[index].MetricName.get_string(),CalcIndices[index].MetricLoc->get_double());
00932 }
00933 }
00934
00935 fprintf(FPVAL,"\n");
00936
00937
00938 if (metric_interval != 0)
00939 {
00940 first_written = false;
00941
00942 for (index=0; index<num_indices; index++)
00943 {
00944 if (CalcIndices[index].MetricLocInterval != NULL)
00945 {
00946 if (first_written == false)
00947 {
00948
00949 fprintf(FPVAL,"Interval values: %s = %f",CalcIndices[index].MetricName.get_string(),CalcIndices[index].MetricLocInterval->get_double());
00950 first_written = true;
00951 }
00952 else
00953 {
00954
00955 fprintf(FPVAL,", %s = %f",CalcIndices[index].MetricName.get_string(),CalcIndices[index].MetricLocInterval->get_double());
00956 }
00957 }
00958 }
00959 fprintf(FPVAL,"\n");
00960 }
00961
00962
00963 fclose(FPVAL);
00964 }
00965
00966
00967 EXPORT STATUS metrics_get_interrupted_count(OBJECT *obj,int *in_outage)
00968 {
00969 metrics *mymet = OBJECTDATA(obj,metrics);
00970
00971 try
00972 {
00973 *in_outage = mymet->get_interrupted_count();
00974 }
00975 catch (char *msg)
00976 {
00977 gl_error("metrics_get_interrupted_count: %s", msg);
00978 return FAILED;
00979 }
00980 catch (const char *msg)
00981 {
00982 gl_error("metrics_get_interrupted_count: %s", msg);
00983 return FAILED;
00984 }
00985 catch (...)
00986 {
00987 gl_error("metrics_get_interrupted_count: unhandled exception");
00988 return FAILED;
00989 }
00990
00991 return SUCCESS;
00992 }
00993
00994 EXPORT STATUS metrics_get_interrupted_count_secondary(OBJECT *obj,int *in_outage, int *in_outage_secondary)
00995 {
00996 metrics *mymet = OBJECTDATA(obj,metrics);
00997
00998 try
00999 {
01000 mymet->get_interrupted_count_secondary(in_outage,in_outage_secondary);
01001 }
01002 catch (char *msg)
01003 {
01004 gl_error("metrics_get_interrupted_count: %s", msg);
01005 return FAILED;
01006 }
01007 catch (const char *msg)
01008 {
01009 gl_error("metrics_get_interrupted_count: %s", msg);
01010 return FAILED;
01011 }
01012 catch (...)
01013 {
01014 gl_error("metrics_get_interrupted_count: unhandled exception");
01015 return FAILED;
01016 }
01017
01018 return SUCCESS;
01019 }
01020
01021 EXPORT STATUS metrics_event_ended(OBJECT *obj, OBJECT *event_obj,OBJECT *fault_obj,OBJECT *faulting_obj,TIMESTAMP event_start_time,TIMESTAMP event_end_time,char *fault_type,char *impl_fault,int number_customers_int)
01022 {
01023 metrics *mymet = OBJECTDATA(obj,metrics);
01024
01025 try
01026 {
01027 mymet->event_ended(event_obj,fault_obj,faulting_obj,event_start_time,event_end_time,fault_type,impl_fault,number_customers_int);
01028 }
01029 catch (char *msg)
01030 {
01031 gl_error("metrics_event_ended: %s", msg);
01032 return FAILED;
01033 }
01034 catch (const char *msg)
01035 {
01036 gl_error("metrics_event_ended: %s", msg);
01037 return FAILED;
01038 }
01039 catch (...)
01040 {
01041 gl_error("metrics_event_ended: unhandled exception");
01042 return FAILED;
01043 }
01044
01045 return SUCCESS;
01046 }
01047
01048 EXPORT STATUS metrics_event_ended_secondary(OBJECT *obj, OBJECT *event_obj,OBJECT *fault_obj,OBJECT *faulting_obj,TIMESTAMP event_start_time,TIMESTAMP event_end_time,char *fault_type,char *impl_fault,int number_customers_int, int number_customers_int_secondary)
01049 {
01050 metrics *mymet = OBJECTDATA(obj,metrics);
01051
01052 try
01053 {
01054 mymet->event_ended_sec(event_obj,fault_obj,faulting_obj,event_start_time,event_end_time,fault_type,impl_fault,number_customers_int,number_customers_int_secondary);
01055 }
01056 catch (char *msg)
01057 {
01058 gl_error("metrics_event_ended_secondary: %s", msg);
01059 return FAILED;
01060 }
01061 catch (const char *msg)
01062 {
01063 gl_error("metrics_event_ended_secondary: %s", msg);
01064 return FAILED;
01065 }
01066 catch (...)
01067 {
01068 gl_error("metrics_event_ended_secondary: unhandled exception");
01069 return FAILED;
01070 }
01071
01072 return SUCCESS;
01073 }
01074
01076
01078 EXPORT int create_metrics(OBJECT **obj, OBJECT *parent)
01079 {
01080 try
01081 {
01082 *obj = gl_create_object(metrics::oclass);
01083 if (*obj!=NULL)
01084 {
01085 metrics *my = OBJECTDATA(*obj,metrics);
01086 gl_set_parent(*obj,parent);
01087 return my->create();
01088 }
01089 else
01090 return 0;
01091 }
01092 CREATE_CATCHALL(metrics);
01093 }
01094
01095 EXPORT int init_metrics(OBJECT *obj, OBJECT *parent)
01096 {
01097 try
01098 {
01099 if (obj!=NULL)
01100 return OBJECTDATA(obj,metrics)->init(parent);
01101 else
01102 return 0;
01103 }
01104 INIT_CATCHALL(metrics);
01105 }
01106
01107 EXPORT TIMESTAMP sync_metrics(OBJECT *obj, TIMESTAMP t1, PASSCONFIG pass)
01108 {
01109 TIMESTAMP t2 = TS_NEVER;
01110 metrics *my = OBJECTDATA(obj,metrics);
01111 try
01112 {
01113 switch (pass) {
01114 case PC_POSTTOPDOWN:
01115 t2 = my->postsync(obj->clock,t1);
01116 break;
01117 case PC_PRETOPDOWN:
01118 case PC_BOTTOMUP:
01119 default:
01120 GL_THROW("invalid pass request (%d)", pass);
01121 break;
01122 }
01123 if (pass==clockpass)
01124 obj->clock = t1;
01125 return t2;
01126 }
01127 SYNC_CATCHALL(metrics);
01128 }