/**
  ******************************************************************************
  * @file    Blv_485_Dev_DOOYACurtain.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2022年07月20日
  * @brief   485窗帘总驱动  杜亚窗帘驱动
	*       
  ******************************************************************************
  */

#include "Blv_485_Dev_CurtainFun.h"

#include "includes.h"
#include "stdint.h"
#include "BLV_485_Protocol.h"
#include "BLV_Dev_Action.h"
#include "BLV_All_Dev_Init.h"

//设备驱动宏
#define RS485_DEV_PRO_FUN_01    DevExistJudgge(RS485_DOOYA_Curtain_Flag, BLV_485_Dev_DOOYACurtain_Init)        //杜亚窗帘驱动
#define RS485_DEV_PRO_FUN_02    DevExistJudgge(RS485_BinShen_Curtain_Flag, BLV_485_Dev_BinShen_Curtain_Init)   //丙申窗帘驱动

void BLV_485_Dev_DOOYACurtain_Init(Device_Public_Information_G *BUS_Public, RS485_Cur_INFO *Rs485CurtainInfo);
uint8_t BLV_RS485_DOOYACurtain_Cycle_Dis(uint32_t dev_addr);
uint8_t BLV_RS485_DOOYACurtain_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len);
void BLW_485_Curtain_Control(uint32_t CfgDevAddIn, uint16_t DevInputAddr,uint32_t devaddr,uint16_t DevOutputLoop,uint16_t state);
uint16_t DYCurtain_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop);
void Cur_ConDataSend(uint8_t port,uint8_t data,uint8_t dev_addr,uint8_t commcod);
void Cur_ConDataSend2(uint8_t port,uint8_t data,uint8_t data2,uint8_t dev_addr,uint8_t commcod);
void Cur_ReqDataSend(uint8_t port,uint8_t dev_addr,uint8_t commcod);
void BLW_RS485_Curtain_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len);



/*******************************************************************************
* Function Name : BLV_485_Dev_Curtain_Data_Init
* Description   : 485窗帘设备初始化
* Input         : 
	DataLen	      : 数据长度
	*Data   	    : 数据地址
	len           :数据长度
* Return        :void
*******************************************************************************/

void BLV_485_Dev_Curtain_Data_Init(uint16_t DataLen, uint8_t *Data)
{
	
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CurtainInfo,0,sizeof(RS485_Cur_INFO));
	
	BUS_Public.addr = Data[1];			            //设备地址
	BUS_Public.type = Data[0];		              //设备类型
	BUS_Public.port = Active_Port;			        //设备发送端口
	BUS_Public.baud = 9600;			                //设备发送波特率
	BUS_Public.retry_num = 0x03;		            //设备数据重发次数
	BUS_Public.wait_time = 0x0064;		          //设备数据发送等待回复时间 - 100ms

	BUS_Public.DevFunInfo.Dev_Output_Ctrl = BLW_485_Curtain_Control;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = DYCurtain_Loop_State;
	
	Rs485CurtainInfo.read_flag=0x01;
	Rs485CurtainInfo.DevOffline = Rs485CurtainInfo.DevOfflineLast = DEV_IS_LINEUNINIT;   //在线状态初始化
	switch(Data[7])
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CurtainInfo);break; //        
	}
	
	Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO));
	Act485_Info.device_num += 1;
}



