/**
  ******************************************************************************
  * @file    BLV_Nor_Dev_SceneRestore.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2025年01月04日
  * @brief   场景还原   
  ******************************************************************************
  */
  
#include "includes.h"


#include "BLV_Nor_DevFun.h"
#include "BLV_Nor_Dev_CurtainFun.h"

/*本地函数申明开始*/
void Dev_SceneRestore_Dis(uint32_t DevAddr);

uint16_t SceneRestore_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop);
void BLW_SceneRestore_Control_State(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t devaddr,uint16_t DevOutputLoop,uint16_t start);
uint8_t Dev_SceneRestore_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType);
void Scene_State_Save(DEV_ACTION_INFO *DevActionInfo,NOR_SRESTORE_INFO *DevSRestoreInfo);
void DevAction_ReStore_Ctrl(NOR_SRESTORE_INFO *DevSRestoreInfo);
/*本地函数申明结束*/




/*******************************************************************************
* Function Name  : BLV_Nor_Dev_SceneRestore_For_Logic_Init 
* Description    : 场景还原初始化信息来自逻辑文件
* Parameter      : 逻辑数据
*******************************************************************************/
void BLV_Nor_Dev_SceneRestore_For_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	NOR_SRESTORE_INFO DevSRestoreInfo;       
	
	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&DevSRestoreInfo,0,sizeof(NOR_SRESTORE_INFO));
	
	BUS_Public.addr = dev_info->addr;			//设备地址
	BUS_Public.type = dev_info->type;		    //设备类型
	BUS_Public.port = dev_info->port;			//设备发送端口
	BUS_Public.baud = 0000;			            //设备发送波特率

	BUS_Public.DevFunInfo.Dev_Data_Process = Dev_SceneRestore_Dis;                 
	BUS_Public.DevFunInfo.Dev_Input_Type_Get = Dev_SceneRestore_InType_Get;        
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = BLW_SceneRestore_Control_State;        
	//BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = SceneRestore_Loop_State;  

	DevSRestoreInfo.SceneOpenNo = dev_info->priproperty[0] + (dev_info->priproperty[1] << 8);
	DevSRestoreInfo.SceneCloseNo = 	dev_info->priproperty[2] + (dev_info->priproperty[3] << 8);
	
	DevSRestoreInfo.LoopValidNum = dev_info->output_num;
	DevSRestoreInfo.SceneState = 0x02;			//上电默认场景为关状态
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"SceneRestore SceneOpenNo:%d   SceneCloseNo:%d",DevSRestoreInfo.SceneOpenNo,DevSRestoreInfo.SceneCloseNo);

	Add_Nor_Device_To_List2(&BUS_Public,(uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO));
}


/**
  * @name  回路状态得到
  * @param  
  *    devaddr             当前设备的地址
  *    DevOutputLoop       需要查找的回路 从0开始
  * @retval 
  *    ret                 回路状态返回    1 开   2关
  * @brief
  */
uint16_t SceneRestore_Loop_State(uint32_t devaddr, uint16_t DevOutputLoop)
{
	Device_Public_Information_G BUS_Public;	
	NOR_SRESTORE_INFO DevSRestoreInfo;       
	
//	uint8_t keepflag = 0x00;
	
	if(devaddr == 0x00)	return 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);	//拷贝所有共有数据
	SRAM_DMA_Read_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),devaddr+Dev_Privately);	
	
	
	if(DevOutputLoop >= DevSRestoreInfo.LoopValidNum)
	{
		return 0x00;
	}
	
	
	DEV_ACTION_INFO DevActionInfo;     //配置中设备动作全部信息  
	
	if(DevSRestoreInfo.SceneOpenAddr == 0x00)
	{
		DevSRestoreInfo.SceneOpenAddr = DevAction_No_Get(DevSRestoreInfo.SceneOpenNo);
	}
	
	if(DevSRestoreInfo.SceneOpenAddr != NULL)
	{
		SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), DevSRestoreInfo.SceneOpenAddr);   //完整拷贝设备动作信息 
	
		DevAction_State_Get(&DevActionInfo);//当前场景状态更新 
	}
	
	return DevActionInfo.DevActionState.SceneState;
}



