/************************************************************************* 
* 版权所有：	
* 文件版本： V1.00
* 文件名称：mea.c
* 生成日期： 2008年7月1日
* 作	者： hqs
* 功	能： 计算测量值
* 更新信息：
* 更新日志1：
* 日期：	  
* 修改者：	  sunxi
* 修改内容：  
* 修改原因：  
* 更新日志2：
**************************************************************************/
#include "head.h"

long lMeaVal[PUB_AC_NUM_ALL+SW_AC_NUM_ALL]; //测量值保存
long lMeaAng[PUB_AC_NUM_ALL+SW_AC_NUM_ALL]; //测量值角度
bool lMeaCal[PUB_AC_NUM_ALL+SW_AC_NUM_ALL]; //测量值是否自产

/*刷新公用测量值*/
/**************************************************************************
函数名称：FreshMeaPub
函数版本：1.00 
作者：    电力产品部
创建日期：2013.4.20
函数功能：刷新公用测量值
输入参数：
其他输入:
输出参数：
返回值：  
***************************************************************************/

void FreshMeaPub(long *pVal,long *pAng,bool *pCal)
{
	int i;
	qs16 val,ang;
	
	for(i=0;i<PUB_AC_NUM_ALL;i++)
	{
		pCal[i]=false;
		
		val=g_sw_pub.ac_in[i];
		if(i<PUB_AC_NUM)
		{
			ang=g_ui[i].p;
			if(g_ui[i].ui_base_make!=-1)
			{
				pCal[i]=true;
			}
		}
		else
		{
			ang=0;
		}
		
		if(g_unit[g_pub_ac_desc[i].unit].zero>0&&_AbsL(val) < g_unit[g_pub_ac_desc[i].unit].zero && pRunSet->bTT_RET_ZERO)
		{
			val=0;
			ang=ANGEL_INVALID;
		}
		
		pVal[i]=val;
		pAng[i]=ang;
	}
}


/*刷新开关测量值*/
/**************************************************************************
函数名称：FreshMeaSw
函数版本：1.00 
作者：    电力产品部
创建日期：2013.4.20
函数功能：刷新公用测量值
输入参数：
其他输入:
输出参数：
返回值：  
***************************************************************************/

void FreshMeaSw(long *pVal,long* pAng,bool *pCal,int sw)
{
	int i;
	qs16 val,ang;
	
	sw-=1;
	for(i=0;i<SW_AC_NUM_ALL;i++)
	{
		pCal[i]=false;
		
		val=g_sw[sw].ac_in[i];
		if(i<SW_AC_NUM)
		{
			ang=g_ui[UI_SW_INDEX(sw,i)].p;
			if(g_ui[UI_SW_INDEX(sw,i)].ui_base_make!=-1)
			{
				pCal[i]=true;
			}			
		}
		else
		{
			ang=0;
		}

		if(g_unit[g_sw_ac_desc[i].unit].zero>0&&_AbsL(val) < g_unit[g_sw_ac_desc[i].unit].zero && pRunSet->bTT_RET_ZERO)
		{
			val=0;
			ang=ANGEL_INVALID;
		}
		
		pVal[i]=val;
		pAng[i]=ang;
	}
}


long GetRmtMeaVal(int owner,int index,u8 *link_qds)  //取遥测值
{
	long val=0;
	long lzero=0;
	int sw=owner;
	
	if(sw==0) // 公共测量值
	{
		if(index < PUB_AC_NUM_ALL)
		{
			val=g_sw_pub.ac_in[index];
		}
		lzero=g_unit[g_pub_ac_desc[index].unit].zero;
	}
	else if(sw<=SWITCH_NUM_EXT)
	{
		sw-=1;
		if(index < SW_AC_NUM_ALL)
		{
			val=g_sw[sw].ac_in[index];
			if(link_qds)
			{
				*link_qds=g_sw[sw].link_qds[index];
			}
				
		}
		lzero=g_unit[g_sw_ac_desc[index].unit].zero;		
	}
	
	if(lzero>0&&_AbsL(val)<lzero && pRunSet->bTT_RET_ZERO)
	{
		val=0;
	}

	if(g_run_stu.bToolRmtTest||g_run_stu.bHmiRmtTest)  //测试模式下，
	{
		if((g_rmt_set_yc.owner==owner)&&(g_rmt_set_yc.indexno==(index+1)))
		{
			val=g_rmt_set_yc.val;
		}
	}
	
	return val;
}


float GetRmtDdVal(int owner,int index)  //取遥测值
{
	float val=0;
	int sw=owner;
	
	if(sw==0) // 公共测量值
	{
		return 0;
	}
	
	sw --;
	if(sw<SWITCH_NUM_EXT)
	{
		if(index < SW_DD_NUM_ALL)
		{
			val=g_sw[sw].dd[index].fv;
		} 		
	}
	
	if(g_run_stu.bToolRmtTest||g_run_stu.bHmiRmtTest)  //测试模式下，
	{
		if((g_rmt_set_dd.owner==owner)&&(g_rmt_set_dd.indexno==(index+1)))
		{
			val=(float)g_rmt_set_dd.val/Q16_BASE;
		}
	}
	
	return val;
}