/*******************************************************************************
* Function Name  : BLW_RS485_Curtain_For_Logic_Init 
* Description    : 485窗帘初始化信息来自逻辑文件
*******************************************************************************/
void BLW_RS485_Curtain_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;

	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CurtainInfo,0,sizeof(RS485_Cur_INFO));
	
	BUS_Public.addr = dev_info->addr;		//设备485地址
	BUS_Public.type = dev_info->type;		//设备类型
	BUS_Public.baud = dev_info->baud;;		//设备发送波特率9600
	BUS_Public.retry_num = dev_info->retry;	//设备数据重发次数
	BUS_Public.wait_time = dev_info->writ_time;	//设备数据发送等待回复时间 - 100ms
	BUS_Public.Protocol = dev_info->version;
	
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = BLW_485_Curtain_Control;
	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = DYCurtain_Loop_State;   
	
	Rs485CurtainInfo.reverse_enable = dev_info->priproperty[0];			//电机控制输出反向使能		2025-08-14
	if(Rs485CurtainInfo.reverse_enable != 0x01)
	{
		Rs485CurtainInfo.reverse_enable = 0x00;
	}
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘 电机控制反向使能:%d",Rs485CurtainInfo.reverse_enable);
	
	Rs485CurtainInfo.DevOfflineLast = DEV_IS_ONLINE;   //在线状态初始化
	Rs485CurtainInfo.DevOffline = Rs485CurtainInfo.DevOfflineLast;
	switch(BUS_Public.Protocol)		//协议版本
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485CurtainInfo);break;  
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485CurtainInfo);break;
	
	}
	
	switch(dev_info->port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO));   //将填充后的数据添加到链表
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			BUS_Public.port = Bus_port;		//设备发送端口		
			Add_BUS_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO));
			BUS485_Info.device_num += 1;
			break;
	}
	
}



/*******************************************************************************
* Function Name : BLV_485_Dev_DOOYACurtain_Init 
* Description   : 杜亚窗帘初始化
* Input         : 
* Return        :void
*******************************************************************************/

void BLV_485_Dev_DOOYACurtain_Init(Device_Public_Information_G *BUS_Public, RS485_Cur_INFO *Rs485CurtainInfo)
{
	
	BUS_Public->polling_cf = (uint32_t)&BLV_RS485_DOOYACurtain_Cycle_Dis;
	BUS_Public->processing_cf = (uint32_t)&BLV_RS485_DOOYACurtain_Check;
	
}


/*******************************************************************************
* Function Name : BLV_RS485_DOOYACurtain_Cycle_Dis
* Description   : 485窗帘设备控制轮询发送
* Input         : 
  devaddr       : 设备地址
* Return        : Ret==RS485OCCUPYTIME
*******************************************************************************/

uint8_t BLV_RS485_DOOYACurtain_Cycle_Dis(uint32_t devaddr)
{
	uint8_t Ret = RS485OCCUPYNOTIME;
	uint8_t tempfalg = 0x00;
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CurtainInfo,0,sizeof(RS485_Cur_INFO));
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);		
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);
	
	
	uint8_t dev_addr=SRAM_Read_Byte(devaddr+Dev_Addr);
	
	uint8_t port = SRAM_Read_Byte(devaddr+Dev_port);
	
	if(Rs485CurtainInfo.request_flag==0x01&&Rs485CurtainInfo.DevSendCnt<3)
	{
		Cur_ReqDataSend(port,dev_addr,0x02);
		Rs485CurtainInfo.DevSendCnt++;
		tempfalg = 0x01;
	}
	
	if(Rs485CurtainInfo.read_flag==0x01&&Rs485CurtainInfo.DevSendCnt<3)
	{
		Cur_ConDataSend2(port,0x02,0x01,dev_addr,0x01);
		Rs485CurtainInfo.DevSendCnt++;
		tempfalg = 0x01;
	}
	
	
	switch(Rs485CurtainInfo.control_flag)
	{
		case 0x01:
		case 0x02:
		case 0x04:
		case 0x06:
			Cur_ConDataSend(port,Rs485CurtainInfo.DooYaCon_data.DATE,dev_addr,0x03);
			Rs485CurtainInfo.DevSendCnt++;
			Ret = RS485OCCUPYTIME;
			tempfalg = 0x01;
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘发送控制命令:%d SN:%d",Rs485CurtainInfo.DooYaCon_data.DATE,Rs485CurtainInfo.DevSendCnt);
			break;
		case 0x05:
			Cur_ConDataSend2(port,Rs485CurtainInfo.DooYaCon_data.DATE,Rs485CurtainInfo.DooYaCon_data.DATE1,dev_addr,0x03);
			Rs485CurtainInfo.DevSendCnt++;
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘发送控制命令:%d SN:%d",Rs485CurtainInfo.DooYaCon_data.DATE,Rs485CurtainInfo.DevSendCnt);
			Ret = RS485OCCUPYTIME;
			tempfalg = 0x01;
			break;
	}
		
	
	if(Rs485CurtainInfo.DevSendCnt>3)
	{
		if(Rs485CurtainInfo.DevOffline != DEV_IS_OFFLINE)
		{
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_485_Curtain LogInfo_Device_Offline...........");
			LOG_Device_Online_Record(DEV_RS485_CURTAIN, BUS_Public.addr,LogInfo_Device_Offline);	//记录设备离线
		}
		Rs485CurtainInfo.DevOffline = DEV_IS_OFFLINE;   //判为离线
		Rs485CurtainInfo.read_flag=0x00;
		Rs485CurtainInfo.control_flag=0x00;
		Rs485CurtainInfo.request_flag=0x00;
		Rs485CurtainInfo.DevSendCnt=0x00;
		if(Rs485CurtainInfo.DevOffline != Rs485CurtainInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
		{
			Rs485CurtainInfo.DevOfflineLast = Rs485CurtainInfo.DevOffline;	//更新上一次在线状态
			Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
		}
		tempfalg = 0x01;
	}

	BLV_Communication_Record(&Rs485CurtainInfo.comm_record,0x01,0x00);
	
	if(tempfalg)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CurtainInfo, sizeof(RS485_Cur_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);
	}
	
	return Ret;

}


