#include "sys_config.h"
#include "Uwater_frame_app.h"
#include "sys_processor.h"
#include "nb_upload_monitor.h"
#include "UWater_DataTools_App.h"
#include "UWater_ir_app.h"
#include "UWater_eeprom_driver.h"
#include "UWater_power_app.h"
#include "UWater_valve_driver.h"
#include <string.h>

#if UPLOAD_MODE_1
static u8 s_eep_complete_up_monitor=0; //ee存储标志
static u8 up_monitor_para_buf[UP_PARA_NUM];//上报参数缓存
static ENUM_APP_LIFE_CNT nb_life_time_state=APP_LIFE_CNT_S0;//NB电量计算状态机
static ENUM_APP_LIFE_CNT ir_life_time_state=APP_LIFE_CNT_S0;//红外电量计算状态机
static u32 nb_life_time_start_time=0;//NB激活开始时间
static u32 ir_life_time_start_time=0;//红外激活开始时间
static u32 total_wake_time = 0;//红外唤醒时长
static u16 life_time_cnt = 0;//秒钟数
static u8 life_time_minute_cnt = 0;//分钟数
static u16 tmp_life_time = 0;//计算时长临时变量
//剩余电量和寿命比值
static float remain_percent_use_life;
static float remain_percent_use_energy;
static float remain_para_energy_life;
//上报偏移时间参数
static u8 up_delay_para_cnt=0;
static ENUM_APP_LIFE_CNT valve_life_time_state=APP_LIFE_CNT_S0;//阀控电量计算状态机
#if defined(VALVE)
static u32 valve_life_time_start_time=0;//阀控开始工作时间
#endif


//设置上报控制参数
void setUploadControlPara(ENUM_UPLOAD_CONTROL paraId, u8 paraData)
{
	if(paraId<UP_PARA_NUM)
	{
		up_monitor_para_buf[paraId] = paraData;
	}
}
//获取上报控制参数
u8 getUploadControlPara(ENUM_UPLOAD_CONTROL paraId)
{
	if(paraId<UP_PARA_NUM)
	{
		return up_monitor_para_buf[paraId];
	}
	return 0;
}