int GetRmtDdTmVal(int owner,int index,struct rtc_time_t  *p_ct,float *f_v)  //取带时标电度遥测值
{
	int sw=owner;
	struct timespec ts;
	struct rtc_time_t ct;

	if(sw==0) // 公共测量值
	{
		return -1;
	}

	sw --;
	if(sw<SWITCH_NUM_EXT)
	{
		if(index < SW_DD_NUM_ALL)
		{
			*f_v=g_sw[sw].dd[index].fv;
			*p_ct = g_sw[sw].dd[index].ct;	
		} 
	}
	else
	{
		return -2;
	}

	if(g_run_stu.bToolRmtTest||g_run_stu.bHmiRmtTest)  //测试模式下，
	{
		if((g_rmt_set_dd.owner==owner)&&(g_rmt_set_dd.indexno==(index+1)))
		{
			
			*f_v=(float)g_rmt_set_dd.val/Q16_BASE;
			clk_time_get(&ts);
			timespec_to_rtc(ts,&ct,1);
			*p_ct = ct;
			
		}
	}

	return 0;

}

BYTE GetRmtYxVal(int sw,int index) //取遥信值index从1开始，==0为无效编号
{
	if(index==0)
	{
		return 0;
	}
	index--;

	if(sw==0) // 公共遥信
	{
		return g_sw_pub.di[index];
	}
	else if(sw<=SWITCH_NUM_EXT)
	{
		sw--;
		return g_sw[sw].di[index];
	}

	return 0;
}



void iec_mea_filter(void)
{
	int i;
	u8	owner;	

	if(g_run_stu.bToolRmtTest||g_run_stu.bHmiRmtTest||(pRunSet->f_yc_filter_factor==0))  //测试模式下，
	{
		byc_filter = false;
		return;
	}

	byc_filter = false;


	for (i=0; i<g_table_head->ac_num; i++)
	{
		u8 no=g_ac_table[i].indexno;
		DWORD dwMax=0;
		DWORD dwDeadVal=0;
	

		if(no>0)
		{
			owner = g_ac_table[i].owner;
			dwMax=(DWORD)g_ac_table[i].normal;	
			no -= 1;
		
			if(dwMax==0) //防止额定或者前一次保存值为0
				dwMax=1;
			dwDeadVal=_Mul_Div_U(g_ac_table[i].dead_value,dwMax,6553600);	

			if(dwDeadVal==0)
				continue;
			
			/*
			rt_printf("%s(%d):dead_value=%d,normal=%d,dwDeadVal=%d\r\n",
					__func__,i,
					g_ac_table[i].dead_value,
					g_ac_table[i].normal,
					dwDeadVal);
			*/

			if(dwDeadVal==0)dwDeadVal=1;

			if(owner==0) // 公共测量值
			{
				if(no < PUB_AC_NUM_ALL)
				{
					//超过死区变化量的5%就认为遥测值没有稳定
					if(_AbsL(g_sw_pub.ac_in_buf[no]-g_sw_pub.ac_in[no])>(dwDeadVal*pRunSet->f_yc_filter_factor))
					{
						byc_filter = true;
					}
				
					g_sw_pub.ac_in_buf[no] = g_sw_pub.ac_in[no];
					
				}
				
			}
			else if(owner<=SWITCH_NUM_EXT)
			{
				owner-=1;

				//为了防止有功、无功、功率因素等波动太大，而无法刷新上送数据，屏蔽这些
				if((no == SW_AC_IN_P)||(no == SW_AC_IN_Pa)||(no == SW_AC_IN_Pb)
					||(no == SW_AC_IN_Pc)||(no == SW_AC_IN_Q)||(no == SW_AC_IN_Qa)
					||(no == SW_AC_IN_Qb)||(no == SW_AC_IN_Qc)||(no == SW_AC_IN_COS))
				{
					continue;
				}
			
				if(no < SW_AC_NUM_ALL)
				{
					if(_AbsL(g_sw[owner].ac_in_buf[no] - g_sw[owner].ac_in[no])>(dwDeadVal*0.05))
					{
						byc_filter = true;
						
					}
					g_sw[owner].ac_in_buf[no] = g_sw[owner].ac_in[no];

				}
					
			}

			
		}
			
	}

}

