00001
00002 #include <iostream>
00003 #include "violation_recorder.h"
00004
00005 CLASS *violation_recorder::oclass = NULL;
00006 CLASS *violation_recorder::pclass = NULL;
00007 violation_recorder *violation_recorder::defaults = NULL;
00008
00009 void new_violation_recorder(MODULE *mod){
00010 new violation_recorder(mod);
00011 }
00012
00013 violation_recorder::violation_recorder(MODULE *mod){
00014 if(oclass == NULL)
00015 {
00016 #ifdef _DEBUG
00017 gl_debug("construction violation_recorder class");
00018 #endif
00019 oclass = gl_register_class(mod,"violation_recorder",sizeof(violation_recorder), PC_POSTTOPDOWN);
00020 if(oclass == NULL)
00021 GL_THROW("unable to register object class implemented by %s",__FILE__);
00022
00023 if(gl_publish_variable(oclass,
00024 PT_char256, "file", PADDR(filename), PT_DESCRIPTION, "output file name",
00025 PT_char256, "summary", PADDR(summary), PT_DESCRIPTION, "summary output file name",
00026 PT_char256, "virtual_substation", PADDR(virtual_substation), PT_DESCRIPTION, "name of the substation node to monitor for reverse flow violation",
00027 PT_double, "interval[s]", PADDR(dInterval), PT_DESCRIPTION, "recording interval (0 'every iteration', -1 'on change')",
00028 PT_double, "flush_interval[s]", PADDR(dFlush_interval), PT_DESCRIPTION, "file flush interval (0 never, negative on samples)",
00029 PT_bool, "strict", PADDR(strict), PT_DESCRIPTION, "causes the violation_recorder to stop the simulation should there be a problem opening or writing with the violation_recorder",
00030 PT_bool, "echo", PADDR(echo), PT_DESCRIPTION, "causes the violation_recorder to echo messages to the screen",
00031 PT_int32, "limit", PADDR(limit), PT_DESCRIPTION, "the maximum number of lines to write to the file",
00032 PT_int32, "violation_delay", PADDR(violation_start_delay), PT_DESCRIPTION, "the number of seconds to skip before recording violations",
00033 PT_double, "xfrmr_thermal_limit_upper", PADDR(xfrmr_thermal_limit_upper), PT_DESCRIPTION, "xfrmr_thermal_limit_upper",
00034 PT_double, "xfrmr_thermal_limit_lower", PADDR(xfrmr_thermal_limit_lower), PT_DESCRIPTION, "xfrmr_thermal_limit_lower",
00035 PT_double, "line_thermal_limit_upper", PADDR(line_thermal_limit_upper), PT_DESCRIPTION, "line_thermal_limit_upper",
00036 PT_double, "line_thermal_limit_lower", PADDR(line_thermal_limit_lower), PT_DESCRIPTION, "line_thermal_limit_lower",
00037 PT_double, "node_instantaneous_voltage_limit_upper", PADDR(node_instantaneous_voltage_limit_upper), PT_DESCRIPTION, "node_instantaneous_voltage_limit_upper",
00038 PT_double, "node_instantaneous_voltage_limit_lower", PADDR(node_instantaneous_voltage_limit_lower), PT_DESCRIPTION, "node_instantaneous_voltage_limit_lower",
00039 PT_double, "node_continuous_voltage_limit_upper", PADDR(node_continuous_voltage_limit_upper), PT_DESCRIPTION, "node_continuous_voltage_limit_upper",
00040 PT_double, "node_continuous_voltage_limit_lower", PADDR(node_continuous_voltage_limit_lower), PT_DESCRIPTION, "node_continuous_voltage_limit_lower",
00041 PT_double, "node_continuous_voltage_interval", PADDR(node_continuous_voltage_interval), PT_DESCRIPTION, "node_continuous_voltage_interval",
00042 PT_double, "secondary_dist_voltage_rise_upper_limit", PADDR(secondary_dist_voltage_rise_upper_limit), PT_DESCRIPTION, "secondary_dist_voltage_rise_upper_limit",
00043 PT_double, "secondary_dist_voltage_rise_lower_limit", PADDR(secondary_dist_voltage_rise_lower_limit), PT_DESCRIPTION, "secondary_dist_voltage_rise_lower_limit",
00044 PT_double, "substation_breaker_A_limit", PADDR(substation_breaker_A_limit), PT_DESCRIPTION, "breaker_phase_A_limit",
00045 PT_double, "substation_breaker_B_limit", PADDR(substation_breaker_B_limit), PT_DESCRIPTION, "breaker_phase_B_limit",
00046 PT_double, "substation_breaker_C_limit", PADDR(substation_breaker_C_limit), PT_DESCRIPTION, "breaker_phase_C_limit",
00047 PT_double, "substation_pf_lower_limit", PADDR(substation_pf_lower_limit), PT_DESCRIPTION, "substation_pf_lower_limit",
00048 PT_double, "inverter_v_chng_per_interval_upper_bound", PADDR(inverter_v_chng_per_interval_upper_bound), PT_DESCRIPTION, "inverter_v_chng_per_interval_upper_bound",
00049 PT_double, "inverter_v_chng_per_interval_lower_bound", PADDR(inverter_v_chng_per_interval_lower_bound), PT_DESCRIPTION, "inverter_v_chng_per_interval_lower_bound",
00050 PT_double, "inverter_v_chng_interval", PADDR(inverter_v_chng_interval), PT_DESCRIPTION, "inverter_v_chng_interval",
00051 PT_set, "violation_flag", PADDR(violation_flag), PT_DESCRIPTION, "bit set for determining which violations to check",
00052 PT_KEYWORD,"VIOLATION0",(set)VIOLATION0,
00053 PT_KEYWORD,"VIOLATION1",(set)VIOLATION1,
00054 PT_KEYWORD,"VIOLATION2",(set)VIOLATION2,
00055 PT_KEYWORD,"VIOLATION3",(set)VIOLATION3,
00056 PT_KEYWORD,"VIOLATION4",(set)VIOLATION4,
00057 PT_KEYWORD,"VIOLATION5",(set)VIOLATION5,
00058 PT_KEYWORD,"VIOLATION6",(set)VIOLATION6,
00059 PT_KEYWORD,"VIOLATION7",(set)VIOLATION7,
00060 PT_KEYWORD,"VIOLATION8",(set)VIOLATION8,
00061 PT_KEYWORD,"ALLVIOLATIONS",(set)ALLVIOLATIONS,
00062 NULL) < 1){
00063 ;
00064 }
00065
00066 defaults = this;
00067 memset(this, 0, sizeof(violation_recorder));
00068 }
00069 }
00070
00071 int violation_recorder::create(){
00072 memcpy(this, defaults, sizeof(violation_recorder));
00073 strict = false;
00074 return 1;
00075 }
00076
00077 int violation_recorder::init(OBJECT *obj){
00078
00079
00080 if(0 == filename[0]){
00081
00082 if(strict){
00083 gl_error("violation_recorder::init(): no filename defined in strict mode");
00084 return 0;
00085 } else {
00086 sprintf(filename, "%s-violation-log.csv", oclass->name);
00087 gl_warning("violation_recorder::init(): no filename defined, auto-generating '%s'", filename.get_string());
00088 }
00089 }
00090
00091
00092 if(0 == summary[0]){
00093
00094 if(strict){
00095 gl_error("violation_recorder::init(): no summary defined in strict mode");
00096 return 0;
00097 } else {
00098 sprintf(summary, "%s-violation-summary.csv", oclass->name);
00099 gl_warning("violation_recorder::init(): no summary defined, auto-generating '%s'", summary.get_string());
00100 }
00101 }
00102
00103
00104 write_interval = (int64)(dInterval);
00105 if(-1 > write_interval){
00106 gl_error("violation_recorder::init(): invalid write_interval of %i, must be -1 or greater", write_interval);
00107 return 0;
00108 }
00109
00110
00111 flush_interval = (int64)dFlush_interval;
00112
00113
00114 rec_file = fopen(filename.get_string(), "w");
00115 if(0 == rec_file){
00116 if(strict){
00117 gl_error("violation_recorder::init(): unable to open file '%s' for writing", filename.get_string());
00118 return 0;
00119 } else {
00120 gl_warning("violation_recorder::init(): unable to open file '%s' for writing", filename.get_string());
00121 tape_status = TS_ERROR;
00122 return 1;
00123 }
00124 }
00125
00126 tape_status = TS_OPEN;
00127 if(0 == write_header()){
00128 gl_error("violation_recorder::init(): an error occured when writing the file header");
00129 tape_status = TS_ERROR;
00130 return 0;
00131 }
00132
00133 sim_start = -1;
00134
00135
00136 xfrmr_obj_list = vobjlist_alloc_fxn(xfrmr_obj_list);
00137 ohl_obj_list = vobjlist_alloc_fxn(ohl_obj_list);
00138 ugl_obj_list = vobjlist_alloc_fxn(ugl_obj_list);
00139 tplxl_obj_list = vobjlist_alloc_fxn(tplxl_obj_list);
00140 node_obj_list = vobjlist_alloc_fxn(node_obj_list);
00141 tplx_node_obj_list = vobjlist_alloc_fxn(tplx_node_obj_list);
00142 tplx_mtr_obj_list = vobjlist_alloc_fxn(tplx_mtr_obj_list);
00143 comm_mtr_obj_list = vobjlist_alloc_fxn(comm_mtr_obj_list);
00144 inverter_obj_list = vobjlist_alloc_fxn(inverter_obj_list);
00145 powerflow_obj_list = vobjlist_alloc_fxn(powerflow_obj_list);
00146
00147 make_object_list(FT_CLASS, "transformer", xfrmr_obj_list);
00148 make_object_list(FT_CLASS, "overhead_line", ohl_obj_list);
00149 make_object_list(FT_CLASS, "underground_line", ugl_obj_list);
00150 make_object_list(FT_CLASS, "triplex_line", tplxl_obj_list);
00151 make_object_list(FT_CLASS, "node", node_obj_list);
00152 make_object_list(FT_CLASS, "triplex_node", tplx_node_obj_list);
00153 make_object_list(FT_CLASS, "triplex_meter", tplx_mtr_obj_list);
00154 make_object_list(FT_GROUPID, "commercialMeter", comm_mtr_obj_list);
00155 make_object_list(FT_CLASS, "inverter", inverter_obj_list);
00156 make_object_list(FT_MODULE, "powerflow", powerflow_obj_list);
00157 assoc_meter_w_xfrmr_node(tplx_mtr_obj_list, xfrmr_obj_list, node_obj_list);
00158 assoc_meter_w_xfrmr_node(comm_mtr_obj_list, xfrmr_obj_list, node_obj_list);
00159 find_substation_node(virtual_substation, node_obj_list);
00160
00161
00162 xfrmr_list_v1 = uniqueList_alloc_fxn(xfrmr_list_v1);
00163 ohl_list_v1 = uniqueList_alloc_fxn(ohl_list_v1);
00164 ugl_list_v1 = uniqueList_alloc_fxn(ugl_list_v1);
00165 tplxl_list_v1 = uniqueList_alloc_fxn(tplxl_list_v1);
00166 node_list_v2 = uniqueList_alloc_fxn(node_list_v2);
00167 tplx_node_list_v2 = uniqueList_alloc_fxn(tplx_node_list_v2);
00168 tplx_meter_list_v2 = uniqueList_alloc_fxn(tplx_meter_list_v2);
00169 comm_meter_list_v2 = uniqueList_alloc_fxn(comm_meter_list_v2);
00170 tplx_node_list_v3 = uniqueList_alloc_fxn(tplx_node_list_v3);
00171 tplx_meter_list_v3 = uniqueList_alloc_fxn(tplx_meter_list_v3);
00172 comm_meter_list_v3 = uniqueList_alloc_fxn(comm_meter_list_v3);
00173 inverter_list_v6 = uniqueList_alloc_fxn(inverter_list_v6);
00174 tplx_meter_list_v7 = uniqueList_alloc_fxn(tplx_meter_list_v7);
00175 comm_meter_list_v7 = uniqueList_alloc_fxn(comm_meter_list_v7);
00176
00177 return 1;
00178 }
00179
00180 int violation_recorder::make_object_list(int type, char * s_grp, vobjlist *q_obj_list){
00181 OBJECT *gr_obj = 0;
00182
00183 FINDLIST *items = gl_find_objects(FL_NEW, type, SAME, s_grp, FT_END);
00184 if(0 == items){
00185 if(strict){
00186 gl_error("violation_recorder::init(): unable to construct a set with group definition '%s'", s_grp);
00187 return 0;
00188 } else {
00189 gl_warning("violation_recorder::init(): unable to construct a set with group definition '%s'", s_grp);
00190 return 1;
00191 }
00192 }
00193 if(1 > items->hit_count){
00194 if(strict){
00195 gl_error("violation_recorder::init(): the defined group returned an empty set for '%s'", s_grp);
00196 return 0;
00197 } else {
00198 gl_warning("violation_recorder::init(): the defined group returned an empty set for '%s'", s_grp);
00199 return 1;
00200 }
00201 }
00202
00203 for(gr_obj = gl_find_next(items, 0); gr_obj != 0; gr_obj = gl_find_next(items, gr_obj) ){
00204
00205 if(q_obj_list == 0){
00206 gl_error("violation_recorder::make_object_list(): requires a pointer to a vobjlist");
00207 return 0;
00208 } else {
00209 q_obj_list->tack(gr_obj);
00210 }
00211 }
00212
00213 return 1;
00214 }
00215
00216
00217 int violation_recorder::assoc_meter_w_xfrmr_node(vobjlist *meter_list, vobjlist *xfrmr_list, vobjlist *node_list){
00218 vobjlist *meter, *xfrmr, *node, *node1, *node2;
00219 PROPERTY *p_ptr;
00220 char to[128], from[128];
00221 bool found;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 for(xfrmr = xfrmr_list; xfrmr != 0; xfrmr = xfrmr->next){
00234 if (xfrmr->obj == 0) continue;
00235
00236 found = false;
00237 node1 = xfrmr;
00238 gl_output("");
00239
00240 while (!found) {
00241
00242 p_ptr = gl_get_property(node1->obj, "to");
00243 gl_get_value(node1->obj, GETADDR(node1->obj, p_ptr), to, 127, p_ptr);
00244
00245
00246 for(meter = meter_list; meter != 0; meter = meter->next){
00247 if (meter->obj == 0) continue;
00248
00249 if (strcmp(to, meter->obj->name) == 0) {
00250 p_ptr = gl_get_property(xfrmr->obj, "from");
00251 gl_get_value(xfrmr->obj, GETADDR(xfrmr->obj, p_ptr), from, 127, p_ptr);
00252
00253 for(node = node_list; node != 0; node = node->next){
00254 if (node->obj == 0) continue;
00255
00256 if (strcmp(from, node->obj->name) == 0) {
00257
00258
00259 meter->ref_obj = node->obj;
00260 found = true;
00261 break;
00262 }
00263 }
00264 break;
00265 }
00266 }
00267
00268
00269 for(node2 = powerflow_obj_list; node2 != 0; node2 = node2->next){
00270 if (node2->obj == 0) continue;
00271 p_ptr = gl_get_property(node2->obj, "from");
00272 if (p_ptr != 0) {
00273 gl_get_value(node2->obj, GETADDR(node2->obj, p_ptr), from, 127, p_ptr);
00274
00275 if (strcmp(to, from) == 0) {
00276
00277 node1 = node2;
00278 break;
00279 }
00280 }
00281 }
00282
00283
00284 if (node2 == 0) {
00285 break;
00286 }
00287 }
00288 }
00289
00290 return 1;
00291 }
00292
00293
00294 int violation_recorder::find_substation_node(char256 node_name, vobjlist *node_list){
00295
00296 char256 name;
00297
00298 if (0 != node_name[0]) {
00299 OBJECT *obj = gl_get_object(node_name);
00300 if (obj != 0) {
00301 if (strcmp(node_name, obj->name) == 0) {
00302 link_monitor_obj = obj;
00303 return 1;
00304 }
00305 }
00306 } else {
00307
00308 gl_warning("No object specified for monitoring reverse flow; no reverse flow violations will be reported.");
00309 }
00310
00311 return 0;
00312 }
00313
00314 TIMESTAMP violation_recorder::postsync(TIMESTAMP t0, TIMESTAMP t1){
00315
00316
00317 if(0 == write_interval){
00318
00319 check_violations(t1);
00320 } else if(0 < write_interval){
00321
00322 if(last_write + write_interval <= t1){
00323 interval_write = true;
00324 last_write = t1;
00325 next_write = t1 + write_interval;
00326 }
00327 return next_write;
00328 } else {
00329
00330 return TS_NEVER;
00331 }
00332
00333
00334 return TS_NEVER;
00335 }
00336
00337 int violation_recorder::commit(TIMESTAMP t1){
00338
00339 if (!pass_error_check()){return 0;}
00340
00341
00342 if(TS_OPEN != tape_status){
00343 return 1;
00344 }
00345
00346
00347 if(write_interval > 0){
00348 if(interval_write){
00349 check_violations(t1);
00350 last_write = t1;
00351 interval_write = false;
00352 }
00353 }
00354
00355
00356
00357
00358 if(-1 == write_interval){
00359
00360 check_violations(t1);
00361 }
00362
00363
00364 if (!pass_error_check()){return 0;}
00365
00366 return 1;
00367 }
00368
00369 int violation_recorder::pass_error_check () {
00370
00371 if((TS_ERROR == tape_status) && strict){
00372 gl_error("violation_recorder::commit(): the object has error'ed and is halting the simulation");
00373 return 0;
00374 }
00375 return 1;
00376 }
00377
00378 int violation_recorder::isa(char *classname){
00379 return (strcmp(classname, oclass->name) == 0);
00380 }
00381
00385 int violation_recorder::write_header(){
00386
00387 time_t now = time(NULL);
00388
00389 OBJECT *obj=OBJECTHDR(this);
00390
00391 if(TS_OPEN != tape_status){
00392
00393 return 0;
00394 }
00395 if(0 == rec_file){
00396 gl_error("violation_recorder::write_header(): the output file was not opened");
00397 tape_status = TS_ERROR;
00398 return 0;
00399 }
00400
00401
00402 if(0 > fprintf(rec_file,"# file...... %s\n", filename.get_string())){ return 0; }
00403 if(0 > fprintf(rec_file,"# date...... %s", asctime(localtime(&now)))){ return 0; }
00404 #ifdef WIN32
00405 if(0 > fprintf(rec_file,"# user...... %s\n", getenv("USERNAME"))){ return 0; }
00406 if(0 > fprintf(rec_file,"# host...... %s\n", getenv("MACHINENAME"))){ return 0; }
00407 #else
00408 if(0 > fprintf(rec_file,"# user...... %s\n", getenv("USER"))){ return 0; }
00409 if(0 > fprintf(rec_file,"# host...... %s\n", getenv("HOST"))){ return 0; }
00410 #endif
00411 if(0 > fprintf(rec_file,"# limit..... %d\n", limit)){ return 0; }
00412 if(0 > fprintf(rec_file,"# interval.. %d\n", write_interval)){ return 0; }
00413 if(0 > fprintf(rec_file,"# timestamp, violation, observation, upper_limit, lower_limit, object(s), object type(s), phase, message\n")){ return 0; }
00414
00415 return 1;
00416 }
00417
00418 int violation_recorder::check_violations(TIMESTAMP t1) {
00419
00420 if (sim_start == -1) {
00421 sim_start = t1;
00422 }
00423
00424 if ((t1-sim_start) < violation_start_delay) return 1;
00425
00426 if (violation_flag & VIOLATION1)
00427 check_violation_1(t1);
00428
00429 if (violation_flag & VIOLATION2)
00430 check_violation_2(t1);
00431
00432 if (violation_flag & VIOLATION3)
00433 check_violation_3(t1);
00434
00435 if (violation_flag & VIOLATION4)
00436 check_violation_4(t1);
00437
00438 if (violation_flag & VIOLATION5)
00439 check_violation_5(t1);
00440
00441 if (violation_flag & VIOLATION6)
00442 check_violation_6(t1);
00443
00444 if (violation_flag & VIOLATION7)
00445 check_violation_7(t1);
00446
00447 if (violation_flag & VIOLATION8)
00448 check_violation_8(t1);
00449
00450 return 1;
00451 }
00452
00453
00454 int violation_recorder::check_violation_1(TIMESTAMP t1) {
00455
00456 vobjlist *curr = 0;
00457
00458 check_xfrmr_thermal_limit(t1, xfrmr_obj_list, xfrmr_list_v1, XFMR, xfrmr_thermal_limit_upper, xfrmr_thermal_limit_lower);
00459 check_line_thermal_limit(t1, ohl_obj_list, ohl_list_v1, OHLN, line_thermal_limit_upper, line_thermal_limit_lower);
00460 check_line_thermal_limit(t1, ugl_obj_list, ugl_list_v1, UGLN, line_thermal_limit_upper, line_thermal_limit_lower);
00461 check_line_thermal_limit(t1, tplxl_obj_list, tplxl_list_v1, TPXL, line_thermal_limit_upper, line_thermal_limit_lower);
00462
00463 return 1;
00464
00465 }
00466
00467 int violation_recorder::check_line_thermal_limit(TIMESTAMP t1, vobjlist *list, uniqueList *uniq_list, int type, double upper_bound, double lower_bound) {
00468
00469 vobjlist *curr = 0;
00470 double nominal, nominalA, nominalB, nominalC;
00471 char objname[128];
00472 double retval;
00473
00474 for(curr = list; curr != 0; curr = curr->next){
00475 if (curr->obj == 0) continue;
00476
00477
00478 if (has_phase(curr->obj, PHASE_S)) {
00479 triplex_line *pTriplex_line = OBJECTDATA(curr->obj,triplex_line);
00480 triplex_line_configuration *pConfiguration1 = OBJECTDATA(pTriplex_line->configuration,triplex_line_configuration);
00481
00482 triplex_line_conductor *pConfigurationA = OBJECTDATA(pConfiguration1->phaseA_conductor,triplex_line_conductor);
00483 nominal = pConfigurationA->summer.continuous;
00484 if (fails_static_condition(curr->obj, "current_out_A", upper_bound, lower_bound, nominal, &retval)) {
00485 uniq_list->insert(curr->obj->name);
00486 increment_violation(VIOLATION1, type);
00487 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, S1, Current violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00488 }
00489 triplex_line_conductor *pConfigurationB = OBJECTDATA(pConfiguration1->phaseB_conductor,triplex_line_conductor);
00490 nominal = pConfigurationB->summer.continuous;
00491 if (fails_static_condition(curr->obj, "current_out_B", upper_bound, lower_bound, nominal, &retval)) {
00492 uniq_list->insert(curr->obj->name);
00493 increment_violation(VIOLATION1, type);
00494 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, S2, Current violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00495 }
00496 } else {
00497 if ( gl_object_isa(curr->obj,"underground_line","powerflow") ) {
00498 underground_line *pThree_phase_line = OBJECTDATA(curr->obj,underground_line);
00499 line_configuration *pConfiguration1 = OBJECTDATA(pThree_phase_line->configuration,line_configuration);
00500
00501 if (has_phase(curr->obj, PHASE_A)) {
00502 underground_line_conductor *pConfigurationA = OBJECTDATA(pConfiguration1->phaseA_conductor,underground_line_conductor);
00503 if ( pConfigurationA == NULL)
00504 nominalA = pConfiguration1->summer.continuous;
00505 else
00506 nominalA = pConfigurationA->summer.continuous;
00507 }
00508
00509 if (has_phase(curr->obj, PHASE_B)) {
00510 underground_line_conductor *pConfigurationB = OBJECTDATA(pConfiguration1->phaseB_conductor,underground_line_conductor);
00511 if ( pConfigurationB == NULL)
00512 nominalB = pConfiguration1->summer.continuous;
00513 else
00514 nominalB = pConfigurationB->summer.continuous;
00515 }
00516
00517 if (has_phase(curr->obj, PHASE_C)) {
00518 underground_line_conductor *pConfigurationC = OBJECTDATA(pConfiguration1->phaseC_conductor,underground_line_conductor);
00519 if ( pConfigurationC == NULL)
00520 nominalC = pConfiguration1->summer.continuous;
00521 else
00522 nominalC = pConfigurationC->summer.continuous;
00523 }
00524 }
00525 else {
00526 overhead_line *pThree_phase_line = OBJECTDATA(curr->obj,overhead_line);
00527 line_configuration *pConfiguration1 = OBJECTDATA(pThree_phase_line->configuration,line_configuration);
00528
00529 if (has_phase(curr->obj, PHASE_A)) {
00530 overhead_line_conductor *pConfigurationA = OBJECTDATA(pConfiguration1->phaseA_conductor,overhead_line_conductor);
00531 if ( pConfigurationA == NULL)
00532 nominalA = pConfiguration1->summer.continuous;
00533 else
00534 nominalA = pConfigurationA->summer.continuous;
00535 }
00536
00537 if (has_phase(curr->obj, PHASE_B)) {
00538 overhead_line_conductor *pConfigurationB = OBJECTDATA(pConfiguration1->phaseB_conductor,overhead_line_conductor);
00539 if ( pConfigurationB == NULL)
00540 nominalB = pConfiguration1->summer.continuous;
00541 else
00542 nominalB = pConfigurationB->summer.continuous;
00543 }
00544
00545 if (has_phase(curr->obj, PHASE_C)) {
00546 overhead_line_conductor *pConfigurationC = OBJECTDATA(pConfiguration1->phaseC_conductor,overhead_line_conductor);
00547 if ( pConfigurationC == NULL)
00548 nominalC = pConfiguration1->summer.continuous;
00549 else
00550 nominalC = pConfigurationC->summer.continuous;
00551 }
00552
00553 }
00554 if (has_phase(curr->obj, PHASE_A)) {
00555 if (fails_static_condition(curr->obj, "current_out_A", upper_bound, lower_bound, nominalA, &retval)) {
00556 uniq_list->insert(curr->obj->name);
00557 increment_violation(VIOLATION1, type);
00558 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, A, Current violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00559 }
00560 }
00561 if (has_phase(curr->obj, PHASE_B)) {
00562 if (fails_static_condition(curr->obj, "current_out_B", upper_bound, lower_bound, nominalB, &retval)) {
00563 uniq_list->insert(curr->obj->name);
00564 increment_violation(VIOLATION1, type);
00565 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, B, Current violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00566 }
00567 }
00568 if (has_phase(curr->obj, PHASE_C)) {
00569 if (fails_static_condition(curr->obj, "current_out_C", upper_bound, lower_bound, nominalC, &retval)) {
00570 uniq_list->insert(curr->obj->name);
00571 increment_violation(VIOLATION1, type);
00572 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, C, Current violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00573 }
00574 }
00575 }
00576 }
00577
00578 return 1;
00579
00580 }
00581
00582 int violation_recorder::check_xfrmr_thermal_limit(TIMESTAMP t1, vobjlist *list, uniqueList *uniq_list, int type, double upper_bound, double lower_bound) {
00583
00584 vobjlist *curr = 0;
00585 double nominal;
00586 char objname[128];
00587 double retval;
00588
00589 for(curr = list; curr != 0; curr = curr->next){
00590 if (curr->obj == 0) continue;
00591
00592 if (has_phase(curr->obj, PHASE_S)) {
00593 transformer *pTransformer = OBJECTDATA(curr->obj,transformer);
00594 transformer_configuration *pConfiguration = OBJECTDATA(pTransformer->configuration,transformer_configuration);
00595 nominal = pConfiguration->kVA_rating*1000.;
00596 if (fails_static_condition(curr->obj, "power_out", upper_bound, lower_bound, nominal, &retval)) {
00597 uniq_list->insert(curr->obj->name);
00598 increment_violation(VIOLATION1, type);
00599 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, S, Power violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00600 }
00601
00602 } else {
00603 transformer *pTransformer = OBJECTDATA(curr->obj,transformer);
00604 transformer_configuration *pConfiguration = OBJECTDATA(pTransformer->configuration,transformer_configuration);
00605 if (has_phase(curr->obj, PHASE_A)) {
00606 nominal = pConfiguration->phaseA_kVA_rating*1000.;
00607 if (fails_static_condition(curr->obj, "power_out_A", upper_bound, lower_bound, nominal, &retval)) {
00608 uniq_list->insert(curr->obj->name);
00609 increment_violation(VIOLATION1, type);
00610 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, A, Power violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00611 }
00612 }
00613 if (has_phase(curr->obj, PHASE_B)) {
00614 nominal = pConfiguration->phaseB_kVA_rating*1000.;
00615 if (fails_static_condition(curr->obj, "power_out_B", upper_bound, lower_bound, nominal, &retval)) {
00616 uniq_list->insert(curr->obj->name);
00617 increment_violation(VIOLATION1, type);
00618 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, B, Power violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00619 }
00620 }
00621 if (has_phase(curr->obj, PHASE_C)) {
00622 nominal = pConfiguration->phaseC_kVA_rating*1000.;
00623 if (fails_static_condition(curr->obj, "power_out_C", upper_bound, lower_bound, nominal, &retval)) {
00624 uniq_list->insert(curr->obj->name);
00625 increment_violation(VIOLATION1, type);
00626 write_to_stream(t1, echo, "VIOLATION1, %f, %f, %f, %s, %s, C, Power violates thermal limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00627 }
00628 }
00629 }
00630 }
00631
00632 return 1;
00633
00634 }
00635
00636
00637 int violation_recorder::check_violation_2(TIMESTAMP t1) {
00638
00639 vobjlist *curr = 0;
00640 PROPERTY *p_ptr;
00641 double nominal;
00642 char objname[128];
00643 int c = 0;
00644 double node_upper_bound = node_instantaneous_voltage_limit_upper;
00645 double node_lower_bound = node_instantaneous_voltage_limit_lower;
00646 double retval;
00647
00648 for(curr = node_obj_list; curr != 0; curr = curr->next){
00649 if (curr->obj == 0) continue;
00650 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00651 nominal = get_observed_double_value(curr->obj, p_ptr);
00652 if (has_phase(curr->obj, PHASE_A)) {
00653 if (fails_static_condition(curr->obj, "voltage_A", node_upper_bound, node_lower_bound, nominal, &retval)) {
00654 node_list_v2->insert(curr->obj->name);
00655 increment_violation(VIOLATION2, NODE);
00656 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, A, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00657 }
00658 }
00659 if (has_phase(curr->obj, PHASE_B)) {
00660 if (fails_static_condition(curr->obj, "voltage_B", node_upper_bound, node_lower_bound, nominal, &retval)) {
00661 node_list_v2->insert(curr->obj->name);
00662 increment_violation(VIOLATION2, NODE);
00663 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, B, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00664 }
00665 }
00666 if (has_phase(curr->obj, PHASE_C)) {
00667 if (fails_static_condition(curr->obj, "voltage_C", node_upper_bound, node_lower_bound, nominal, &retval)) {
00668 node_list_v2->insert(curr->obj->name);
00669 increment_violation(VIOLATION2, NODE);
00670 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, C, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00671 }
00672 }
00673 }
00674
00675 for(curr = comm_mtr_obj_list; curr != 0; curr = curr->next){
00676 if (curr->obj == 0) continue;
00677 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00678 nominal = get_observed_double_value(curr->obj, p_ptr);
00679 if (has_phase(curr->obj, PHASE_A)) {
00680 if (fails_static_condition(curr->obj, "voltage_A", node_upper_bound, node_lower_bound, nominal, &retval)) {
00681 comm_meter_list_v2->insert(curr->obj->name);
00682 increment_violation(VIOLATION2, CMTR);
00683 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, A, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00684 }
00685 }
00686 if (has_phase(curr->obj, PHASE_B)) {
00687 if (fails_static_condition(curr->obj, "voltage_B", node_upper_bound, node_lower_bound, nominal, &retval)) {
00688 comm_meter_list_v2->insert(curr->obj->name);
00689 increment_violation(VIOLATION2, CMTR);
00690 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, B, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00691 }
00692 }
00693 if (has_phase(curr->obj, PHASE_C)) {
00694 if (fails_static_condition(curr->obj, "voltage_C", node_upper_bound, node_lower_bound, nominal, &retval)) {
00695 comm_meter_list_v2->insert(curr->obj->name);
00696 increment_violation(VIOLATION2, CMTR);
00697 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, C, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00698 }
00699 }
00700 }
00701
00702 for(curr = tplx_node_obj_list; curr != 0; curr = curr->next){
00703 if (curr->obj == 0) continue;
00704 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00705 nominal = get_observed_double_value(curr->obj, p_ptr) * 2.;
00706 if (has_phase(curr->obj, PHASE_S1) && has_phase(curr->obj, PHASE_S2)) {
00707 if (fails_static_condition(curr->obj, "voltage_12", node_upper_bound, node_lower_bound, nominal, &retval)) {
00708 tplx_node_list_v2->insert(curr->obj->name);
00709 increment_violation(VIOLATION2, TPXN);
00710 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, S, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00711 }
00712 }
00713 }
00714
00715 for(curr = tplx_mtr_obj_list; curr != 0; curr = curr->next){
00716 if (curr->obj == 0) continue;
00717 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00718 nominal = get_observed_double_value(curr->obj, p_ptr) * 2.;
00719 if (has_phase(curr->obj, PHASE_S1) && has_phase(curr->obj, PHASE_S2)) {
00720 if (fails_static_condition(curr->obj, "voltage_12", node_upper_bound, node_lower_bound, nominal, &retval)) {
00721 tplx_meter_list_v2->insert(curr->obj->name);
00722 increment_violation(VIOLATION2, TPXM);
00723 write_to_stream(t1, echo, "VIOLATION2, %f, %f, %f, %s, %s, S, Per unit voltage violates limit.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name);
00724 }
00725 }
00726 }
00727
00728 return 1;
00729
00730 }
00731
00732
00733 int violation_recorder::check_violation_3(TIMESTAMP t1) {
00734
00735 vobjlist *curr = 0;
00736 PROPERTY *p_ptr;
00737 double nominal;
00738 char objname[128];
00739 int c = 0;
00740 double node_upper_bound = node_continuous_voltage_limit_upper;
00741 double node_lower_bound = node_continuous_voltage_limit_lower;
00742 double interval = node_continuous_voltage_interval;
00743 double retval;
00744
00745 for(curr = tplx_node_obj_list; curr != 0; curr = curr->next){
00746 if (curr->obj == 0) continue;
00747 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00748 nominal = get_observed_double_value(curr->obj, p_ptr) * 2.;
00749 if (has_phase(curr->obj, PHASE_S1) && has_phase(curr->obj, PHASE_S2)) {
00750 if (fails_continuous_condition(curr, 0, "voltage_12", t1, interval, node_upper_bound, node_lower_bound, nominal, &retval)) {
00751 tplx_node_list_v3->insert(curr->obj->name);
00752 increment_violation(VIOLATION3, TPXN);
00753 write_to_stream(t1, echo, "VIOLATION3, %f, %f, %f, %s, %s, S, Per unit voltage violates limit continuously over %is interval.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)node_continuous_voltage_interval);
00754 }
00755 }
00756 }
00757
00758 for(curr = tplx_mtr_obj_list; curr != 0; curr = curr->next){
00759 if (curr->obj == 0) continue;
00760 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00761 nominal = get_observed_double_value(curr->obj, p_ptr) * 2.;
00762 if (has_phase(curr->obj, PHASE_S1) && has_phase(curr->obj, PHASE_S2)) {
00763 if (fails_continuous_condition(curr, 0, "voltage_12", t1, interval, node_upper_bound, node_lower_bound, nominal, &retval)) {
00764 tplx_meter_list_v3->insert(curr->obj->name);
00765 increment_violation(VIOLATION3, TPXM);
00766 write_to_stream(t1, echo, "VIOLATION3, %f, %f, %f, %s, %s, S, Per unit voltage violates limit continuously over %is interval.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)node_continuous_voltage_interval);
00767 }
00768 }
00769 }
00770
00771 for(curr = comm_mtr_obj_list; curr != 0; curr = curr->next){
00772 if (curr->obj == 0) continue;
00773 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00774 nominal = get_observed_double_value(curr->obj, p_ptr);
00775 if (has_phase(curr->obj, PHASE_A)) {
00776 if (fails_continuous_condition(curr, 0, "voltage_A", t1, interval, node_upper_bound, node_lower_bound, nominal, &retval)) {
00777 comm_meter_list_v3->insert(curr->obj->name);
00778 increment_violation(VIOLATION3, CMTR);
00779 write_to_stream(t1, echo, "VIOLATION3, %f, %f, %f, %s, %s, A, Per unit voltage violates limit continuously over %is interval.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)node_continuous_voltage_interval);
00780 }
00781 }
00782 if (has_phase(curr->obj, PHASE_B)) {
00783 if (fails_continuous_condition(curr, 0, "voltage_B", t1, interval, node_upper_bound, node_lower_bound, nominal, &retval)) {
00784 comm_meter_list_v3->insert(curr->obj->name);
00785 increment_violation(VIOLATION3, CMTR);
00786 write_to_stream(t1, echo, "VIOLATION3, %f, %f, %f, %s, %s, B, Per unit voltage violates limit continuously over %is interval.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)node_continuous_voltage_interval);
00787 }
00788 }
00789 if (has_phase(curr->obj, PHASE_C)) {
00790 if (fails_continuous_condition(curr, 0, "voltage_C", t1, interval, node_upper_bound, node_lower_bound, nominal, &retval)) {
00791 comm_meter_list_v3->insert(curr->obj->name);
00792 increment_violation(VIOLATION3, CMTR);
00793 write_to_stream(t1, echo, "VIOLATION3, %f, %f, %f, %s, %s, C, Per unit voltage violates limit continuously over %is interval.", retval, node_upper_bound, node_lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)node_continuous_voltage_interval);
00794 }
00795 }
00796 }
00797
00798 return 1;
00799
00800 }
00801
00802
00803 int violation_recorder::check_violation_4(TIMESTAMP t1) {
00804 return check_reverse_flow_violation(t1, VIOLATION4, 0.50, "Reverse flow current warning.");
00805 }
00806
00807
00808 int violation_recorder::check_violation_5(TIMESTAMP t1) {
00809 return check_reverse_flow_violation(t1, VIOLATION5, 0.75, "Reverse flow current violates limit.");
00810 }
00811
00812 int violation_recorder::check_reverse_flow_violation(TIMESTAMP t1, int violation_num, double pct, char *str) {
00813
00814 if (link_monitor_obj == 0)
00815 return 0;
00816
00817 double retval;
00818 char objname[128];
00819 double breaker_limit_A_upper = substation_breaker_A_limit*pct;
00820 double breaker_limit_A_lower = 0.;
00821 double breaker_limit_B_upper = substation_breaker_B_limit*pct;
00822 double breaker_limit_B_lower = 0.;
00823 double breaker_limit_C_upper = substation_breaker_C_limit*pct;
00824 double breaker_limit_C_lower = 0.;
00825
00826 double nominal = 1.;
00827 PROPERTY *p_ptr;
00828 set *directions;
00829 p_ptr = gl_get_property(link_monitor_obj, "flow_direction");
00830 if (p_ptr == NULL)
00831 return 0;
00832 directions = gl_get_set(link_monitor_obj, p_ptr);
00833
00834 if (has_phase(link_monitor_obj, PHASE_A) && ((*directions & AR) == AR)) {
00835 if (fails_static_condition(link_monitor_obj, "current_out_A", breaker_limit_A_upper, breaker_limit_A_lower, nominal, &retval)) {
00836 increment_violation(violation_num);
00837 write_to_stream(t1, echo, "VIOLATION%i, %f, %f, %f, %s, %s, A, %s", (int)l2((double)violation_num)+1, retval, breaker_limit_A_upper, breaker_limit_A_lower, gl_name(link_monitor_obj, objname, 127), link_monitor_obj->oclass->name, str);
00838 }
00839 }
00840 if (has_phase(link_monitor_obj, PHASE_B) && ((*directions & BR) == BR)) {
00841 if (fails_static_condition(link_monitor_obj, "current_out_B", breaker_limit_B_upper, breaker_limit_B_lower, nominal, &retval)) {
00842 increment_violation(violation_num);
00843 write_to_stream(t1, echo, "VIOLATION%i, %f, %f, %f, %s, %s, B, %s", (int)l2((double)violation_num)+1, retval, breaker_limit_B_upper, breaker_limit_B_lower, gl_name(link_monitor_obj, objname, 127), link_monitor_obj->oclass->name, str);
00844 }
00845 }
00846 if (has_phase(link_monitor_obj, PHASE_C) && ((*directions & CR) == CR)) {
00847 if (fails_static_condition(link_monitor_obj, "current_out_C", breaker_limit_C_upper, breaker_limit_C_lower, nominal, &retval)) {
00848 increment_violation(violation_num);
00849 write_to_stream(t1, echo, "VIOLATION%i, %f, %f, %f, %s, %s, C, %s", (int)l2((double)violation_num)+1, retval, breaker_limit_C_upper, breaker_limit_C_lower, gl_name(link_monitor_obj, objname, 127), link_monitor_obj->oclass->name, str);
00850 }
00851 }
00852
00853 return 1;
00854 }
00855
00856
00857 int violation_recorder::check_violation_6(TIMESTAMP t1) {
00858
00859 vobjlist *curr = 0;
00860 char objname[128];
00861 double upper_bound = inverter_v_chng_per_interval_upper_bound;
00862 double lower_bound = inverter_v_chng_per_interval_lower_bound;
00863 double interval = inverter_v_chng_interval;
00864 double nominal = 1.0;
00865 double retval;
00866
00867 for(curr = inverter_obj_list; curr != 0; curr = curr->next){
00868 if (curr->obj == 0) continue;
00869 if (has_phase(curr->obj, PHASE_S)) {
00870 if (fails_dynamic_condition(curr, 1, "phaseB_V_Out", t1, interval, upper_bound, lower_bound, nominal, &retval)) {
00871 inverter_list_v6->insert(curr->obj->name);
00872 increment_violation(VIOLATION6);
00873 write_to_stream(t1, echo, "VIOLATION6, %f, %f, %f, %s, %s, S, Voltage change between %is intervals violates limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)inverter_v_chng_interval);
00874 }
00875 } else {
00876 if (has_phase(curr->obj, PHASE_A)) {
00877 if (fails_dynamic_condition(curr, 0, "phaseA_V_Out", t1, interval, upper_bound, lower_bound, nominal, &retval)) {
00878 inverter_list_v6->insert(curr->obj->name);
00879 increment_violation(VIOLATION6);
00880 write_to_stream(t1, echo, "VIOLATION6, %f, %f, %f, %s, %s, A, Voltage change between %is intervals violates limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)inverter_v_chng_interval);
00881 }
00882 }
00883 if (has_phase(curr->obj, PHASE_B)) {
00884 if (fails_dynamic_condition(curr, 1, "phaseB_V_Out", t1, interval, upper_bound, lower_bound, nominal, &retval)) {
00885 inverter_list_v6->insert(curr->obj->name);
00886 increment_violation(VIOLATION6);
00887 write_to_stream(t1, echo, "VIOLATION6, %f, %f, %f, %s, %s, B, Voltage change between %is intervals violates limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)inverter_v_chng_interval);
00888 }
00889 }
00890 if (has_phase(curr->obj, PHASE_C)) {
00891 if (fails_dynamic_condition(curr, 2, "phaseC_V_Out", t1, interval, upper_bound, lower_bound, nominal, &retval)) {
00892 inverter_list_v6->insert(curr->obj->name);
00893 increment_violation(VIOLATION6);
00894 write_to_stream(t1, echo, "VIOLATION6, %f, %f, %f, %s, %s, C, Voltage change between %is intervals violates limit.", retval, upper_bound, lower_bound, gl_name(curr->obj, objname, 127), curr->obj->oclass->name, (int)inverter_v_chng_interval);
00895 }
00896 }
00897 }
00898 }
00899
00900 return 1;
00901 }
00902
00903
00904 int violation_recorder::check_violation_7(TIMESTAMP t1) {
00905
00906 vobjlist *curr = 0;
00907 PROPERTY *p_ptr;
00908 double meter_voltage, meter_nominal, xfrmr_voltage, xfrmr_nominal, pu;
00909 char metername[128];
00910 char xfrmrname[128];
00911 double pu_upper_bound = secondary_dist_voltage_rise_upper_limit;
00912 double pu_lower_bound = secondary_dist_voltage_rise_lower_limit;
00913 double retval;
00914
00915 for(curr = tplx_mtr_obj_list; curr != 0; curr = curr->next){
00916 if (curr->obj == 0) continue;
00917 if (curr->ref_obj == 0) continue;
00918 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
00919 meter_nominal = get_observed_double_value(curr->obj, p_ptr);
00920 pu = 0;
00921 if (has_phase(curr->obj, PHASE_S1)) {
00922 p_ptr = gl_get_property(curr->obj, "voltage_1");
00923 meter_voltage = get_observed_double_value(curr->obj, p_ptr);
00924 if (has_phase(curr->obj, PHASE_A)) {
00925 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00926 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00927 p_ptr = gl_get_property(curr->ref_obj, "voltage_A");
00928 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00929 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00930 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00931 tplx_meter_list_v7->insert(curr->obj->name);
00932 increment_violation(VIOLATION7, TPXM);
00933 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, A S1, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00934 }
00935 }
00936 if (has_phase(curr->obj, PHASE_B)) {
00937 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00938 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00939 p_ptr = gl_get_property(curr->ref_obj, "voltage_B");
00940 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00941 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00942 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00943 tplx_meter_list_v7->insert(curr->obj->name);
00944 increment_violation(VIOLATION7, TPXM);
00945 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, B S1, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00946 }
00947 }
00948 if (has_phase(curr->obj, PHASE_C)) {
00949 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00950 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00951 p_ptr = gl_get_property(curr->ref_obj, "voltage_C");
00952 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00953 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00954 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00955 tplx_meter_list_v7->insert(curr->obj->name);
00956 increment_violation(VIOLATION7, TPXM);
00957 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, C S1, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00958 }
00959 }
00960 }
00961 if (has_phase(curr->obj, PHASE_S2)) {
00962 p_ptr = gl_get_property(curr->obj, "voltage_2");
00963 meter_voltage = get_observed_double_value(curr->obj, p_ptr);
00964 if (has_phase(curr->obj, PHASE_A)) {
00965 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00966 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00967 p_ptr = gl_get_property(curr->ref_obj, "voltage_A");
00968 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00969 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00970 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00971 tplx_meter_list_v7->insert(curr->obj->name);
00972 increment_violation(VIOLATION7, TPXM);
00973 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, A S2, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00974 }
00975 }
00976 if (has_phase(curr->obj, PHASE_B)) {
00977 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00978 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00979 p_ptr = gl_get_property(curr->ref_obj, "voltage_B");
00980 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00981 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00982 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00983 tplx_meter_list_v7->insert(curr->obj->name);
00984 increment_violation(VIOLATION7, TPXM);
00985 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, B S2, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00986 }
00987 }
00988 if (has_phase(curr->obj, PHASE_C)) {
00989 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
00990 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
00991 p_ptr = gl_get_property(curr->ref_obj, "voltage_C");
00992 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
00993 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
00994 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
00995 tplx_meter_list_v7->insert(curr->obj->name);
00996 increment_violation(VIOLATION7, TPXM);
00997 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, C S2, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
00998 }
00999 }
01000 }
01001 }
01002
01003 for(curr = comm_mtr_obj_list; curr != 0; curr = curr->next){
01004 if (curr->obj == 0) continue;
01005 if (curr->ref_obj == 0) continue;
01006 p_ptr = gl_get_property(curr->obj, "nominal_voltage");
01007 meter_nominal = get_observed_double_value(curr->obj, p_ptr);
01008 pu = 0;
01009 if (has_phase(curr->obj, PHASE_A)) {
01010 p_ptr = gl_get_property(curr->obj, "voltage_A");
01011 meter_voltage = get_observed_double_value(curr->obj, p_ptr);
01012 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
01013 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
01014 p_ptr = gl_get_property(curr->ref_obj, "voltage_A");
01015 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
01016 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
01017 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
01018 comm_meter_list_v7->insert(curr->obj->name);
01019 increment_violation(VIOLATION7, CMTR);
01020 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, A, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
01021 }
01022 }
01023 if (has_phase(curr->obj, PHASE_B)) {
01024 p_ptr = gl_get_property(curr->obj, "voltage_B");
01025 meter_voltage = get_observed_double_value(curr->obj, p_ptr);
01026 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
01027 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
01028 p_ptr = gl_get_property(curr->ref_obj, "voltage_B");
01029 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
01030 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
01031 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
01032 comm_meter_list_v7->insert(curr->obj->name);
01033 increment_violation(VIOLATION7, CMTR);
01034 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, B, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
01035 }
01036 }
01037 if (has_phase(curr->obj, PHASE_C)) {
01038 p_ptr = gl_get_property(curr->obj, "voltage_C");
01039 meter_voltage = get_observed_double_value(curr->obj, p_ptr);
01040 p_ptr = gl_get_property(curr->ref_obj, "nominal_voltage");
01041 xfrmr_nominal = get_observed_double_value(curr->ref_obj, p_ptr);
01042 p_ptr = gl_get_property(curr->ref_obj, "voltage_C");
01043 xfrmr_voltage = get_observed_double_value(curr->ref_obj, p_ptr);
01044 pu = meter_voltage/meter_nominal-xfrmr_voltage/xfrmr_nominal;
01045 if (fails_static_condition(pu, pu_upper_bound, pu_lower_bound, 1.0, &retval)) {
01046 comm_meter_list_v7->insert(curr->obj->name);
01047 increment_violation(VIOLATION7, CMTR);
01048 write_to_stream(t1, echo, "VIOLATION7, %f, %f, %f, %s %s, %s %s, C, Per unit voltage difference between objects violates limit.", retval, pu_upper_bound, pu_lower_bound, gl_name(curr->obj, metername, 127), gl_name(curr->ref_obj, xfrmrname, 127), curr->obj->oclass->name, curr->ref_obj->oclass->name);
01049 }
01050 }
01051 }
01052
01053 return 1;
01054
01055 }
01056
01057
01058 int violation_recorder::check_violation_8(TIMESTAMP t1) {
01059
01060 if (link_monitor_obj == 0)
01061 return 0;
01062
01063 double retval;
01064 char objname[128];
01065
01066 double nominal = 1.;
01067 PROPERTY *p_ptr;
01068 p_ptr = gl_get_property(link_monitor_obj, "power_in");
01069
01070 if (p_ptr == NULL)
01071 return 0;
01072
01073 complex power_in = get_observed_complex_value(link_monitor_obj, p_ptr);
01074 double pf = power_in.Re()/power_in.Mag();
01075
01076 if (fails_static_condition (pf, 1.0, substation_pf_lower_limit, 1.0, &retval)) {
01077 increment_violation(VIOLATION8);
01078 write_to_stream(t1, echo, "VIOLATION8, %f, %f, %f, %s, %s,, %s", retval, 1.0, substation_pf_lower_limit, gl_name(link_monitor_obj, objname, 127), link_monitor_obj->oclass->name, "Power factor violates limit.");
01079 }
01080
01081 return 1;
01082 }
01083
01084 double violation_recorder::get_observed_double_value(OBJECT *curr, PROPERTY *prop) {
01085 char objname[128];
01086 double part_value = 0.0;
01087 if(prop->ptype == PT_complex){
01088 complex *cptr = 0;
01089
01090 cptr = gl_get_complex(curr, prop);
01091 if(0 == cptr){
01092 gl_error("group_recorder::read_line(): unable to get complex property '%s' from object '%s'", prop->name, gl_name(curr, objname, 127));
01093
01094
01095
01096 return 0;
01097 }
01098 part_value = cptr->Mag();
01099 } else {
01100 part_value = *(gl_get_double(curr, prop));
01101 }
01102 return part_value;
01103 }
01104
01105 complex violation_recorder::get_observed_complex_value(OBJECT *curr, PROPERTY *prop) {
01106 char objname[128];
01107 complex *cptr = 0;
01108 if(prop->ptype == PT_complex){
01109
01110 cptr = gl_get_complex(curr, prop);
01111 if(0 == cptr){
01112 gl_error("group_recorder::read_line(): unable to get complex property '%s' from object '%s'", prop->name, gl_name(curr, objname, 127));
01113
01114
01115
01116 return 0;
01117 }
01118 }
01119 return *cptr;
01120 }
01121
01122 int violation_recorder::fails_static_condition (OBJECT *curr, char *prop_name, double upper_bound, double lower_bound, double normalization_value, double *retval) {
01123 PROPERTY *p_ptr;
01124 double value;
01125 p_ptr = gl_get_property(curr, prop_name);
01126 if (p_ptr == NULL)
01127 return 0;
01128 value = get_observed_double_value(curr, p_ptr);
01129 return fails_static_condition (value, upper_bound, lower_bound, normalization_value, retval);
01130 }
01131
01132 int violation_recorder::fails_static_condition (double value, double upper_bound, double lower_bound, double normalization_value, double *retval) {
01133 double pu;
01134 (normalization_value != 0. && normalization_value != 1.) ? pu = value/normalization_value : pu = value;
01135 if (pu > upper_bound || pu < lower_bound) {
01136 *retval = pu;
01137 return 1;
01138 }
01139 return 0;
01140 }
01141
01142 int violation_recorder::fails_dynamic_condition (vobjlist *curr, int i, char *prop_name, TIMESTAMP t1, double interval, double upper_bound, double lower_bound, double normalization_value, double *retval) {
01143 PROPERTY *p_ptr;
01144 double value, pu;
01145 p_ptr = gl_get_property(curr->obj, prop_name);
01146 if (p_ptr == NULL)
01147 return 0;
01148 value = get_observed_double_value(curr->obj, p_ptr);
01149 pu = value/normalization_value;
01150 if (curr->last_t[i] == 0) {
01151
01152 curr->update_last(i, pu, t1, 0);
01153 return 0;
01154 }
01155
01156 double pct = ((pu-curr->last_v[i])/curr->last_v[i]);
01157 *retval = pct;
01158 int s_curr, s_prev;
01159
01160 if (pct > upper_bound || pct < lower_bound) {
01161
01162
01163
01164 s_prev = sign(curr->last_s[i]);
01165 s_curr = sign(pct);
01166 if ((s_prev == 0) || (s_prev == s_curr)) {
01167 if ((t1-curr->last_t[i]) >= (long)interval) {
01168 curr->update_last(i, pu, t1, s_curr);
01169 return 1;
01170
01171
01172
01173 } else {
01174 curr->update_last(i, curr->last_v[i], curr->last_t[i], s_curr);
01175 return 0;
01176 }
01177 }
01178 }
01179 curr->update_last(i, pu, t1, 0);
01180 return 0;
01181 }
01182
01183 int violation_recorder::fails_continuous_condition (vobjlist *curr, int i, char *prop_name, TIMESTAMP t1, double interval, double upper_bound, double lower_bound, double normalization_value, double *retval) {
01184 PROPERTY *p_ptr;
01185 double value, pu;
01186 p_ptr = gl_get_property(curr->obj, prop_name);
01187 if (p_ptr == NULL)
01188 return 0;
01189 int s_curr = 0, s_prev = 0;
01190 value = get_observed_double_value(curr->obj, p_ptr);
01191 pu = value/normalization_value;
01192 *retval = pu;
01193
01194 if (curr->last_t[i] == 0) {
01195
01196 if (pu > upper_bound || pu < lower_bound) {
01197 s_curr = sign(pu);
01198 }
01199 curr->update_last(i, pu, t1, s_curr);
01200 return 0;
01201 }
01202
01203
01204 if (pu > upper_bound || pu < lower_bound) {
01205
01206
01207
01208 s_prev = sign(curr->last_s[i]);
01209 s_curr = sign(pu);
01210 if ((s_prev == 0) || (s_prev == s_curr)) {
01211 if ((t1-curr->last_t[i]) >= (long)interval) {
01212 curr->update_last(i, pu, t1, s_curr);
01213 return 1;
01214
01215
01216
01217
01218 } else if (s_prev == 0) {
01219 curr->update_last(i, pu, t1, s_curr);
01220 return 0;
01221 } else {
01222 curr->update_last(i, curr->last_v[i], curr->last_t[i], s_curr);
01223 return 0;
01224 }
01225 }
01226 }
01227 curr->update_last(i, pu, t1, 0);
01228 return 0;
01229 }
01230
01231 int violation_recorder::has_phase(OBJECT *obj, int phase) {
01232 PROPERTY *p_ptr;
01233 set *phases;
01234 p_ptr = gl_get_property(obj, "phases");
01235 phases = gl_get_set(obj, p_ptr);
01236 if ((*phases & phase) == phase)
01237 return true;
01238 return 0;
01239 }
01240
01241 int violation_recorder::increment_violation(int number) {
01242 violation_count[(int)l2(number)][0]++;
01243 return 1;
01244 }
01245
01246 int violation_recorder::increment_violation(int number, int type) {
01247 violation_count[(int)l2(number)][0]++;
01248 violation_count[(int)l2(number)][type]++;
01249 return 1;
01250 }
01251
01252 int violation_recorder::get_violation_count(int number) {
01253 return violation_count[(int)l2(number)][0];
01254 }
01255
01256 int violation_recorder::get_violation_count(int number, int type) {
01257 return violation_count[(int)l2(number)][type];
01258 }
01259
01260 int violation_recorder::write_to_stream (TIMESTAMP t1, bool echo, char *fmt, ...) {
01261 char time_str[64];
01262 DATETIME dt;
01263 if(TS_OPEN != tape_status){
01264 gl_error("violation_recorder::write_line(): trying to write line when the tape is not open");
01265
01266 return 0;
01267 }
01268 if(0 == rec_file){
01269 gl_error("violation_recorder::write_line(): no output file open and state is 'open'");
01270
01271
01272
01273
01274 tape_status = TS_ERROR;
01275 return 0;
01276 }
01277 if(0 == gl_localtime(t1, &dt)){
01278 gl_error("violation_recorder::write_line(): error when converting the sync time");
01279
01280
01281
01282 tape_status = TS_ERROR;
01283 return 0;
01284 }
01285 if(0 == gl_strtime(&dt, time_str, sizeof(time_str) ) ){
01286 gl_error("violation_recorder::write_line(): error when writing the sync time as a string");
01287
01288
01289
01290 tape_status = TS_ERROR;
01291 return 0;
01292 }
01293 char buffer[1024];
01294 va_list ptr;
01295 va_start(ptr,fmt);
01296 vsprintf(buffer,fmt,ptr);
01297 va_end(ptr);
01298
01299 if(0 >= fprintf(rec_file, "%s,%s\n", time_str, buffer)){
01300 gl_error("violation_recorder::write_line(): error when writing to the output file");
01301
01302
01303
01304 tape_status = TS_ERROR;
01305 return 0;
01306 }
01307 ++write_count;
01308
01309 if(flush_interval > 0){
01310 if(last_flush + flush_interval <= t1){
01311 last_flush = t1;
01312 }
01313 } else if(flush_interval < 0){
01314 if( ((write_count + 1) % (-flush_interval)) == 0 ){
01315 flush_line();
01316 }
01317 }
01318
01319 if(limit > 0 && write_count >= limit){
01320
01321 write_footer();
01322 fclose(rec_file);
01323 rec_file = 0;
01324 free(line_buffer);
01325 line_buffer = 0;
01326 line_size = 0;
01327 tape_status = TS_DONE;
01328 }
01329 if (echo)
01330 gl_output("%s", buffer);
01331
01332 return 1;
01333 }
01334
01338 int violation_recorder::flush_line(){
01339 if(TS_OPEN != tape_status){
01340 gl_error("violation_recorder::flush_line(): tape is not open");
01341
01342 return 0;
01343 }
01344 if(0 == rec_file){
01345 gl_error("violation_recorder::flush_line(): output file is not open");
01346
01347
01348
01349
01350 tape_status = TS_ERROR;
01351 return 0;
01352 }
01353 if(0 != fflush(rec_file)){
01354 gl_error("violation_recorder::flush_line(): unable to flush output file");
01355
01356
01357
01358 tape_status = TS_ERROR;
01359 return 0;
01360 }
01361 return 1;
01362 }
01363
01368 int violation_recorder::write_summary() {
01369 FILE *f;
01370
01371 f = fopen(summary.get_string(), "w");
01372 if(0 == f){
01373 gl_warning("violation_recorder::init(): unable to open file '%s' for writing", summary.get_string());
01374 return 0;
01375 }
01376
01377 char buffer[1024];
01378 time_t now = time(NULL);
01379
01380 if(0 > fprintf(f,"# file...... %s\n", summary.get_string())){ return 0; }
01381 if(0 > fprintf(f,"# date...... %s", asctime(localtime(&now)))){ return 0; }
01382 #ifdef WIN32
01383 if(0 > fprintf(f,"# user...... %s\n", getenv("USERNAME"))){ return 0; }
01384 if(0 > fprintf(f,"# host...... %s\n", getenv("MACHINENAME"))){ return 0; }
01385 #else
01386 if(0 > fprintf(f,"# user...... %s\n", getenv("USER"))){ return 0; }
01387 if(0 > fprintf(f,"# host...... %s\n", getenv("HOST"))){ return 0; }
01388 #endif
01389 if(0 > fprintf(f,"VIOLATION1 TOTAL,%i\n", get_violation_count(VIOLATION1))){ return 0; }
01390 if (xfrmr_list_v1 != NULL)
01391 {
01392 if(0 > fprintf(f," TRANSFORMER (%i of %i transformers in violation),%i\n", xfrmr_list_v1->length(), xfrmr_obj_list->length(), get_violation_count(VIOLATION1,XFMR))){ return 0; }
01393 }
01394 if (ohl_list_v1 != NULL)
01395 {
01396 if(0 > fprintf(f," OVERHEAD LINE (%i of %i lines in violation),%i\n", ohl_list_v1->length(), ohl_obj_list->length(), get_violation_count(VIOLATION1,OHLN))){ return 0; }
01397 }
01398 if (ugl_list_v1 != NULL)
01399 {
01400 if(0 > fprintf(f," UNDERGROUND LINE (%i of %i lines in violation),%i\n", ugl_list_v1->length(), ugl_obj_list->length(), get_violation_count(VIOLATION1,UGLN))){ return 0; }
01401 }
01402 if (tplxl_list_v1 != NULL)
01403 {
01404 if(0 > fprintf(f," TRIPLEX LINE (%i of %i lines in violation),%i\n", tplxl_list_v1->length(), tplxl_obj_list->length(), get_violation_count(VIOLATION1,TPXL))){ return 0; }
01405 }
01406 if(0 > fprintf(f,"VIOLATION2 TOTAL,%i\n", get_violation_count(VIOLATION2))){ return 0; }
01407 if (node_list_v2 != NULL)
01408 {
01409 if(0 > fprintf(f," NODE (%i of %i nodes in violation),%i\n", node_list_v2->length(), node_obj_list->length(), get_violation_count(VIOLATION2,NODE))){ return 0; }
01410 }
01411 if (tplx_node_list_v2 != NULL)
01412 {
01413 if(0 > fprintf(f," TRIPLEX NODE (%i of %i nodes in violation),%i\n", tplx_node_list_v2->length(), tplx_node_obj_list->length(), get_violation_count(VIOLATION2,TPXN))){ return 0; }
01414 }
01415 if (tplx_meter_list_v2 != NULL)
01416 {
01417 if(0 > fprintf(f," TRIPLEX METER (%i of %i meters in violation),%i\n", tplx_meter_list_v2->length(), tplx_mtr_obj_list->length(), get_violation_count(VIOLATION2,TPXM))){ return 0; }
01418 }
01419 if (comm_meter_list_v2 != NULL)
01420 {
01421 if(0 > fprintf(f," COMMERCIAL METER (%i of %i meters in violation),%i\n", comm_meter_list_v2->length(), comm_mtr_obj_list->length(), get_violation_count(VIOLATION2,CMTR))){ return 0; }
01422 }
01423
01424 if(0 > fprintf(f,"VIOLATION3 TOTAL,%i\n", get_violation_count(VIOLATION3))){ return 0; }
01425 if (tplx_node_list_v3 != NULL)
01426 {
01427 if(0 > fprintf(f," TRIPLEX NODE (%i of %i nodes in violation),%i\n", tplx_node_list_v3->length(), tplx_node_obj_list->length(), get_violation_count(VIOLATION3,TPXN))){ return 0; }
01428 }
01429 if (tplx_meter_list_v3 != NULL)
01430 {
01431 if(0 > fprintf(f," TRIPLEX METER (%i of %i meters in violation),%i\n", tplx_meter_list_v3->length(), tplx_mtr_obj_list->length(), get_violation_count(VIOLATION3,TPXM))){ return 0; }
01432 }
01433 if (comm_meter_list_v3 != NULL)
01434 {
01435 if(0 > fprintf(f," COMMERCIAL METER (%i of %i meters in violation),%i\n", comm_meter_list_v3->length(), comm_mtr_obj_list->length(), get_violation_count(VIOLATION3,CMTR))){ return 0; }
01436 }
01437
01438 if(0 > fprintf(f,"VIOLATION4 TOTAL,%i\n", get_violation_count(VIOLATION4))){ return 0; }
01439 if(0 > fprintf(f,"VIOLATION5 TOTAL,%i\n", get_violation_count(VIOLATION5))){ return 0; }
01440 if (inverter_list_v6 != NULL)
01441 {
01442 if(0 > fprintf(f,"VIOLATION6 TOTAL (%i of %i inverters in violation),%i\n", inverter_list_v6->length(), inverter_obj_list->length(), get_violation_count(VIOLATION6))){ return 0; }
01443 }
01444 if(0 > fprintf(f,"VIOLATION7 TOTAL,%i\n", get_violation_count(VIOLATION7))){ return 0; }
01445
01446 if (tplx_meter_list_v7 != NULL)
01447 {
01448 if(0 > fprintf(f," TRIPLEX METER (%i of %i meters in violation),%i\n", tplx_meter_list_v7->length(), tplx_mtr_obj_list->length(), get_violation_count(VIOLATION7,TPXM))){ return 0; }
01449 }
01450 if (comm_meter_list_v7 != NULL)
01451 {
01452 if(0 > fprintf(f," COMMERCIAL METER (%i of %i meters in violation),%i\n", comm_meter_list_v7->length(), comm_mtr_obj_list->length(), get_violation_count(VIOLATION7,CMTR))){ return 0; }
01453 }
01454
01455 if(0 > fprintf(f,"VIOLATION8 TOTAL,%i\n", get_violation_count(VIOLATION8))){ return 0; }
01456
01457 fclose(f);
01458
01459 return 1;
01460 }
01461
01462 STATUS violation_recorder::finalize(OBJECT *obj) {
01463 write_summary();
01464 return SUCCESS;
01465 }
01466
01467 int violation_recorder::write_footer(){
01468 if(TS_OPEN != tape_status){
01469 gl_error("violation_recorder::write_footer(): tape is not open");
01470
01471 return 0;
01472 }
01473 if(0 == rec_file){
01474 gl_error("violation_recorder::write_footer(): output file is not open");
01475
01476
01477
01478
01479 tape_status = TS_ERROR;
01480 return 0;
01481 }
01482
01483
01484 if(0 >= fprintf(rec_file, "# end of file\n")){ return 0; }
01485
01486 return 1;
01487 }
01488
01489
01490
01491 vobjlist *violation_recorder::vobjlist_alloc_fxn(vobjlist *input_list)
01492 {
01493 OBJECT *obj = OBJECTHDR(this);
01494
01495
01496 input_list = NULL;
01497
01498
01499 input_list = (vobjlist *)gl_malloc(sizeof(vobjlist));
01500
01501
01502 if (input_list == NULL)
01503 {
01504 GL_THROW("violation_recorder:%d %s - Failed to allocate space for object list to check",obj->id,obj->name ? obj->name : "Unnamed");
01505
01506
01507
01508
01509 }
01510
01511
01512 new (input_list) vobjlist();
01513
01514 return input_list;
01515 }
01516
01517
01518 uniqueList *violation_recorder::uniqueList_alloc_fxn(uniqueList *input_unlist)
01519 {
01520 OBJECT *obj = OBJECTHDR(this);
01521
01522
01523 input_unlist = NULL;
01524
01525
01526 input_unlist = (uniqueList *)gl_malloc(sizeof(uniqueList));
01527
01528
01529 if (input_unlist == NULL)
01530 {
01531 GL_THROW("violation_recorder:%d %s - Failed to allocate space for unique list",obj->id,obj->name ? obj->name : "Unnamed");
01532
01533
01534
01535
01536 }
01537
01538
01539 new (input_unlist) uniqueList();
01540
01541 return input_unlist;
01542 }
01543
01545
01546
01547 EXPORT int create_violation_recorder(OBJECT **obj, OBJECT *parent){
01548 int rv = 0;
01549 try {
01550 *obj = gl_create_object(violation_recorder::oclass);
01551 if(*obj != NULL){
01552 violation_recorder *my = OBJECTDATA(*obj, violation_recorder);
01553 gl_set_parent(*obj, parent);
01554 rv = my->create();
01555 }
01556 }
01557 catch (char *msg){
01558 gl_error("create_violation_recorder: %s", msg);
01559 }
01560 catch (const char *msg){
01561 gl_error("create_violation_recorder: %s", msg);
01562 }
01563 catch (...){
01564 gl_error("create_violation_recorder: unexpected exception caught");
01565 }
01566 return rv;
01567 }
01568
01569 EXPORT int init_violation_recorder(OBJECT *obj){
01570 violation_recorder *my = OBJECTDATA(obj, violation_recorder);
01571 int rv = 0;
01572 try {
01573 rv = my->init(obj->parent);
01574 }
01575 catch (char *msg){
01576 gl_error("init_violation_recorder: %s", msg);
01577 }
01578 catch (const char *msg){
01579 gl_error("init_violation_recorder: %s", msg);
01580 }
01581 return rv;
01582 }
01583
01584 EXPORT TIMESTAMP sync_violation_recorder(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass){
01585 violation_recorder *my = OBJECTDATA(obj, violation_recorder);
01586 TIMESTAMP rv = 0;
01587 try {
01588 switch(pass){
01589 case PC_PRETOPDOWN:
01590 rv = TS_NEVER;
01591 break;
01592 case PC_BOTTOMUP:
01593 rv = TS_NEVER;
01594 break;
01595 case PC_POSTTOPDOWN:
01596 rv = my->postsync(obj->clock, t0);
01597 obj->clock = t0;
01598 break;
01599 default:
01600 throw "invalid pass request";
01601 }
01602 }
01603 catch(char *msg){
01604 gl_error("sync_violation_recorder: %s", msg);
01605 }
01606 catch(const char *msg){
01607 gl_error("sync_violation_recorder: %s", msg);
01608 }
01609 return rv;
01610 }
01611
01612 EXPORT int commit_violation_recorder(OBJECT *obj){
01613 int rv = 0;
01614 violation_recorder *my = OBJECTDATA(obj, violation_recorder);
01615 try {
01616 rv = my->commit(obj->clock);
01617 }
01618 catch (char *msg){
01619 gl_error("commit_violation_recorder: %s", msg);
01620 }
01621 catch (const char *msg){
01622 gl_error("commit_violation_recorder: %s", msg);
01623 }
01624 return rv;
01625 }
01626
01627 EXPORT int isa_violation_recorder(OBJECT *obj, char *classname)
01628 {
01629 return OBJECTDATA(obj, violation_recorder)->isa(classname);
01630 }
01631
01632 EXPORT STATUS finalize_violation_recorder(OBJECT *obj)
01633 {
01634 violation_recorder *my = OBJECTDATA(obj,violation_recorder);
01635 try {
01636 return obj!=NULL ? my->finalize(obj) : FAILED;
01637 }
01638
01639 catch (char *msg) {
01640 gl_error("finalize_violation_recorder" "(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
01641 return FAILED;
01642 }
01643 catch (const char *msg) {
01644 gl_error("finalize_violation_recorder" "(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
01645 return FAILED;
01646 }
01647 catch (...) {
01648 gl_error("finalize_violation_recorder" "(obj=%d;%s): unhandled exception", obj->id, obj->name?obj->name:"unnamed");
01649 return FAILED;
01650 }
01651 }
01652
01653