TIMESTAMP meter::postsync(TIMESTAMP t0, TIMESTAMP t1) { measured_voltage[0] = voltageA; measured_voltage[1] = voltageB; measured_voltage[2] = voltageC; measured_voltageD[0] = voltageA - voltageB; measured_voltageD[1] = voltageB - voltageC; measured_voltageD[2] = voltageC - voltageA; if ((solver_method == SM_NR && NR_cycle == true)||solver_method == SM_FBS) { //Reliability addition - if momentary flag set - clear it if (meter_interrupted_secondary == true) meter_interrupted_secondary = false; if (t1 > last_t) { dt = t1 - last_t; last_t = t1; } else dt = 0; measured_current[0] = current_inj[0]; measured_current[1] = current_inj[1]; measured_current[2] = current_inj[2]; // compute energy use from previous cycle // - everything below this can moved to commit function once tape player is collecting from commit function7 if (dt > 0 && last_t != dt) { measured_real_energy += measured_real_power * TO_HOURS(dt); measured_reactive_energy += measured_reactive_power * TO_HOURS(dt); } // compute demand power indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]); indiv_measured_power[1] = measured_voltage[1]*(~measured_current[1]); indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]); measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2]; measured_real_power = (indiv_measured_power[0]).Re() + (indiv_measured_power[1]).Re() + (indiv_measured_power[2]).Re(); measured_reactive_power = (indiv_measured_power[0]).Im() + (indiv_measured_power[1]).Im() + (indiv_measured_power[2]).Im(); if (measured_real_power > measured_demand) measured_demand = measured_real_power; if (bill_mode == BM_UNIFORM || bill_mode == BM_TIERED) { if (dt > 0) process_bill(t1); // Decide when the next billing HAS to be processed (one month later) if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } if( (bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP) && power_market != NULL && price_prop != NULL){ double seconds; if (dt != last_t) seconds = (double)(dt); else seconds = 0; if (seconds > 0) { hourly_acc += seconds/3600 * price * last_measured_real_power/1000; process_bill(t1); } // Now that we've accumulated the bill for the last time period, update to the new price double *pprice = (gl_get_double(power_market, price_prop)); last_price = price = *pprice; last_measured_real_power = measured_real_power; if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } } return node::postsync(t1); }
TIMESTAMP meter::postsync(TIMESTAMP t0, TIMESTAMP t1) { OBJECT *obj = OBJECTHDR(this); complex temp_current; TIMESTAMP tretval; //Perform node update - do it now, otherwise current_inj isn't populated tretval = node::postsync(t1); measured_voltage[0] = voltageA; measured_voltage[1] = voltageB; measured_voltage[2] = voltageC; measured_voltageD[0] = voltageA - voltageB; measured_voltageD[1] = voltageB - voltageC; measured_voltageD[2] = voltageC - voltageA; if ((solver_method == SM_NR)||solver_method == SM_FBS) { if (t1 > last_t) { dt = t1 - last_t; last_t = t1; } else dt = 0; measured_current[0] = current_inj[0]; measured_current[1] = current_inj[1]; measured_current[2] = current_inj[2]; // compute energy use from previous cycle // - everything below this can moved to commit function once tape player is collecting from commit function7 if (dt > 0 && last_t != dt) { measured_real_energy += measured_real_power * TO_HOURS(dt); measured_reactive_energy += measured_reactive_power * TO_HOURS(dt); } // compute demand power indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]); indiv_measured_power[1] = measured_voltage[1]*(~measured_current[1]); indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]); measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2]; measured_real_power = (indiv_measured_power[0]).Re() + (indiv_measured_power[1]).Re() + (indiv_measured_power[2]).Re(); measured_reactive_power = (indiv_measured_power[0]).Im() + (indiv_measured_power[1]).Im() + (indiv_measured_power[2]).Im(); if (measured_real_power > measured_demand) measured_demand = measured_real_power; if (bill_mode == BM_UNIFORM || bill_mode == BM_TIERED) { if (dt > 0) process_bill(t1); // Decide when the next billing HAS to be processed (one month later) if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } if( (bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP) && power_market != NULL && price_prop != NULL){ double seconds; if (dt != last_t) seconds = (double)(dt); else seconds = 0; if (seconds > 0) { hourly_acc += seconds/3600 * price * last_measured_real_power/1000; process_bill(t1); } // Now that we've accumulated the bill for the last time period, update to the new price double *pprice = (gl_get_double(power_market, price_prop)); last_price = price = *pprice; last_measured_real_power = measured_real_power; if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } } //Multi run (for now) updates to power values if (meter_NR_servered) { // compute demand power indiv_measured_power[0] = voltage[0]*(~current_inj[0]); indiv_measured_power[1] = voltage[1]*(~current_inj[1]); indiv_measured_power[2] = voltage[2]*(~current_inj[2]); } return tretval; }
// Synchronize a distribution triplex_meter TIMESTAMP triplex_meter::postsync(TIMESTAMP t0, TIMESTAMP t1) { OBJECT *obj = OBJECTHDR(this); TIMESTAMP rv = TS_NEVER; TIMESTAMP hr = TS_NEVER; //Call node postsync now, otherwise current_inj isn't right rv = triplex_node::postsync(t1); //measured_voltage[0] = voltageA; //measured_voltage[1] = voltageB; //measured_voltage[2] = voltageC; measured_voltage[0].SetPolar(voltageA.Mag(),voltageA.Arg()); measured_voltage[1].SetPolar(voltageB.Mag(),voltageB.Arg()); measured_voltage[2].SetPolar(voltageC.Mag(),voltageC.Arg()); if (t1 > last_t) { dt = t1 - last_t; last_t = t1; } else dt = 0; //READLOCK_OBJECT(obj); measured_current[0] = current_inj[0]; measured_current[1] = current_inj[1]; //READUNLOCK_OBJECT(obj); measured_current[2] = -(measured_current[1]+measured_current[0]); // if (dt > 0 && last_t != dt) if (dt > 0) { measured_real_energy += measured_real_power * TO_HOURS(dt); measured_reactive_energy += measured_reactive_power * TO_HOURS(dt); } indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]); indiv_measured_power[1] = complex(-1,0) * measured_voltage[1]*(~measured_current[1]); indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]); measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2]; measured_real_power = (indiv_measured_power[0]).Re() + (indiv_measured_power[1]).Re() + (indiv_measured_power[2]).Re(); measured_reactive_power = (indiv_measured_power[0]).Im() + (indiv_measured_power[1]).Im() + (indiv_measured_power[2]).Im(); if (measured_real_power>measured_demand) measured_demand=measured_real_power; if (bill_mode == BM_UNIFORM || bill_mode == BM_TIERED) { if (dt > 0) process_bill(t1); // Decide when the next billing HAS to be processed (one month later) if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } if( (bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP) && power_market != NULL && price_prop != NULL){ double seconds; if (dt != last_t) seconds = (double)(dt); else seconds = 0; if (seconds > 0) { hourly_acc += seconds/3600 * price * last_measured_real_power/1000; process_bill(t1); } // Now that we've accumulated the bill for the last time period, update to the new price double *pprice = (gl_get_double(power_market, price_prop)); last_price = price = *pprice; last_measured_real_power = measured_real_power; if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } if (next_time != 0 && next_time < rv) return -next_time; else return rv; }
// Synchronize a distribution triplex_meter TIMESTAMP triplex_meter::postsync(TIMESTAMP t0, TIMESTAMP t1) { TIMESTAMP rv = TS_NEVER; TIMESTAMP hr = TS_NEVER; //measured_voltage[0] = voltageA; //measured_voltage[1] = voltageB; //measured_voltage[2] = voltageC; measured_voltage[0].SetPolar(voltageA.Mag(),voltageA.Arg()); measured_voltage[1].SetPolar(voltageB.Mag(),voltageB.Arg()); measured_voltage[2].SetPolar(voltageC.Mag(),voltageC.Arg()); if ((solver_method == SM_NR && NR_cycle == true)||solver_method == SM_FBS) { //Reliability addition - clear momentary flag if set if (tpmeter_interrupted_secondary == true) tpmeter_interrupted_secondary = false; if (t1 > last_t) { dt = t1 - last_t; last_t = t1; } else dt = 0; measured_current[0] = current_inj[0]; measured_current[1] = current_inj[1]; measured_current[2] = -(measured_current[1]+measured_current[0]); // if (dt > 0 && last_t != dt) if (dt > 0) { measured_real_energy += measured_real_power * TO_HOURS(dt); measured_reactive_energy += measured_reactive_power * TO_HOURS(dt); } indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]); indiv_measured_power[1] = complex(-1,0) * measured_voltage[1]*(~measured_current[1]); indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]); measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2]; measured_real_power = (indiv_measured_power[0]).Re() + (indiv_measured_power[1]).Re() + (indiv_measured_power[2]).Re(); measured_reactive_power = (indiv_measured_power[0]).Im() + (indiv_measured_power[1]).Im() + (indiv_measured_power[2]).Im(); if (measured_real_power>measured_demand) measured_demand=measured_real_power; if (bill_mode == BM_UNIFORM || bill_mode == BM_TIERED) { if (dt > 0) process_bill(t1); // Decide when the next billing HAS to be processed (one month later) if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } if( (bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP) && power_market != NULL && price_prop != NULL){ double seconds; if (dt != last_t) seconds = (double)(dt); else seconds = 0; if (seconds > 0) { hourly_acc += seconds/3600 * price * measured_real_power/1000; process_bill(t1); } // Now that we've accumulated the bill for the last time period, update to the new price double *pprice = (gl_get_double(power_market, price_prop)); last_price = price = *pprice; if (monthly_bill == previous_monthly_bill) { DATETIME t_next; gl_localtime(t1,&t_next); t_next.day = bill_day; if (t_next.month != 12) t_next.month += 1; else { t_next.month = 1; t_next.year += 1; } t_next.tz[0] = 0; next_time = gl_mktime(&t_next); } } } rv = triplex_node::postsync(t1); if (next_time != 0 && next_time < rv) return -next_time; else return rv; //return triplex_node::postsync(t1); }
TIMESTAMP pqload::sync(TIMESTAMP t0) { TIMESTAMP result = TS_NEVER; double SysFreq = 376.991118431; //System frequency in radians/sec, nominalized 60 Hz for now. int i = 0; /* must take place in sync in order to let the climate update itself */ if(weather != NULL){ if(temperature != NULL){ input[0] = *gl_get_double(weather, temperature); } else { input[0] = 0.0; } if(humidity != NULL){ input[1] = *gl_get_double(weather, humidity); } else { input[1] = 0.0; } if(solar != NULL){ input[2] = *gl_get_double(weather, solar); } else { input[2] = 0.0; } if(wind != NULL){ input[3] = *gl_get_double(weather, wind); } else { input[3] = 0.0; } if(rain != NULL){ input[4] = *gl_get_double(weather, rain); } else { input[4] = 0.0; } } else { input[0] = input[1] = input[2] = input[3] = input[4] = 0.0; } input[5] = 1.0; output[0] = output[1] = output[2] = output[3] = output[4] = output[5] = 0.0; for(i = 0; i < 6; ++i){ output[0] += imped_p[i] * input[i]; output[1] += input[i] * imped_q[i]; output[2] += current_m[i] * input[i]; output[3] += current_a[i] * input[i]; output[4] += power_p[i] * input[i]; output[5] += power_q[i] * input[i]; } kZ.SetRect(output[0], output[1]); kI.SetPolar(output[2], output[3] * PI/180.0); kP.SetRect(output[4], output[5]); /* ---scale by schedule here--- */ constant_power[0] = constant_power[1] = constant_power[2] = kP; // rotate currents by voltage angles //constant_current[0] = constant_current[1] = constant_current[2] = kI; for(i = 0; i < 3; ++i){ double v_angle = voltage[i].Arg(); constant_current[i].SetPolar(output[2], output[3] * PI/180.0 + v_angle); } if (kZ != 0.0) constant_impedance[0] = constant_impedance[1] = constant_impedance[2] = kZ; //Must be at the bottom, or the new values will be calculated after the fact result = load::sync(t0); return result; }
int histogram::feed_bins(OBJECT *obj){ double value = 0.0; complex cval = 0.0; //gl_get_complex(obj, ; int64 ival = 0; int i = 0; switch(prop_ptr->ptype){ case PT_complex: cval = (prop_ptr ? *gl_get_complex(obj, prop_ptr) : *gl_get_complex_by_name(obj, property) ); switch(this->comp_part){ case REAL: value = cval.Re(); break; case IMAG: value = cval.Im(); break; case MAG: value = cval.Mag(); break; case ANG: value = cval.Arg(); break; default: gl_error("Complex property with no part defined in %s", (obj->name ? obj->name : "(unnamed)")); } ival = 1; /* fall through */ case PT_double: if(ival == 0) value = (prop_ptr ? *gl_get_double(obj, prop_ptr) : *gl_get_double_by_name(obj, property.get_string()) ); for(i = 0; i < bin_count; ++i){ if(value > bin_list[i].low_val && value < bin_list[i].high_val){ ++binctr[i]; } else if(bin_list[i].low_inc && bin_list[i].low_val == value){ ++binctr[i]; } else if(bin_list[i].high_inc && bin_list[i].high_val == value){ ++binctr[i]; } } break; case PT_int16: ival = (prop_ptr ? *gl_get_int16(obj, prop_ptr) : *gl_get_int16_by_name(obj, property.get_string()) ); value = 1.0; case PT_int32: if(value == 0.0){ ival = (prop_ptr ? *gl_get_int32(obj, prop_ptr) : *gl_get_int32_by_name(obj, property.get_string()) ); value = 1.0; } case PT_int64: if(value == 0.0){ ival = (prop_ptr ? *gl_get_int64(obj, prop_ptr) : *gl_get_int64_by_name(obj, property.get_string()) ); value = 1.0; } case PT_enumeration: if(value == 0.0){ ival = (prop_ptr ? *gl_get_enum(obj, prop_ptr) : *gl_get_enum_by_name(obj, property.get_string()) ); value = 1.0; } case PT_set: if(value == 0.0){ ival = (prop_ptr ? *gl_get_set(obj, prop_ptr) : *gl_get_set_by_name(obj, property.get_string()) ); value = 1.0; } /* may be prone to fractional errors */ for(i = 0; i < bin_count; ++i){ if(ival > bin_list[i].low_val && ival < bin_list[i].high_val){ ++binctr[i]; } else if(bin_list[i].low_inc && bin_list[i].low_val == ival){ ++binctr[i]; } else if(bin_list[i].high_inc && bin_list[i].high_val == ival){ ++binctr[i]; } } break; } return 0; }