#ifdef METERING_ENERGY
struct eventd_format_st evt_st[METERING_EVT_NUM];
EventNumType   EventNumData;
TDLVAL tDLVal;
bool byDLFreezen=false;
void DLInit(void)
{
	SYSTEM_DATA st;
	int sw = 0;
	
	memset(&tDLVal,0,sizeof(tDLVal));
	byDLFreezen=true;
	ReadSysData(&st);
	tDLVal.dPEz=st.dwDD[0];
	tDLVal.dPWz=st.dwDD[1];
	tDLVal.dNEz=st.dwDD[2];
	tDLVal.dNWz=st.dwDD[3];
	tDLVal.dWz[0]=st.dwDD[4];
	tDLVal.dWz[1]=st.dwDD[5];
	tDLVal.dWz[2]=st.dwDD[6];
	tDLVal.dWz[3]=st.dwDD[7];
	tDLVal.sDir=-1;
	byDLFreezen=false;

	g_sw[sw].dd[SW_DD_NOW1].fv=tDLVal.dPEz/1000.0;  //更新到测量结构体中
	g_sw[sw].dd[SW_DD_NOW2].fv=tDLVal.dPWz/1000.0;
	g_sw[sw].dd[SW_DD_NOW3].fv=tDLVal.dWz[0]/1000.0;
	g_sw[sw].dd[SW_DD_NOW4].fv=tDLVal.dWz[3]/1000.0;
	g_sw[sw].dd[SW_DD_NOW5].fv=tDLVal.dNEz/1000.0;
	g_sw[sw].dd[SW_DD_NOW6].fv=tDLVal.dNWz/1000.0;
	g_sw[sw].dd[SW_DD_NOW7].fv=tDLVal.dWz[1]/1000.0;
	g_sw[sw].dd[SW_DD_NOW8].fv=tDLVal.dWz[2]/1000.0;

	g_sw[sw].dd[SW_DD_DAY1].fv=g_sw[sw].dd[SW_DD_NOW1].fv;  //更新到日冻结中
	g_sw[sw].dd[SW_DD_DAY2].fv=g_sw[sw].dd[SW_DD_NOW2].fv;
	g_sw[sw].dd[SW_DD_DAY3].fv=g_sw[sw].dd[SW_DD_NOW3].fv;
	g_sw[sw].dd[SW_DD_DAY4].fv=g_sw[sw].dd[SW_DD_NOW4].fv;
	g_sw[sw].dd[SW_DD_DAY5].fv=g_sw[sw].dd[SW_DD_NOW5].fv;
	g_sw[sw].dd[SW_DD_DAY6].fv=g_sw[sw].dd[SW_DD_NOW6].fv;
	g_sw[sw].dd[SW_DD_DAY7].fv=g_sw[sw].dd[SW_DD_NOW7].fv;
	g_sw[sw].dd[SW_DD_DAY8].fv=g_sw[sw].dd[SW_DD_NOW8].fv;
	
	g_sw[sw].dd[SW_DD_15M1].fv=g_sw[sw].dd[SW_DD_NOW1].fv;  //更新到15分钟冻结中
	g_sw[sw].dd[SW_DD_15M2].fv=g_sw[sw].dd[SW_DD_NOW2].fv;
	g_sw[sw].dd[SW_DD_15M3].fv=g_sw[sw].dd[SW_DD_NOW3].fv;
	g_sw[sw].dd[SW_DD_15M4].fv=g_sw[sw].dd[SW_DD_NOW4].fv;
	g_sw[sw].dd[SW_DD_15M5].fv=g_sw[sw].dd[SW_DD_NOW5].fv;
	g_sw[sw].dd[SW_DD_15M6].fv=g_sw[sw].dd[SW_DD_NOW6].fv;
	g_sw[sw].dd[SW_DD_15M7].fv=g_sw[sw].dd[SW_DD_NOW7].fv;
	g_sw[sw].dd[SW_DD_15M8].fv=g_sw[sw].dd[SW_DD_NOW8].fv;

}


void QdSaveDLCal(void)
{
	tRunPara.sysData.dwDD[0]=tDLVal.dPEz;  //更新到待保存区
	tRunPara.sysData.dwDD[1]=tDLVal.dPWz;
	tRunPara.sysData.dwDD[2]=tDLVal.dNEz;
	tRunPara.sysData.dwDD[3]=tDLVal.dNWz;
	tRunPara.sysData.dwDD[4]=tDLVal.dWz[0];
	tRunPara.sysData.dwDD[5]=tDLVal.dWz[1];
	tRunPara.sysData.dwDD[6]=tDLVal.dWz[2];
	tRunPara.sysData.dwDD[7]=tDLVal.dWz[3];
	tRunPara.sysData.bWriteFlag=true;
}

void DL_clear(void)
{
	tDLVal.bClr=true;
}