/*******************************************************************************
* Function Name : BLV_RS485_DOOYACurtain_Check
* Description   : 485窗帘设备数据接收处理
* Input         : 
  dev_addr      : 设备地址
  data_addr     : 数据地址
* Return        : rev      0x01失败    0x00成功
*******************************************************************************/

uint8_t BLV_RS485_DOOYACurtain_Check(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t rev = 0x01;     //默认失败
	uint8_t data[CUR_RECDATALENMAX]={0};
	uint8_t tempflag;
	uint16_t crc_val;
	
	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	
	if(len > CUR_RECDATALENMAX||len<7)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"不是485窗帘数据!");
		return 0x01;
	}
	
	SRAM_DMA_Read_Buff(data,len,data_addr);   //拷贝482数据
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),dev_addr);
	
//	Dbg_Print_Buff(DBG_BIT_DEVICE_STATUS_bit,"485Cur_REV:",data,len);
	
	if(data[0] != 0x55)	
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘校验文件头不对!!");
		rev=0x01;				//校验文件头
	}
	
	if(data[1] != SRAM_Read_Byte(dev_addr+Dev_Addr))	
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘设备地址不对!!");
		rev=0x01;				//校验地址
	}
	
	if(data[2] != 0x0D)	
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘设备类型不对!!");
		rev=0x01;				//校验设备类型
	}
	
	crc_val = data[len-2] + (data[len-1]<<8);
	
	if(crc_val == NetCRC16_2(&data[0],len - 2))            //CRC校验成功
	{
		rev = 0x00;
		SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),dev_addr+Dev_Privately);
		if(Rs485CurtainInfo.DevOffline != DEV_IS_ONLINE)
	  {
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_485_Curtain LogInfo_Device_Online...........");
			LOG_Device_Online_Record(DEV_RS485_CURTAIN,BUS_Public.addr,LogInfo_Device_Online);	//记录设备在线
	  }
		Rs485CurtainInfo.DevOffline = DEV_IS_ONLINE;    		//设备在线
		if(Rs485CurtainInfo.DevOffline != Rs485CurtainInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
		{
			Rs485CurtainInfo.DevOfflineLast = Rs485CurtainInfo.DevOffline;	//更新上一次在线状态
			Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
		}
		BLV_Communication_Record(&Rs485CurtainInfo.comm_record,0x02,0x01);		//记录通讯成功
		Rs485CurtainInfo.DevSendCnt = 0x00;             		//收到回复就清计数
	  tempflag=0x01;
	}
	
	if(rev)                //回复校验失败处理
	{
		switch(data[3])
		{
			case 0x01:
				if(Rs485CurtainInfo.DevSendCnt==3)
				{
					Rs485CurtainInfo.read_flag=0x00;
				}
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘读取失败");
				tempflag=0x01;
				break;
			case 0x02:
				if(Rs485CurtainInfo.DevSendCnt==3)
				{
					Rs485CurtainInfo.request_flag=0x00;   //请求地址动作清空
				}
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘写失败");
				tempflag=0x01;
				break;
			case 0x03:
				if(Rs485CurtainInfo.DevSendCnt==3)
				{
					Rs485CurtainInfo.control_flag=0x00;
				}
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制失败");
				tempflag=0x01;
				break;
		}
	}
	
	switch(data[3])      //设备回复成功处理
	{
		case 0x01:         //读命令
			if(data[5]==0x00)
			{
				Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
			}
			else if(data[5]==0x64)
			{
				Rs485CurtainInfo.DYCurtainNextState=CUR_CLOSE;
			}
			else if(data[5]>0x00&&data[5]<0x64)
			{
				Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
			}
			else if(data[5]==0xFF)
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘未设置行程");
				Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
			}
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘行程：%d",data[5]);
			tempflag=0x01;
			Rs485CurtainInfo.read_flag=0x00;
			Rs485CurtainInfo.DevSendCnt=0x00;
			break;
		case 0x02:        //写命令