/*******************************************************************************
* Function Name  : BLW_SceneRestore_Control_State 
* Description    : 状态控制函数
* Input          : 
* devaddr	     : 设备信息地址
* Return         : 无
* attention      : temp1非0才会进行保存
*******************************************************************************/
void BLW_SceneRestore_Control_State(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t devaddr,uint16_t DevOutputLoop,uint16_t start)
{
	uint8_t temp1 = 0; 
	Device_Public_Information_G BUS_Public;   //共用	
	NOR_SRESTORE_INFO DevSRestoreInfo;      
	
	uint8_t ctrlmode = 0, content = 0;
	
	if(devaddr == 0x00)	return;
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),devaddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),devaddr+Dev_Privately);


	if(DevOutputLoop >= DevSRestoreInfo.LoopValidNum)
	{
		return ;
	}
	
	ctrlmode = start & 0xff;
	content = (start >> 8) & 0xff;
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"SceneRestore Ctrl:%02X Content:%2X",ctrlmode,content);
	
	switch(ctrlmode)
	{
		case 0x01:       //场景开
			DevSRestoreInfo.SceneState = 0x01;
			DevSRestoreInfo.SceneCtrlFlag = 0x01;
			temp1++;
			break;
		case 0x02:       //场景关
			DevSRestoreInfo.SceneState = 0x02;
			DevSRestoreInfo.SceneCtrlFlag = 0x01;
			temp1++;
			break;
		case 0x03:       //清除记忆
			DevSRestoreInfo.StateSaveFlag = 0x00;
			DevSRestoreInfo.SaveNum = 0x00;
			temp1++;
			break;
	    case 0x04:       //温控相对调节
			if( ((content & 0x0f) >=1)  && ((content & 0x0f) <=15) )
			{
				DevSRestoreInfo.TempInf[((content >> 4) & 0x0f) - 1].Addr = (content >> 4) & 0x0f;
				DevSRestoreInfo.TempInf[((content >> 4) & 0x0f) - 1].Temp = content & 0x0f;
				DevSRestoreInfo.TempInfFlag[((content >> 4) & 0x0f) - 1] = 0x01;
				temp1++;
			}
			break;
	}
	
	
	if(temp1 != 0x00)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&DevSRestoreInfo, sizeof(NOR_SRESTORE_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);   /*将数据保存进入SRAM中*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),devaddr+Dev_Privately);
	}	
}


/**
*@name 输入检测函数
*@para
*  DevAddr      设备地址
*  DevInputLoop 回路输入地址  范围0~LoopValidNum  
*  DevInputType 输入类型
*/

uint8_t Dev_SceneRestore_InType_Get(uint32_t DevAddr, uint16_t DevInputLoop, uint16_t DevInputType)
{
	Device_Public_Information_G BUS_Public;   //共用
	NOR_SRESTORE_INFO DevSRestoreInfo;      
	uint8_t Ret = CtrlInvalid;                //控制无效

	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),DevAddr+Dev_Privately);	/*拷贝设备私有信息*/
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"Dev_SceneRestore_InType_Get Loop:%d  Ctrl:%04X",DevInputLoop,DevInputType);
	
	if(DevInputLoop >= DevSRestoreInfo.LoopValidNum)
	{
		return Ret;
	}

	switch(DevInputType)
	{
		case 0x01:
		case 0x02:
			if(DevInputType == DevSRestoreInfo.DevAction)
			{
				DevSRestoreInfo.DevAction = NULL;
				Ret = CtrlValid;
			}
			break;
	}
	

	if(CtrlValid == Ret)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原动作清空");

		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&DevSRestoreInfo, sizeof(NOR_SRESTORE_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),DevAddr+Dev_Privately);
			
	}
	
	return Ret;
	
}


/**
*@name 回路扫描函数
*@para
*  DevAddr      设备地址
*@brief 拿到回路的状态，并转换为动作
*/