#define DL_0001D  65536ul*36000ul//0x8CA00000  // 0.001度
void DLCal(void)
{
	static bool bValid = false;
	static DWORD dPassTime=0;
	static DWORD dLastTime=0;
	DWORD  dPEzTemp;
	DWORD  dNEzTemp;
	DWORD  dPWzTemp;
	DWORD  dNWzTemp;
//	DWORD  dTTemp;
	long    lPTemp;
	long    lQTemp;
	int sw=0;
	DWORD dd_val;
	DWORD dir_num;
	u32 U;
	#define MINI_VALUE		600

	if(tDLVal.bClr)
	{
		memset(&tDLVal,0,sizeof(tDLVal));
		QdSaveDLCal();
		tDLVal.bClr=false;
		return;
	}

	if(byDLFreezen)
	{
		bValid = false;
		return;
	}	
	if(!bValid)
	{
		bValid = true;
		dLastTime = dTCounter;
        	dPassTime = 0;
		tDLVal.dPEzChip =0;
		tDLVal.dNEzChip = 0;
		tDLVal.dPWzChip =0;
		tDLVal.dNWzChip = 0;        
		tDLVal.dWzChip[0] = 0;        
		tDLVal.dWzChip[1] = 0;        
		tDLVal.dWzChip[2] = 0; 
		tDLVal.dWzChip[3] = 0;        
	        return;
	}

	U = pRunSet->tSwSet[sw].bTT_Power_v2 ? PUB_AC_UA2 : PUB_AC_UA1;
	if( ((g_sw_pub.ac_in[U] < MINI_VALUE) || (g_sw[sw].ac_in[SW_AC_CIA] < MINI_VALUE))
		&& ((g_sw_pub.ac_in[U+1] < MINI_VALUE) || (g_sw[sw].ac_in[SW_AC_CIB] < MINI_VALUE))
		&& ((g_sw_pub.ac_in[U+2] < MINI_VALUE) || (g_sw[sw].ac_in[SW_AC_CIC] < MINI_VALUE)))
	{
		tDLVal.dirus0= ustimer_get_origin();
		dLastTime = dTCounter;
		return;
	}
	/*
	dTTemp = dTCounter;
	dPassTime += dTTemp - dLastTime;
	dLastTime = dTTemp;
	if(dPassTime < T_100ms )return;
	dPassTime -= T_100ms;
	*/
	dPassTime = dTCounter - dLastTime;
	if(dPassTime < T_100ms )
		return;
	dLastTime += T_100ms;
	
    //计算第一路积分电度
	lPTemp =g_sw[sw].ac_in[SW_AC_IN_P];
	lQTemp =g_sw[sw].ac_in[SW_AC_IN_Q];
	if(lPTemp < 0)//反向有功
	{
		dPEzTemp = 0;
		dNEzTemp = _AbsL(lPTemp);
	}
	else                        //正向有功
	{
		dPEzTemp = (DWORD)lPTemp;
		dNEzTemp = 0;
	}

	if(lQTemp < 0)//反向无功
	{
		dPWzTemp = 0;
		dNWzTemp = _AbsL(lQTemp);
	}
	else                        //正向无功
	{
		dPWzTemp = (DWORD)lQTemp;
		dNWzTemp = 0;
	}

	if(tDLVal.sDir<0)
	{
		tDLVal.sDir=(lPTemp>=0)?1:0; //潮流方向 初始化
		tDLVal.dirus0= ustimer_get_origin();
	}

	//正向有功累加
	if(dPEzTemp)
	{
		tDLVal.dPEzChip += dPEzTemp;		
		if(tDLVal.dPEzChip >= DL_0001D)//0.001度 = 36000*65536 =0x8CA00000
		{
			tDLVal.dPEzChip -= DL_0001D;
			tDLVal.dPEz++;
			if(tDLVal.dPEz >= 999999999ul)
			{
				tDLVal.dPEz=0;//如果积分电度大于等于1000000.000则清零并请求保存
				QdSaveDLCal();
			}
			if(tDLVal.dPEz - tDLVal.dPEzSave >= 10)//电度累计到0.01度时才保存
			{
				QdSaveDLCal();
			}
		}
	}
	//反向有功累加
	if(dNEzTemp)
	{
		tDLVal.dNEzChip += dNEzTemp;
		if(tDLVal.dNEzChip >= DL_0001D)//0.001度
		{
			tDLVal.dNEzChip -= DL_0001D;
			tDLVal.dNEz++;
			if(tDLVal.dNEz >= 999999999ul)
			{
				tDLVal.dNEz=0;//如果积分电度大于等于1000000.000则清零并请求保存
				QdSaveDLCal();
			}
			if(tDLVal.dNEz - tDLVal.dNEzSave >= 10)//电度累计到0.01度时才保存
			{
				QdSaveDLCal();
			}
			
		}
	}
	//正向无功累加	
	if(dPWzTemp)
	{
		tDLVal.dPWzChip += dPWzTemp;

		if(tDLVal.dPWzChip >= DL_0001D)//0.001度
		{
			tDLVal.dPWzChip -= DL_0001D;
			tDLVal.dPWz++;
			if(tDLVal.dPWz >= 999999999ul)
			{
				tDLVal.dPWz=0;//如果积分电度大于等于1000000.000则清零并请求保存
				QdSaveDLCal();
			}
			if(tDLVal.dPWz - tDLVal.dPWzSave >= 10)//电度累计到0.01度时才保存
			{
				QdSaveDLCal();
			}
			
		}
	}
	//反向无功累加	
	if(dNWzTemp)
	{
		tDLVal.dNWzChip += dNWzTemp;
		if(tDLVal.dNWzChip >= DL_0001D)//0.001度
		{
			tDLVal.dNWzChip -= DL_0001D;
			tDLVal.dNWz++;
			if(tDLVal.dNWz >= 999999999ul)
			{
				tDLVal.dNWz=0;//如果积分电度大于等于1000000.000则清零,并请求保存
				QdSaveDLCal();;
			}
			if(tDLVal.dNWz - tDLVal.dNWzSave >= 10)//电度累计到0.01度时才保存
			{
				QdSaveDLCal();;
			}
			
		}
	}
//四象限无功累计
	{
#if 0	
		qs16 ang;	
		bool Ua1base;
		int    quardrant=0; //象限

		ang=g_ui[UI_SW_INDEX(sw,SW_AC_IA)].p;
		Ua1base=(g_ui[PUB_AC_UA1].chn_index != CFG_ADC_CHANNEL_ZERO);  //参考电压为Ua1，Ia和Ua的角度判断象限，不然，以Ia和Uab角度判断象限
		if(Ua1base)  // 以Ua1为参考电压
		{
			if(ang>=-90*65536&&ang<0)
			{
				quardrant=0;
			}
			else if(ang>=0&&ang<90*65536)
			{
				quardrant=1;
			}
			else if(ang>=90*65536&&ang<180*65536)
			{
				quardrant=2;
			}
			else
			{
				quardrant=3;
			}		
		}
		else   // 以Uab1为参考电压
		{
			if(ang>=-60*65536&&ang<30*65536)
			{
				quardrant=0;
			}
			else if(ang>=30&&ang<120*65536)
			{
				quardrant=1;
			}
			else if(ang>=-150*65536&&ang<-60*65536)
			{
				quardrant=3;
			}
			else
			{
				quardrant=2;
			}		
		}
#endif
		int    quardrant=0; //象限
		
		if((lPTemp > 0) && (lQTemp > 0))
			quardrant = 0;  			//第一象限
		else if((lPTemp < 0) && (lQTemp > 0))
			quardrant = 1;				//第二象限
		else if((lPTemp < 0) && (lQTemp < 0))
			quardrant = 2;				//第三象限
		else if((lPTemp > 0) && (lQTemp < 0))
			quardrant = 3;				//第四象限
		else
			quardrant = -1;
	/*	count++;
		if(count >= 50)
		{
			count = 0;
			rt_printf("*******************************\r\n ");
			rt_printf("quardrant = %d\r\n ", quardrant);
		}*/
		if(quardrant >= 0)
		{
			tDLVal.dWzChip[quardrant] += _AbsL(lQTemp);
			if(tDLVal.dWzChip[quardrant] >= DL_0001D)//0.001度
			{
				tDLVal.dWzChip[quardrant] -= DL_0001D;
				tDLVal.dWz[quardrant]++;
				if(tDLVal.dWz[quardrant] >= 999999999ul)
				{
					tDLVal.dWz[quardrant]=0;//如果积分电度大于等于1000000.000则清零,并请求保存
					QdSaveDLCal();
				}
				if(tDLVal.dWz[quardrant] - tDLVal.dWzSave[quardrant] >= 100)//电度累计到0.1度时才保存
				{
					QdSaveDLCal();
				}
			}
		}
	}
/*
	{"当前正向有功",		UNIT_kWh,UNIT_NULL},        //6401 
	{"当前正向无功",    		UNIT_kVarh,UNIT_NULL},      //6402 
	{"当前一象限无功", 		UNIT_kVarh,UNIT_NULL},      //6403 
	{"当前四象限无功",  	UNIT_kVarh,UNIT_NULL},      //6404 
	{"当前反向有功",   		UNIT_kWh,UNIT_NULL},        //6405 
	{"当前反向无功",   		UNIT_kVarh,UNIT_NULL},      //6406 
	{"当前二象限无功",  	UNIT_kVarh,UNIT_NULL},    	//6407 
	{"当前三象限无功",  	UNIT_kVarh,UNIT_NULL},      //6408 
*/

	g_sw[sw].dd[SW_DD_NOW1].fv=tDLVal.dPEz/1000.0;  //更新到测量结构体中
	g_sw[sw].dd[SW_DD_NOW2].fv=tDLVal.dPWz/1000.0;
	g_sw[sw].dd[SW_DD_NOW3].fv=tDLVal.dWz[0]/1000.0;
	g_sw[sw].dd[SW_DD_NOW4].fv=tDLVal.dWz[3]/1000.0;
	g_sw[sw].dd[SW_DD_NOW5].fv=tDLVal.dNEz/1000.0;
	g_sw[sw].dd[SW_DD_NOW6].fv=tDLVal.dNWz/1000.0;
	g_sw[sw].dd[SW_DD_NOW7].fv=tDLVal.dWz[1]/1000.0;
	g_sw[sw].dd[SW_DD_NOW8].fv=tDLVal.dWz[2]/1000.0;

	g_sw[sw].dd[SW_DD_DAY1].fv=g_sw[sw].dd[SW_DD_NOW1].fv;  //更新到日冻结中
	g_sw[sw].dd[SW_DD_DAY2].fv=g_sw[sw].dd[SW_DD_NOW2].fv;
	g_sw[sw].dd[SW_DD_DAY3].fv=g_sw[sw].dd[SW_DD_NOW3].fv;
	g_sw[sw].dd[SW_DD_DAY4].fv=g_sw[sw].dd[SW_DD_NOW4].fv;
	g_sw[sw].dd[SW_DD_DAY5].fv=g_sw[sw].dd[SW_DD_NOW5].fv;
	g_sw[sw].dd[SW_DD_DAY6].fv=g_sw[sw].dd[SW_DD_NOW6].fv;
	g_sw[sw].dd[SW_DD_DAY7].fv=g_sw[sw].dd[SW_DD_NOW7].fv;
	g_sw[sw].dd[SW_DD_DAY8].fv=g_sw[sw].dd[SW_DD_NOW8].fv;
	
	g_sw[sw].dd[SW_DD_15M1].fv=g_sw[sw].dd[SW_DD_NOW1].fv;  //更新到15分钟冻结中
	g_sw[sw].dd[SW_DD_15M2].fv=g_sw[sw].dd[SW_DD_NOW2].fv;
	g_sw[sw].dd[SW_DD_15M3].fv=g_sw[sw].dd[SW_DD_NOW3].fv;
	g_sw[sw].dd[SW_DD_15M4].fv=g_sw[sw].dd[SW_DD_NOW4].fv;
	g_sw[sw].dd[SW_DD_15M5].fv=g_sw[sw].dd[SW_DD_NOW5].fv;
	g_sw[sw].dd[SW_DD_15M6].fv=g_sw[sw].dd[SW_DD_NOW6].fv;
	g_sw[sw].dd[SW_DD_15M7].fv=g_sw[sw].dd[SW_DD_NOW7].fv;
	g_sw[sw].dd[SW_DD_15M8].fv=g_sw[sw].dd[SW_DD_NOW8].fv;

	if((tDLVal.sDir==1&&lPTemp>=0)||(tDLVal.sDir==0&&lPTemp<0)) // 功率反向
	{
		tDLVal.dirus0= ustimer_get_origin();
	}

	if(ustimer_get_duration(tDLVal.dirus0) >USTIMER_SEC*2)// 2秒功率翻转确认时间
	{
		int i;
		struct timespec 	ts;
		struct rtc_time_t	rt;	

		rt_printf("潮流方向变化 tDLVal.sDir=%d, lPTemp=%d\r\n", tDLVal.sDir, lPTemp);
		
		clk_time_get(&ts);
		timespec_to_rtc(ts, &rt, 1);
		g_sw[sw].dd[SW_DD_CHA1].fv=tDLVal.dPEz/1000.0;  //更新到测量结构体中
		g_sw[sw].dd[SW_DD_CHA2].fv=tDLVal.dPWz/1000.0;
		g_sw[sw].dd[SW_DD_CHA3].fv=tDLVal.dWz[0]/1000.0;
		g_sw[sw].dd[SW_DD_CHA4].fv=tDLVal.dWz[3]/1000.0;
		g_sw[sw].dd[SW_DD_CHA5].fv=tDLVal.dNEz/1000.0;
		g_sw[sw].dd[SW_DD_CHA6].fv=tDLVal.dNWz/1000.0;
		g_sw[sw].dd[SW_DD_CHA7].fv=tDLVal.dWz[1]/1000.0;
		g_sw[sw].dd[SW_DD_CHA8].fv=tDLVal.dWz[2]/1000.0;
		for(i=SW_DD_CHA1;i<=SW_DD_CHA8;i++)
		{
			g_sw[sw].dd[i].ct=rt;
			g_sw[sw].dd[i].bchanged=true;

		}
		tDLVal.sDir=(lPTemp>=0)?1:0; //潮流方向 初始化

        tDLVal.sDir_Num++;
        dd_val = g_sw[0].dd[SW_DD_NOW1].fv*65536.0f;
        dir_num = tDLVal.sDir_Num;
	#ifdef METERING_ENERGY	
        soe_record_ev(EV_DD_DIR+sw*EV_SW_NUM, 1, dd_val, dir_num, 0 );
	#endif	
        //e2prom_write(EEP_DD_DATA, (u8 *)&tDLVal.sDir_Num, sizeof(tDLVal.sDir_Num));

	}
}