//			if(data[4]==0x00&&data[5]==0x02)      //写地址回复
//			{
//				Rs485CurtainInfo.request_flag=0x00;
//			}
//			tempflag=0x01;
			break;
		case 0x03:        //控制命令
			if(data[4]==CUR_OPEN&&Rs485CurtainInfo.DYCurtainState==CUR_OPEN)
			{
				Rs485CurtainInfo.DYCurtainNextState=CUR_CLOSE;
			}
		
			if(data[4]==CUR_CLOSE&&Rs485CurtainInfo.DYCurtainState==CUR_CLOSE)
			{
				Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
			}
			
			if(data[4]==CUR_STOP&&Rs485CurtainInfo.DYCurtainState==CUR_STOP)
			{
				if(Rs485CurtainInfo.DYCurtainStateLast==CUR_OPEN)
				{
					Rs485CurtainInfo.DYCurtainNextState=CUR_CLOSE;
				}
				else if(Rs485CurtainInfo.DYCurtainStateLast==CUR_CLOSE)
				{
					Rs485CurtainInfo.DYCurtainNextState=CUR_OPEN;
				}
			}
			
			tempflag=0x01;
			Rs485CurtainInfo.control_flag=0x00;
			Rs485CurtainInfo.DevSendCnt=0x00;
			break;
//		case 0x04:        //请求命令
//			if(data[4]==0x01)
//			{
//				Rs485CurtainInfo.request_flag=0x01;
//			}
//			tempflag=0x01;
//			break;
	}
	
	
	/*日志记录*/
	LOG_Device_COMM_Control_Reply_Record(BUS_Public.port,BUS_Public.baud,data,len);
	
	if(tempflag==0x01)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CurtainInfo, sizeof(RS485_Cur_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);/*将数据保存*/
	  SRAM_DMA_Write_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),dev_addr+Dev_Privately);
	}

	return rev;

}


/*******************************************************************************
* Function Name : BLW_485_Curtain_Control
* Description   : 485窗帘设备动作获取并转换
* Input         : 
  CfgDevAddIn   : 暂未使用
  DevInputAddr  : 暂未使用
  DevOutputLoop : 暂未使用
  devaddr       : 设备地址
  state         : 动作参数
* Return        : void
*******************************************************************************/