void Dev_SceneRestore_Dis(uint32_t DevAddr)
{
	Device_Public_Information_G BUS_Public;   //共用	
	NOR_SRESTORE_INFO DevSRestoreInfo;        //私有属性局部变量
	
	DEV_ACTION_INFO DevActionInfo;            //配置中设备动作全部信息 
	
	uint8_t KeepFlag = 0x00;
	
	uint8_t refresh = 0x00;
	
	uint32_t dev_addr = 0x00;
	Device_Public_Information_G BUS_PublicOut;   //共用	
	RS485_TEMP_INFO Rs485Temp;
	
	
	if(NULL == DevAddr)
	{
		return ;
	}
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddr);	//拷贝所有共有数据	
	SRAM_DMA_Read_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),DevAddr+Dev_Privately); 
	
	if(DevSRestoreInfo.OpenAddrGetFlag == 0x00)
	{
		DevSRestoreInfo.SceneOpenAddr = DevAction_No_Get(DevSRestoreInfo.SceneOpenNo);
		DevSRestoreInfo.OpenAddrGetFlag = 0x01;
		KeepFlag = 0x01;
	}
	
	if(DevSRestoreInfo.CloseAddrGetFlag == 0x00)
	{
		DevSRestoreInfo.SceneCloseAddr = DevAction_No_Get(DevSRestoreInfo.SceneCloseNo);
		DevSRestoreInfo.CloseAddrGetFlag = 0x01;
		KeepFlag = 0x01;
	}
	
	
	
	if(DevSRestoreInfo.SceneCtrlFlag == 0x01)
	{
		DevSRestoreInfo.SceneCtrlFlag = 0x00;
	
		/*1.获取当前场景的状态*/
		/*2.1如果当前场景是开，则先执行场景状态保存，然后执行场景关*/
		/*2.2如果当前场景是关，且之前有记忆状态，则执行恢复场景状态*/
		if(DevSRestoreInfo.SceneOpenAddr != NULL)
		{
			SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), DevSRestoreInfo.SceneOpenAddr);   //完整拷贝设备动作信息 
		
			if(DevSRestoreInfo.SceneState == DEV_STATE_CLOSE)
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原：执行保存并关闭");
				
				DevSRestoreInfo.SaveNum = 0x00;      //保存前，先清除之前保存动作
				
				Scene_State_Save(&DevActionInfo,&DevSRestoreInfo);
				
				if(DevSRestoreInfo.SceneCloseAddr == 0x00)      //没有配置关动作就默认执行关
				{
					DevAction_ExpandClose(&DevActionInfo, NOR_MODE_CTRL);
				}
				else
				{
					DevSRestoreInfo.DevAction = DevSRestoreInfo.SceneState;
				}
				
				DevSRestoreInfo.StateSaveFlag = 0x01;
				
				refresh = 0x01;
			}
			if(DevSRestoreInfo.SceneState == DEV_STATE_OPEN)
			{
				if(DevSRestoreInfo.StateSaveFlag == 0x01)
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原：执行场景还原");
					
					DevAction_ReStore_Ctrl(&DevSRestoreInfo);
					
					DevSRestoreInfo.SaveNum = 0x00;
					DevSRestoreInfo.StateSaveFlag = 0x00;
					
					refresh = 0x01;
				}
				else if(DevSRestoreInfo.StateSaveFlag == 0x00)
				{
					/*之前没有记忆状态，执行配置的动作*/
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原：无记忆状态，执行默认动作");
					
					DevSRestoreInfo.DevAction = DevSRestoreInfo.SceneState;
				}
			}
			
			if(refresh == 0x01)
			{
				DevAction_State_Get(&DevActionInfo); //当前场景状态更新   结合所有设备输出去判断

				if(DevActionInfo.DevActionState.SceneStateLast != DevActionInfo.DevActionState.SceneState)   //场景状态改变
				{
					DevActionInfo.DevActionState.SceneStateLast = DevActionInfo.DevActionState.SceneState;
					DevAction_IndicateCtrl(&DevActionInfo);/*控制反馈灯*/
					
					DevActionInfo.CheckVal = 0x00;
					DevActionInfo.CheckVal = CheckSum((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO)); //
					SRAM_DMA_Write_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), DevSRestoreInfo.SceneOpenAddr); 
				}
			}
		}
		

		KeepFlag = 0x01;
	}
	
	
	for(uint8_t i = 0; i < SCENE_TEMP_LIST_MAX; i++)
	{
		if(DevSRestoreInfo.TempInfFlag[i] == 0x01)
		{
			DevSRestoreInfo.TempInfFlag[i] = 0x00;
			
			uint8_t temp_ctrl = 0x00;
			uint16_t temp = 0x00;
			
			dev_addr = Find_AllDevice_List_Information(DEV_RS485_TEMP,DevSRestoreInfo.TempInf[i].Addr);
			
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原 控制空调%d：%d  Addr:%04X",i,DevSRestoreInfo.TempInf[i].Addr,dev_addr);
			
			if(dev_addr != NULL)
			{
				SRAM_DMA_Read_Buff((uint8_t *)&BUS_PublicOut,sizeof(Device_Public_Information_G),dev_addr);	//拷贝所有共有数据	
				SRAM_DMA_Read_Buff((uint8_t *)&Rs485Temp,sizeof(RS485_TEMP_INFO),dev_addr+Dev_Privately);
				if(Rs485Temp.TemState.mode == TEMP_COLD)
				{
					if((Rs485Temp.TemState.set_t != 0x00) && ((DevSRestoreInfo.TempInf[i].Temp  + Rs485Temp.TemState.set_t) <= 32))
					{
						temp = DevSRestoreInfo.TempInf[i].Temp + Rs485Temp.TemState.set_t;
						temp_ctrl = 0x01;
						DevSRestoreInfo.TempInf[i].SetTemp = temp;
					}
				}
				else if(Rs485Temp.TemState.mode == TEMP_HOT)
				{
					if((Rs485Temp.TemState.set_t != 0x00) && (Rs485Temp.TemState.set_t - DevSRestoreInfo.TempInf[i].Temp >= 16))
					{
						temp = Rs485Temp.TemState.set_t - DevSRestoreInfo.TempInf[i].Temp;
						temp_ctrl = 0x01;
					}
					else if(Rs485Temp.TemState.set_t == 0x00)
					{
						temp = 32 - DevSRestoreInfo.TempInf[i].Temp;
						temp_ctrl = 0x01;
					}
					DevSRestoreInfo.TempInf[i].SetTemp = temp;
				}
				
				if(temp_ctrl == 0x01)
				{
					//直接修改温控器的温度，而不是调用Dev_TEMPCTRL_Ctrl()函数		2025-11-20
					Rs485Temp.TemStateCtrl.set_t = temp;
					Rs485Temp.Carbon_Set_Temp = temp;
					
					BUS_PublicOut.check = 0x00;
					BUS_PublicOut.check = DoubleData_CheckSum((uint8_t *)&BUS_PublicOut, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485Temp, sizeof(RS485_TEMP_INFO));
					SRAM_DMA_Write_Buff((uint8_t *)&BUS_PublicOut, sizeof(Device_Public_Information_G),dev_addr);
					SRAM_DMA_Write_Buff((uint8_t *)&Rs485Temp,sizeof(RS485_TEMP_INFO),dev_addr+Dev_Privately);
					
					//Dev_TEMPCTRL_Ctrl(0x00, 0x00, dev_addr, 0x00, temp);
				}
			}
			
			KeepFlag = 0x01;
		}
	}
	
	

	if(0x01 == KeepFlag)
	{
		//Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"DevSRestoreInfo Save!!! ");
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&DevSRestoreInfo, sizeof(NOR_SRESTORE_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&DevSRestoreInfo,sizeof(NOR_SRESTORE_INFO),DevAddr+Dev_Privately);		
	}
	
}