void HW_DLCal(void)
{
	u8 dir;
	//int sw=0;
	//DWORD dd_val;
	//DWORD dir_num;
	static struct rtc_time_t time;  //时标	
    struct timespec ts;
    //获取当前时间
    clk_time_get(&ts);
    timespec_to_rtc(ts,&time,0);

    if(tDLVal.bClr)
    {
        memset(&tDLVal,0,sizeof(tDLVal));
        QdSaveDLCal();
        tDLVal.bClr=false;
        return;
    }
    metering_freeze_refresh(ENERGY_RT_DATA,&time);
#ifdef ADD_MULTIPLE_FILE_WR_FUN
    dir = metering_dir_change(ID_TD_DIR);
    if(dir)
    {
        if((tDLVal.sDir != dir)&&(tDLVal.sDir!=0))   //1-正向    2-反向
        {
            if(tDLVal.dirus0==0)
                tDLVal.dirus0= ustimer_get_origin();
            if(ustimer_get_duration(tDLVal.dirus0) >USTIMER_SEC*2)// 2秒功率翻转确认时间
            {
                if(line_loss_event_start(METERING_EVT_DIR,EventNumData.sDir_Num+1)>=1)
                {
                    EventNumData.sDir_Num++;                                                         //本地保存潮流方向总次数
                    save_event_num_data();
                }



                tDLVal.dirus0 = 0;    //计时清零
                tDLVal.sDir=dir;      //潮流方向 初始化 记录当前总功率功率方向                1：正向     2：反向

                //dd_val = g_sw[0].dd[SW_DD_NOW1].fv*65536.0f;
                //dir_num = tDLVal.sDir_Num;
                //soe_record_ev(EV_DD_DIR+sw*EV_SW_NUM, 1, dd_val, dir_num, 0 );
                //rt_printf("潮流方向变化 tDLVal.sDir_Num=%d\r\n",EventNumData.sDir_Num);
            }
        }
        else if((tDLVal.sDir != dir)&&(tDLVal.sDir==0))   //上电初始状态
        {
            tDLVal.sDir=dir;
            
        }

    }

    dir = metering_dir_change(ID_PA_INV);
    if(dir)
    {
        if((tDLVal.sADir != dir)&&(tDLVal.sADir!=0))   //1-正向    2-反向
        {
            if(tDLVal.dirus[0]==0)
                tDLVal.dirus[0]= ustimer_get_origin();
            if(ustimer_get_duration(tDLVal.dirus[0]) >USTIMER_SEC*2)// 2秒功率翻转确认时间
            {
                short DirNum=EventNumData.sADir_Num+1;
                BYTE flag=0;

                if((tDLVal.sADir==1)&&(dir==2))   //正向-》反向
                {
                    if(line_loss_event_start(METERING_EVT_ADIR,DirNum)>=1)
                        flag=1;
                    //rt_printf("A相功率方向变化0->1\r\n");
                }
                else if((tDLVal.sADir==2)&&(dir==1))   //反向-》正向
                {
                    if(line_loss_event_end(METERING_EVT_ADIR,DirNum)>=1)
                        flag=1;

                    //rt_printf("A相功率方向变化1->0\r\n");
                }

                if(flag)
                {
                    EventNumData.sADir_Num++;
                    save_event_num_data();
                    //rt_printf("A相潮流方向变化 EventNumData.sADir_Num=%d\r\n",EventNumData.sADir_Num);
                }

                tDLVal.dirus[0] = 0;
                tDLVal.sADir = dir;
            }
        }
        else if((tDLVal.sADir != dir)&&(tDLVal.sADir==0))   //上电初始状态
        {
            tDLVal.sADir=dir;
        }
    }
    dir = metering_dir_change(ID_PB_INV);
    if(dir)
    {
        if((tDLVal.sBDir != dir)&&(tDLVal.sBDir!=0))   //1-正向    2-反向
        {
            if(tDLVal.dirus[1]==0)
                tDLVal.dirus[1]= ustimer_get_origin();
            if(ustimer_get_duration(tDLVal.dirus[1]) >USTIMER_SEC*2)// 2秒功率翻转确认时间
            {
                short DirNum=EventNumData.sBDir_Num+1;
                BYTE flag=0;

                if((tDLVal.sBDir==1)&&(dir==2))   //正向-》反向
                {
                    if(line_loss_event_start(METERING_EVT_BDIR,DirNum)>=1)
                        flag=1;
                    //rt_printf("B相功率方向变化0->1\r\n");
                }
                else if((tDLVal.sBDir==2)&&(dir==1))   //反向-》正向
                {
                    if(line_loss_event_end(METERING_EVT_BDIR,DirNum)>=1)
                        flag=1;

                    //rt_printf("B相功率方向变化1->0\r\n");
                }

                if(flag)
                {
                    EventNumData.sBDir_Num++;
                    save_event_num_data();
                    //rt_printf("B相潮流方向变化 tDLVal.sBDir_Num=%d\r\n",EventNumData.sBDir_Num);
                }

                tDLVal.dirus[1] = 0;
                tDLVal.sBDir = dir; //潮流方向 初始化
            }
        }
        else if((tDLVal.sBDir != dir)&&(tDLVal.sBDir==0))   //上电初始状态
        {
            tDLVal.sBDir=dir;
        }
    }
    dir = metering_dir_change(ID_PC_INV);
    if(dir)
    {
        if((tDLVal.sCDir != dir)&&(tDLVal.sCDir!=0))   //1-正向    2-反向
        {
            if(tDLVal.dirus[2]==0)
                tDLVal.dirus[2]= ustimer_get_origin();
            if(ustimer_get_duration(tDLVal.dirus[2]) >USTIMER_SEC*2)// 2秒功率翻转确认时间
            {
                short DirNum=EventNumData.sCDir_Num+1;
                BYTE flag=0;

                if((tDLVal.sCDir==1)&&(dir==2))   //正向-》反向
                {
                    if(line_loss_event_start(METERING_EVT_CDIR,DirNum)>=1)
                        flag=1;
                    //rt_printf("C相功率方向变化0->1\r\n");
                }
                else if((tDLVal.sCDir==2)&&(dir==1))   //反向-》正向
                {
                    if(line_loss_event_end(METERING_EVT_CDIR,DirNum)>=1)
                        flag=1;

                    //rt_printf("C相功率方向变化1->0\r\n");
                }

                if(flag)
                {
                    EventNumData.sCDir_Num++;
                    save_event_num_data();
                    //rt_printf("C相潮流方向变化 EventNumData.sCDir_Num=%d\r\n",EventNumData.sCDir_Num);
                }

                tDLVal.dirus[2] = 0;
                tDLVal.sCDir = dir; //潮流方向 初始化
            }
        }
        else if((tDLVal.sCDir != dir)&&(tDLVal.sCDir==0))   //上电初始状态
        {
            tDLVal.sCDir=dir;
        }
    }
#endif

}


