/*************************** (C) COPYRIGHT 2017 Ping ****************************
 * 文件名  ：user_app.c
 * 描  述  ：用户应用程序
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/09/04
*********************************************************************************/
#include "user_app.h"
#include "usart1.h"
#include "delay.h"
#include "timer.h"
#include "display.h"

#include "sound.h"
#include "pc_protocol.h"
#include "stmflash.h"
#include "user_manag.h"
#include "deviceSet.h"

/*
***********************************************************************
*	函 数 名: showHexData
*	功能说明: 以十六进制显示数组里的内容
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void showHexData(uint8_t num[], uint8_t n)
{
    uint8_t i;
		printf("\r\n");
    for(i=0; i<n; i++)
		{
//       printf("%02X ",num[i]);
			printf("0x%02X ",num[i]);
		}
		printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: UserInfoIdentityTask
*	功能说明: 用户身份识别
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void UserIdentificationTask(void)
{
	getPutInType = 0;
	
	if(RFID_state == 1)
	{
		RFID_state = 0;
		
		getPutInType = 1;
		getDataLength = strlen((char*)cardNumberStr);
		memset(getDataBuf, 0, 256);
		memcpy(getDataBuf, cardNumberStr, getDataLength);
			
	}else if(sweep2CodeState == 1){
		sweep2CodeState = 0;
		
		getPutInType = 2;
		getDataLength = codeDataLength;
		memset(getDataBuf, 0, 256);
		memcpy(getDataBuf, codeBuf, getDataLength);
	}else{}
	
	if((getPutInType != 0) && (getDataLength > 0))
	{
		beep_shortBeepMark = 1;
		
		sendPutInType = 0;
		sendDataLength = 0;
		memset(sendDataBuf, 0, 256);
		
		sendPutInType = getPutInType;
		sendDataLength = getDataLength;
		memcpy(sendDataBuf, getDataBuf, getDataLength);
		
		printf("\r\n用户身份识别：\r\n");
		printf("Type: %d\r\n", sendPutInType);
		printf("Len: %d\r\n", sendDataLength);
		printf("DataBuf: %s\r\n", sendDataBuf);
		
		PC_ProCommandSend(0x01);
	}
}

/*
***********************************************************************
*	函 数 名: GetPutInType
*	功能说明: 取得投放开门方式类型
*	形    参：无
*	返 回 值: 0x01->IC卡；0x02->二维码；0x03->条形码；0x04-> 按钮
***********************************************************************
*/
uint8_t GetPutInType(void)
{
	uint8_t retData;
	if(keyOpenDoorRequest == 1)											//开门按钮判断
	{
		retData = 0x04;
		keyOpenDoorRequest = 0;
	}else if((RFID_state == 1) || (scanIC_2CodeState == 1)){			//刷IC卡或IC卡二维码判断
		retData = 0x01;
		RFID_state = 0;
		scanIC_2CodeState = 0; 
	}else if(sweep2CodeState == 1){									//二维码扫码判断
		retData = 0x02;
		sweep2CodeState = 0;
	}else if(scanBarCodeState == 1){								//扫垃圾袋二维码
		retData = 0x03;
		scanBarCodeState = 0;
	}else if(scanLabelCodeState == 1){							//二维码贴纸（2018-04-28新增）
		retData = 0x05;
		scanLabelCodeState = 0;
	}else if(RFID_state == 3){											//银行卡
		if(cardNumberLen == 10)												//卡号长度为10位（自定义卡号）
		{
			retData = 0x0A;
		}else{																				//银行卡号作为绿色生活卡号
			retData = 0x07;
		}
		RFID_state = 0;
	}else if(RFID_state == 4){											//身份证
		retData = 0x08;
		RFID_state = 0;
	}else if(RFID_state == 5){											//中联IC卡
		retData = 0x09;
		RFID_state = 0;
	}else{
		retData = 0x00;
	}
	return retData;
}

/*
***********************************************************************
*	函 数 名: GetUserInfo
*	功能说明: 根据用户请求的开门方式来取得用户的相关信息（IC卡或二维码）
*	形    参：inputType->用户开门方式（IC卡或二维码）
*	返 回 值: 无（调用后改变了全局变量getDataLength、getDataBuf的值）
***********************************************************************
*/
void GetUserInfo(uint8_t inputType)
{
	uint8_t dataBuf[17] = {0};
	
	switch(inputType)																	//根据开门请求方式加载对应的身份信息
	{
		case 0x01:		//刷IC卡开门
			getDataLength = 9;														//IC卡身份信息为9字节
			memcpy(getDataBuf, RFID_ID, 9);								//保存IC卡身份信息
			memcpy(get_IC_ID, RFID_ID, 9);								//保存IC卡身份信息
			memcpy(getCardNumberBit, cardNumberBit, 17);	//保存IC卡身份信息（按位表示）
// 			printf("\r\ngetDataLength = %d\r\n", getDataLength);
// 			printf("\r\nRFID = %x\r\n", RFID_ID[0]);
			break;
			
		case 0x02:		//扫二维码开门
			getDataLength = codeDataLength;								//二维码身份信息长度
			memcpy(getDataBuf, codeBuf, codeDataLength);	//保存二维码发送信息
			memset(codeBuf, 0x00, 35);										//清除缓存内容
// 			printf("\r\ngetDataLength = %d\r\n", getDataLength);
			break;
			
		case 0x03:		//垃圾袋条形码或二维码开门
			getDataLength = codeDataLength;								//二维码身份信息长度
			memcpy(getDataBuf, codeBuf, codeDataLength);	//保存二维码发送信息
			memset(codeBuf, 0x00, 35);										//清除缓存内容
			break;
			
		case 0x04:		//按钮开门无身份信息
			getDataLength = 0;								
			break;
			
		case 0x05:		//二维码贴纸开门
			getDataLength = codeDataLength;								//二维码身份信息长度
			memcpy(getDataBuf, codeBuf, codeDataLength);	//保存二维码发送信息
			memset(codeBuf, 0x00, 35);										//清除缓存内容
			break;
			
		case 0x07:		//银行卡
		case 0x0A:		//银行卡(自定义卡号)
			getDataLength = cardNumberLen;
			memcpy(getDataBuf, cardNumberStr, getDataLength);
			
			memcpy(&dataBuf[11], &cardNumberBit[getDataLength-6], 6);			//取卡号的后6位用于显示
			memcpy(getCardNumberBit, dataBuf, 17);
			memset(cardNumberStr, 0x00, 33);
			break;
			
		case 0x09:		//中联IC卡
			getDataLength = 24;														//二维码身份信息长度
			memcpy(getDataBuf, cardNumberStr, getDataLength);	//保存二维码发送信息
			memset(cardNumberStr, 0x00, 33);										//清除缓存内容
			break;
	}
}