void Scene_State_Save(DEV_ACTION_INFO *DevActionInfo,NOR_SRESTORE_INFO *DevSRestoreInfo)
{
	uint8_t i;//,j;

	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	uint8_t DevCtrlWay;     //执行方式
	uint8_t DevCtrlCont;    //执行内容
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)  
	{
		if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行才参与反馈灯判断
		{
			DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，当前设备判断:类型:%d 回路:%d，控制状态:%04X",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//	
			if(NULL != DevAddrOut)   //地址非空
			{
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case Dev_Host_HVout:
					case Dev_Host_LVoutput:
					case DEV_RS485_CURTAIN:
					#if RS485_PB20_Relay_Flag
					case Dev_Rs485_PB20_Relay:
					#endif
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							if((DEV_CTRLWAY_OPEN == DevCtrlWay)
								||(DEV_CTRLWAY_CLOSE == DevCtrlWay)
								||(DEV_CTRLWAY_STOP == DevCtrlWay)
								)   //且控制状态 为开和关
							{
								if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
								{
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
									
									
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"保存的设备类型:%d 地址:%d 回路:%d，控制状态:%04X",\
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType,\
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr, \
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop, \
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState);	
									
									DevSRestoreInfo->SaveNum++;
								}
							}
						}
						break;
					#if RS485_LED_Flag
					case DEV_RS485_PWM:   //PWM调光
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							if((DEV_CTRLWAY_OPEN == DevCtrlWay)
								||(DEV_CTRLWAY_CLOSE == DevCtrlWay)
							)
							{
								if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
								{
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DevCtrlWay;
									DevCtrlCont = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
									if(DevCtrlCont != 0x00)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DEV_CTRLWAY_OPEN;
									}
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
									DevSRestoreInfo->SaveNum++;
								}
							}
						}
						break;
					#endif
					#if Dev_Nor_ColorTemp
					case DEV_Virtual_ColorTemp:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据					
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							DevCtrlCont = ((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)>>8)&0x00ff;  //高字节
							
							if((DevCtrlWay == 0x01) || (DevCtrlWay == 0x02) )
							{
								if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
								{
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DevCtrlWay;
									DevCtrlCont = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
									if(DevCtrlCont != 0x00)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DEV_CTRLWAY_OPEN;
									}
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
									DevSRestoreInfo->SaveNum++;
								}
							}
						}
						break;
					#endif
					#if C8_TYPE
					case Dev_Rs485_PB20:
					case Dev_Rs485_PB20_LD:
					case Dev_Rs485_PB20_LS:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据					
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							uint8_t CtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState & 0x00ff);  //低字节
							DevCtrlCont = ((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState) >> 8) & 0x00ff;  //高字节
							switch(CtrlWay)
							{
								case PB20_Strip_OnlyBright:
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = CtrlWay;
										DevCtrlCont = (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f);
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
										DevSRestoreInfo->SaveNum++;
									}												
									break;
								case PB20_Strip_OnlySwitch:
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = CtrlWay;
										DevCtrlCont = ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7);
										if(DevCtrlCont == 0x00)
										{
											DevCtrlCont = 0x02;
										}
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
										DevSRestoreInfo->SaveNum++;
									}	
									break;
								case PB20_Strip_LIGHT_OPEN:
								case PB20_Strip_LIGHT_CLOSE:
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										CtrlWay = ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7);
										if(CtrlWay == 0x00)
										{
											CtrlWay = 0x02;
										}
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = CtrlWay;
										DevCtrlCont = (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f);
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
										DevSRestoreInfo->SaveNum++;
									}
									break;
								default:break;
							}
							
						}
						break;
					#endif
					case DEV_RS485_TEMP:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							TemState_Struct TemState;
							TemCtrl ctrlstate;
							memset(&TemState,0,sizeof(TemState_Struct));
							memset(&ctrlstate,0,sizeof(TemCtrl));
							uint16_t g_state = 0x00;
							
							if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
							{
								DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
								DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
								DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
								g_state = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
								
								TemState.on_off = (g_state >> 15) & 0x01;
								TemState.mode = (g_state >> 13) & 0x03;
								TemState.fan = (g_state >> 11) & 0x03;
								TemState.valve = (g_state >> 10) & 0x01;
								TemState.set_t = (g_state >> 5) & 0x1f;
								TemState.indoor_t = g_state & 0x1f;
								
								ctrlstate.on_off = TemState.on_off;
								ctrlstate.mode = TemState.mode;
								ctrlstate.fan = TemState.fan;
								ctrlstate.valve = TemState.valve;
								if(TemState.set_t == 0x00)
								{
									ctrlstate.set_t = 32;
								}
								else 
								{
									ctrlstate.set_t = TemState.set_t;
								}
								
								DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = (*((uint16_t *)&ctrlstate));
								DevSRestoreInfo->SaveNum++;
							}
						}
						break;
					#if RS485_FloorHeat_Flag
					case DEV_RS485_HEATER:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							if(BUS_Public.Protocol == ENUM_RS485_DEV_PRO_01)
							{
								if((DevCtrlWay == FLOORHEAT_ON_OFF_FUNCTION) || (DevCtrlWay == FLOORHEAT_SET_OC_FUNCTION))
								{
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DevCtrlWay;
										if(DevCtrlWay == FLOORHEAT_ON_OFF_FUNCTION)
										{
											DevCtrlCont = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0xff;
										}
										else if(DevCtrlWay == FLOORHEAT_SET_OC_FUNCTION)
										{
											DevCtrlCont = (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) >> 8) & 0xff;
										}
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
										DevSRestoreInfo->SaveNum++;
									}
								}
							}
							else if(BUS_Public.Protocol == ENUM_RS485_DEV_PRO_02)
							{
								if((DevCtrlWay == 0x00) || (DevCtrlWay == 0x01))
								{
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
										DevSRestoreInfo->SaveNum++;
									}
								}
							}
						}
						break;
					#endif
					#if RS485_FreshAir_Flag
					case DEV_RS485_FreshAir:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							if(BUS_Public.Protocol == ENUM_RS485_DEV_PRO_01)
							{
								if((DevCtrlWay == FRESHAIR_ON_OFF_FUNCTION) || (DevCtrlWay == FRESHAIR_WIND_VELOCITY_FUNCTION))
								{
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = DevCtrlWay;
										if(DevCtrlWay == FRESHAIR_ON_OFF_FUNCTION)
										{
											DevCtrlCont = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0xff;
										}
										else if(DevCtrlWay == FRESHAIR_WIND_VELOCITY_FUNCTION)
										{
											DevCtrlCont = (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) >> 8) & 0xff;
										}
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState |= (DevCtrlCont << 8);
										DevSRestoreInfo->SaveNum++;
									}
								}
							}
							else if(BUS_Public.Protocol == ENUM_RS485_DEV_PRO_02)
							{
								if((DevCtrlWay == 0x00) || (DevCtrlWay == 0x01))
								{
									if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
									{
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
										DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
										DevSRestoreInfo->SaveNum++;
									}
								}
							}
						}
						break;
					#endif
					case Dev_NodeCurtain:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
//						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlWay = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)&0x00ff;        //低字节
							if((DEV_CTRLWAY_OPEN == DevCtrlWay)
								||(DEV_CTRLWAY_CLOSE == DevCtrlWay)
								)   //且控制状态 为开和关
							{
								if(DevSRestoreInfo->SaveNum < SAVE_DEV_LOOP_MAX)
								{
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevType = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevAddr = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevOutputLoop = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
									DevSRestoreInfo->SaveAction[DevSRestoreInfo->SaveNum].DevCtrlState = Curtain_Loop_Save_State(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);
									DevSRestoreInfo->SaveNum++;
								}
							}
						}
						break;
				}
			}

		}
	}

}





void DevAction_ReStore_Ctrl(NOR_SRESTORE_INFO *DevSRestoreInfo)
{
	for(uint8_t i = 0; i < DevSRestoreInfo->SaveNum; i++)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景还原,动作：%d：", i);
		Dbg_Print_Buff(DBG_BIT_LOGIC_STATUS_bit,"控制数据：",(uint8_t*)&DevSRestoreInfo->SaveAction[i],6);
		DevActionCtrl((uint8_t*)&DevSRestoreInfo->SaveAction[i],6);
	}
}