void DD_Calc(void)
{
	if(pRunSet->dd_calc_mode == 0)
	{
		HW_DLCal();
	}
	else if(pRunSet->dd_calc_mode == 1)
	{
		DLCal();
	}
}

void soft_dd_val_clr(void)
{
    int sw=0;

    if(pRunSet->dd_calc_mode == 1)
    {
        memset(&g_sw[sw].dd[0], 0, sizeof(struct dd_v)*SW_DD_NUM_ALL);
		DL_clear();
    }

    if(line_loss_event_start(METERING_EVT_DD_CLEAR,EventNumData.sClr_Num+1)>=1)
    {
        EventNumData.sClr_Num++;                                                         //本地保存潮流方向总次数
        save_event_num_data();
        //rt_printf("写电度清0事件\r\n");
    }

	rt_printf("电度清0事件EventNumData.sClr_Num=%d\r\n",EventNumData.sClr_Num);
}


void save_event_num_data(void)
{
    EventNumData.CheckValue=0x5a5a;
    e2prom_write(EEP_DD_DATA, (u8 *)&EventNumData, sizeof(EventNumData));
//  rt_printf("读潮流变化 tDLVal.sDir_Num=%d\r\n", tDLVal.sDir_Num);
}

void get_eep_dd_data(void)
{
    e2prom_read(EEP_DD_DATA, (u8 *)&EventNumData, sizeof(EventNumData));
    if(EventNumData.CheckValue!=0x5a5a)
        memset((u8*)&EventNumData,0,sizeof(EventNumData));
    //rt_printf("读取潮流事件记录次数\r\n");
    
	//memset((u8*)&EventNumData,0,sizeof(EventNumData));
	//save_event_num_data();

 //   rt_printf("s=%d,a=%d,b=%d,c=%d,clr=%d\r\n",EventNumData.sDir_Num,EventNumData.sADir_Num,
 //   EventNumData.sBDir_Num,EventNumData.sCDir_Num,EventNumData.sClr_Num);
}