/*
***********************************************************************
*	函 数 名: ShowPutInMSG
*	功能说明: 显示投放开门类型及身份识别相关信息 
*	形    参：投放类型0x01->IC卡；0x02->二维码；0x03->条形码；0x04-> 按钮
*	返 回 值: 无
***********************************************************************
*/
void ShowPutInInfo(uint8_t uType)
{
	switch(uType)																//根据开门请求方式加载对应的身份信息
	{
		case 0x01:		//刷IC卡开门
			printf("\r\n刷IC卡或扫IC卡二维码开门\r\n");
			break;
			
		case 0x02:		//扫二维码开门
			printf("\r\n扫二维码开门\r\n");
			break;
			
		case 0x03:		//垃圾袋条形码开门
			printf("\r\n扫垃圾袋条形码或二维码开门\r\n");
			break;
			
		case 0x04:		//按钮开门无身份信息
			printf("\r\n按钮开门\r\n");							
			break;
			
		case 0x05:		//二维码贴纸开门
			printf("\r\n二维码贴纸开门\r\n");							
			break;
	}
	
	printf("\r\n用户识别信息为：\r\n");	
	printf("\r\n <>开门类型：%d\r\n", getPutInType);
	printf("\r\n <>身份长度：%d\r\n", getDataLength);
// 	printf("\r\n <>内容：%s\r\n", getDataBuf);
// 	showHexData(getDataBuf, 33);
}

/*
***********************************************************************
*	函 数 名: ClearPutInInfo
*	功能说明: 投放完成后清除投放信息，为下一次请求做准备
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void ClearPutInInfo(void)
{
	keyOpenDoorRequest = 0;													//清除按钮按下标志
	RFID_state = 0;																	//清除RFID_IC卡刷卡标志
	scanIC_2CodeState = 0;													//清除扫IC卡二维码卡号标志
	sweep2CodeState = 0;														//清除二维码扫描标志
	scanBarCodeState = 0;														//清除扫垃圾袋二维码标志
	scanLabelCodeState = 0;
	
	optoKeyStatus = 0;
	putInProgress = 0;	
	
	getPutInType = 0x00;														//清除发送身份验证类型
	getDataLength = 0x00;														//清除发送身份验证信息的数据长度
	memset(getDataBuf, 0x00, 33);										//清除发送身份验证信息内容
	memset(get_IC_ID, 0x00, 9);											//清除取得的IC卡号内容
	memset(getCardNumberBit, 0x00, 17);							//清除取得的IC卡号内容
}

/*
***********************************************************************
*	函 数 名: FaultCodeCheck
*	功能说明: 设备故障码检测，处理结束后1:表示有故障需上传故障码
*           0:表示没有故障不需上传故障码
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
#define codeLen 9
uint8_t faultCode[codeLen] = {11, 12, 13, 22, 23, 24, 32, 33, 34};		//回收箱故障代码

static void FaultCodeCheck(uint8_t devType)
{
	uint8_t i = 0;
	uint8_t faultMark = 0;
	
	switch(devType)
	{
		case DOUBLE_CLASSIFICATION:		//双桶480L
			for(i = 0; i < codeLen; i++)
			{
				if((faultCode_1 == faultCode[i]) || (faultCode_2 == faultCode[i]))
				{
					faultMark = 1;
					break;
				}
			}
			break;
			
		case DOUBLE_CLASSIFICATION_BOTTLE:		//双桶480L（含瓶子）
			for(i = 0; i < codeLen; i++)
			{
				if(faultCode_1 == faultCode[i])
				{
					faultMark = 1;
					break;
				}
			}
			break;
			
		case SINGLE_CLASSIFICATION:		//单桶660L
			for(i = 0; i < codeLen; i++)
			{
				if(faultCode_1 == faultCode[i])
				{
					faultMark = 1;
					break;
				}
			}
			break;
			
		default:
			break;
	}
	
	if(faultMark == 1)		//有故障则上传故障码
	{
		sendMsg.msgType = 6005;										//故障代码上传
		MessageSend(MSG_FIFO_PROTOCOL, sendMsg);
	}
}

/*
***********************************************************************
*	函 数 名: GetLimitKeyStatus
*	功能说明: 取得限位开关的状态
*	形    参：无
*	返 回 值: 返回限位开关限位状态正常与否（1：异常，0：正常）
***********************************************************************
*/
uint8_t GetLimitKeyStatus(void)
{
	uint8_t retData = 0;
	
	if(limitKeyExceptionMark > 0)
	{	
		switch(deviceType)
		{
			case DOUBLE_CLASSIFICATION:		//双桶480L
				if(limitKeyExceptionMark & 0x10)
				{
					faultCode_1 = 20;
				}
				if(limitKeyExceptionMark & 0x01)
				{
					faultCode_2 = 20;
				}
				break;
				
			case DOUBLE_CLASSIFICATION_BOTTLE:
				faultCode_1 = 0;										//目前瓶子桶没有设置故障码
				if(limitKeyExceptionMark & 0x10)		//共用左边的限位开关
				{
					faultCode_2 = 20;
				}
				break;
				
			case SINGLE_CLASSIFICATION:		//单桶660L	
				if(limitKeyExceptionMark & 0x10)
				{
					faultCode_1 = 20;
				}
				faultCode_2 = 0;
				break;
				
			default:
				break;
		}
		
		displayFaultCode = 20;
		retData = 1;
	}
	return retData;
}