void BLW_485_Curtain_Control(uint32_t CfgDevAddIn, uint16_t DevInputAddr,uint32_t devaddr,uint16_t DevOutputLoop,uint16_t state)
{

	Device_Public_Information_G BUS_Public;
	RS485_Cur_INFO 	Rs485CurtainInfo;
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485CurtainInfo,0,sizeof(RS485_Cur_INFO));
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);
	
	uint8_t port = SRAM_Read_Byte(devaddr+Dev_port);
	
	uint8_t dev_addr=SRAM_Read_Byte(devaddr+Dev_Addr);
	
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"%s state:%4x  addr:%2x",__func__,state,dev_addr);
	
	switch((state)&0x00ff)
	{
		case 0x01:     //打开
			//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：打开\r\n");
			Rs485CurtainInfo.DooYaCon_data.COMMAND=0x03;
			
			//2025-08-14 增加电机控制反向
			if(Rs485CurtainInfo.reverse_enable == 0x01)
			{
				Rs485CurtainInfo.DooYaCon_data.DATE=CUR_CLOSE;
				//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：反向 - 打开\r\n");
			}else {
				Rs485CurtainInfo.DooYaCon_data.DATE=CUR_OPEN;
				//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：打开\r\n");
			}
			
			Rs485CurtainInfo.control_flag=0x01;
			Rs485CurtainInfo.DYCurtainStateLast=Rs485CurtainInfo.DYCurtainState;    //保存当前状态
			Rs485CurtainInfo.DYCurtainState=CUR_OPEN;                               //改变状态
			break;
		case 0x02:     //关闭
			//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：关闭\r\n");
			Rs485CurtainInfo.DooYaCon_data.COMMAND=0x03;
			
			//2025-08-14 增加电机控制反向
			if(Rs485CurtainInfo.reverse_enable == 0x01)
			{
				Rs485CurtainInfo.DooYaCon_data.DATE=CUR_OPEN;
				//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：反向 - 关闭\r\n");
			}else {
				Rs485CurtainInfo.DooYaCon_data.DATE=CUR_CLOSE;
				//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：关闭\r\n");
			}
			
			Rs485CurtainInfo.control_flag=0x02;
			Rs485CurtainInfo.DYCurtainStateLast=Rs485CurtainInfo.DYCurtainState;
			Rs485CurtainInfo.DYCurtainState=CUR_CLOSE;
			break;
		case 0x04:     //互切
			//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：互切 state:%d\r\n",Rs485CurtainInfo.DYCurtainNextState);
			if(Rs485CurtainInfo.DYCurtainNextState!=0x00)
			{
					Rs485CurtainInfo.DooYaCon_data.COMMAND=0x03;
					if(Rs485CurtainInfo.reverse_enable == 0x01)
					{
						if(Rs485CurtainInfo.DYCurtainNextState == 0x01)
						{
							Rs485CurtainInfo.DooYaCon_data.DATE = 0x02;
						}else if(Rs485CurtainInfo.DYCurtainNextState == 0x02)
						{
							Rs485CurtainInfo.DooYaCon_data.DATE = 0x01;
						}else {
							Rs485CurtainInfo.DooYaCon_data.DATE=Rs485CurtainInfo.DYCurtainNextState;
						}
					}else{
						Rs485CurtainInfo.DooYaCon_data.DATE=Rs485CurtainInfo.DYCurtainNextState;
					}
					
			}
			Rs485CurtainInfo.control_flag=0x04;
			Rs485CurtainInfo.DYCurtainStateLast=Rs485CurtainInfo.DYCurtainState;
			Rs485CurtainInfo.DYCurtainState=Rs485CurtainInfo.DYCurtainNextState;
			break;
		case 0x05:     //百分比
			//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：百分比\r\n");
			Rs485CurtainInfo.DooYaCon_data.COMMAND=0x03;
			Rs485CurtainInfo.DooYaCon_data.DATE=CUR_PER;
			Rs485CurtainInfo.DooYaCon_data.DATE1=((state>>8)&0x00ff);
			Rs485CurtainInfo.control_flag=0x05;
			break;
		case 0x06:     //停止
			//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"485窗帘控制标志位：停止\r\n");
			Rs485CurtainInfo.DooYaCon_data.COMMAND=0x03;
			Rs485CurtainInfo.DooYaCon_data.DATE=CUR_STOP;
			Rs485CurtainInfo.control_flag=0x06;
			Rs485CurtainInfo.DYCurtainStateLast=Rs485CurtainInfo.DYCurtainState;
			Rs485CurtainInfo.DYCurtainState=0x06;
			break;
		
	}
	
	BUS_Public.check = 0x00;
	BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485CurtainInfo, sizeof(RS485_Cur_INFO));
	SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
	SRAM_DMA_Write_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);

}


