Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
// 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);

}
Пример #5
0
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;
}
Пример #6
0
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;
}