/*
***********************************************************************
*	函 数 名: PutInOpenDoorTask
*	功能说明: 开门投放请求任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void PutInOpenDoorTask(void)
{
	uint8_t tempData = 0;
	uint8_t temp = 0;
	static uint8_t putInStatus = 0x00;
	static uint8_t infoDisplayStatus = 0;
	
	static uint8_t putInPrompt = 0;					//投放提示播放（每操作一次播放一次）
	
	static timer waitingTimer;
	static timer playWaitingTimer;
	static timer waitingPutInTimer;
	static timer displayTimer;
	static timer waitingUploadTimer;
	static timer outTimer;
	static timer waitingTimer4S;
	static timer faceEntryTimer;
	
	static uint8_t timer_ok = 0;

	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&waitingTimer, 10);
		timer_set(&playWaitingTimer, 15);
		timer_set(&waitingPutInTimer, CLOCK_SECOND*200);
		timer_set(&displayTimer, CLOCK_SECOND*3);
		timer_set(&waitingUploadTimer, CLOCK_SECOND*10);
		timer_set(&outTimer, CLOCK_SECOND*2);
		timer_set(&waitingTimer4S, CLOCK_SECOND*3);
		timer_set(&faceEntryTimer, CLOCK_SECOND*60*5);
	}
	
	switch(putInStatus)
	{
		case 0x00:		//初始状态
			if(pcRequestOpenDoorMark == 1)														//有开门请求
			{
				pcRequestOpenDoorMark = 0;
				
				beep_shortBeepMark = 1;										//开门提示声
				
				//进入程序处理前清除各类状态标志
				putInOKMark = 0;													//先清除投放完成标志
				disablePutInMark = 0;											//先清除装满禁止开门标志
				userInfoQueryStatus = 0;									//先清除从后台获取得的用户信息
				putInUploadSuccessMark = 0;								//先清除投放上传成功标志
				
				infoDisplayStatus = 0;										//用户信息每开一次门只显示一次
				getUserInfoMark = 0;
				putInPrompt = 0;													//清除提示分类投放语音标识（用于一次投放只播放一次）
				
				Audio_Play(1);

				Screen_Landing();

				printf("\r\n---------> 用户请求开门投放！！！\r\n");
				isOpenDoor = 1;														//标志要开门操作
				putInProgress = 1;												//标志设备正在进行操作
				printf("\r\n正在进行投放操作......\r\n");
				timer_restart(&playWaitingTimer);
				timer_restart(&waitingPutInTimer);
				timer_restart(&waitingTimer4S);
				
				putInStatus = 0x01;
				break;
			}
			break;
			
		case 0x01:		//等待投放
			if(timer_expired(&waitingPutInTimer))
			{
				putInStatus = 0x00;
				ClearPutInInfo();

				Screen_Default();
				printf("\r\n等待投放完成超时返回\r\n");
				break;
			}
			
			//-----------------------------------------------------
			//语音提示用户按分类进行投放
			if(putInPrompt == 0)
			{
				if(timer_expired(&waitingTimer4S))
				{
					if(synchronousOpenDoorMark == 1)
					{
						Audio_Play(2);
					}else{
						Audio_Play(6);
					}
					putInPrompt = 1;
				}
			}
			
			//是否有延迟投放
			if(delayCloseDoorStatus == 1)
			{
				delayCloseDoorStatus = 0;
				timer_restart(&waitingPutInTimer);
// 				printf("\r\n延迟投放时间\r\n");
			}
			
			//显示倒计时
			if(getRemainingTimerStatus == 1)
			{
				getRemainingTimerStatus = 0;
			
				//显示倒计时
				Screen_Countdown(remainingTimer);		
				PC_ProCommandSend(0x60);											//向上位机发送用于显示的关门倒计时				

				//-----------------------------------------------------
				//提示箱门即将关闭
				if(remainingTimer == 6)
				{
					Audio_Play(3);
				}
			}
			
			//如果有收到退出操作指令，则退出
			if(exitMark == 1)
			{
				exitMark = 0;
				putInStatus = 0x05;
				timer_restart(&outTimer);
				break;
			}
			
			//判断是否投放完成
			if(putInOKMark == 1)
			{
				putInOKMark = 0;
	
				printf("\r\n收到投放完成，正在处理......\r\n");
				
				//投口状态检测
				DropOffPortCheckTask();

				PC_ProCommandSend(0x61);											//向上位机发送用户投放数据用于显示
				
				printf("\r\n--> 收到本次投放数据如下：");
				printf("\r\n--> Type: %d", sendPutInType);
				printf("\r\n--> Len: %d", sendDataLength);
				if(getPutInType == 1)
				{
					printf("\r\n--> Data: ");
					showHexData(sendDataBuf, sendDataLength);
				}else{
					printf("\r\n--> Data: %s\r\n", sendDataBuf);
				}
				
				switch(deviceType)
				{
					case THREE_CLASSIFICATION:		//三分类
						printf("\r\n桶1: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight1/100, (float)getWeightBefore1/100, (float)getWeightAfter1/100, (float)getDistance1);
									
						printf("\r\n桶2: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight2/100, (float)getWeightBefore2/100, (float)getWeightAfter2/100, (float)getDistance2);
									
						printf("\r\n桶3: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight3/100, (float)getWeightBefore3/100, (float)getWeightAfter3/100, (float)getDistance3);
						
// 						printf("\r\n故障码 = %d\r\n", faultCode_L);
						
						//显示用户投放信息
						Screen_ShowPutInInfo2(getWeight1, getWeight2, getWeight3, getWeight4);
						break;
						
					case FOUR_CLASSIFICATION:		//四分类
						printf("\r\n桶1: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight1/100, (float)getWeightBefore1/100, (float)getWeightAfter1/100, (float)getDistance1);
									
						printf("\r\n桶2: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight2/100, (float)getWeightBefore2/100, (float)getWeightAfter2/100, (float)getDistance2);
									
						printf("\r\n桶3: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight3/100, (float)getWeightBefore3/100, (float)getWeightAfter3/100, (float)getDistance3);
									
						printf("\r\n桶4: %2.2f Kg，%2.2f Kg -> %2.2f Kg，距离：%3.1f cm\r\n",\
									(float)getWeight4/100, (float)getWeightBefore4/100, (float)getWeightAfter4/100, (float)getDistance4);
						
// 						printf("\r\n故障码 = %d\r\n", faultCode_L);
						
						//显示用户投放信息
						Screen_ShowPutInInfo2(getWeight1, getWeight2, getWeight3, getWeight4);
						break;
						
					default:
						break;
				}

// 				FaultCodeCheck(deviceType);			//故障检测上传
				
				printf("\r\n---------->投放完成！！！\r\n");
				
				fillLightMask = 1;
				
// 				putInStatus = 0x02;
// 				timer_restart(&displayTimer);
				
				timer_restart(&outTimer);
				putInStatus = 0x05;
				break;
			}
			break;
			
		case 0x02:		//停留显示投放信息界面
			if(timer_expired(&displayTimer))
			{
				//如果有投放，则等待上传回复投放后的余额
				if((getWeight1 > 0) || (getWeight2 > 0) || (getWeight3 > 0) || (getWeight4 > 0) || (smallBottleCount > 0))
				{
					printf("\r\n本次有投放，等待后台回应奖励\r\n");
					
					timer_restart(&waitingUploadTimer);
					putInStatus = 0x03;
					break;
				}else{																//没有投放则转到谢谢使用界面退出					
					Audio_Play(4);
					Screen_Exit();											//显示“退出使用界面”
					printf("\r\n显示投放时间到，且无投放退出\r\n");
					timer_restart(&outTimer);
					putInStatus = 0x05;
					break;
				}
				
			}
			break;
			
		case 0x03:		//等待上传成功显示投放后的余额
			if(putInUploadSuccessMark == 1)
			{
				putInUploadSuccessMark = 0;
				printf("\r\n之前余额 = %.2f \r\n", (float)capital/100);
				printf("\r\n之后余额 = %.2f \r\n", (float)capitalAfter/100);
				
				if(capitalAfter >= capital)
				{
					Screen_ShowPutInReward(capital, capitalAfter);
					PC_ProCommandSend(0x05);											//向上位机发送用户投放数据用于显示
					printf("\r\n奖励金额 = %.2f \r\n", (float)(capitalAfter - capital)/100);
				
// 					printf("\r\n奖励金额 = %.2f \r\n", (float)(capitalAfter - capital)/100);
// 					printf("\r\n余    额 = %.2f \r\n", (float)capitalAfter/100);
				}
				
				putInStatus = 0x04;
				timer_restart(&displayTimer);
			}
			
			if(timer_expired(&waitingUploadTimer))
			{
				Audio_Play(4);
					
				Screen_Exit();											//显示“退出使用界面”
				printf("\r\n显示投放时间到\r\n");
				putInStatus = 0x05;
				timer_restart(&outTimer);
			}
			break;
			
		case 0x04:
			if(timer_expired(&displayTimer))
			{
				Audio_Play(4);
				
				Screen_Exit();											//显示“退出使用界面”
				printf("\r\n显示投放时间到\r\n");
				putInStatus = 0x05;
				timer_restart(&outTimer);
			}
			break;
			
		case 0x05:		//停留显示退出界面
			if(timer_expired(&outTimer))
			{
				printf("\r\n显示结束\r\n");
				Screen_Default();
				
				PC_ProCommandSend(0x09);											//向上位机发送投放结束
				ClearPutInInfo();
				putInProgress = 0;
				pcRequestOpenDoorMark = 0;
				putInStatus = 0x00;
			}
			break;
			
		case 0x06:
			if(timer_expired(&outTimer))
			{
				putInStatus = 0x00;
			}
			break;
			
//-----------------------------------------------------------------------------------------	
		
		case 0x66:		//装满禁止开门时显示装满提示
			if(timer_expired(&displayTimer))
			{
				printf("\r\n显示结束\r\n");
				Screen_Default();
				ClearPutInInfo();
				putInStatus = 0x00;
			}
			break;
			
		case 0x10:		//设备故障转到此处等待处理
			Screen_Error(0, displayFaultCode, 0);
			PC_ProCommandSend(0x30);											//向上位机发送设备故障用于显示
			putInStatus = 0x11;
			break;
			
		case 0x11:
			//当限位开关出现故障之后运行到此，直到修复
			break;

//----------------------------------------------------------------------------------
//用户禁用处理过程			
		case 0x20:		//禁用的用户提示
			Screen_Query(0x03, 0, NULL, 0, 0);
			
			sendMsg.msgType = 4301;
			MessageSend(MSG_FIFO_PROTOCOL, sendMsg);	//向后台服务器发出请求获取用户信息指令
			printf("\r\nGet user Info\r\n");
					
			putInStatus = 0x21;
			timer_restart(&waitingUploadTimer);
			timer_restart(&outTimer);
			break;
			
		case 0x21:		//等待后台返回用户信息
			if(timer_expired(&waitingUploadTimer))
			{
				putInStatus = 0x05;
				break;
			}
			
			//收到后台应答的用户请求信息
			if(userInfoQueryStatus == 1)
			{
				userInfoQueryStatus = 0;
				
				if(isAuth == 1)			//账号有效
				{
					printf("\r\n账号恢复正常！\r\n");
					DelDisableUser(curIcCard);
					ShowDisableUserList();
				}else{
					printf("\r\n账号处于禁用状态！\r\n");
				}
				putInStatus = 0x05;
				break;
			}
			break;

//------------------------------------------------------------------------------------
//有脸录入处理过程			
		case 0x30:		//进入人脸录入操作
			sendMsg.msgType = 4401;
			MessageSend(MSG_FIFO_PROTOCOL, sendMsg);	//向后台服务器发出请求获取用户信息指令
			putInStatus = 0x31;
			timer_restart(&faceEntryTimer);
			break;
		
		case 0x31:		//人脸录入操作
			if(userInfoQueryStatus == 1)
			{
				userInfoQueryStatus = 0;
				
				PC_ProCommandSend(0x02);											//向上位机发送用户身份相关信息用于显示
			}
			
			//录入操作过程中失败可以继续监测身分信息
			tempData = GetPutInType();									//检查是否有开门投放请求
			if(tempData > 0)														//有开门请求
			{
				getPutInType = tempData;									//保存开门投放的类型（按钮、IC卡、二维码、垃圾袋条形码）
				tempData = 0;
				
				//20190627修改清除前一次的用户信息
				accountNum = 0;
				isAuth = 0;
				userInfoQueryStatus = 0;
				memset(get_IC_ID, 0x00, 9);								//清除取得的IC卡号内容
				
				GetUserInfo(getPutInType);								//根据开门方式取得用户相关信息
// 				ShowPutInInfo(getPutInType);							//显示投放请求相关信息
				
				//将用户身份识别信息保存到发送缓存
				sendPutInType = getPutInType;							//身份识别方式
				sendDataLength = getDataLength;						//发送身份信息的长度
				memcpy(sendDataBuf, getDataBuf, 33);			//加载身份信息
		
				putInStatus = 0x30;
				printf("\r\n人脸录入重新操作\r\n");
				break;
			}
			
			if(faceEntryFlag == 0)
			{
				printf("\r\n人脸录入退出！\r\n");
				ClearPutInInfo();
				putInStatus = 0x00;
				break;
			}
			
			if(timer_expired(&faceEntryTimer))
			{
				printf("\r\n录入超时退出！\r\n");
				ClearPutInInfo();
				faceEntryFlag = 0;
				putInStatus = 0x00;
				break;
			}
			break;
			
		default:
			putInStatus = 0x00;
			break;
	}
}

/*
***********************************************************************
*	函 数 名: BoxOpenTask
*	功能说明: 箱体门（收运门）开门控制任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void BoxOpenTask(void)
{
	uint8_t temp = 0;
	static uint8_t boxOpenSteps = 0;
	static uint8_t boxOpenType = 0;									//打开收箱体收运门的方式

	static timer waitingTimer;
	static timer waitingAckTimer;										//等待后台应答时间
	static timer waitingUnlockingTimer;							//等待打开收运锁时间
	
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&waitingTimer, CLOCK_SECOND*1);	
		timer_set(&waitingAckTimer, CLOCK_SECOND*10);	
		timer_set(&waitingUnlockingTimer, CLOCK_SECOND*2);
	}

	switch(boxOpenSteps)
	{
		case 0x00:		//初始状态
			//刷收运卡开门
			if(RFID_state == 2)
			{
				RFID_state = 0;
				
				boxOpenType = 1;											//标志当前为IC卡打开收运门
				beep_shortBeepMark = 1;								//开门提示声
				
				//取出当前客户号
				getCustomerID = 0;
				getCustomerID = RFID_ID[0] << 16;
				getCustomerID |= RFID_ID[1] << 8;
				getCustomerID |= RFID_ID[2];
				
				if(getCustomerID == customerID)		//是否为归属的收运卡
				{
					printf("\r\n开门卡匹配！\r\n");						
					
					memcpy(curIcCard, RFID_ID, 9);				//取出当前的IC卡号信息
					printf("\r\n开始检索\r\n");
					temp = FindUserStatus(curIcCard);
					if(temp > 0)
					{
						beep_warningBeepMark = 1;
						printf("\r\n当前用户已经被禁用！在 %d 位\r\n", temp);
						boxOpenSteps =0x20;
						break;
					}else{
						printf("\r\n当前用户正常！\r\n");
						boxOpenSteps = 0x01;
						break;
					}
				}else{
					beep_warningBeepMark = 1;
					printf("\r\n开门卡不匹配！\r\n");
					timer_restart(&waitingTimer);
					boxOpenSteps = 0x04;									//退出
					break;
				}
			}
			
			//临时二维码开收运清理门
			if(boxOpenQRMark == 1)
			{
				boxOpenQRMark = 0;											//标志要打开收运门（由开锁控制任务处理）
				beep_shortBeepMark = 1;									//开门提示声
				
				if(enableCleanQRCodeStatus == 1)				//启用了收运二维码开门
				{
					printf("\r\n临时开门二维码开门！\r\n");
					boxOpenType = 2;
					boxOpenSteps = 0x01;
					break;
				}else{
					printf("\r\n“收运二维码开门”功能已停用！\r\n");
					boxOpenSteps = 0x04;
					break;
				}
			}
			break;
			
		case 0x01:		//上传收运人员身份信息
			if(boxOpenType == 1)
			{
				boxOpenMark = 1;												//标志要打开收运门（由开锁控制任务处理）
				
				//上传收运人员卡号信息
				getDataLength = 9;											//IC卡身份信息为9字节
				memcpy(getDataBuf, RFID_ID, 9);					//保存IC卡身份信息
			}else if(boxOpenType == 2){
				//暂时还没有二维码开门信息
			}else{
				boxOpenSteps = 0x04;
			}
			
			//将用户身份识别信息保存到发送缓存
			collectorSendAuthType = boxOpenType;							//身份识别方式
			collectorSendDataLength = getDataLength;					//发送身份信息的长度
			memcpy(collectorSendDataBuf, getDataBuf, 33);			//加载身份信息
			
			
			if(ConnectionStatus == OFFLINE)
			{
				boxOpenSteps = 0x04;
				break;
			}
			
			//直接退出
			timer_restart(&waitingUnlockingTimer);
			boxOpenSteps = 0x03;
			break;
			
// 			sendMsg.msgType = 4701;
// 			MessageSend(MSG_FIFO_PROTOCOL, sendMsg);	//向后台服务器发出请求获取用户信息指令
// 			
// 			timer_restart(&waitingAckTimer);
// 			boxOpenSteps = 0x02;
// 			break;
			
		case 0x02:		//等待后台用户身份认证
			if(timer_expired(&waitingAckTimer))
			{
				printf("\r\n认证超时退出！\r\n");
				boxOpenSteps = 0x04;
				break;
			}
			
			if(getBoxOpenAckMark == 1)		//收到后台返回收运上传应答
			{
				getBoxOpenAckMark = 0;
				
				//根据后台的应答状态进行相应的处理
				switch(boxOpenAckStatus)	
				{
					case 0:		//无效或未登记
						//暂时不作处理，如果是IC卡前一状态已经可以开门，二维码则无法打开
						printf("\r\n收运账号无效或未登记！\r\n");
						break;
						
					case 1:		//正常收运账号
						printf("\r\n收运账号正常！\r\n");
						if(boxOpenType == 1)				//收运IC卡开门
						{
// 								boxOpenMark = 1;												//标志要打开收运门（由开锁控制任务处理）
// 							unlockMark = 1;																	//旧款桑拿锁控制标志
							break;
						}else if(boxOpenType == 2)	//收运二维码开门
						{
							boxOpenMark = 1;												//标志要打开收运门（由开锁控制任务处理）
							break;
						}
						break;
						
					case 2:		//禁用的收运账号
						if(boxOpenType == 1)				//收运IC卡开门
						{
							AddDisableUser(curIcCard);							// 添加到禁用列表
							ShowDisableUserList();
						}else if(boxOpenType == 2)	//收运二维码开门
						{
							//禁用的账号无法开门
							printf("\r\n收运账号被禁用！\r\n");
						}
						break;
						
					default:
						break;
				}
				
				timer_restart(&waitingUnlockingTimer);
				boxOpenSteps = 0x03;
				break;
			}
			break;
			
		case 0x03:		//等待打开箱体收运门完成
			if(timer_expired(&waitingUnlockingTimer))
			{
				boxOpenSteps = 0x04;
			}
			break;
			
		case 0x04:		//退出
			//清除相关的变量
			RFID_state = 0;
			boxOpenMark = 0;
			boxOpenSteps = 0x00;
			break;
			
//----------------------------------------------------------------------------
//禁用的收运账号处理			
		case 0x20:		//禁用的收运账号处理（再次请求判断是否恢复正常）
// 			Screen_Query(0x03, 0, NULL, 0, 0);
			//上传收运人员卡号信息
			getDataLength = 9;											//IC卡身份信息为9字节
			memcpy(getDataBuf, RFID_ID, 9);					//保存IC卡身份信息
				
			//将用户身份识别信息保存到发送缓存			
			collectorSendAuthType = boxOpenType;							//身份识别方式
			collectorSendDataLength = getDataLength;					//发送身份信息的长度
			memcpy(collectorSendDataBuf, getDataBuf, 33);			//加载身份信息
			
			sendMsg.msgType = 4701;
			MessageSend(MSG_FIFO_PROTOCOL, sendMsg);	//向后台服务器发出请求获取用户信息指令
			printf("\r\nGet user Info\r\n");
					
			boxOpenSteps = 0x21;
			timer_restart(&waitingAckTimer);
			break;
			
		case 0x21:		//等待后台返回用户信息
			if(timer_expired(&waitingAckTimer))
			{
				boxOpenSteps = 0x04;
				break;
			}
			
			//收到后台应答的用户请求信息
			if(getBoxOpenAckMark == 1) 
			{
				getBoxOpenAckMark = 0;
				
				//根据后台的应答状态进行相应的处理
				switch(boxOpenAckStatus)	
				{
					case 0:		//无效或未登记
						//暂时不作处理
						printf("\r\n收运账号无效或未登记！\r\n");
						break;
						
					case 1:		//正常收运账号
						printf("\r\n收运账号正常！\r\n");
						if(boxOpenType == 1)				//收运IC卡开门
						{
							printf("\r\n账号恢复正常！\r\n");
							DelDisableUser(curIcCard);
							ShowDisableUserList();
							break;
						}else if(boxOpenType == 2)	//收运二维码开门
						{
							boxOpenMark = 1;												//标志要打开收运门（由开锁控制任务处理）
							break;
						}
						break;
						
					case 2:		//禁用的收运账号
						if(boxOpenType == 1)				//收运IC卡开门
						{
							printf("\r\n账号处于禁用状态！\r\n");
						}else if(boxOpenType == 2)	//收运二维码开门
						{
							//禁用的账号无法开门
							printf("\r\n收运账号被禁用！\r\n");
						}
						break;
						
					default:
						break;
				}
				
				boxOpenSteps = 0x04;
				break;
			}
			break;
			
		default:
			boxOpenSteps = 0x00;
			break;
	}
}

/*
***********************************************************************
*	函 数 名: ServerSetupParam
*	功能说明: 后台设置参数任务
*	形    参：无 
*	返 回 值: 无
***********************************************************************
*/
void ServerSetupParamTask(void)
{
	uint8_t passMark = 0;
	
	if(getSetDistanceParamMark == 1)
	{
		getSetDistanceParamMark = 0;
		
		printf("\r\nGetDis: N=%d, T1=%d, h1=%d, H1=%d, A1=%d; T2=%d, h2=%d, H2=%d, A2=%d\r\n", getDevChannelNumbers,
						getDevChannel1Type, getDevChannel1DisDepthVal, getDevChannel1DisMaxVal, getDevChannel1DisAlarmPercent,
						getDevChannel2Type, getDevChannel2DisDepthVal, getDevChannel2DisMaxVal, getDevChannel2DisAlarmPercent);
		
		//数据检验
		if((getDevChannelNumbers == devChannelNumbers) &&
			 (getDevChannel1Type == devChannel1Type) &&
			 (getDevChannel2Type == devChannel2Type) &&
			 (getDevChannel3Type == devChannel3Type) &&
			 (getDevChannel4Type == devChannel4Type) &&
			 (getDevChannel1DisDepthVal > 0) && (getDevChannel1DisMaxVal >= getDevChannel1DisDepthVal) &&
			 (getDevChannel2DisDepthVal > 0) && (getDevChannel2DisMaxVal >= getDevChannel2DisDepthVal) &&
			 (getDevChannel3DisDepthVal > 0) && (getDevChannel3DisMaxVal >= getDevChannel3DisDepthVal) &&
			 (getDevChannel4DisDepthVal > 0) && (getDevChannel4DisMaxVal >= getDevChannel4DisDepthVal) &&
			 (getDevChannel1DisAlarmPercent <= 140) && (getDevChannel2DisAlarmPercent <= 140) &&
			 (getDevChannel3DisAlarmPercent <= 140) && (getDevChannel4DisAlarmPercent <= 140))
		{
			passMark = 1;
		}else{
			passMark = 0;
			printf("\r\n数据检验错误！\r\n");
		}
		
		if(passMark == 1)
		{
			setDevChannel1DisMaxVal = getDevChannel1DisMaxVal;
			setDevChannel1DisDepthVal = getDevChannel1DisDepthVal;
			setDevChannel1DisAlarmPercent = getDevChannel1DisAlarmPercent;

			setDevChannel2DisMaxVal = getDevChannel2DisMaxVal;
			setDevChannel2DisDepthVal = getDevChannel2DisDepthVal;
			setDevChannel2DisAlarmPercent = getDevChannel2DisAlarmPercent;

			setDevChannel3DisMaxVal = getDevChannel3DisMaxVal;
			setDevChannel3DisDepthVal = getDevChannel3DisDepthVal;
			setDevChannel3DisAlarmPercent = getDevChannel3DisAlarmPercent;

			setDevChannel4DisMaxVal = getDevChannel4DisMaxVal;
			setDevChannel4DisDepthVal = getDevChannel4DisDepthVal;
			setDevChannel4DisAlarmPercent = getDevChannel4DisAlarmPercent;
			
			SaveDeviceConfig();
			DeviceParamInit();							//参数有变动，则重新初始化设备参数
			CalcOverflowStartPointParam();
		}
	}
}