int line_loss_event_start(u8 evt_id,short sum)
{
	int i;
	int sw=0;
	struct timespec ts;
	struct rtc_time_t time;	//时标

    //获取当前时间
    clk_time_get(&ts);
    timespec_to_rtc(ts,&time,0);

	
    
    memset(&evt_st[evt_id], 0, sizeof(evt_st[evt_id]));
    evt_st[evt_id].type = evt_id+1;
    evt_st[evt_id].times=sum;
    evt_st[evt_id].start.tm = time;
    evt_st[evt_id].start.ele[0].val = meter_dd[ID_EP_P].value;;
    evt_st[evt_id].start.ele[1].val = meter_dd[ID_EQ_P].value;
    evt_st[evt_id].start.ele[2].val = meter_dd[ID_EQ_1].value;
    evt_st[evt_id].start.ele[3].val = meter_dd[ID_EQ_4].value;
    evt_st[evt_id].start.ele[4].val = meter_dd[ID_EP_N].value;
    evt_st[evt_id].start.ele[5].val = meter_dd[ID_EQ_N].value;
    evt_st[evt_id].start.ele[6].val = meter_dd[ID_EQ_2].value;
    evt_st[evt_id].start.ele[7].val = meter_dd[ID_EQ_3].value;


    if(evt_id<METERING_EVT_DIR)
        fresh_eventd_file(&evt_st[evt_id],0);   //功率方向开始
    else
        fresh_eventd_file(&evt_st[evt_id],2);   //其他事件写入

	eventd_file_info.b_new = true;
	g_sw[sw].dd[SW_DD_CHA1].fv=meter_dd[ID_EP_P].value;  //更新到测量结构体中
	g_sw[sw].dd[SW_DD_CHA2].fv=meter_dd[ID_EQ_P].value;
	g_sw[sw].dd[SW_DD_CHA3].fv=meter_dd[ID_EQ_1].value;
	g_sw[sw].dd[SW_DD_CHA4].fv=meter_dd[ID_EQ_4].value;
	g_sw[sw].dd[SW_DD_CHA5].fv=meter_dd[ID_EP_N].value;
	g_sw[sw].dd[SW_DD_CHA6].fv=meter_dd[ID_EQ_N].value;
	g_sw[sw].dd[SW_DD_CHA7].fv=meter_dd[ID_EQ_2].value;
	g_sw[sw].dd[SW_DD_CHA8].fv=meter_dd[ID_EQ_3].value;
	for(i=SW_DD_CHA1;i<=SW_DD_CHA8;i++)
	{
#ifdef M_IT_TC
		int j;
		
		for(j=0;j<CFG_UART_NUM_MAX;j++)
		{
			g_sw[sw].dd[i].bsend101[j] = true;
		}

		for(j=0;j<CFG_ETH_MAX_LOGIC;j++)
		{
			g_sw[sw].dd[i].bsend104[j] = true;
		}
#endif
		g_sw[sw].dd[i].ct=time;
		g_sw[sw].dd[i].bchanged=true;			

	}
	
    return 1;  //总次数累计有效
}


