Ejemplo n.º 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);
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
0
TIMESTAMP csv_reader::get_data(TIMESTAMP t0, double *temp, double *humid, double *direct, double *diffuse, double *global, double *wind, double *rain, double *snow){
	DATETIME now, then;
//	TIMESTAMP until;
	int next_year = 0;
	int i = 0;
	int idx = index;
	int start = index;

	int localres;

	if(t0 < next_ts){ /* still good ~ go home */
		return -next_ts;
	}

	localres = gl_localtime(t0, &now); // error check

	if(next_ts == 0){
		//	initialize to the correct index & next_ts
		DATETIME guess_dt;
		TIMESTAMP guess_ts;
		int i;
		for(i = 0; i < sample_ct; ++i){
			guess_dt.year = now.year;
			guess_dt.month = samples[sample_ct-i-1]->month;
			guess_dt.day = samples[sample_ct-i-1]->day;
			guess_dt.hour = samples[sample_ct-i-1]->hour;
			guess_dt.minute = samples[sample_ct-i-1]->minute;
			guess_dt.second = samples[sample_ct-i-1]->second;
			strcpy(guess_dt.tz, now.tz);
//			strcpy(guess_dt.tz, "GMT");
			guess_ts = (TIMESTAMP)gl_mktime(&guess_dt);

			if(guess_ts <= t0){
				break;
			}
		}
		index = sample_ct - i - 1;

		if(index > -1){
			*temp = samples[index]->temperature;
			*humid = samples[index]->humidity;
			*direct = samples[index]->solar_dir;
			*diffuse = samples[index]->solar_diff;
			*global = samples[index]->solar_global;
			*wind = samples[index]->wind_speed;
			*rain = samples[index]->rainfall;
			*snow = samples[index]->snowdepth;
		} else {
			*temp = samples[sample_ct - 1]->temperature;
			*humid = samples[sample_ct - 1]->humidity;
			*direct = samples[sample_ct - 1]->solar_dir;
			*diffuse = samples[sample_ct - 1]->solar_diff;
			*global = samples[sample_ct - 1]->solar_global;
			*wind = samples[sample_ct - 1]->wind_speed;
			*rain = samples[sample_ct - 1]->rainfall;
			*snow = samples[sample_ct - 1]->snowdepth;
		}

		then.year = now.year + (index+1 == sample_ct ? 1 : 0);
		then.month = samples[(index+1)%sample_ct]->month;
		then.day = samples[(index+1)%sample_ct]->day;
		then.hour = samples[(index+1)%sample_ct]->hour;
		then.minute = samples[(index+1)%sample_ct]->minute;
		then.second = samples[(index+1)%sample_ct]->second;
		strcpy(then.tz, now.tz);

		next_ts = (TIMESTAMP)gl_mktime(&then);
		//next_ts = (TIMESTAMP)gl_mktime(&then);

		return -next_ts;
	}

	if(sample_ct == 1){ /* only one sample ~ ignore it and keep feeding the same data back, but in a year */
		next_ts += 365 * 24 * 3600;
		return -next_ts;
	}

	do{
		// should we roll the year over?
		if(index+1 >= sample_ct){
			index = 0;
		} else {
			++index;
		}

		if(index+1 == sample_ct){
			next_year = 1;
		} else {
			next_year = 0;
		}

		then.year = now.year + next_year;
		then.month = samples[(index+1)%sample_ct]->month;
		then.day = samples[(index+1)%sample_ct]->day;
		then.hour = samples[(index+1)%sample_ct]->hour;
		then.minute = samples[(index+1)%sample_ct]->minute;
		then.second = samples[(index+1)%sample_ct]->second;
		strcpy(then.tz, now.tz);

		// next_ts is the time the current sample is overwritten by another sample.
		next_ts = (TIMESTAMP)gl_mktime(&then);
	} while (next_ts < t0 && index != start); // skip samples that try to reverse the time
	
	*temp = samples[index]->temperature;
	*humid = samples[index]->humidity;
	*direct = samples[index]->solar_dir;
	*diffuse = samples[index]->solar_diff;
	*global = samples[index]->solar_global;
	*wind = samples[index]->wind_speed;
	*rain = samples[index]->rainfall;
	*snow = samples[index]->snowdepth;

	// having found the index, update the data
	if(index == start){
		GL_THROW("something strange happened with the schedule in csv_reader");
		/*	TROUBLESHOOT
			An unidentified error occured while reading data and constructing the weather
			data schedule.  Please post a ticket detailing this event on the GridLAB-D
			SourceForge page.
		*/
	}
	
	return -next_ts;
}
Ejemplo n.º 4
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);

}
Ejemplo n.º 6
0
TIMESTAMP player_read(OBJECT *obj)
{
	char buffer[256];
	char timebuf[64], valbuf[256], tbuf[64];
	char tz[6];
	int Y=0,m=0,d=0,H=0,M=0;
	double S=0;
	struct player *my = OBJECTDATA(obj,struct player);
	char unit[2];
	TIMESTAMP t1;
	char *result=NULL;
	char256 value;
	int voff=0;

	/* TODO move this to tape.c and make the variable available to all classes in tape */
	static enum {UNKNOWN,ISO,US,EURO} dateformat = UNKNOWN;
	if ( dateformat==UNKNOWN )
	{
		static char global_dateformat[8]="";
		gl_global_getvar("dateformat",global_dateformat,sizeof(global_dateformat));
		if (strcmp(global_dateformat,"ISO")==0) dateformat = ISO;
		else if (strcmp(global_dateformat,"US")==0) dateformat = US;
		else if (strcmp(global_dateformat,"EURO")==0) dateformat = EURO;
		else dateformat = ISO;
	}

Retry:
	result = my->ops->read(my, buffer, sizeof(buffer));

	memset(timebuf, 0, 64);
	memset(valbuf, 0, 256);
	memset(tbuf, 0, 64);
	memset(value, 0, 256);
	memset(tz, 0, 6);
	if (result==NULL)
	{
		if (my->loopnum>0)
		{
			rewind_player(my);
			my->loopnum--;
			goto Retry;
		}
		else {
			close_player(my);
			my->status=TS_DONE;
			my->next.ts = TS_NEVER;
			my->next.ns = 0;
			goto Done;
		}
	}
	if (result[0]=='#' || result[0]=='\n') /* ignore comments and blank lines */
		goto Retry;

	if(sscanf(result, "%32[^,],%256[^\n\r;]", tbuf, valbuf) == 2){
		trim(tbuf, timebuf);
		trim(valbuf, value);
		if (sscanf(timebuf,"%d-%d-%d %d:%d:%lf %4s",&Y,&m,&d,&H,&M,&S, tz)==7){
			//struct tm dt = {S,M,H,d,m-1,Y-1900,0,0,0};
			DATETIME dt;
			switch ( dateformat ) {
			case ISO:
				dt.year = Y;
				dt.month = m;
				dt.day = d;
				break;
			case US:
				dt.year = d;
				dt.month = Y;
				dt.day = m;
				break;
			case EURO:
				dt.year = d;
				dt.month = m;
				dt.day = Y;
				break;
			}
			dt.hour = H;
			dt.minute = M;
			dt.second = (unsigned short)S;
			dt.nanosecond = (unsigned int)(1e9*(S-dt.second));
			strcpy(dt.tz, tz);
			t1 = (TIMESTAMP)gl_mktime(&dt);
			if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
				enable_deltamode(dt.nanosecond==0?TS_NEVER:t1);
			if (t1!=TS_INVALID && my->loop==my->loopnum){
				my->next.ts = t1;
				my->next.ns = dt.nanosecond;
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else if (sscanf(timebuf,"%d-%d-%d %d:%d:%lf",&Y,&m,&d,&H,&M,&S)>=4)
		{
			//struct tm dt = {S,M,H,d,m-1,Y-1900,0,0,0};
			DATETIME dt;
			switch ( dateformat ) {
			case ISO:
				dt.year = Y;
				dt.month = m;
				dt.day = d;
				break;
			case US:
				dt.year = d;
				dt.month = Y;
				dt.day = m;
				break;
			case EURO:
				dt.year = d;
				dt.month = m;
				dt.day = Y;
				break;
			}
			dt.hour = H;
			dt.minute = M;
			dt.second = (unsigned short)S;
			dt.tz[0] = 0;
			dt.nanosecond = (unsigned int)(1e9*(S-dt.second));
			t1 = (TIMESTAMP)gl_mktime(&dt);
			if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
				enable_deltamode(dt.nanosecond==0?TS_NEVER:t1);
			if (t1!=TS_INVALID && my->loop==my->loopnum){
				my->next.ts = t1;
				my->next.ns = dt.nanosecond;
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else if (sscanf(timebuf,"%" FMT_INT64 "d%1s", &t1, unit)==2)
		{
			{
				int64 scale=1;
				switch(unit[0]) {
				case 's': scale=TS_SECOND; break;
				case 'm': scale=60*TS_SECOND; break;
				case 'h': scale=3600*TS_SECOND; break;
				case 'd': scale=86400*TS_SECOND; break;
				default: break;
				}
				t1 *= scale;
				if (result[0]=='+'){ /* timeshifts have leading + */
					my->next.ts += t1;
					while(value[voff] == ' '){
						++voff;
					}
					strcpy(my->next.value, value+voff);
				} else if (my->loop==my->loopnum){ /* absolute times are ignored on all but first loops */
					my->next.ts = t1;
					while(value[voff] == ' '){
						++voff;
					}
					strcpy(my->next.value, value+voff);
				}
			}
		}
		else if (sscanf(timebuf,"%lf", &S)==1)
		{
			if (my->loop==my->loopnum) {
				my->next.ts = (unsigned short)S;
				my->next.ns = (unsigned int)(1e9*(S-my->next.ts));
				if ((obj->flags & OF_DELTAMODE)==OF_DELTAMODE)	/* Only request deltamode if we're explicitly enabled */
					enable_deltamode(my->next.ns==0?TS_NEVER:t1);
				while(value[voff] == ' '){
					++voff;
				}
				strcpy(my->next.value, value+voff);
			}
		}
		else
		{
			gl_warning("player was unable to parse timestamp \'%s\'", result);
		}
	} else {
		gl_warning("player was unable to split input string \'%s\'", result);
	}

Done:
	return my->next.ns==0 ? my->next.ts : (my->next.ts+1);
}