/*
***********************************************************************
*	函 数 名: DeviceEnableTask
*	功能说明: 设备启用/禁用控制任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void DeviceEnableTask(void)
{
	uint8_t dataTemp = 0;
	
	if(getDeviceWorkStatusMark == 1)
	{
		getDeviceWorkStatusMark = 0;
		
		printf("\r\nWorkSta = %d\r\n", getDeviceWorkStatusVal);

		if(getDeviceWorkStatusVal >= 1)
		{
			deviceWorkStatus = 1;
		}else{
			deviceWorkStatus = 0;
		}
		
		//根据设备当前工作状态进行显示
		if(deviceWorkStatus == 0)
		{
			Screen_DeviceDisable();
		}else{
			Screen_Default();
		}
		
		if(deviceWorkStatus != deviceWorkStatusPre)
		{
			printf("\r\n设备工作状态有变化！\r\n");
			deviceWorkStatusPre = deviceWorkStatus;
		}
	}
}

/*
***********************************************************************
*	函 数 名: KeysSendTask
*	功能说明: 按键触摸转发给上位机任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void KeysSendTask(void)
{
	if(keyType == 1)		//单纯使用触摸按键
	{
		if(keyValue > 0)
		{
	// 		printf("\r\nkey = %x\r\n", keyValue);
			if((keyValue & 0xF0) == 0)		//按键短按输出
			{
				keyNum = keyValue;
				keyStatus = 1;
	// 			printf("\r\n按键短按，key = %x\r\n", keyNum);
			}else{												//按键长按输出
				keyNum = keyValue & 0x0F;
				keyStatus = 2;
	// 			printf("\r\n按键长按，key = %x\r\n", keyNum);
			}
			
			PC_ProCommandSend(0x11);											//向上位机发送用户身份相关信息用于显示
			printf("\r\n按键输出: Num = %x, Sta = %x\r\n", keyNum, keyStatus);
			keyValue = 0;
		}
		
		if(keyReleaseMark == 1)			//按键松开时的输出
		{
			keyStatus = 3;
			PC_ProCommandSend(0x11);											//向上位机发送用户身份相关信息用于显示
			printf("\r\n按键输出: Num = %x, Sta = %x\r\n", keyNum, keyStatus);
			
			keyReleaseMark = 0;
		}
	}
	
	
	//同时使用机械按键和触摸按键（人脸切换发送的键值由MCU2的光电开关接口输入）
// 	if(optoKeyStatus > 0)		
// 	{
// 		if(optoKeyStatus == 1)
// 		{
// 			keyNum = 3;
// 			keyStatus = 1;
// 		}else if(optoKeyStatus == 3){
// 			keyNum = 3;
// 			keyStatus = 3;
// 		}else{}
// 		
// 		PC_ProCommandSend(0x11);											//向上位机发送用户身份相关信息用于显示
// 		printf("\r\n按键输出: Num = %x, Sta = %x\r\n", keyNum, keyStatus);
// 		
// 		optoKeyStatus = 0;
// 	}
}

/*
***********************************************************************
*	函 数 名: HumanSensingTask
*	功能说明: 人体感应任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void HumanSensingTask(void)
{
	if(optoKeyStatus > 0)		
	{
		if(optoKeyStatus == 1)
		{
			humanSensingKeyStatus = 1;
		}else if(optoKeyStatus == 3){
			humanSensingKeyStatus = 3;
		}else{}
		
		PC_ProCommandSend(0x64);											//向上位机发送用户身份相关信息用于显示
		printf("\r\n人体感应状态: Num = %x, Sta = %x\r\n", 1, humanSensingKeyStatus);
		
		optoKeyStatus = 0;
	}
}

/*
***********************************************************************
*	函 数 名: DropOffPortCheck
*	功能说明: 投放口状态检测任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void DropOffPortCheckTask(void)
{
	static uint8_t preDropOffPortSta1 = 0;
	static uint8_t preDropOffPortSta2 = 0;
	
	if(preDropOffPortSta1 != switchKey1Status)
	{
		dropOffPortMark1 = 1;							//标志当前投放口状态发生变化
		dropPortClosedStatus1 = switchKey1Status;
		preDropOffPortSta1 = dropPortClosedStatus1;
		printf("\r\n投放口1状态发生变化（%d）\r\n", dropPortClosedStatus1);
	}
	
	if(preDropOffPortSta2 != switchKey2Status)
	{
		dropOffPortMark2 = 1;							//标志当前投放口状态发生变化
		dropPortClosedStatus2 = switchKey2Status;
		preDropOffPortSta2 = dropPortClosedStatus2;
		printf("\r\n投放口2状态发生变化（%d）\r\n", dropPortClosedStatus2);
	}
	
	if((dropOffPortMark1 == 1) || (dropOffPortMark2 == 1)) 
	{
		PC_ProCommandSend(0x66);											//向上位机发送投口关闭状态
	}
}

/*
***********************************************************************
*	函 数 名: RecycleClearDoorCheckTask
*	功能说明: 收运门状态检测任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void RecycleClearDoorCheckTask(void)
{
	static uint8_t currentStatus = 0x00;
	static uint8_t nextStatus = 0x00;
	
	static uint8_t preStatus = 0;
	uint8_t curStatus = 0;
	
	static uint8_t preRecycleClearDoorMark = 0;
	
	static uint8_t initOk = 0;
	
	static timer waitingInitTimer;
	static timer waitingTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		
		timer_set(&waitingInitTimer, CLOCK_SECOND*30);
		timer_set(&waitingTimer, CLOCK_SECOND*2);
	}
	
	curStatus = getRecycleClearDoorMark;
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case 0x00:
			if(curStatus != preStatus)
			{
				timer_restart(&waitingTimer);
				nextStatus = 0x01;
				break;
			}
			break;
			
		case 0x01:
			if(timer_expired(&waitingTimer))
			{
				if(curStatus != preStatus)
				{
					printf("\r\n收运门状态发生变化！\r\n");
					recycleClearDoorMark = curStatus;
					preStatus = curStatus;
				}
				nextStatus = 0x00;
			}
			break;
			
		default:
			nextStatus = 0x00;
			break;		
	}
	
	
	if(recycleClearDoorMark != preRecycleClearDoorMark)
	{
		if(recycleClearDoorMark == 0)
		{
			printf("\r\n收运门关闭！\r\n");
		}else{
			printf("\r\n收运门打开！\r\n");
		}
		
		preRecycleClearDoorMark = recycleClearDoorMark;
		
		PC_ProCommandSend(0x23);
	}
	
	
	if(initOk == 0)
	{
		if(timer_expired(&waitingInitTimer))
		{
			initOk = 1;
			
			printf("\r\n初次开机向上位机发送收运门状态！\r\n");
			if(recycleClearDoorMark == 0)
			{
				printf("\r\n收运门关闭！\r\n");
			}else{
				printf("\r\n收运门打开！\r\n");
			}
			PC_ProCommandSend(0x23);
		}
	}
}

/*
***********************************************************************
*	函 数 名: NowTimeIsOnTheHour
*	功能说明: 当前时间是否为整点
*	形    参：无
*	返 回 值: 整点返回1,否则返回0
***********************************************************************
*/
uint8_t NowTimeIsOnTheHour(void)
{
	if((nowTime->tm_min == 0) && (nowTime->tm_sec == 0))
	{
		return 1;
	}else{
		return 0;
	}
}