//NB工作时间及电量消耗统计
void AppLifeTimeCountMachine(void)
{
	if(RtccCheckMsg()&0x10)//秒中断,用于NB或红外唤醒的时间计算
	{
		RtccClearMsg(4); 
		life_time_cnt++; 
		life_time_cnt %= HOUR_TO_SECOND;
	}
	if(RtccCheckMsg()&0x20)//分钟中断,待机功耗计算
	{
		RtccClearMsg(5);
		life_time_minute_cnt++;
		if(life_time_minute_cnt>=60)
		{
			life_time_minute_cnt=0;
			Sys_data_object.P1.run_information_object.total_use_sum_times_sec.to_uint32 += HOUR_TO_SECOND;//累计使用时间
			Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= ONE_HOUR_STATIC_ENERGY;
		}
	}
	//NB功耗计算
	switch(nb_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if(TASK_BUSY == FixedTimeNbIoTUploadIfIdle())
			{
				nb_life_time_start_time = life_time_cnt;
				nb_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if(TASK_IDLE == FixedTimeNbIoTUploadIfIdle())
			{
				s16 s_temp_snr=0;
				s16 s_temp_rsrp=0;
				if(life_time_cnt >= nb_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - nb_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - nb_life_time_start_time;
				}
				//如果收到有效升级指令,则加上升级时间
				if(getUploadControlPara(UP_BOOT_MSG) == UPDATE_MODE_DIFF)
				{
					tmp_life_time += 600;//增加10分钟
				}
				else if(getUploadControlPara(UP_BOOT_MSG) == UPDATE_MODE_NORMAL)
				{
					tmp_life_time += 1800;//增加30分钟
				}
				setUploadControlPara(UP_BOOT_MSG,0);
				
				//记录NB工作时间和NB活跃次数
				Sys_data_object.P1.run_information_object.nb_use_sum_times_sec.to_uint32 += tmp_life_time;
				Sys_data_object.P1.run_information_object.nb_upload_happen_num++; 
				
				//根据本次信号值以及时间减去相应的电量消耗	
				NbiotGetSNR(&s_temp_snr);
				NbiotGetRSRP(&s_temp_rsrp);
				s_temp_snr /=10;
				s_temp_rsrp /=10;
				
				if(getUploadControlPara(UP_CGATT_FAIL)==TRUE)//本次符网失败
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_FAIL_ONE_SECOND_ENERGY*tmp_life_time;
					//上报偏移时间参数修改
					if(GetEventUploadType()==UPLOAD_TYPE_FIX_TIME)//定时上报
					{
						up_delay_para_cnt++;
						up_delay_para_cnt = (up_delay_para_cnt%7);
						setUploadControlPara(UP_DELAY_COUNT,up_delay_para_cnt);
						setUploadControlPara(UP_AT_ALL_MSG,TRUE); //上报失败,下次上报使用全指令上报消息
					}
				}
				else if(s_temp_snr < 0)//负值,信号很差
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_WEAK_ONE_SECOND_ENERGY*tmp_life_time;
				}
				else if(s_temp_rsrp < -120)//120
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_WEAK_ONE_SECOND_ENERGY*tmp_life_time;
				}
				else if(s_temp_rsrp < -115)//115~120
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_120_ONE_SECOND_ENERGY*tmp_life_time;
				}
				else if(s_temp_rsrp < -105)//105~115
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_115_ONE_SECOND_ENERGY*tmp_life_time;
				}
				else if(s_temp_rsrp < -90)//90~105
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_105_ONE_SECOND_ENERGY*tmp_life_time;
				}
				else//> -90
				{
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= NB_UPLOAD_RSRP_90_ONE_SECOND_ENERGY*tmp_life_time;
				}			
				nb_life_time_state = APP_LIFE_CNT_S2;
			}
		}
		break;
		case APP_LIFE_CNT_S2://EE存储
		{
			if (TASK_IDLE == EepIfIdle())
			{
				EepWrite(&(Sys_data_object.P1.run_information_object.total_use_sum_times_sec.to_uint8[0]), EEP_FRMAE_BATTERY_ENERGY, sizeof(Sys_data_object.P1.run_information_object), &s_eep_complete_up_monitor);
				nb_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;
		default:
			nb_life_time_state = APP_LIFE_CNT_S0;
		break;
	}
	//红外功耗计算
	switch(ir_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if(FALSE == IrIfSleepApp())
			{
				ir_life_time_start_time = life_time_cnt;
				ir_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if(TRUE == IrIfSleepApp())
			{
				if(life_time_cnt >= ir_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - ir_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - ir_life_time_start_time;
				}
				total_wake_time += tmp_life_time;
				if(total_wake_time > MINITE_TO_SECOND)  //唤醒时间 
				{
					total_wake_time -= MINITE_TO_SECOND;
					Sys_data_object.P1.run_information_object.use_sum_times_sec.to_uint32 += 60;//红外累计非休眠时间增加1分钟
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= ONE_MIN_WAKE_ENERGY; //减少1分钟的唤醒功耗
				}		
				ir_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;	
		default:
		{
			ir_life_time_state = APP_LIFE_CNT_S0;
		}
		break;
	}
	#if defined(VALVE)
//阀控功耗计算
	switch(valve_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if(FALSE == ValveIfIdle())
			{
				valve_life_time_start_time = life_time_cnt;
				valve_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if(TRUE == ValveIfIdle())
			{
				if(life_time_cnt >= valve_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - valve_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - valve_life_time_start_time;
				}
				Sys_data_object.P1.run_information_object.valve_use_sum_times_sec += tmp_life_time;//阀门累计工作时间
				Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= VAVLE_WORK_ENERGY*tmp_life_time; //减少阀门活动的功耗
				valve_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;	
		default:
		{
			valve_life_time_state = APP_LIFE_CNT_S0;
		}
		break;
	}
	#endif
}

//NB上报控制参数调整
void NbUploadParaSet(void)
{
	char imei_buf[16];
	DateTime temp_rtcc_time;
	RtccGetDateTime(&temp_rtcc_time);
	//计算剩余使用寿命占比
	if(HOURS_OF_7YEARS > Sys_data_object.ee_data.data.work_hour)
	{
		//remain_percent_use_life = (float)(HOURS_OF_7YEARS-Sys_data_object.ee_data.data.work_hour)/(float)HOURS_OF_7YEARS;
		remain_percent_use_life = (float)(HOURS_OF_7YEARS-Sys_data_object.P1.run_information_object.total_use_sum_times_sec.to_uint32/HOUR_TO_SECOND)/(float)HOURS_OF_7YEARS;
	}
	else
	{
		remain_percent_use_life = 0;
	}
	//计算剩余电量占比
	remain_percent_use_energy = (float)Sys_data_object.P1.run_information_object.bat_surplus.to_uint32/(float)ENERGY_OF_26500;
	setUploadControlPara(UP_BAT_STATE, remain_percent_use_energy*15);//状态字显示电量
	
	//计算剩余电量和剩余使用时间比值
	if(PowerCheckStatusSys() == LOW_POWER)//电池欠压
	{
		remain_para_energy_life = 0.1;
	}
	else
	{
		if(remain_percent_use_life == 0)//已经用了7年
		{
			remain_para_energy_life = 1;
		}
		else
		{
			if(Sys_data_object.P1.run_information_object.bat_surplus.to_uint32>(remain_percent_use_life*ENERGY_OF_IDLE))//待机预留电量
			{
				remain_para_energy_life = (float)(remain_percent_use_energy/remain_percent_use_life)*NB_BAT_PARA;
			}
			else//无法满足待机需求
			{
				remain_para_energy_life = 0.1;
			}
		}
	}
	
	//比值切换判断
	if((Sys_data_object.P1.run_information_object.ee_remain_para_energy_life>0)&&(Sys_data_object.P1.run_information_object.ee_remain_para_energy_life<=1.5))
	{
		if(remain_para_energy_life < Sys_data_object.P1.run_information_object.ee_remain_para_energy_life)
		{
			Sys_data_object.P1.run_information_object.ee_remain_para_energy_life = remain_para_energy_life;
		}
	}
	else
	{
		Sys_data_object.P1.run_information_object.ee_remain_para_energy_life = remain_para_energy_life;
	}
	//根据电量和剩余时间比值调整上报频率
	if(Sys_data_object.P1.run_information_object.ee_remain_para_energy_life>1.5)
	{
		setUploadControlPara(UP_RETRY_NUM, Sys_data_object.P1.report_retry_times);//重试1次
		setUploadControlPara(UP_DELAY_TIME1, NB_WAIT_TIME_5S);//等指令时间3s
		setUploadControlPara(UP_DAY_COUNT,(Sys_data_object.P1.func_cfg_bytes[13]>>4)&0x0F);//上报间隔天数1
	}
	else if(Sys_data_object.P1.run_information_object.ee_remain_para_energy_life>1)
	{
		setUploadControlPara(UP_RETRY_NUM,0);//重试0次
		setUploadControlPara(UP_DELAY_TIME1, NB_WAIT_TIME_5S);
		setUploadControlPara(UP_DAY_COUNT,Sys_data_object.P1.func_cfg_bytes[13]&0x0F);//上报间隔天数1
	}
	else if(Sys_data_object.P1.run_information_object.ee_remain_para_energy_life>0.8)
	{
		setUploadControlPara(UP_RETRY_NUM,0);//重试0次
		setUploadControlPara(UP_DELAY_TIME1, NB_WAIT_TIME_5S);
		setUploadControlPara(UP_DAY_COUNT,(Sys_data_object.P1.func_cfg_bytes[14]>>4)&0x0F);//上报间隔天数2
	}
	else if(Sys_data_object.P1.run_information_object.ee_remain_para_energy_life>0.5)
	{
		setUploadControlPara(UP_RETRY_NUM,0);//重试0次
		setUploadControlPara(UP_DELAY_TIME1,NB_WAIT_TIME_5S);
		setUploadControlPara(UP_DAY_COUNT,Sys_data_object.P1.func_cfg_bytes[14]&0x0F);//上报间隔天数3
	}
	else
	{
		setUploadControlPara(UP_RETRY_NUM,0);//重试0次
		setUploadControlPara(UP_DELAY_TIME1,NB_WAIT_TIME_5S);
		setUploadControlPara(UP_DAY_COUNT,(Sys_data_object.P1.func_cfg_bytes[15]>>4)&0x0F);//上报间隔天数7
		setUploadControlPara(UP_WITH_UDP,TRUE);//开启UDP上报
	}
	Sys_data_object.P1.report_retry_times = getUploadControlPara(UP_RETRY_NUM);//重试次数
	//设置上报是否精简
	NbiotGetIMEI(imei_buf); 
	if(strlen(imei_buf)<15)//先判断IMEI缓存
	{
		setUploadControlPara(UP_AT_SIMPLE, AT_SIMPLE_NULL);//不精简AT指令
		setUploadControlPara(UP_DELAY_TIME1,NB_WAIT_TIME_5S);
		setUploadControlPara(UP_WITH_UDP,TRUE);//开启UDP上报
	}
	else
	{
		if((GetEventUploadType()==UPLOAD_TYPE_HAND_KEY)||
			(GetEventUploadType()==UPLOAD_TYPE_FRAME_ORDER)||
			(GetEventUploadType()==UPLOAD_TYPE_SET_IP)||
			(getUploadControlPara(UP_AT_ALL_MSG)==TRUE))
		{
			setUploadControlPara(UP_AT_ALL_MSG,FALSE);//清除使用全指令上报消息
			setUploadControlPara(UP_AT_SIMPLE, AT_SIMPLE_NULL);//不精简AT指令
			setUploadControlPara(UP_DELAY_TIME1,NB_WAIT_TIME_5S);
			setUploadControlPara(UP_WITH_UDP,TRUE);//开启UDP上报
		} 
		else
		{
			if((GetEventUploadType()==UPLOAD_TYPE_FIX_TIME)||(GetEventUploadType()==UPLOAD_TYPE_RETRY_AGAIN))//定时\重传上报
			{
				setUploadControlPara(UP_AT_SIMPLE, AT_SIMPLE_M1);//AT精简1
				setUploadControlPara(UP_DELAY_TIME1, NB_WAIT_TIME_5S);
				if((BCD2HEX(temp_rtcc_time.s.day)%3)==0)
				{
					setUploadControlPara(UP_WITH_UDP, TRUE);//开启UDP上报
				}
				else
				{
					setUploadControlPara(UP_WITH_UDP,FALSE);//关闭UDP上报
				}
			}
			else if(GetEventUploadType()==UPLOAD_TYPE_VALVE_CLOSE)//关阀频繁上报
			{
				setUploadControlPara(UP_AT_SIMPLE, AT_SIMPLE_M2);//AT精简2
				setUploadControlPara(UP_DELAY_TIME1, NB_WAIT_TIME_5S);
				setUploadControlPara(UP_WITH_UDP,FALSE);//关闭UDP上报

			}
		}
	}
}

//各功能生命周期记录是否空闲
u8 AppLifeTimeCountMachineIfIdle(void)
{
	if((APP_LIFE_CNT_S0 == nb_life_time_state)&&(APP_LIFE_CNT_S0 == ir_life_time_state)&&(APP_LIFE_CNT_S0 == valve_life_time_state))
	{
		return TASK_IDLE;
	}
	else
	{
		return TASK_BUSY;
	}	
}
#elif UPLOAD_MODE_2
static u8 up_monitor_para_buf[UP_PARA_NUM];//上报参数缓存
static ENUM_APP_LIFE_CNT ble_life_time_state=APP_LIFE_CNT_S0;//蓝牙电量计算状态机
static ENUM_APP_LIFE_CNT ir_life_time_state=APP_LIFE_CNT_S0;//红外电量计算状态机
static u32 ble_life_time_start_time=0;//蓝牙激活开始时间
static u32 ble_total_wake_time = 0;//蓝牙唤醒时长
static u32 ir_life_time_start_time=0;//红外激活开始时间
static u32 ir_total_wake_time = 0;//红外唤醒时长
static u16 life_time_cnt = 0;//秒钟数
static u8 life_time_minute_cnt = 0;//分钟数
static u16 tmp_life_time = 0;//计算时长临时变量

static ENUM_APP_LIFE_CNT valve_life_time_state=APP_LIFE_CNT_S0;//阀控电量计算状态机
#if defined(VALVE)
static u32 valve_life_time_start_time=0;//阀控开始工作时间
#endif

//设置上报控制参数
void setUploadControlPara(ENUM_UPLOAD_CONTROL paraId, u8 paraData)
{
	if(paraId<UP_PARA_NUM)
	{
		up_monitor_para_buf[paraId] = paraData;
	}
}
//获取上报控制参数
u8 getUploadControlPara(ENUM_UPLOAD_CONTROL paraId)
{
	if(paraId<UP_PARA_NUM)
	{
		return up_monitor_para_buf[paraId];
	}
	return 0;
}

//电量消耗统计
void AppLifeTimeCountMachine(void)
{
	if(RtccCheckMsg()&0x10)//秒中断,用于蓝牙或红外唤醒的时间计算
	{
		RtccClearMsg(4); 
		life_time_cnt++; 
		life_time_cnt %= HOUR_TO_SECOND;
	}
	if(RtccCheckMsg()&0x20)//分钟中断,待机功耗计算
	{
		RtccClearMsg(5);
		life_time_minute_cnt++;
		if(life_time_minute_cnt>=60)
		{
			life_time_minute_cnt=0;
			Sys_data_object.P1.run_information_object.total_use_sum_times_sec.to_uint32 += HOUR_TO_SECOND;//累计使用时间
			Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= ONE_HOUR_STATIC_ENERGY;
		}
	}
	//蓝牙功耗计算
	switch(ble_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if((BleConnectIfIdle() == TASK_BUSY)||(BleIfSleep()==TASK_BUSY))
			{
				ble_life_time_start_time = life_time_cnt;
				ble_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if((BleConnectIfIdle() == TASK_IDLE)&&(BleIfSleep()==TASK_IDLE))
			{
				if(life_time_cnt >= ble_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - ble_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - ble_life_time_start_time;
				}
				ble_total_wake_time += tmp_life_time;
				if(ble_total_wake_time > MINITE_TO_SECOND)  //唤醒时间 
				{
					ble_total_wake_time -= MINITE_TO_SECOND;
									//记录NB工作时间和NB活跃次数
					Sys_data_object.P1.run_information_object.nb_use_sum_times_sec.to_uint32 += 60;//蓝牙累计非休眠时间增加1分钟
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= BLE_ONE_MIN_ENERGY; //减少1分钟的蓝牙激活功耗
				}	
				Sys_data_object.P1.run_information_object.nb_upload_happen_num++;				
				ble_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;
		
		default:
		{
			ble_life_time_state = APP_LIFE_CNT_S0;
		}
		break;
	}
	//红外功耗计算
	switch(ir_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if(FALSE == IrIfSleepApp())
			{
				ir_life_time_start_time = life_time_cnt;
				ir_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if(TRUE == IrIfSleepApp())
			{
				if(life_time_cnt >= ir_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - ir_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - ir_life_time_start_time;
				}
				ir_total_wake_time += tmp_life_time;
				if(ir_total_wake_time > MINITE_TO_SECOND)  //唤醒时间 
				{
					ir_total_wake_time -= MINITE_TO_SECOND;
					Sys_data_object.P1.run_information_object.use_sum_times_sec.to_uint32 += 60;//红外累计非休眠时间增加1分钟
					Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= ONE_MIN_WAKE_ENERGY; //减少1分钟的唤醒功耗
				}		
				ir_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;	
		default:
		{
			ir_life_time_state = APP_LIFE_CNT_S0;
		}
		break;
	}
	#if defined(VALVE)
//阀控功耗计算
	switch(valve_life_time_state)
	{
		case(APP_LIFE_CNT_S0):
		{
			if(FALSE == ValveIfIdle())
			{
				valve_life_time_start_time = life_time_cnt;
				valve_life_time_state = APP_LIFE_CNT_S1;
			}
		}
		break;
		
		case(APP_LIFE_CNT_S1):
		{
			if(TRUE == ValveIfIdle())
			{
				if(life_time_cnt >= valve_life_time_start_time)
				{
					tmp_life_time = life_time_cnt - valve_life_time_start_time;
				}
				else
				{
					tmp_life_time = HOUR_TO_SECOND + life_time_cnt - valve_life_time_start_time;
				}
				Sys_data_object.P1.run_information_object.valve_use_sum_times_sec += tmp_life_time;//阀门累计工作时间
				Sys_data_object.P1.run_information_object.bat_surplus.to_uint32 -= VAVLE_WORK_ENERGY*tmp_life_time; //减少阀门活动的功耗
				valve_life_time_state = APP_LIFE_CNT_S0;
			}
		}
		break;	
		default:
		{
			valve_life_time_state = APP_LIFE_CNT_S0;
		}
		break;
	}
	#endif
}

//各功能生命周期记录是否空闲
u8 AppLifeTimeCountMachineIfIdle(void)
{
	if((APP_LIFE_CNT_S0 == ble_life_time_state)&&(APP_LIFE_CNT_S0 == ir_life_time_state)&&(APP_LIFE_CNT_S0 == valve_life_time_state))
	{
		return TASK_IDLE;
	}
	else
	{
		return TASK_BUSY;
	}	
}

#endif