int line_loss_event_end(u8 evt_id,short sum)
{
    struct timespec ts;
    struct rtc_time_t time; //时标

    if(evt_id>=METERING_EVT_DIR)    //功率方向结束
        return -1;

    //获取当前时间
    clk_time_get(&ts);
    timespec_to_rtc(ts,&time,0);

    memset(&evt_st[evt_id], 0, sizeof(evt_st[evt_id]));
    evt_st[evt_id].type = evt_id+1;
    evt_st[evt_id].times=sum;       //虚拟的次数 若覆盖则无用 不累计
    evt_st[evt_id].end.tm = time;

    evt_st[evt_id].end.ele[0].val = meter_dd[ID_EP_P].value;;
    evt_st[evt_id].end.ele[1].val = meter_dd[ID_EQ_P].value;
    evt_st[evt_id].end.ele[2].val = meter_dd[ID_EQ_1].value;
    evt_st[evt_id].end.ele[3].val = meter_dd[ID_EQ_4].value;
    evt_st[evt_id].end.ele[4].val = meter_dd[ID_EP_N].value;
    evt_st[evt_id].end.ele[5].val = meter_dd[ID_EQ_N].value;
    evt_st[evt_id].end.ele[6].val = meter_dd[ID_EQ_2].value;
    evt_st[evt_id].end.ele[7].val = meter_dd[ID_EQ_3].value;

	eventd_file_info.b_new = true;
    if(fresh_eventd_file(&evt_st[evt_id],1)>=1)
        return 1;     //总次数累计有效
    else
        return 0;
}
#endif