/*
***********************************************************************
*	函 数 名: TimingSprayTask
*	功能说明: 定时喷淋消毒任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void TimingSprayTask(void)
{
	static uint8_t currentStatus = 0x00;
	static uint8_t nextStatus = 0x00;
	uint8_t onTheHourStatus = 0;
	
	static timer waitingTimer;
	static timer turnOnTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		
		timer_set(&waitingTimer, CLOCK_SECOND*1);
 		timer_set(&turnOnTimer, CLOCK_SECOND*2);
	}
	
	onTheHourStatus = NowTimeIsOnTheHour();
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case 0x00:
			if((getDateTimeMark == 1) && (onTheHourStatus == 1))
			{
//				//根据不同时间段设置喷淋次数（00:00 - 08:59 3小时喷一次；09:00 - 23:59M 1小时喷一次）
//				if((nowTime->tm_hour == 0) || (nowTime->tm_hour == 3) || (nowTime->tm_hour == 6) || (nowTime->tm_hour >= 9))
				
				if((nowTime->tm_hour)%3 == 0)		//每3小时喷一次 20230727修改
				{
					printf("\r\n定时到打开喷淋消毒！(%s)\r\n", systemTime);
					
					if((sprayDisinfectingMark != 2) && (putInProgress != 1))			//当前收运门没有打开状态和没有投放操作，才执行喷淋消毒动作
					{
						StartUpSprayDisinfection();
					}
					timer_restart(&turnOnTimer);
					nextStatus = 0x01;
					break;
				}
			}
			break;
			
		case 0x01:		//消毒状态
			if(timer_expired(&turnOnTimer))
			{
				printf("\r\n消毒时间到关闭喷淋消毒！\r\n");
				
				StopSprayDisinfection();
				nextStatus = 0x00;
				break;
			}
			
			//投放时暂停消毒
			if(putInProgress == 1)
			{
				printf("\r\n当前正在投放！暂停喷淋消毒！\r\n");
				
				StopSprayDisinfection();
				nextStatus = 0x02;
				break;
			}
			
			//打开收运门结束消毒
			if(sprayDisinfectingMark == 2)
			{
				printf("\r\n打开收运门结束喷淋消毒！\r\n");
				
				StopSprayDisinfection();
				sprayDisinfectingMark = 0;
				
				timer_restart(&waitingTimer);
				nextStatus = 0x10;
				break;
			}
			break;
			
		case 0x02:		//暂停状态
			if(putInProgress == 0)
			{
				printf("\r\n投放结束！恢复喷淋消毒！\r\n");
				
				StartUpSprayDisinfection();
				timer_restart(&turnOnTimer);
				nextStatus = 0x01;
				break;
			}
			break;
			
		case 0x10:
			if(timer_expired(&waitingTimer))
			{
				sprayDisinfectingMark = 0;
				nextStatus = 0x00;
				break;
			}
			break;
			
		default:
			break;
	}
}

/*
***********************************************************************
*	函 数 名: TimingUVTask
*	功能说明: 定时紫外线消毒任务
*	形    参：无
*	返 回 值: 无
***********************************************************************
*/
void TimingUVTask(void)
{
	static uint8_t currentStatus = 0x00;
	static uint8_t nextStatus = 0x00;
	uint8_t onTheHourStatus = 0;
	
	static timer waitingTimer;
	static timer turnOnTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		
		timer_set(&waitingTimer, CLOCK_SECOND*1);
 		timer_set(&turnOnTimer, CLOCK_SECOND*60*10);
	}
	
	onTheHourStatus = NowTimeIsOnTheHour();
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case 0x00:
			if((getDateTimeMark == 1) && (onTheHourStatus == 1))
			{
				printf("\r\n定时到打开UV消毒！(%s)\r\n", systemTime);
				
				if((disinfectingMark != 2) && (putInProgress != 1))			//当前收运门没有打开状态和没有投放操作，才执行UV消毒动作
				{
					StartUpDisinfection();
				}
				timer_restart(&turnOnTimer);
				nextStatus = 0x01;
				break;
			}
			break;
			
		case 0x01:		//消毒状态
			if(timer_expired(&turnOnTimer))
			{
				printf("\r\n消毒时间到关闭UV消毒！\r\n");
				
				StopDisinfection();
				nextStatus = 0x00;
			}
			
			//投放时暂停消毒
			if(putInProgress == 1)
			{
				printf("\r\n当前正在投放！暂停UV消毒！\r\n");
				
				StopDisinfection();
				nextStatus = 0x02;
				break;
			}
			
			//打开收运门结束UV消毒
			if(disinfectingMark == 2)
			{
				printf("\r\n打开收运门结束UV消毒！\r\n");
				
				StopDisinfection();
				disinfectingMark = 0;
				
				timer_restart(&waitingTimer);
				nextStatus = 0x10;
				break;
			}
			break;
			
		case 0x02:		//暂停状态
			if(putInProgress == 0)
			{
				printf("\r\n投放结束！恢复UV消毒！\r\n");
				
				StartUpDisinfection();
//				timer_restart(&turnOnTimer);
				nextStatus = 0x01;
				break;
			}
			break;
			
		case 0x10:
			if(timer_expired(&waitingTimer))
			{
				disinfectingMark = 0;
				nextStatus = 0x00;
				break;
			}
			break;
			
		default:
			break;
	}
}

/******************** (C) COPYRIGHT 2017 Ping *****END OF FILE*******************/
