00001
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <errno.h>
00021 #include <math.h>
00022
00023 #include "meter.h"
00024 #include "timestamp.h"
00025
00026
00027 #define TO_HOURS(t) (((double)t) / (3600 * TS_SECOND))
00028
00029
00030 EXPORT int64 meter_reset(OBJECT *obj)
00031 {
00032 meter *pMeter = OBJECTDATA(obj,meter);
00033 pMeter->measured_demand = 0;
00034 return 0;
00035 }
00036
00038
00040
00041 CLASS* meter::oclass = NULL;
00042 CLASS* meter::pclass = NULL;
00043
00044
00045 meter::meter(MODULE *mod) : node(mod)
00046 {
00047
00048 if (oclass==NULL)
00049 {
00050
00051 pclass = node::oclass;
00052
00053
00054 oclass = gl_register_class(mod,"meter",sizeof(meter),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
00055 if (oclass==NULL)
00056 throw "unable to register class meter";
00057 else
00058 oclass->trl = TRL_PROVEN;
00059
00060
00061 if (gl_publish_variable(oclass,
00062 PT_INHERIT, "node",
00063 PT_double, "measured_real_energy[Wh]", PADDR(measured_real_energy),PT_DESCRIPTION,"metered real energy consumption, cummalitive",
00064 PT_double, "measured_real_energy_delta[Wh]", PADDR(measured_real_energy_delta),PT_DESCRIPTION,"delta in metered real energy consumption from last specified measured_energy_delta_timestep",
00065 PT_double, "measured_reactive_energy[VAh]",PADDR(measured_reactive_energy),PT_DESCRIPTION,"metered reactive energy consumption, cummalitive",
00066 PT_double, "measured_reactive_energy_delta[VAh]",PADDR(measured_reactive_energy_delta),PT_DESCRIPTION,"delta in metered reactive energy consumption from last specified measured_energy_delta_timestep",
00067 PT_double, "measured_energy_delta_timestep[s]",PADDR(measured_energy_delta_timestep),PT_DESCRIPTION,"Period of timestep for real and reactive delta energy calculation",
00068 PT_complex, "measured_power[VA]", PADDR(measured_power),PT_DESCRIPTION,"metered real power",
00069 PT_complex, "measured_power_A[VA]", PADDR(indiv_measured_power[0]),PT_DESCRIPTION,"metered complex power on phase A",
00070 PT_complex, "measured_power_B[VA]", PADDR(indiv_measured_power[1]),PT_DESCRIPTION,"metered complex power on phase B",
00071 PT_complex, "measured_power_C[VA]", PADDR(indiv_measured_power[2]),PT_DESCRIPTION,"metered complex power on phase C",
00072 PT_double, "measured_demand[W]", PADDR(measured_demand),PT_DESCRIPTION,"greatest metered real power during simulation",
00073 PT_double, "measured_real_power[W]", PADDR(measured_real_power),PT_DESCRIPTION,"metered real power",
00074 PT_double, "measured_reactive_power[VAr]", PADDR(measured_reactive_power),PT_DESCRIPTION,"metered reactive power",
00075 PT_complex, "meter_power_consumption[VA]", PADDR(meter_power_consumption),PT_DESCRIPTION,"metered power used for operating the meter; standby and communication losses",
00076
00077
00078 PT_complex, "measured_voltage_A[V]", PADDR(measured_voltage[0]),PT_DESCRIPTION,"measured line-to-neutral voltage on phase A",
00079 PT_complex, "measured_voltage_B[V]", PADDR(measured_voltage[1]),PT_DESCRIPTION,"measured line-to-neutral voltage on phase B",
00080 PT_complex, "measured_voltage_C[V]", PADDR(measured_voltage[2]),PT_DESCRIPTION,"measured line-to-neutral voltage on phase C",
00081 PT_complex, "measured_voltage_AB[V]", PADDR(measured_voltageD[0]),PT_DESCRIPTION,"measured line-to-line voltage on phase AB",
00082 PT_complex, "measured_voltage_BC[V]", PADDR(measured_voltageD[1]),PT_DESCRIPTION,"measured line-to-line voltage on phase BC",
00083 PT_complex, "measured_voltage_CA[V]", PADDR(measured_voltageD[2]),PT_DESCRIPTION,"measured line-to-line voltage on phase CA",
00084
00085
00086 PT_double, "measured_real_max_voltage_A_in_interval[V]", PADDR(measured_real_max_voltage_in_interval[0]),PT_DESCRIPTION,"measured real max line-to-neutral voltage on phase A over a specified interval",
00087 PT_double, "measured_real_max_voltage_B_in_interval[V]", PADDR(measured_real_max_voltage_in_interval[1]),PT_DESCRIPTION,"measured real max line-to-neutral voltage on phase B over a specified interval",
00088 PT_double, "measured_real_max_voltage_C_in_interval[V]", PADDR(measured_real_max_voltage_in_interval[2]),PT_DESCRIPTION,"measured real max line-to-neutral voltage on phase C over a specified interval",
00089 PT_double, "measured_reactive_max_voltage_A_in_interval[V]", PADDR(measured_reactive_max_voltage_in_interval[0]),PT_DESCRIPTION,"measured reactive max line-to-neutral voltage on phase A over a specified interval",
00090 PT_double, "measured_reactive_max_voltage_B_in_interval[V]", PADDR(measured_reactive_max_voltage_in_interval[1]),PT_DESCRIPTION,"measured reactive max line-to-neutral voltage on phase B over a specified interval",
00091 PT_double, "measured_reactive_max_voltage_C_in_interval[V]", PADDR(measured_reactive_max_voltage_in_interval[2]),PT_DESCRIPTION,"measured reactive max line-to-neutral voltage on phase C over a specified interval",
00092 PT_double, "measured_real_max_voltage_AB_in_interval[V]", PADDR(measured_real_max_voltageD_in_interval[0]),PT_DESCRIPTION,"measured real max line-to-line voltage on phase A over a specified interval",
00093 PT_double, "measured_real_max_voltage_BC_in_interval[V]", PADDR(measured_real_max_voltageD_in_interval[1]),PT_DESCRIPTION,"measured real max line-to-line voltage on phase B over a specified interval",
00094 PT_double, "measured_real_max_voltage_CA_in_interval[V]", PADDR(measured_real_max_voltageD_in_interval[2]),PT_DESCRIPTION,"measured real max line-to-line voltage on phase C over a specified interval",
00095 PT_double, "measured_reactive_max_voltage_AB_in_interval[V]", PADDR(measured_reactive_max_voltageD_in_interval[0]),PT_DESCRIPTION,"measured reactive max line-to-line voltage on phase A over a specified interval",
00096 PT_double, "measured_reactive_max_voltage_BC_in_interval[V]", PADDR(measured_reactive_max_voltageD_in_interval[1]),PT_DESCRIPTION,"measured reactive max line-to-line voltage on phase B over a specified interval",
00097 PT_double, "measured_reactive_max_voltage_CA_in_interval[V]", PADDR(measured_reactive_max_voltageD_in_interval[2]),PT_DESCRIPTION,"measured reactive max line-to-line voltage on phase C over a specified interval",
00098 PT_double, "measured_real_min_voltage_A_in_interval[V]", PADDR(measured_real_min_voltage_in_interval[0]),PT_DESCRIPTION,"measured real min line-to-neutral voltage on phase A over a specified interval",
00099 PT_double, "measured_real_min_voltage_B_in_interval[V]", PADDR(measured_real_min_voltage_in_interval[1]),PT_DESCRIPTION,"measured real min line-to-neutral voltage on phase B over a specified interval",
00100 PT_double, "measured_real_min_voltage_C_in_interval[V]", PADDR(measured_real_min_voltage_in_interval[2]),PT_DESCRIPTION,"measured real min line-to-neutral voltage on phase C over a specified interval",
00101 PT_double, "measured_reactive_min_voltage_A_in_interval[V]", PADDR(measured_reactive_min_voltage_in_interval[0]),PT_DESCRIPTION,"measured reactive min line-to-neutral voltage on phase A over a specified interval",
00102 PT_double, "measured_reactive_min_voltage_B_in_interval[V]", PADDR(measured_reactive_min_voltage_in_interval[1]),PT_DESCRIPTION,"measured reactive min line-to-neutral voltage on phase B over a specified interval",
00103 PT_double, "measured_reactive_min_voltage_C_in_interval[V]", PADDR(measured_reactive_min_voltage_in_interval[2]),PT_DESCRIPTION,"measured reactive min line-to-neutral voltage on phase C over a specified interval",
00104 PT_double, "measured_real_min_voltage_AB_in_interval[V]", PADDR(measured_real_min_voltageD_in_interval[0]),PT_DESCRIPTION,"measured real min line-to-line voltage on phase A over a specified interval",
00105 PT_double, "measured_real_min_voltage_BC_in_interval[V]", PADDR(measured_real_min_voltageD_in_interval[1]),PT_DESCRIPTION,"measured real min line-to-line voltage on phase B over a specified interval",
00106 PT_double, "measured_real_min_voltage_CA_in_interval[V]", PADDR(measured_real_min_voltageD_in_interval[2]),PT_DESCRIPTION,"measured real min line-to-line voltage on phase C over a specified interval",
00107 PT_double, "measured_reactive_min_voltage_AB_in_interval[V]", PADDR(measured_reactive_min_voltageD_in_interval[0]),PT_DESCRIPTION,"measured reactive min line-to-line voltage on phase A over a specified interval",
00108 PT_double, "measured_reactive_min_voltage_BC_in_interval[V]", PADDR(measured_reactive_min_voltageD_in_interval[1]),PT_DESCRIPTION,"measured reactive min line-to-line voltage on phase B over a specified interval",
00109 PT_double, "measured_reactive_min_voltage_CA_in_interval[V]", PADDR(measured_reactive_min_voltageD_in_interval[2]),PT_DESCRIPTION,"measured reactive min line-to-line voltage on phase C over a specified interval",
00110 PT_double, "measured_avg_voltage_A_mag_in_interval[V]", PADDR(measured_avg_voltage_mag_in_interval[0]),PT_DESCRIPTION,"measured avg line-to-neutral voltage magnitude on phase A over a specified interval",
00111 PT_double, "measured_avg_voltage_B_mag_in_interval[V]", PADDR(measured_avg_voltage_mag_in_interval[1]),PT_DESCRIPTION,"measured avg line-to-neutral voltage magnitude on phase B over a specified interval",
00112 PT_double, "measured_avg_voltage_C_mag_in_interval[V]", PADDR(measured_avg_voltage_mag_in_interval[2]),PT_DESCRIPTION,"measured avg line-to-neutral voltage magnitude on phase C over a specified interval",
00113 PT_double, "measured_avg_voltage_AB_mag_in_interval[V]", PADDR(measured_avg_voltageD_mag_in_interval[0]),PT_DESCRIPTION,"measured avg line-to-line voltage magnitude on phase A over a specified interval",
00114 PT_double, "measured_avg_voltage_BC_mag_in_interval[V]", PADDR(measured_avg_voltageD_mag_in_interval[1]),PT_DESCRIPTION,"measured avg line-to-line voltage magnitude on phase B over a specified interval",
00115 PT_double, "measured_avg_voltage_CA_mag_in_interval[V]", PADDR(measured_avg_voltageD_mag_in_interval[2]),PT_DESCRIPTION,"measured avg line-to-line voltage magnitude on phase C over a specified interval",
00116
00117
00118 PT_double, "measured_real_max_power_in_interval[W]", PADDR(measured_real_max_power_in_interval),PT_DESCRIPTION,"measured maximum real power over a specified interval",
00119 PT_double, "measured_reactive_max_power_in_interval[VAr]", PADDR(measured_reactive_max_power_in_interval),PT_DESCRIPTION,"measured maximum reactive power over a specified interval",
00120 PT_double, "measured_real_min_power_in_interval[W]", PADDR(measured_real_min_power_in_interval),PT_DESCRIPTION,"measured minimum real power over a specified interval",
00121 PT_double, "measured_reactive_min_power_in_interval[VAr]", PADDR(measured_reactive_min_power_in_interval),PT_DESCRIPTION,"measured minimum reactive power over a specified interval",
00122 PT_double, "measured_avg_real_power_in_interval[W]", PADDR(measured_real_avg_power_in_interval),PT_DESCRIPTION,"measured average real power over a specified interval",
00123 PT_double, "measured_avg_reactive_power_in_interval[VAr]", PADDR(measured_reactive_avg_power_in_interval),PT_DESCRIPTION,"measured average reactive power over a specified interval",
00124
00125
00126 PT_double, "measured_stats_interval[s]",PADDR(measured_min_max_avg_timestep),PT_DESCRIPTION,"Period of timestep for min/max/average calculations",
00127
00128 PT_complex, "measured_current_A[A]", PADDR(measured_current[0]),PT_DESCRIPTION,"measured current on phase A",
00129 PT_complex, "measured_current_B[A]", PADDR(measured_current[1]),PT_DESCRIPTION,"measured current on phase B",
00130 PT_complex, "measured_current_C[A]", PADDR(measured_current[2]),PT_DESCRIPTION,"measured current on phase C",
00131 PT_bool, "customer_interrupted", PADDR(meter_interrupted),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in an 'interrupted' state",
00132 PT_bool, "customer_interrupted_secondary", PADDR(meter_interrupted_secondary),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in an 'secondary interrupted' state - i.e., momentary",
00133 #ifdef SUPPORT_OUTAGES
00134 PT_int16, "sustained_count", PADDR(sustained_count),
00135 PT_int16, "momentary_count", PADDR(momentary_count),
00136 PT_int16, "total_count", PADDR(total_count),
00137 PT_int16, "s_flag", PADDR(s_flag),
00138 PT_int16, "t_flag", PADDR(t_flag),
00139 PT_complex, "pre_load", PADDR(pre_load),
00140 #endif
00141 PT_double, "monthly_bill[$]", PADDR(monthly_bill),PT_DESCRIPTION,"Accumulator for the current month's bill",
00142 PT_double, "previous_monthly_bill[$]", PADDR(previous_monthly_bill),PT_DESCRIPTION,"Total monthly bill for the previous month",
00143 PT_double, "previous_monthly_energy[kWh]", PADDR(previous_monthly_energy),PT_DESCRIPTION,"Total monthly energy for the previous month",
00144 PT_double, "monthly_fee[$]", PADDR(monthly_fee),PT_DESCRIPTION,"Once a month flat fee for customer hook-up",
00145 PT_double, "monthly_energy[kWh]", PADDR(monthly_energy),PT_DESCRIPTION,"Accumulator for the current month's energy consumption",
00146 PT_enumeration, "bill_mode", PADDR(bill_mode),PT_DESCRIPTION,"Billing structure desired",
00147 PT_KEYWORD,"NONE",(enumeration)BM_NONE,
00148 PT_KEYWORD,"UNIFORM",(enumeration)BM_UNIFORM,
00149 PT_KEYWORD,"TIERED",(enumeration)BM_TIERED,
00150 PT_KEYWORD,"HOURLY",(enumeration)BM_HOURLY,
00151 PT_KEYWORD,"TIERED_RTP",(enumeration)BM_TIERED_RTP,
00152 PT_KEYWORD,"TIERED_TOU",(enumeration)BM_TIERED_TOU,
00153 PT_object, "power_market", PADDR(power_market),PT_DESCRIPTION,"Market (auction object) where the price is being received from",
00154 PT_int32, "bill_day", PADDR(bill_day),PT_DESCRIPTION,"day of month bill is to be processed (currently limited to days 1-28)",
00155 PT_double, "price[$/kWh]", PADDR(price),PT_DESCRIPTION,"current price of electricity",
00156 PT_double, "price_base[$/kWh]", PADDR(price_base), PT_DESCRIPTION, "Used only in TIERED_RTP mode to describe the price before the first tier",
00157 PT_double, "first_tier_price[$/kWh]", PADDR(tier_price[0]),PT_DESCRIPTION,"price of electricity between first tier and second tier energy usage",
00158 PT_double, "first_tier_energy[kWh]", PADDR(tier_energy[0]),PT_DESCRIPTION,"switching point between base price and first tier price",
00159 PT_double, "second_tier_price[$/kWh]", PADDR(tier_price[1]),PT_DESCRIPTION,"price of electricity between second tier and third tier energy usage",
00160 PT_double, "second_tier_energy[kWh]", PADDR(tier_energy[1]),PT_DESCRIPTION,"switching point between first tier price and second tier price",
00161 PT_double, "third_tier_price[$/kWh]", PADDR(tier_price[2]),PT_DESCRIPTION,"price of electricity when energy usage exceeds third tier energy usage",
00162 PT_double, "third_tier_energy[kWh]", PADDR(tier_energy[2]),PT_DESCRIPTION,"switching point between second tier price and third tier price",
00163
00164
00165 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00166
00167
00168 if (gl_publish_function(oclass,"reset",(FUNCTIONADDR)meter_reset)==NULL)
00169 GL_THROW("unable to publish meter_reset function in %s",__FILE__);
00170
00171
00172 if (gl_publish_function(oclass, "interupdate_pwr_object", (FUNCTIONADDR)interupdate_meter)==NULL)
00173 GL_THROW("Unable to publish meter deltamode function");
00174 if (gl_publish_function(oclass, "pwr_object_swing_swapper", (FUNCTIONADDR)swap_node_swing_status)==NULL)
00175 GL_THROW("Unable to publish meter swing-swapping function");
00176 if (gl_publish_function(oclass, "pwr_current_injection_update_map", (FUNCTIONADDR)node_map_current_update_function)==NULL)
00177 GL_THROW("Unable to publish meter current injection update mapping function");
00178 if (gl_publish_function(oclass, "attach_vfd_to_pwr_object", (FUNCTIONADDR)attach_vfd_to_node)==NULL)
00179 GL_THROW("Unable to publish meter VFD attachment function");
00180 if (gl_publish_function(oclass, "pwr_object_reset_disabled_status", (FUNCTIONADDR)node_reset_disabled_status) == NULL)
00181 GL_THROW("Unable to publish meter island-status-reset function");
00182 }
00183 }
00184
00185 int meter::isa(char *classname)
00186 {
00187 return strcmp(classname,"meter")==0 || node::isa(classname);
00188 }
00189
00190
00191 int meter::create()
00192 {
00193 int result = node::create();
00194
00195 #ifdef SUPPORT_OUTAGES
00196 sustained_count=0;
00197 momentary_count=0;
00198 total_count=0;
00199 s_flag=0;
00200 t_flag=0;
00201 pre_load=0;
00202 #endif
00203
00204 measured_voltage[0] = measured_voltage[1] = measured_voltage[2] = complex(0,0,A);
00205 measured_voltageD[0] = measured_voltageD[1] = measured_voltageD[2] = complex(0,0,A);
00206 measured_real_max_voltage_in_interval[0] = measured_real_max_voltage_in_interval[1] = measured_real_max_voltage_in_interval[2] = 0.0;
00207 measured_reactive_max_voltage_in_interval[0] = measured_reactive_max_voltage_in_interval[1] = measured_reactive_max_voltage_in_interval[2] = 0.0;
00208 measured_real_max_voltageD_in_interval[0] = measured_real_max_voltageD_in_interval[1] = measured_real_max_voltageD_in_interval[2] = 0.0;
00209 measured_reactive_max_voltageD_in_interval[0] = measured_reactive_max_voltageD_in_interval[1] = measured_reactive_max_voltageD_in_interval[2] = 0.0;
00210 measured_real_min_voltage_in_interval[0] = measured_real_min_voltage_in_interval[1] = measured_real_min_voltage_in_interval[2] = 0.0;
00211 measured_reactive_min_voltage_in_interval[0] = measured_reactive_min_voltage_in_interval[1] = measured_reactive_min_voltage_in_interval[2] = 0.0;
00212 measured_real_min_voltageD_in_interval[0] = measured_real_min_voltageD_in_interval[1] = measured_real_min_voltageD_in_interval[2] = 0.0;
00213 measured_reactive_min_voltageD_in_interval[0] = measured_reactive_min_voltageD_in_interval[1] = measured_reactive_min_voltageD_in_interval[2] = 0.0;
00214 measured_avg_voltage_mag_in_interval[0] = measured_avg_voltage_mag_in_interval[1] = measured_avg_voltage_mag_in_interval[2] = 0.0;
00215 measured_current[0] = measured_current[1] = measured_current[2] = complex(0,0,J);
00216 measured_real_energy = measured_reactive_energy = 0.0;
00217 measured_real_energy_delta = measured_reactive_energy_delta = 0;
00218 last_measured_real_energy = last_measured_reactive_energy = 0;
00219 last_measured_real_power = last_measured_reactive_power = 0.0;
00220 measured_energy_delta_timestep = -1;
00221 measured_min_max_avg_timestep = -1;
00222 measured_power = complex(0,0,J);
00223 measured_demand = 0.0;
00224 measured_real_power = 0.0;
00225 measured_reactive_power = 0.0;
00226
00227 meter_interrupted = false;
00228 meter_interrupted_secondary = false;
00229
00230 hourly_acc = 0.0;
00231 monthly_bill = 0.0;
00232 monthly_energy = 0.0;
00233 previous_monthly_energy = 0.0;
00234 bill_mode = BM_NONE;
00235 power_market = 0;
00236 price_prop = 0;
00237 bill_day = 15;
00238 last_bill_month = -1;
00239 price = 0.0;
00240 tier_price[0] = tier_price[1] = tier_price[2] = 0;
00241 tier_energy[0] = tier_energy[1] = tier_energy[2] = 0;
00242 last_price = 0;
00243 last_tier_price[0] = 0;
00244 last_tier_price[1] = 0;
00245 last_tier_price[2] = 0;
00246 last_price_base = 0;
00247 meter_power_consumption = complex(0,0);
00248
00249
00250 node_type = METER_NODE;
00251
00252 meter_NR_servered = false;
00253
00254
00255 measured_real_max_power_in_interval = 0.0;
00256 measured_reactive_max_power_in_interval = 0.0;
00257 measured_real_min_power_in_interval = 0.0;
00258 measured_reactive_min_power_in_interval = 0.0;
00259 measured_real_avg_power_in_interval = 0.0;
00260 measured_reactive_avg_power_in_interval = 0.0;
00261
00262 last_measured_max_real_power = 0.0;
00263 last_measured_min_real_power = 0.0;
00264 last_measured_max_reactive_power = 0.0;
00265 last_measured_min_reactive_power = 0.0;
00266 last_measured_avg_real_power = 0.0;
00267 last_measured_avg_reactive_power = 0.0;
00268
00269 return result;
00270 }
00271
00272
00273 int meter::init(OBJECT *parent)
00274 {
00275 char temp_buff[128];
00276
00277 if(power_market != 0){
00278 price_prop = gl_get_property(power_market, "current_market.clearing_price");
00279 if(price_prop == 0){
00280 GL_THROW("meter::power_market object \'%s\' does not publish \'current_market.clearing_price\'", (power_market->name ? power_market->name : "(anon)"));
00281 }
00282 }
00283
00284
00285 if (meter_power_consumption != complex(0,0))
00286 {
00287 no_phases = 0;
00288 if (has_phase(PHASE_A))
00289 no_phases += 1;
00290 if (has_phase(PHASE_B))
00291 no_phases += 1;
00292 if (has_phase(PHASE_C))
00293 no_phases += 1;
00294 }
00295
00296 check_prices();
00297 last_t = dt = 0;
00298
00299
00300
00301 gl_global_getvar("multirun_mode",temp_buff,sizeof(temp_buff));
00302
00303
00304 if (strcmp(temp_buff,"STANDALONE"))
00305 {
00306 if ((solver_method == SM_NR) && (bustype == SWING))
00307 {
00308 meter_NR_servered = true;
00309
00310
00311 prev_voltage_value = (complex *)gl_malloc(3*sizeof(complex));
00312
00313
00314 if (prev_voltage_value==NULL)
00315 {
00316 GL_THROW("Failure to allocate memory for voltage tracking array");
00317
00318
00319
00320
00321
00322
00323 }
00324
00325
00326 prev_voltage_value[0] = complex(0.0,0.0);
00327 prev_voltage_value[1] = complex(0.0,0.0);
00328 prev_voltage_value[2] = complex(0.0,0.0);
00329 }
00330 }
00331
00332 return node::init(parent);
00333 }
00334
00335 int meter::check_prices(){
00336 if(bill_mode == BM_UNIFORM){
00337 if(price < 0.0){
00338
00339 }
00340 } else if(bill_mode == BM_TIERED || bill_mode == BM_TIERED_RTP){
00341 if(tier_price[1] == 0){
00342 tier_price[1] = tier_price[0];
00343 tier_energy[1] = tier_energy[0];
00344 }
00345 if(tier_price[2] == 0){
00346 tier_price[2] = tier_price[1];
00347 tier_energy[2] = tier_energy[1];
00348 }
00349 if(tier_energy[2] < tier_energy[1] || tier_energy[1] < tier_energy[0]){
00350 GL_THROW("meter energy tiers quantity trend improperly");
00351 }
00352 for(int i = 0; i < 3; ++i){
00353 if(tier_price[i] < 0.0 || tier_energy[i] < 0.0)
00354 GL_THROW("meter tiers cannot have negative values");
00355 }
00356 } else if (bill_mode == BM_TIERED_TOU) {
00357 if(tier_energy[1] == 0){
00358 tier_price[1] = tier_price[0];
00359 tier_energy[1] = DBL_MAX;
00360 }
00361 if(tier_energy[2] == 0){
00362 tier_price[2] = tier_price[1];
00363 tier_energy[2] = DBL_MAX;
00364 }
00365 if(tier_energy[2] < tier_energy[1] || tier_energy[1] < tier_energy[0]){
00366 GL_THROW("meter energy tiers quantity trend improperly");
00367 }
00368 for(int i = 0; i < 3; ++i){
00369 if(tier_price[i] < 0.0 || tier_energy[i] < 0.0)
00370 GL_THROW("meter tiers cannot have negative values");
00371 }
00372 }
00373
00374 if(bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP){
00375 if(power_market == 0 || price_prop == 0){
00376 GL_THROW("meter cannot use real time energy prices without a power market that publishes the next price");
00377 }
00378
00379 }
00380
00381
00382 last_price = price;
00383 last_price_base = price_base;
00384 last_tier_price[0] = tier_price[0];
00385 last_tier_price[1] = tier_price[1];
00386 last_tier_price[2] = tier_price[2];
00387
00388 return 0;
00389 }
00390 TIMESTAMP meter::presync(TIMESTAMP t0)
00391 {
00392 if (meter_power_consumption != complex(0,0))
00393 power[0] = power[1] = power[2] = 0.0;
00394
00395
00396 if (meter_interrupted_secondary == true)
00397 meter_interrupted_secondary = false;
00398
00399
00400 if (t0 != 0 && start_timestamp == 0)
00401 start_timestamp = t0;
00402
00403 return node::presync(t0);
00404 }
00405
00406
00407 void meter::BOTH_meter_sync_fxn()
00408 {
00409 int TempNodeRef;
00410
00411
00412 if ((fault_check_object != NULL) && (solver_method == SM_NR))
00413 {
00414 if (NR_node_reference==-99)
00415 {
00416 TempNodeRef=*NR_subnode_reference;
00417 }
00418 else
00419 {
00420
00421 TempNodeRef=NR_node_reference;
00422 }
00423
00424 if ((NR_busdata[TempNodeRef].origphases & NR_busdata[TempNodeRef].phases) != NR_busdata[TempNodeRef].origphases)
00425 {
00426 meter_interrupted = true;
00427
00428
00429 if (meter_interrupted_secondary == true)
00430 meter_interrupted_secondary = false;
00431 }
00432 else
00433 {
00434 meter_interrupted = false;
00435 }
00436 }
00437
00438 if (meter_power_consumption != complex(0,0))
00439 {
00440 if (has_phase(PHASE_A))
00441 power[0] += meter_power_consumption / no_phases;
00442 if (has_phase(PHASE_B))
00443 power[1] += meter_power_consumption / no_phases;
00444 if (has_phase(PHASE_C))
00445 power[2] += meter_power_consumption / no_phases;
00446 }
00447 }
00448
00449 TIMESTAMP meter::sync(TIMESTAMP t0)
00450 {
00451
00452 BOTH_meter_sync_fxn();
00453
00454 return node::sync(t0);
00455 }
00456
00457 TIMESTAMP meter::postsync(TIMESTAMP t0, TIMESTAMP t1)
00458 {
00459 OBJECT *obj = OBJECTHDR(this);
00460 complex temp_current;
00461 TIMESTAMP tretval;
00462
00463
00464 tretval = node::postsync(t1);
00465
00466 measured_voltage[0] = voltageA;
00467 measured_voltage[1] = voltageB;
00468 measured_voltage[2] = voltageC;
00469
00470 measured_voltageD[0] = voltageA - voltageB;
00471 measured_voltageD[1] = voltageB - voltageC;
00472 measured_voltageD[2] = voltageC - voltageA;
00473
00474 if ((solver_method == SM_NR)||solver_method == SM_FBS)
00475 {
00476 if (t1 > last_t)
00477 {
00478 dt = t1 - last_t;
00479 last_t = t1;
00480 }
00481 else
00482 dt = 0;
00483
00484 measured_current[0] = current_inj[0];
00485 measured_current[1] = current_inj[1];
00486 measured_current[2] = current_inj[2];
00487
00488
00489
00490 if (dt > 0 && last_t != dt)
00491 {
00492 measured_real_energy += measured_real_power * TO_HOURS(dt);
00493 measured_reactive_energy += measured_reactive_power * TO_HOURS(dt);
00494 }
00495
00496
00497 indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]);
00498 indiv_measured_power[1] = measured_voltage[1]*(~measured_current[1]);
00499 indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]);
00500
00501 measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2];
00502
00503 measured_real_power = (indiv_measured_power[0]).Re()
00504 + (indiv_measured_power[1]).Re()
00505 + (indiv_measured_power[2]).Re();
00506
00507 measured_reactive_power = (indiv_measured_power[0]).Im()
00508 + (indiv_measured_power[1]).Im()
00509 + (indiv_measured_power[2]).Im();
00510
00511 if (measured_real_power > measured_demand)
00512 measured_demand = measured_real_power;
00513
00514
00515 if (measured_energy_delta_timestep > 0) {
00516 if (t0 == start_timestamp) {
00517 last_delta_timestamp = start_timestamp;
00518
00519 if (tretval > last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep)) {
00520 tretval = last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep);
00521 }
00522 }
00523
00524 if ((t1 > last_delta_timestamp) && (t1 < last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep)) && (t1 != t0)) {
00525 if (tretval > last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep)) {
00526 tretval = last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep);
00527 }
00528 }
00529
00530 if ((t1 == last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep)) && (t1 != t0) && measured_energy_delta_timestep > 0) {
00531 measured_real_energy_delta = measured_real_energy - last_measured_real_energy;
00532 measured_reactive_energy_delta = measured_reactive_energy - last_measured_reactive_energy;
00533 last_measured_real_energy = measured_real_energy;
00534 last_measured_reactive_energy = measured_reactive_energy;
00535 last_delta_timestamp = t1;
00536
00537 if (tretval > last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep)) {
00538 tretval = last_delta_timestamp + TIMESTAMP(measured_energy_delta_timestep);
00539 }
00540 }
00541 }
00542
00543
00544 if (measured_min_max_avg_timestep > 0) {
00545 if (t0 == start_timestamp) {
00546 last_stat_timestamp = start_timestamp;
00547 voltage_avg_count = 0;
00548 interval_dt = 0;
00549
00550
00551 measured_real_max_voltage_in_interval[0] = voltageA.Re();
00552 measured_real_max_voltage_in_interval[1] = voltageB.Re();
00553 measured_real_max_voltage_in_interval[2] = voltageC.Re();
00554 measured_real_max_voltageD_in_interval[0] = measured_voltageD[0].Re();
00555 measured_real_max_voltageD_in_interval[1] = measured_voltageD[1].Re();
00556 measured_real_max_voltageD_in_interval[2] = measured_voltageD[2].Re();
00557 measured_real_min_voltage_in_interval[0] = voltageA.Re();
00558 measured_real_min_voltage_in_interval[1] = voltageB.Re();
00559 measured_real_min_voltage_in_interval[2] = voltageC.Re();
00560 measured_real_min_voltageD_in_interval[0] = measured_voltageD[0].Re();
00561 measured_real_min_voltageD_in_interval[1] = measured_voltageD[1].Re();
00562 measured_real_min_voltageD_in_interval[2] = measured_voltageD[2].Re();
00563 measured_reactive_max_voltage_in_interval[0] = voltageA.Im();
00564 measured_reactive_max_voltage_in_interval[1] = voltageB.Im();
00565 measured_reactive_max_voltage_in_interval[2] = voltageC.Im();
00566 measured_reactive_max_voltageD_in_interval[0] = measured_voltageD[0].Im();
00567 measured_reactive_max_voltageD_in_interval[1] = measured_voltageD[1].Im();
00568 measured_reactive_max_voltageD_in_interval[2] = measured_voltageD[2].Im();
00569 measured_reactive_min_voltage_in_interval[0] = voltageA.Im();
00570 measured_reactive_min_voltage_in_interval[1] = voltageB.Im();
00571 measured_reactive_min_voltage_in_interval[2] = voltageC.Im();
00572 measured_reactive_min_voltageD_in_interval[0] = measured_voltageD[0].Im();
00573 measured_reactive_min_voltageD_in_interval[1] = measured_voltageD[1].Im();
00574 measured_reactive_min_voltageD_in_interval[2] = measured_voltageD[2].Im();
00575 measured_avg_voltage_mag_in_interval[0] = 0.0;
00576 measured_avg_voltage_mag_in_interval[1] = 0.0;
00577 measured_avg_voltage_mag_in_interval[2] = 0.0;
00578 measured_avg_voltageD_mag_in_interval[0] = 0.0;
00579 measured_avg_voltageD_mag_in_interval[1] = 0.0;
00580 measured_avg_voltageD_mag_in_interval[2] = 0.0;
00581
00582
00583 measured_real_max_power_in_interval = measured_real_power;
00584 measured_real_min_power_in_interval = measured_real_power;
00585 measured_real_avg_power_in_interval = 0.0;
00586
00587 measured_reactive_max_power_in_interval = measured_reactive_power;
00588 measured_reactive_min_power_in_interval = measured_reactive_power;
00589 measured_reactive_avg_power_in_interval = 0.0;
00590
00591 last_measured_voltage[0] = voltageA;
00592 last_measured_voltage[1] = voltageB;
00593 last_measured_voltage[2] = voltageC;
00594 last_measured_voltageD[0] = measured_voltageD[0];
00595 last_measured_voltageD[1] = measured_voltageD[1];
00596 last_measured_voltageD[2] = measured_voltageD[2];
00597 if (tretval > last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) {
00598 tretval = last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep);
00599 }
00600 }
00601
00602 if ((t1 > last_stat_timestamp) && (t1 < last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) && (t1 != t0)) {
00603 if (voltage_avg_count <= 0) {
00604 last_measured_max_voltage_mag[0] = voltageA;
00605 last_measured_max_voltage_mag[1] = voltageB;
00606 last_measured_max_voltage_mag[2] = voltageC;
00607 last_measured_max_voltageD_mag[0] = measured_voltageD[0];
00608 last_measured_max_voltageD_mag[1] = measured_voltageD[1];
00609 last_measured_max_voltageD_mag[2] = measured_voltageD[2];
00610 last_measured_min_voltage_mag[0] = voltageA;
00611 last_measured_min_voltage_mag[1] = voltageB;
00612 last_measured_min_voltage_mag[2] = voltageC;
00613 last_measured_min_voltageD_mag[0] = measured_voltageD[0];
00614 last_measured_min_voltageD_mag[1] = measured_voltageD[1];
00615 last_measured_min_voltageD_mag[2] = measured_voltageD[2];
00616 last_measured_avg_voltage_mag[0] = last_measured_voltage[0].Mag();
00617 last_measured_avg_voltage_mag[1] = last_measured_voltage[1].Mag();
00618 last_measured_avg_voltage_mag[2] = last_measured_voltage[2].Mag();
00619 last_measured_avg_voltageD_mag[0] = last_measured_voltageD[0].Mag();
00620 last_measured_avg_voltageD_mag[1] = last_measured_voltageD[1].Mag();
00621 last_measured_avg_voltageD_mag[2] = last_measured_voltageD[2].Mag();
00622
00623
00624 last_measured_min_real_power = last_measured_real_power;
00625 last_measured_max_real_power = last_measured_real_power;
00626 last_measured_avg_real_power = last_measured_real_power;
00627 last_measured_min_reactive_power = last_measured_reactive_power;
00628 last_measured_max_reactive_power = last_measured_reactive_power;
00629 last_measured_avg_reactive_power = last_measured_reactive_power;
00630
00631 } else {
00632 if ( last_measured_voltage[0].Mag() > last_measured_max_voltage_mag[0].Mag()) {
00633 last_measured_max_voltage_mag[0] = last_measured_voltage[0];
00634 }
00635 if ( last_measured_voltage[1].Mag() > last_measured_max_voltage_mag[1].Mag()) {
00636 last_measured_max_voltage_mag[1] = last_measured_voltage[1];
00637 }
00638 if ( last_measured_voltage[2].Mag() > last_measured_max_voltage_mag[2].Mag()) {
00639 last_measured_max_voltage_mag[2] = last_measured_voltage[2];
00640 }
00641 if (last_measured_voltageD[0].Mag() > last_measured_max_voltageD_mag[0].Mag()) {
00642 last_measured_max_voltageD_mag[0] = last_measured_voltageD[0];
00643 }
00644 if (last_measured_voltageD[1].Mag() > last_measured_max_voltageD_mag[1].Mag()) {
00645 last_measured_max_voltageD_mag[1] = last_measured_voltageD[1];
00646 }
00647 if (last_measured_voltageD[2].Mag() > last_measured_max_voltageD_mag[2].Mag()) {
00648 last_measured_max_voltageD_mag[2] = last_measured_voltageD[2];
00649 }
00650 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[0].Mag()) {
00651 last_measured_min_voltage_mag[0] = last_measured_voltage[0];
00652 }
00653 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[1].Mag()) {
00654 last_measured_min_voltage_mag[1] = last_measured_voltage[0];
00655 }
00656 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[2].Mag()) {
00657 last_measured_min_voltage_mag[2] = last_measured_voltage[0];
00658 }
00659 if (last_measured_voltageD[0].Mag() < last_measured_min_voltageD_mag[0].Mag()) {
00660 last_measured_min_voltageD_mag[0] = last_measured_voltageD[0];
00661 }
00662 if (last_measured_voltageD[1].Mag() < last_measured_min_voltageD_mag[1].Mag()) {
00663 last_measured_min_voltageD_mag[1] = last_measured_voltageD[1];
00664 }
00665 if (last_measured_voltageD[2].Mag() < last_measured_min_voltageD_mag[2].Mag()) {
00666 last_measured_min_voltageD_mag[2] = last_measured_voltageD[2];
00667 }
00668
00669
00670 if (last_measured_max_real_power < last_measured_real_power)
00671 {
00672 last_measured_max_real_power = last_measured_real_power;
00673 }
00674 if (last_measured_max_reactive_power < last_measured_reactive_power)
00675 {
00676 last_measured_max_reactive_power = last_measured_reactive_power;
00677 }
00678 if (last_measured_min_real_power > last_measured_real_power)
00679 {
00680 last_measured_min_real_power = last_measured_real_power;
00681 }
00682 if (last_measured_min_reactive_power > last_measured_reactive_power)
00683 {
00684 last_measured_min_reactive_power = last_measured_reactive_power;
00685 }
00686
00687 last_measured_avg_voltage_mag[0] = ((interval_dt * last_measured_avg_voltage_mag[0]) + (dt * last_measured_voltage[0].Mag()))/(interval_dt + dt);
00688 last_measured_avg_voltage_mag[1] = ((interval_dt * last_measured_avg_voltage_mag[1]) + (dt * last_measured_voltage[1].Mag()))/(interval_dt + dt);
00689 last_measured_avg_voltage_mag[2] = ((interval_dt * last_measured_avg_voltage_mag[2]) + (dt * last_measured_voltage[2].Mag()))/(interval_dt + dt);
00690 last_measured_avg_voltageD_mag[0] = ((interval_dt * last_measured_avg_voltageD_mag[0]) + (dt * last_measured_voltageD[0].Mag()))/(interval_dt + dt);
00691 last_measured_avg_voltageD_mag[1] = ((interval_dt * last_measured_avg_voltageD_mag[1]) + (dt * last_measured_voltageD[1].Mag()))/(interval_dt + dt);
00692 last_measured_avg_voltageD_mag[2] = ((interval_dt * last_measured_avg_voltageD_mag[2]) + (dt * last_measured_voltageD[2].Mag()))/(interval_dt + dt);
00693
00694
00695 last_measured_avg_real_power = ((interval_dt * last_measured_avg_real_power) + (dt * last_measured_real_power))/(dt + interval_dt);
00696 last_measured_avg_reactive_power = ((interval_dt * last_measured_avg_reactive_power) + (dt * last_measured_reactive_power))/(dt + interval_dt);
00697 }
00698 last_measured_voltage[0] = voltageA.Mag();
00699 last_measured_voltage[1] = voltageB.Mag();
00700 last_measured_voltage[2] = voltageC.Mag();
00701 last_measured_voltageD[0] = measured_voltageD[0].Mag();
00702 last_measured_voltageD[1] = measured_voltageD[1].Mag();
00703 last_measured_voltageD[2] = measured_voltageD[2].Mag();
00704 if (t1 != last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) {
00705 voltage_avg_count++;
00706 interval_dt = interval_dt + dt;
00707 }
00708 if (tretval > last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) {
00709 tretval = last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep);
00710 }
00711 }
00712
00713 if ((t1 == last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) && (t1 != t0) && measured_min_max_avg_timestep > 0) {
00714 last_stat_timestamp = t1;
00715 if ( last_measured_voltage[0].Mag() > last_measured_max_voltage_mag[0].Mag()) {
00716 last_measured_max_voltage_mag[0] = last_measured_voltage[0];
00717 }
00718 if ( last_measured_voltage[1].Mag() > last_measured_max_voltage_mag[1].Mag()) {
00719 last_measured_max_voltage_mag[1] = last_measured_voltage[1];
00720 }
00721 if ( last_measured_voltage[2].Mag() > last_measured_max_voltage_mag[2].Mag()) {
00722 last_measured_max_voltage_mag[2] = last_measured_voltage[2];
00723 }
00724 if (last_measured_voltageD[0].Mag() > last_measured_max_voltageD_mag[0].Mag()) {
00725 last_measured_max_voltageD_mag[0] = last_measured_voltageD[0];
00726 }
00727 if (last_measured_voltageD[1].Mag() > last_measured_max_voltageD_mag[1].Mag()) {
00728 last_measured_max_voltageD_mag[1] = last_measured_voltageD[1];
00729 }
00730 if (last_measured_voltageD[2].Mag() > last_measured_max_voltageD_mag[2].Mag()) {
00731 last_measured_max_voltageD_mag[2] = last_measured_voltageD[2];
00732 }
00733 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[0].Mag()) {
00734 last_measured_min_voltage_mag[0] = last_measured_voltage[0];
00735 }
00736 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[1].Mag()) {
00737 last_measured_min_voltage_mag[1] = last_measured_voltage[0];
00738 }
00739 if ( last_measured_voltage[0].Mag() < last_measured_min_voltage_mag[2].Mag()) {
00740 last_measured_min_voltage_mag[2] = last_measured_voltage[0];
00741 }
00742 if (last_measured_voltageD[0].Mag() < last_measured_min_voltageD_mag[0].Mag()) {
00743 last_measured_min_voltageD_mag[0] = last_measured_voltageD[0];
00744 }
00745 if (last_measured_voltageD[1].Mag() < last_measured_min_voltageD_mag[1].Mag()) {
00746 last_measured_min_voltageD_mag[1] = last_measured_voltageD[1];
00747 }
00748 if (last_measured_voltageD[2].Mag() < last_measured_min_voltageD_mag[2].Mag()) {
00749 last_measured_min_voltageD_mag[2] = last_measured_voltageD[2];
00750 }
00751
00752
00753 if (last_measured_max_real_power < last_measured_real_power)
00754 {
00755 last_measured_max_real_power = last_measured_real_power;
00756 }
00757 if (last_measured_max_reactive_power < last_measured_reactive_power)
00758 {
00759 last_measured_max_reactive_power = last_measured_reactive_power;
00760 }
00761 if (last_measured_min_real_power > last_measured_real_power)
00762 {
00763 last_measured_min_real_power = last_measured_real_power;
00764 }
00765 if (last_measured_min_reactive_power > last_measured_reactive_power)
00766 {
00767 last_measured_min_reactive_power = last_measured_reactive_power;
00768 }
00769
00770 last_measured_avg_voltage_mag[0] = ((interval_dt * last_measured_avg_voltage_mag[0]) + (dt * last_measured_voltage[0].Mag()))/(interval_dt + dt);
00771 last_measured_avg_voltage_mag[1] = ((interval_dt * last_measured_avg_voltage_mag[1]) + (dt * last_measured_voltage[1].Mag()))/(interval_dt + dt);
00772 last_measured_avg_voltage_mag[2] = ((interval_dt * last_measured_avg_voltage_mag[2]) + (dt * last_measured_voltage[2].Mag()))/(interval_dt + dt);
00773 last_measured_avg_voltageD_mag[0] = ((interval_dt * last_measured_avg_voltageD_mag[0]) + (dt * last_measured_voltageD[0].Mag()))/(interval_dt + dt);
00774 last_measured_avg_voltageD_mag[1] = ((interval_dt * last_measured_avg_voltageD_mag[1]) + (dt * last_measured_voltageD[1].Mag()))/(interval_dt + dt);
00775 last_measured_avg_voltageD_mag[2] = ((interval_dt * last_measured_avg_voltageD_mag[2]) + (dt * last_measured_voltageD[2].Mag()))/(interval_dt + dt);
00776 last_measured_voltage[0] = voltageA.Mag();
00777 last_measured_voltage[1] = voltageB.Mag();
00778 last_measured_voltage[2] = voltageC.Mag();
00779 last_measured_voltageD[0] = measured_voltageD[0].Mag();
00780 last_measured_voltageD[1] = measured_voltageD[1].Mag();
00781 last_measured_voltageD[2] = measured_voltageD[2].Mag();
00782
00783
00784 last_measured_avg_real_power = ((interval_dt * last_measured_avg_real_power) + (dt * last_measured_real_power))/(dt + interval_dt);
00785 last_measured_avg_reactive_power = ((interval_dt * last_measured_avg_reactive_power) + (dt * last_measured_reactive_power))/(dt + interval_dt);
00786
00787 interval_dt = 0;
00788 voltage_avg_count = 0;
00789 measured_real_max_voltage_in_interval[0] = last_measured_max_voltage_mag[0].Re();
00790 measured_real_max_voltage_in_interval[1] = last_measured_max_voltage_mag[1].Re();
00791 measured_real_max_voltage_in_interval[2] = last_measured_max_voltage_mag[2].Re();
00792 measured_real_max_voltageD_in_interval[0] = last_measured_max_voltageD_mag[0].Re();
00793 measured_real_max_voltageD_in_interval[1] = last_measured_max_voltageD_mag[1].Re();
00794 measured_real_max_voltageD_in_interval[2] = last_measured_max_voltageD_mag[2].Re();
00795 measured_real_min_voltage_in_interval[0] = last_measured_min_voltage_mag[0].Re();
00796 measured_real_min_voltage_in_interval[1] = last_measured_min_voltage_mag[1].Re();
00797 measured_real_min_voltage_in_interval[2] = last_measured_min_voltage_mag[2].Re();
00798 measured_real_min_voltageD_in_interval[0] = last_measured_min_voltageD_mag[0].Re();
00799 measured_real_min_voltageD_in_interval[1] = last_measured_min_voltageD_mag[1].Re();
00800 measured_real_min_voltageD_in_interval[2] = last_measured_min_voltageD_mag[2].Re();
00801 measured_reactive_max_voltage_in_interval[0] = last_measured_max_voltageD_mag[0].Im();
00802 measured_reactive_max_voltage_in_interval[1] = last_measured_max_voltageD_mag[1].Im();
00803 measured_reactive_max_voltage_in_interval[2] = last_measured_max_voltageD_mag[2].Im();
00804 measured_reactive_max_voltageD_in_interval[0] = last_measured_max_voltageD_mag[0].Im();
00805 measured_reactive_max_voltageD_in_interval[1] = last_measured_max_voltageD_mag[1].Im();
00806 measured_reactive_max_voltageD_in_interval[2] = last_measured_max_voltageD_mag[2].Im();
00807 measured_reactive_min_voltage_in_interval[0] = last_measured_min_voltage_mag[0].Im();
00808 measured_reactive_min_voltage_in_interval[1] = last_measured_min_voltage_mag[1].Im();
00809 measured_reactive_min_voltage_in_interval[2] = last_measured_min_voltage_mag[2].Im();
00810 measured_reactive_min_voltageD_in_interval[0] = last_measured_min_voltageD_mag[0].Im();
00811 measured_reactive_min_voltageD_in_interval[1] = last_measured_min_voltageD_mag[1].Im();
00812 measured_reactive_min_voltageD_in_interval[2] = last_measured_min_voltageD_mag[2].Im();
00813
00814
00815 measured_real_max_power_in_interval = last_measured_max_real_power;
00816 measured_real_min_power_in_interval = last_measured_min_real_power;
00817 measured_real_avg_power_in_interval = last_measured_avg_real_power;
00818
00819 measured_reactive_max_power_in_interval = last_measured_max_reactive_power;
00820 measured_reactive_min_power_in_interval = last_measured_min_reactive_power;
00821 measured_reactive_avg_power_in_interval = last_measured_avg_reactive_power;
00822
00823 if (tretval > last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep)) {
00824 tretval = last_stat_timestamp + TIMESTAMP(measured_min_max_avg_timestep);
00825 }
00826 }
00827 }
00828
00829 monthly_energy = measured_real_energy/1000 - previous_energy_total;
00830
00831 if (bill_mode == BM_UNIFORM || bill_mode == BM_TIERED)
00832 {
00833 if (dt > 0)
00834 process_bill(t1);
00835
00836
00837 if (monthly_bill == previous_monthly_bill)
00838 {
00839 DATETIME t_next;
00840 gl_localtime(t1,&t_next);
00841
00842 t_next.day = bill_day;
00843
00844 if (t_next.month != 12)
00845 t_next.month += 1;
00846 else
00847 {
00848 t_next.month = 1;
00849 t_next.year += 1;
00850 }
00851 t_next.tz[0] = 0;
00852 next_time = gl_mktime(&t_next);
00853 }
00854 }
00855
00856 if(bill_mode == BM_HOURLY || bill_mode == BM_TIERED_RTP || bill_mode == BM_TIERED_TOU){
00857 double seconds;
00858 if (dt != last_t)
00859 seconds = (double)(dt);
00860 else
00861 seconds = 0;
00862
00863 if (seconds > 0)
00864 {
00865 double acc_price = price;
00866 if (bill_mode == BM_TIERED_TOU)
00867 {
00868 if(monthly_energy < tier_energy[0])
00869 acc_price = last_price;
00870 else if(monthly_energy < tier_energy[1])
00871 acc_price = last_tier_price[0];
00872 else if(monthly_energy < tier_energy[2])
00873 acc_price = last_tier_price[1];
00874 else
00875 acc_price = last_tier_price[2];
00876 }
00877 hourly_acc += seconds/3600 * acc_price * last_measured_real_power/1000;
00878 process_bill(t1);
00879 }
00880
00881
00882 if (bill_mode != BM_TIERED_TOU && power_market != NULL && price_prop != NULL)
00883 {
00884 double *pprice = (gl_get_double(power_market, price_prop));
00885 last_price = price = *pprice;
00886 }
00887 last_measured_real_power = measured_real_power;
00888
00889
00890 if (monthly_bill == previous_monthly_bill)
00891 {
00892 DATETIME t_next;
00893 gl_localtime(t1,&t_next);
00894
00895 t_next.day = bill_day;
00896
00897 if (t_next.month != 12)
00898 t_next.month += 1;
00899 else
00900 {
00901 t_next.month = 1;
00902 t_next.year += 1;
00903 }
00904 t_next.tz[0] = 0;
00905 next_time = gl_mktime(&t_next);
00906 }
00907 }
00908
00909
00910 last_measured_real_power = measured_real_power;
00911 last_measured_reactive_power = measured_reactive_power;
00912 }
00913
00914
00915 if (meter_NR_servered)
00916 {
00917
00918 indiv_measured_power[0] = voltage[0]*(~current_inj[0]);
00919 indiv_measured_power[1] = voltage[1]*(~current_inj[1]);
00920 indiv_measured_power[2] = voltage[2]*(~current_inj[2]);
00921 }
00922
00923 return tretval;
00924 }
00925
00926 double meter::process_bill(TIMESTAMP t1){
00927 DATETIME dtime;
00928 gl_localtime(t1,&dtime);
00929
00930 monthly_bill = monthly_fee;
00931 switch(bill_mode){
00932 case BM_NONE:
00933 break;
00934 case BM_UNIFORM:
00935 monthly_bill += monthly_energy * price;
00936 break;
00937 case BM_TIERED:
00938 if(monthly_energy < tier_energy[0])
00939 monthly_bill += last_price * monthly_energy;
00940 else if(monthly_energy < tier_energy[1])
00941 monthly_bill += last_price*tier_energy[0] + last_tier_price[0]*(monthly_energy - tier_energy[0]);
00942 else if(monthly_energy < tier_energy[2])
00943 monthly_bill += last_price*tier_energy[0] + last_tier_price[0]*(tier_energy[1] - tier_energy[0]) + last_tier_price[1]*(monthly_energy - tier_energy[1]);
00944 else
00945 monthly_bill += last_price*tier_energy[0] + last_tier_price[0]*(tier_energy[1] - tier_energy[0]) + last_tier_price[1]*(tier_energy[2] - tier_energy[1]) + last_tier_price[2]*(monthly_energy - tier_energy[2]);
00946 break;
00947 case BM_HOURLY:
00948 case BM_TIERED_TOU:
00949 monthly_bill += hourly_acc;
00950 break;
00951 case BM_TIERED_RTP:
00952 monthly_bill += hourly_acc;
00953 if(monthly_energy < tier_energy[0])
00954 monthly_bill += last_price_base * monthly_energy;
00955 else if(monthly_energy < tier_energy[1])
00956 monthly_bill += last_price_base*tier_energy[0] + last_tier_price[0]*(monthly_energy - tier_energy[0]);
00957 else if(monthly_energy < tier_energy[2])
00958 monthly_bill += last_price_base*tier_energy[0] + last_tier_price[0]*(tier_energy[1] - tier_energy[0]) + last_tier_price[1]*(monthly_energy - tier_energy[1]);
00959 else
00960 monthly_bill += last_price_base*tier_energy[0] + last_tier_price[0]*(tier_energy[1] - tier_energy[0]) + last_tier_price[1]*(tier_energy[2] - tier_energy[1]) + last_tier_price[2]*(monthly_energy - tier_energy[2]);
00961 break;
00962 }
00963
00964 if (dtime.day == bill_day && dtime.hour == 0 && dtime.month != last_bill_month)
00965 {
00966 previous_monthly_bill = monthly_bill;
00967 previous_monthly_energy = monthly_energy;
00968 previous_energy_total = measured_real_energy/1000;
00969 last_bill_month = dtime.month;
00970 hourly_acc = 0;
00971 }
00972
00973 last_price = price;
00974 last_price_base = price_base;
00975 last_tier_price[0] = tier_price[0];
00976 last_tier_price[1] = tier_price[1];
00977 last_tier_price[2] = tier_price[2];
00978
00979 return monthly_bill;
00980 }
00981
00982
00983 SIMULATIONMODE meter::inter_deltaupdate_meter(unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val,bool interupdate_pos)
00984 {
00985 OBJECT *hdr = OBJECTHDR(this);
00986 double deltat, deltatimedbl;
00987 STATUS return_status_val;
00988
00989
00990 deltat = (double)dt/(double)DT_SECOND;
00991
00992
00993 if ((iteration_count_val==0) && (interupdate_pos == false))
00994 {
00995
00996 deltatimedbl = (double)delta_time/(double)DT_SECOND;
00997
00998
00999 prev_time_dbl = (double)gl_globalclock + deltatimedbl;
01000
01001
01002 if (fmeas_type != FM_NONE)
01003 {
01004
01005 memcpy(&prev_freq_state,&curr_freq_state,sizeof(FREQM_STATES));
01006 }
01007 }
01008
01009
01010 if ((delta_time==0) && (iteration_count_val==0) && (interupdate_pos == false) && (fmeas_type != FM_NONE))
01011 {
01012
01013 init_freq_dynamics();
01014 }
01015
01016
01017 if ((GFA_enable == true) && (iteration_count_val == 0) && (interupdate_pos == false))
01018 {
01019
01020 GFA_Update_time = perform_GFA_checks(deltat);
01021 }
01022
01023 if (interupdate_pos == false)
01024 {
01025
01026 if (meter_power_consumption != complex(0,0))
01027 power[0] = power[1] = power[2] = 0.0;
01028
01029
01030 if (meter_interrupted_secondary == true)
01031 meter_interrupted_secondary = false;
01032
01033
01034 NR_node_presync_fxn(0);
01035
01036
01037 BOTH_meter_sync_fxn();
01038
01039
01040 NR_node_sync_fxn(hdr);
01041
01042 return SM_DELTA;
01043
01044 }
01045 else
01046 {
01047
01048 BOTH_node_postsync_fxn(hdr);
01049
01050
01051 if (fmeas_type != FM_NONE)
01052 {
01053 return_status_val = calc_freq_dynamics(deltat);
01054
01055
01056 if (return_status_val == FAILED)
01057 {
01058 return SM_ERROR;
01059 }
01060 }
01061
01062
01063
01064 measured_voltage[0] = voltageA;
01065 measured_voltage[1] = voltageB;
01066 measured_voltage[2] = voltageC;
01067
01068 measured_voltageD[0] = voltageA - voltageB;
01069 measured_voltageD[1] = voltageB - voltageC;
01070 measured_voltageD[2] = voltageC - voltageA;
01071
01072 measured_current[0] = current_inj[0];
01073 measured_current[1] = current_inj[1];
01074 measured_current[2] = current_inj[2];
01075
01076
01077 indiv_measured_power[0] = measured_voltage[0]*(~measured_current[0]);
01078 indiv_measured_power[1] = measured_voltage[1]*(~measured_current[1]);
01079 indiv_measured_power[2] = measured_voltage[2]*(~measured_current[2]);
01080
01081 measured_power = indiv_measured_power[0] + indiv_measured_power[1] + indiv_measured_power[2];
01082
01083 measured_real_power = (indiv_measured_power[0]).Re()
01084 + (indiv_measured_power[1]).Re()
01085 + (indiv_measured_power[2]).Re();
01086
01087 measured_reactive_power = (indiv_measured_power[0]).Im()
01088 + (indiv_measured_power[1]).Im()
01089 + (indiv_measured_power[2]).Im();
01090
01091 if (measured_real_power > measured_demand)
01092 measured_demand = measured_real_power;
01093
01094
01095 if (GFA_enable == true)
01096 {
01097
01098 if ((GFA_Update_time > 0.0) && (GFA_Update_time < 1.7))
01099 {
01100
01101 return SM_DELTA;
01102 }
01103 else
01104 {
01105 return SM_EVENT;
01106 }
01107 }
01108 else
01109 {
01110 return SM_EVENT;
01111 }
01112 }
01113 }
01114
01116
01118
01119 EXPORT int isa_meter(OBJECT *obj, char *classname)
01120 {
01121 return OBJECTDATA(obj,meter)->isa(classname);
01122 }
01123
01124 EXPORT int create_meter(OBJECT **obj, OBJECT *parent)
01125 {
01126 try
01127 {
01128 *obj = gl_create_object(meter::oclass);
01129 if (*obj!=NULL)
01130 {
01131 meter *my = OBJECTDATA(*obj,meter);
01132 gl_set_parent(*obj,parent);
01133 return my->create();
01134 }
01135 else
01136 return 0;
01137 }
01138 CREATE_CATCHALL(meter);
01139 }
01140
01141 EXPORT int init_meter(OBJECT *obj)
01142 {
01143 try {
01144 meter *my = OBJECTDATA(obj,meter);
01145 return my->init(obj->parent);
01146 }
01147 INIT_CATCHALL(meter);
01148 }
01149
01150 EXPORT TIMESTAMP sync_meter(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
01151 {
01152 try {
01153 meter *pObj = OBJECTDATA(obj,meter);
01154 TIMESTAMP t1;
01155 switch (pass) {
01156 case PC_PRETOPDOWN:
01157 return pObj->presync(t0);
01158 case PC_BOTTOMUP:
01159 return pObj->sync(t0);
01160 case PC_POSTTOPDOWN:
01161 t1 = pObj->postsync(obj->clock,t0);
01162 obj->clock = t0;
01163 return t1;
01164 default:
01165 throw "invalid pass request";
01166 }
01167 throw "invalid pass request";
01168 }
01169 SYNC_CATCHALL(meter);
01170 }
01171
01172 EXPORT int notify_meter(OBJECT *obj, int update_mode, PROPERTY *prop, char *value){
01173 meter *n = OBJECTDATA(obj, meter);
01174 int rv = 1;
01175
01176 rv = n->notify(update_mode, prop, value);
01177
01178 return rv;
01179 }
01180
01181
01182 EXPORT SIMULATIONMODE interupdate_meter(OBJECT *obj, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val, bool interupdate_pos)
01183 {
01184 meter *my = OBJECTDATA(obj,meter);
01185 SIMULATIONMODE status = SM_ERROR;
01186 try
01187 {
01188 status = my->inter_deltaupdate_meter(delta_time,dt,iteration_count_val,interupdate_pos);
01189 return status;
01190 }
01191 catch (char *msg)
01192 {
01193 gl_error("interupdate_meter(obj=%d;%s): %s", obj->id, obj->name?obj->name:"unnamed", msg);
01194 return status;
01195 }
01196 }
01197
01198 int meter::kmldata(int (*stream)(const char*,...))
01199 {
01200 int phase[3] = {has_phase(PHASE_A),has_phase(PHASE_B),has_phase(PHASE_C)};
01201 double basis[3] = {0,240,120};
01202
01203
01204 stream("<TR><TH ALIGN=LEFT>Power</TH>");
01205 for ( int i = 0 ; i<sizeof(phase)/sizeof(phase[0]) ; i++ )
01206 {
01207 if ( phase[i] )
01208 stream("<TD ALIGN=RIGHT STYLE=\"font-family:courier;\"><NOBR>%.3f</NOBR></TD><TD ALIGN=LEFT>kVA</TD>", indiv_measured_power[i].Mag()/1000);
01209 else
01210 stream("<TD ALIGN=RIGHT STYLE=\"font-family:courier;\">—</TD><TD> </TD>");
01211 }
01212 stream("</TR>\n");
01213
01214
01215 stream("<TR><TH ALIGN=LEFT>Energy</TH>");
01216 stream("<TD ALIGN=RIGHT COLSPAN=3 STYLE=\"font-family:courier;\"><NOBR>%.3f kWh</NOBR></TD>", measured_real_energy/1000);
01217 stream("<TD ALIGN=RIGHT COLSPAN=3 STYLE=\"font-family:courier;\"><NOBR>%.3f kVARh</NOBR></TD>", measured_reactive_energy/1000);
01218 stream("</TR>\n");
01219
01220 return 0;
01221 }
01222