/*******************************************************************************
* Function Name : DYCurtain_Loop_State
* Description   : 485窗帘设备状态获得
* Input         : 
  DevOutputLoop : 暂未使用
  devaddr       : 设备地址
* Return        : DYCurtainState  开:0x01  关:0x02  停:0x06    
*******************************************************************************/

uint16_t DYCurtain_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop)
{	
	RS485_Cur_INFO 	Rs485CurtainInfo;       //窗帘局部变量

	if(devaddr == 0x00)
		return 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485CurtainInfo,sizeof(RS485_Cur_INFO),devaddr+Dev_Privately);	

//	if(Rs485CurtainInfo.DevCurtainDelayState != 0x00)
//	{
//		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"当前窗帘处于延时控制 %d\r\n",DevCurtainInfo.DevCurtainDelayState);
//		return Rs485CurtainInfo.DevCurtainDelayState;
//	}
//	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"当前窗帘处于 %d\r\n",DevCurtainInfo.DevCurtainState);
	return Rs485CurtainInfo.DYCurtainState;
}


/*******************************************************************************
* Function Name : Cur_ConDataSend
* Description   : 485窗帘设备数据打包(数据长度7)
* Input         : 
  port          : 端口
  data          : 控制内容
  command       : 控制命令   读：0x01    写：0x02   控制：0x03     请求：0x04
* Return        : void  
*******************************************************************************/

void Cur_ConDataSend(uint8_t port,uint8_t data,uint8_t dev_addr,uint8_t command)
{

	uint8_t SendBuff[COMMCON_LEN];
	
	SendBuff[0]=StartCode;
	
	SendBuff[1]=dev_addr;
	
	SendBuff[2]=DEVIDH;
	
	SendBuff[3]=command;
	
	SendBuff[4]=data;
	
	NetCRC16(SendBuff,COMMCON_LEN);    
	
	MCU485_SendString(port,SendBuff,COMMCON_LEN);
	
}


/*******************************************************************************
* Function Name : Cur_ConDataSend2
* Description   : 485窗帘设备数据打包(数据长度8)
* Input         : 
  port          : 端口
  data          : 控制内容
  command       : 控制命令   读：0x01    写：0x02   控制：0x03     请求：0x04
* Return        : void  
*******************************************************************************/

void Cur_ConDataSend2(uint8_t port,uint8_t data,uint8_t data2,uint8_t dev_addr,uint8_t commcod)
{
	uint8_t SendBuff[8];
	
	SendBuff[0]=StartCode;
	
	SendBuff[1]=dev_addr;
	
	SendBuff[2]=DEVIDH;
	
	SendBuff[3]=commcod;
	
	SendBuff[4]=data;
	
	SendBuff[5]=data2;
	
	NetCRC16(SendBuff,8);    
	
	MCU485_SendString(port,SendBuff,8);
	
}


/*******************************************************************************
* Function Name : Cur_ReqDataSend
* Description   : 485窗帘设备数据打包(数据长度10),地址设置
* Input         : 
  port          : 端口
  data          : 控制内容
  command       : 控制命令   读：0x01    写：0x02   控制：0x03     请求：0x04
* Return        : void  
*******************************************************************************/

void Cur_ReqDataSend(uint8_t port,uint8_t dev_addr,uint8_t commcod)
{
	uint8_t SendBuff[10];
	
	SendBuff[0]=StartCode;
	
	SendBuff[1]=0x00;
	
	SendBuff[2]=0x00;
	
	SendBuff[3]=commcod;
	
	SendBuff[4]=0x00;
	
	SendBuff[5]=0x02;
	
	SendBuff[6]=dev_addr;
	
	SendBuff[7]=DEVIDH;
	
	NetCRC16(SendBuff,10);    
	
	MCU485_SendString(port,SendBuff,10);
	
}



