
/**
  ******************************************************************************
  * @file    BLV_Dev_Action.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2021年10月25日
  * @brief  
	* 动作链表需要一个一个新增，动作的输出设备，如果带延时功能，需要新增延时设备链表
	* 动作可以调用所有设备的输入与输出   能控制所有设备，能得到所有设备的状态
	*	逻辑运行：
	*1，通过设备存在添加函数，将所有设备按照总线设备，轮询设备，主动设备，特殊设备添加到外部SRAM。
	*2，通过设备动作添加函数，将所有动作添加到外部SRAM。
	*3，主循环调用动作扫描函数，按照设备存在分类，只要设备产生输入动作，条件满足，就执行输出。
	*
	* @log 20220510      SongHan DevActionCtrl  远程控制睡眠场景，直接将控制方式置位关
	*      20220513      SongHan 同步配置文件功能
	*      202205261700  SongHan C12Dimming_CH_MAX替换成 LED_OUT_CH_MAX
	*			 20220903      yhf     解决继电器和调光设备地址限制问题
  ******************************************************************************
  */



#include "includes.h"

#include "BLV_Dev_Action.h"
#include "string.h"
#include "BLV_Logic_Edit.h"
//#include "BLV_Nor_DevFun.h"

/*普通设备驱动头文件开始*/
#include "BLV_Nor_Dev_ServiceFun.h"
#include "BLV_Nor_Dev_LVinputFun.h"
#include "BLV_Nor_Dev_LVoutputFun.h"
#include "BLV_Nor_Dev_HVoutFun.h"

/*普通设备驱动头文件结束*/

#define ComCondNumMax   17    //条件判断个数
#define CondIsPass      0x01  //条件通过
#define CondIsNotPass   0x00  //条件不通过

BLV_DevAction_Manage_G  DevActionGlobal;   //设备信息全局变量  添加设备时，初始化清空

void Add_DevAction_To_List(DEV_ACTION_INFO *DevAction_Info);
void BLV_DevAction_Cycle(uint32_t Dev_processing_addr, Device_Public_Information_G *BUS_Public);  
uint8_t DevAction_CheckSum(uint32_t addr,uint16_t len);
uint8_t Dev_HVout_State_Get(uint32_t DevAddrOut, uint16_t DevOutputLoop);
void Dev_Action_Output_DataGet(DEV_ACTION_INFO *DevAction_Info, uint8_t *DevCtrlBuf);
void Dev_HVout_Ctrl(uint32_t DevAddrIn, uint16_t DevInputLoop, uint32_t DevAddrOut, uint16_t DevOutputLoop, uint16_t DevOutputType);

void RcuLockState_Scan(void);
#if LOGIC_FILE_EN 
uint8_t CondJudge(uint8_t State1, uint8_t State2);
#else
uint8_t CondJudge(uint8_t Flag, uint8_t State1, uint8_t State2);
#endif
void DevAction_DevAddr_Ctrl(uint32_t DevActionAddr, uint8_t Mode, uint8_t SceneMode, uint16_t CtrlState);
void DevAction_DevAddr_CtrlClose(uint32_t DevActionAddr, uint8_t Mode, uint8_t SceneMode, uint16_t CtrlState);

void DevAction_No_Ctrl(uint16_t DevActionNo, uint8_t Mode, uint16_t CtrlState);
uint8_t DevAddrCtr(DEV_ACTION_INFO *DevActionInfo, uint8_t *p, uint8_t DataLen);

/*延时设备相关函数申明开始*/
void DevDly_InfoSet(uint32_t DevDlyAddr, uint8_t DlyExcuteFlag, uint16_t DevOutputType, Dev_Dly_Value DevDelayTime, uint8_t DlyBlinkFlag);
void DevDly_Add(DEV_ACTION_INFO *DevAction_Info);
uint32_t Add_DevDly_To_List(uint8_t DevType, uint32_t DevDlyAddr, uint16_t DevOutputLoop);
uint32_t DevDlyAddr_Get(uint32_t DevDlyAddr, uint16_t DevOutputLoop);

/*延时设备相关函数申明结束*/


void Expand_And_Dimm_Action_Get(DEV_ACTION_INFO *DevActionInfo,EXPAND_TYPE_G *expand_type,DIMM_TYPE_G *dimm_type,uint8_t on_off)
{
	uint8_t TNum=0;    //地址相同计数
	uint8_t i,j;
	
	uint8_t expandexnum=0;        //继电器存在计数
	#if RS485_LED_Flag
	uint8_t dimmexnum=0;          //调光存在计数
	#endif
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"******遍历动作地址开始******");
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)       //添加不同地址的继电器和调光到设备临时列表
	{
		if(expandexnum==0&&Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			expand_type[expandexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器地址1:%d", expand_type[expandexnum].Addr);
			expandexnum++;
		}
		else if(expandexnum>0&&Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			for(j=0;j<=expandexnum;j++)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr==expand_type[j].Addr)
				{
					TNum++;
					break;
				}
			}
			if(TNum==0)
			{
				expand_type[expandexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器增加不同地址到列表:%d", expand_type[expandexnum].Addr);
				expandexnum++;
			}
			else if(TNum>0)
			{
				TNum=0;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器地址相同不增加到列表");
			}
		}
		
		#if RS485_LED_Flag
		if(dimmexnum==0&&DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			dimm_type[dimmexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光地址1:%d", dimm_type[dimmexnum].Addr);
			dimmexnum++;
		}
		else if(dimmexnum>0&&DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			for(j=0;j<=dimmexnum;j++)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr==dimm_type[j].Addr)
				{
					TNum++;
					break;
				}
			}
			if(TNum==0)
			{
				dimm_type[dimmexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光增加不同地址到列表:%d", dimm_type[dimmexnum].Addr);
				dimmexnum++;
			}
			else if(TNum>0)
			{
				TNum=0;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光地址相同不增加到列表");
			}
		}
		#endif
	}
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"******遍历动作地址结束******");

	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第一次遍历，将相同的设备放到一起
	{
		if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行才参与反馈灯判断
		{
			if(Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)   //扩展板  
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop < HVoutNumMAX)
				{
					for(uint8_t j=0;j<30;j++)
					{
						if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
						{
							expand_type[j].ExpandReadFlag|= 0x01<<DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
							if(on_off==0x01)
							{
								expand_type[j].ExpandReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop]= DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState;
							}
							else if(on_off==0x00)
							{
								expand_type[j].ExpandReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop]= DEV_CTRLWAY_CLOSE;
							}
							break;
						}
					}
				}
			}
			
			
			#if RS485_LED_Flag
			else if(DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop < LED_OUT_CH_MAX)
				{
					for(uint8_t j=0;j<30;j++)
					{
						if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
						{
							dimm_type[j].DimmReadFlag |= 0x01<<DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
							if(on_off==0x01)
							{
								dimm_type[j].DimmReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop] = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState;
							}
							else if(on_off==0x00)
							{
								dimm_type[j].DimmReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop] = DEV_CTRLWAY_CLOSE;
							}
							
							break;
						}
					}
				}
			}
			#endif
		}
	}
	
}

void Expand_And_Dimm_Action_Get2(DEV_ACTION_INFO *DevActionInfo,EXPAND_TYPE_G *expand_type,DIMM_TYPE_G *dimm_type,uint8_t on_off)
{
	uint8_t TNum=0;    //地址相同计数
	uint8_t i,j;
	
	uint8_t expandexnum=0;        //继电器存在计数
	#if RS485_LED_Flag
	uint8_t dimmexnum=0;          //调光存在计数
	#endif
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"******遍历动作地址开始******");
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)       //添加不同地址的继电器和调光到设备临时列表
	{
		if(expandexnum==0&&Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			expand_type[expandexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器地址1:%d", expand_type[expandexnum].Addr);
			expandexnum++;
		}
		else if(expandexnum>0&&Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			for(j=0;j<=expandexnum;j++)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr==expand_type[j].Addr)
				{
					TNum++;
					break;
				}
			}
			if(TNum==0)
			{
				expand_type[expandexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器增加不同地址到列表:%d", expand_type[expandexnum].Addr);
				expandexnum++;
			}
			else if(TNum>0)
			{
				TNum=0;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器地址相同不增加到列表");
			}
		}
		
		#if RS485_LED_Flag
		if(dimmexnum==0&&DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			dimm_type[dimmexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光地址1:%d", dimm_type[dimmexnum].Addr);
			dimmexnum++;
		}
		else if(dimmexnum>0&&DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
		{
			for(j=0;j<=dimmexnum;j++)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr==dimm_type[j].Addr)
				{
					TNum++;
					break;
				}
			}
			if(TNum==0)
			{
				dimm_type[dimmexnum].Addr=DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光增加不同地址到列表:%d", dimm_type[dimmexnum].Addr);
				dimmexnum++;
			}
			else if(TNum>0)
			{
				TNum=0;
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光地址相同不增加到列表");
			}
		}
		#endif
	}
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"******遍历动作地址结束******");

	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第一次遍历，将相同的设备放到一起
	{
		if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行才参与反馈灯判断
		{
			if(Dev_Host_HVout == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)   //扩展板  
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop < HVoutNumMAX)
				{
					for(uint8_t j=0;j<30;j++)
					{
						if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
						{
							expand_type[j].ExpandReadFlag|= 0x01<<DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
							if(on_off==0x01)
							{
								expand_type[j].ExpandReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop]= DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState;
							}
							else if(on_off==0x00)
							{
								expand_type[j].ExpandReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop]= DEV_CTRLWAY_CLOSE;
							}
							break;
						}
					}
				}
			}
			
			
			#if RS485_LED_Flag
			else if(DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop < LED_OUT_CH_MAX)
				{
					for(uint8_t j=0;j<30;j++)
					{
						if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
						{
							dimm_type[j].DimmReadFlag |= 0x01<<DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop;
							if(on_off==0x01)
							{
								dimm_type[j].DimmReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop] = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState;
							}
							else if(on_off==0x00)
							{
								dimm_type[j].DimmReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop] = DEV_CTRLWAY_CLOSE;
							}
							else if(on_off==0x02)    //2024-01-25
							{
								uint32_t inputaddr = 0;
								Device_Public_Information_G Public_Input;
								
								inputaddr = Find_AllDevice_List_Information2(Active_Port,DevActionInfo->DevActionInput.DevType,DevActionInfo->DevActionInput.DevAddr);
								if(inputaddr != NULL)
								{
									RS485_SWI_INFO RotaryInfo;       //开关局部变量
									SRAM_DMA_Read_Buff((uint8_t *)&Public_Input,sizeof(Device_Public_Information_G),inputaddr);	
									if(Public_Input.type == Dev_Rs458_RotaryCtrl)
									{
										SRAM_DMA_Read_Buff((uint8_t *)&RotaryInfo,sizeof(RS485_SWI_INFO),inputaddr+Dev_Privately);
										DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0xff;
										if(DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
										{
											DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[0] << 8);
										}
									}
									else if((Public_Input.type == DEV_RS485_PWM) && (Public_Input.Protocol == 0x03))
									{
										RS485_LED_INFO LEDInfo;          //LED局部变量
										SRAM_DMA_Read_Buff((uint8_t *)&LEDInfo,sizeof(RS485_LED_INFO),inputaddr+Dev_Privately);
										DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0xff;
										if(DEV_RS485_PWM == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
										{
											DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (LEDInfo.DevRecBuf[DevActionInfo->DevActionInput.inAddr] << 8);
										}
									}
								}
								
								dimm_type[j].DimmReadState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop] = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState;    
							}
							break;
						}
					}
				}
			}
			#endif
		}
	}
	
}


/**
*@name  BLV_DevAction_Task
*@para  无
*@brief  1，遍历所有带事件的设备  称之为输入节点
*        2，找到一个输入节点之后，就拿着这个输入节点去遍历所有的动作
*        3，找到拥有相同的输入节点的动作，就去判断有没有产生事件，若产生事件，就执行输出，再跳出
*@attention  拥有相同的输入节点的设备，他们的  BUS_Public->ActionCoord 即动作下标一样
*@call 主循环调用
*/
void BLV_DevAction_Task(void)
{
	static uint32_t dev_action_processing_tick = 0;
//	uint32_t action_processing_addr;// 
	uint32_t Dev_processing_addr;
	Device_Public_Information_G BUS_Public;   //公有全局数据
	uint8_t BreakFlag = 0x00;
	
	if( SysTick_1ms - dev_action_processing_tick > 49)		//50ms处理一类设备
	{
		
#if 1		
		if(DevActionGlobal.Devi >= DevActionGlobal.DevNum)   //超出范围，就重新开始
		{
			DevActionGlobal.Devi = 0x00;
		}
		
		for( ;DevActionGlobal.Devi < DevActionGlobal.DevNum; )   //循环遍历所有能够作为输入的设备
		{
			Dev_processing_addr = SRAM_Device_List_Start_Addr + DevActionGlobal.Devi*SRAM_Device_List_Size;
			
			switch(SRAM_Read_Byte(Dev_processing_addr+Dev_Type)) //能够作为输入节点的设备  找到一个，就去遍历所有的动作
			{
				case Dev_Host_LVinput:   //弱电输入
				case Dev_NodeCurtain:    //窗帘
				case DEV_RS485_CARD:     //485插卡取电
				case DEV_RS485_TEMP:  //温控器
				case Dev_Host_Service:   //服务信息  先判断条件
				case DEV_SWI_TYPE:       //开关
				case DEV_RS485_PWM:     //滑动条
				case DEV_RS485_FreshAir:	//485新风
				case DEV_RS485_HEATER:	//485地暖
				case Dev_Rs458_RotaryCtrl:   //旋钮开关
				case DEV_Virtual_Card:
				case DEV_Virtual_NoCard:
				case DEV_Carbon_Saved:
				case Dev_Scene_Restore:
                case DEV_RS485_WxLock:    //微信锁，YYW,2025-12-24
					BreakFlag = 0x01;
					SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), Dev_processing_addr);	//拷贝所有公有数据	
					BLV_DevAction_Cycle(Dev_processing_addr, &BUS_Public);    //找到输入节点，把地址和全局属性传进去
					break;      
			}
			
			
			
			if(0x01 == BreakFlag)
			{
//				Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"跳出for当前设备下标:%d,设备类型:%d 设备地址：%d", DevActionGlobal.Devi, BUS_Public.type, BUS_Public.addr);  
				DevActionGlobal.Devi++;  //找到了，继续偏移，准备判断下一个设备
				break;
			}
			else
			{
				DevActionGlobal.Devi++;  //未找到带输入的设备，继续找
			}
			
			
			
		}
		
		dev_action_processing_tick = SysTick_1ms;
		
#endif

		
	}
	
}

/*******************************************************************************
* @Name  :  延时设备处理函数
* @Description    : 
* @Input          : 
*		DevActionAddr	:延时设备地址
* @attention   : 延时设备执行有两种
*                  设备控制 
*                  挂起动作继续执行
*
*******************************************************************************/
void BLV_DevDly_Process(uint32_t dly_processing_addr)
{
	Struct_Dev_Dly DevDlyInfo;     //延时设备全部信息  
	uint8_t KeepFlag = 0x00; 
	
//	SRAM_Read_Buff((uint8_t *)&DevActionInput, sizeof(Dev_Action_Input), DevActionAddr);   //拷贝输入 与状态
	SRAM_Read_Buff((uint8_t *)&DevDlyInfo, sizeof(Struct_Dev_Dly), dly_processing_addr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
	
	if((0x01 == DevDlyInfo.DlyExcuteFlag) && (SysTick_1ms >= DevDlyInfo.DlyExcuteTime))
	{
		DevDlyInfo.DlyExcuteFlag = 0x00;      //标志清0
		KeepFlag = 0x01;


		if(NULL != DevDlyInfo.DevDlyCore.DevDlyAddr)    //不为0
		{		
			switch(DevDlyInfo.DevDlyCore.DevType)  //普通设备节点
			{
				case Dev_Host_HVout:
				case Dev_Host_LVoutput:
				case Dev_Host_Service:
				case Dev_NodeCurtain:
				case DEV_RS485_TEMP:
				case DEV_SWI_TYPE:
				case DEV_RS485_STRIP:
				case DEV_RS485_PWM:
				case DEV_RS485_MUSIC:
				case DEV_RS485_CURTAIN:
				case DEV_RS485_FreshAir:
				case DEV_RS485_HEATER:
				case Dev_Rs485_PB20:
				case Dev_Rs485_PB20_LD:
				case Dev_Rs485_PB20_LS:
				case Dev_Rs485_PB20_Relay:
				case DEV_Virtual_NoCard:
				case DEV_Virtual_Card:
				case DEV_Virtual_ColorTemp:
				case Dev_485_BLE_Music:
				case DEV_Carbon_Saved:
				case Dev_Energy_Monitor:
					{
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时设备执行类型:%d %d路 内容: %04X",DevDlyInfo.DevDlyCore.DevType, DevDlyInfo.DevDlyCore.DevOutputLoop ,DevDlyInfo.DevOutputType);		//继电器状态赋值		
						Dev_Output_Ctrl_ptr Dev_Output_Ctrl = (Dev_Output_Ctrl_ptr)SRAM_Read_DW(DevDlyInfo.DevDlyCore.DevDlyAddr + Dev_Output_Ctrl_0);  //控制函数
						if(NULL != Dev_Output_Ctrl)
						{
							Dev_Output_Ctrl(NULL, NULL, DevDlyInfo.DevDlyCore.DevDlyAddr, DevDlyInfo.DevDlyCore.DevOutputLoop, DevDlyInfo.DevOutputType);
						}
					}
					break;

				case Dev_Host_Invalid:   //场景*  

					  Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景延时执行到时间，场景地址:%08X 状态: %04X",DevDlyInfo.DevDlyCore.DevDlyAddr, DevDlyInfo.DevOutputType);	

						DevAction_DevAddr_Ctrl(DevDlyInfo.DevDlyCore.DevDlyAddr, 0x01, NOR_MODE_CTRL, DevDlyInfo.DevOutputType);		//立即执行		
//						DevAction_No_Ctrl(DevDlyInfo.DevDlyCore.DevOutputLoop, 0x01, DevDlyInfo.DevOutputType);  //控制场景
						break;
			}
		}
		if(0x01 == KeepFlag)   //保存标志
		{
			SRAM_DMA_Write_Buff((uint8_t *)&DevDlyInfo,sizeof(Struct_Dev_Dly),dly_processing_addr);
		}
		if(0x01 == DevDlyInfo.DlyBlinkFlag)   //如果当前节点存在延时闪烁  准备重新赋值保存
		{
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前延时链表存在延时闪烁执行类型:%d %d路 内容: %04X",DevDlyInfo.DevDlyCore.DevType, DevDlyInfo.DevDlyCore.DevOutputLoop ,DevDlyInfo.DevOutputType);		//继电器状态赋值		
			DevDly_InfoSet(dly_processing_addr, 0x01, DevDlyInfo.DevOutputType, DevDlyInfo.DlyBlinkTime, 0x01);//
		}
		else if(0x02 == DevDlyInfo.DlyBlinkFlag)  //关闭闪烁
		{
			DevDly_InfoSet(dly_processing_addr, 0x01, DEV_CTRLWAY_CLOSE, DevDlyInfo.DlyBlinkTime, 0x00);//延时1秒关灯
		}
		
	}
	

}
/**
*@name   延时设备执行函数
*@para   无
*@return 无
*@loop   主循环调用，调用周期  10ms调用一次
在while里执行*/
void BLV_DevDly_Task(void)
{
	static uint32_t dev_devdly_processing_tick = 0;
	uint32_t dly_processing_addr;// 
	
	if( SysTick_1ms - dev_devdly_processing_tick > 9)		//10ms处理一个设备
	{
		dev_devdly_processing_tick = SysTick_1ms;
		if(DevActionGlobal.DevDlyi > DevActionGlobal.DevDlyNum)   //超出范围，就重新开始
		{
			DevActionGlobal.DevDlyi = 0x00;
		}
		
		dly_processing_addr = SRAM_DevDly_List_Start_Addr + DevActionGlobal.DevDlyi*DevDlyStructLen;
		
//		if(DeAction_Data_Check(dly_processing_addr) == 0)		//设备信息校验成功
		{
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作参数校验通过:%d");

			BLV_DevDly_Process(dly_processing_addr);
		}
		DevActionGlobal.DevDlyi++;
	}	
}


/**
* @name   设备控制专线
* @param  固定6个字节  
* @retval 0x01  成功   0x02 失败   
* @brief   //组   group[0] group[1] group[2] Type_L  Type_H
					 //类型   地址   Loop_L   Loop_H   Type_L  Type_H         Type_L:执行方式   Type_H: 执行内容
*						  01     00      01      00       01       00
* @attention 若控制睡眠  场景就置为关   此函数仅限外部调用
*/ 
uint8_t DevActionCtrl(uint8_t *p, uint8_t DataLen)
{
	uint8_t Ret = 0x02;  //默认失败
	uint16_t SceneCtrlNo;     //控制的场景号
	
	if(DevCtrlLen != DataLen)  //长度不对
	{
		return Ret;
	}
	
	switch(p[0])
	{
		case Dev_Host_Invalid:  //场景
			DevActionGlobal.ServerCtrl = 0x01;       //2024-04-22
			SceneCtrlNo = p[2] + (p[3]<<8);
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备控制场景 场景号:%d", SceneCtrlNo);
			if(SceneCtrlNo == DevActionGlobal.SleepActionNo) //如果是控制的睡眠场景
			{
				p[4] = 0x02;            //关闭
			}
			DevAction_No_Ctrl(SceneCtrlNo, 0x01, (p[4]+(p[5]<<8)));  //控制场景
			break;
		default:
			Ret = DevAddrCtr(NULL, p, DataLen);
			break;
	}
	return Ret;
}

/**
* @name   取电服务信息打开
* @param  无
* @retval 无
* @brief  单纯控制取电服务打开
*/
void Ele_Ctrl_OpenClose(uint8_t Ctrl)
{
	uint8_t DataBuf[6];
	
	DataBuf[0] = Dev_Host_Service;
	DataBuf[1] = 0x00;
	DataBuf[2] = LOOPCH01;           //1号回路取电
	DataBuf[3] = 0x00;            
	DataBuf[4] = Ctrl;
	DataBuf[5] = 0x00;

	DevAddrCtr(NULL, DataBuf, 0x06);         //插卡取电控制
}

/**
* @name   设备控制专线
* @param  固定6个字节  8个字节  和12个字节
* @retval 0x01  成功   0x02 失败   
* @brief   //组   group[0] group[1] group[2] Type_L  Type_H
					 //类型   地址   Loop_L   Loop_H   Type_L  Type_H         Type_L:执行方式   Type_H: 执行内容
*						  01     00      01      00       01       00
*/ 
uint8_t DevAddrCtr(DEV_ACTION_INFO *DevActionInfo, uint8_t *p, uint8_t DataLen)
{
	uint8_t Ret = 0x02;   //默认不存在
	uint32_t DevAddrOut;  //设备地址局部变量
	
	Dev_Action_Output DevActionOutput;   //
	
	memset((uint8_t *)&DevActionOutput, 0x00, sizeof(Dev_Action_Output));  //初始化清0 
	
	switch(DataLen)
	{
		case DevCtrlLen:
//		case DevCtrlDlyLen:
		case DevCtrlDlyLenAddr:
			memcpy((uint8_t *)&DevActionOutput, p, DataLen);
			break;
		default:
			return Ret;
	}
	switch(DataLen)
	{
		case DevCtrlLen:         //6字节      需要自己查设备
//		case DevCtrlDlyLen:     //带延时控制  需要自己查设备 查延时
			DevAddrOut = Find_AllDevice_List_Information(DevActionOutput.DevActionOutCfg.DevType, DevActionOutput.DevActionOutCfg.DevAddr);
			break;
		case DevCtrlDlyLenAddr: //带延时，带地址控制，带延时设备地址
			DevAddrOut = DevActionOutput.DevActionOutAddr;
			break;
	}
	
	if(NULL == DevAddrOut)
	{
		return Ret;
	}
	Ret = 0x01;
	if(0x00 == DevActionOutput.DevActionOutCfg.DevDlyValue.DelayCont)     //延时执行为0，立即执行
	{
		DevDly_InfoSet(DevActionOutput.DevDlyAddr, 0x00, DevActionOutput.DevActionOutCfg.DevCtrlState, DevActionOutput.DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
		{
			Device_Public_Information_G BUS_Public;   //共用
			SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
			switch(DevActionOutput.DevActionOutCfg.DevType)
			{
//			case DEV_C5MUSIC_Type:    //背景音乐
			case DEV_RS485_SWT:       //485开关 
			case DEV_RS485_WxLock:    //微信锁
			case Dev_Host_Service:
			case Dev_Host_HVout:
			case Dev_Host_LVoutput:
			case Dev_NodeCurtain:
			case DEV_RS485_CURTAIN:
			case DEV_RS485_IR_SEND:
			case DEV_RS485_TEMP:
			case DEV_RS485_FreshAir:
			case DEV_RS485_HEATER:
			case Dev_Energy_Monitor:
				if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
				{
															
					if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
					{
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionOutput.DevActionOutCfg.DevType, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
						BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);
					}
					else
					{
						BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);						
					}
				}
				break;
			case DEV_RS485_PWM:              //PWM调光
			case DEV_RS485_STRIP:            //RGB调光
			case Dev_Rs485_PB20:
			case Dev_Rs485_PB20_LD:
			case Dev_Rs485_PB20_LS:
			case Dev_Rs485_PB20_Relay:
			case DEV_Virtual_ColorTemp:
            case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置    
				if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
				{
					if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
					{
//						uint16_t LedState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop); 
						
//						if(((0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag)&&(((CFG_Dev_CtrlWay_Is_Dim_Down == (DevActionOutput.DevActionOutCfg.DevCtrlState&0x00ff))&&(LEDLIGHTMINLIMIT < LedState))||((CFG_Dev_CtrlWay_Is_Dim_Up == (DevActionOutput.DevActionOutCfg.DevCtrlState&0x00ff))&&(0x00 != LedState))))
//							||(0x00 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag))  
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionOutput.DevActionOutCfg.DevType, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
							BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);
						}
					}
					else
					{
						BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);						
					}
				}
				break;
			case DEV_RS485_MUSIC: 
					if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
					{
#if LOGIC_FILE_EN						
						if((NULL != DevActionInfo) && (CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音
#else
						if((NULL != DevActionInfo) && (CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningFlag, DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音						
#endif			
						{
								DEV_MUSIC_CTRLSTATE DevMusicCtrlState;    //背景音乐控制状态

								BLV_Music_CtrlState_Get(&DevMusicCtrlState,DevActionOutput.DevActionOutCfg.DevCtrlState);
#if LOGIC_FILE_EN
								switch(DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect)
								{
									case 0x03: //场景开播放
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐指定文件夹开播放，回路:%d 状态: %04X", DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);			
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);  //执行开场景指定播放											
										break;
									case 0x04: //场景关播放
										break;     
									default:   //其他情况
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐开关机模式控制，状态: %04X", DevActionOutput.DevActionOutCfg.DevCtrlState);										
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);  //执行开场景指定播放												
										break;
								}
#else															
								if((0x00 != DevMusicCtrlState.DevMusicCtrlWay.CtrlDir) && (0x01 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect))  //开场景指定播放
								{		
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐指定文件夹开播放，状态: %04X", DevActionOutput.DevActionOutCfg.DevCtrlState);			
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);  //执行开场景指定播放
								}
								else if(0x00 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDir)
								{
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐开关机模式控制，状态: %04X", DevActionOutput.DevActionOutCfg.DevCtrlState);										
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState);  //执行开场景指定播放								
								}
#endif
						}
					}
					break;

			}
		}
	}
	else if((0x00 != DevActionOutput.DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionOutput.DevDlyAddr))       //延时执行不为0   且延时设备不为0
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionOutput.DevActionOutCfg.DevType, DevActionOutput.DevActionOutCfg.DevOutputLoop, DevActionOutput.DevActionOutCfg.DevCtrlState, DevActionOutput.DevActionOutCfg.DevDlyValue.DelayCont, DevActionOutput.DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		

		DevDly_InfoSet(DevActionOutput.DevDlyAddr, 0x01, DevActionOutput.DevActionOutCfg.DevCtrlState, DevActionOutput.DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
	}
	return Ret;
}

/**
*@name 扩展场景所有设备延时取消
*@para 
* DevActionInfo   当前设备动作
*@Ret  无
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数  
*     带延时的设备取消
*/
void DevAction_ExpandDlyClear(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用


	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{
			if(Dev_Host_Invalid != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)  //普通设备拥有共有数据
			{
				SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
			}
			if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
			}			
		}
	}
}

/**
*@name 扩展场景状态控制函数
*@para 
* DevActionInfo   当前设备动作
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数
*     2022-09-03
*/
void DevAction_ExpandCtrl(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;    //地址相同计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
//	uint8_t DevCtrlWay;     //执行方式
//	uint8_t DevCtrlCont;    //执行内容
//	uint8_t SceneState = 0x00;
	
	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;        //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;          //调光存在计数
	

	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x01);
	

	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控控制开始，回路标志:%08X 场景名:%s ", expand_type[j].ExpandReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;								
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"PWM调光状态群控控制开始地址:%d，回路标志:%08X 场景名:%s ",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, dimm_type[j].DimmReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif 
			}
		}
	}
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{
//			if(Dev_Host_Invalid != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)  //普通设备拥有共有数据
//			{
//			}
			if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行没有继电器
			{
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case Dev_Host_Invalid:   //场景
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"2025-10-11取消 设备输出场景控制,场景地址:%08X 场景控制状态%d", DevActionInfo->DevActionOutput[i].DevActionOutAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
						//DevAction_DevAddr_Ctrl(DevActionInfo->DevActionOutput[i].DevActionOutAddr, 0x01, NOR_MODE_CTRL, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  
						break;
					case DEV_RS485_SWT:       //485开关 
					case DEV_RS485_WxLock:    //微信锁
					case Dev_Host_Service:
//					case Dev_Host_HVout:
					case Dev_Host_LVoutput:
					case Dev_NodeCurtain:
					case DEV_RS485_IR_SEND:
					case DEV_RS485_TEMP:
					case DEV_RS485_CURTAIN:
					case DEV_RS485_FreshAir:
					case DEV_RS485_HEATER:
					case Dev_Rs485_PB20:
					case Dev_Rs485_PB20_LD:
					case Dev_Rs485_PB20_LS:
					case Dev_Rs485_PB20_Relay:
					case DEV_Virtual_NoCard:
					case DEV_Virtual_Card:
					case Dev_485_BLE_Music:
					case DEV_Carbon_Saved:
					case Dev_Scene_Restore:
					case Dev_Energy_Monitor:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
							}
						}
						break;
//					case DEV_RS485_PWM:              //PWM调光  群控
					case DEV_RS485_STRIP:            //RGB调光
					case DEV_Virtual_ColorTemp:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
//								uint16_t LedState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop); 
								
//								if(((0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag)&&(((CFG_Dev_CtrlWay_Is_Dim_Down == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(LEDLIGHTMINLIMIT < LedState))||((CFG_Dev_CtrlWay_Is_Dim_Up == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(0x00 != LedState))))
//									||(0x00 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag))  
								{
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
								}
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
							}
						}
						break;
					case DEV_RS485_MUSIC: 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
#if LOGIC_FILE_EN							
							if((NULL != DevActionInfo) && (CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音
#else
						  if((NULL != DevActionInfo) && (CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningFlag, DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音
							
#endif								
							{
									DEV_MUSIC_CTRLSTATE DevMusicCtrlState;    //背景音乐控制状态
									
									BLV_Music_CtrlState_Get(&DevMusicCtrlState,DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
#if LOGIC_FILE_EN
									switch(DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect)
									{
										case 0x03: //场景开播放
											Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐指定文件夹开播放，回路:%d 状态: %04X",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);			
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行开场景指定播放											
											break;
										case 0x04: //场景关播放
											break;     
										default:   //其他情况
											Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐开关机模式控制，地址:%d 回路:%d状态: %04X",BUS_Public.addr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);										
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行开场景指定播放												
											break;
									}
#else								
									if((0x00 != DevMusicCtrlState.DevMusicCtrlWay.CtrlDir) && (0x01 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect))  //开场景指定播放
									{		
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐指定文件夹开播放，状态: %04X", DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);			
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行开场景指定播放
									}
									else if(0x00 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDir)
									{
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐开关机模式控制，状态: %04X", DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);										
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行开场景指定播放								
									}
#endif									
							}
						}
						break;					
				}
			}
			else if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
			}			
		}
	}
}



/**
*@name 旋转场景状态控制函数
*@para 
* DevActionInfo   当前设备动作
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*	 支持旋钮调光
*     
*/
void DevAction_RotaryCtrl(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;    //地址相同计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
//	uint8_t DevCtrlWay;     //执行方式
//	uint8_t DevCtrlCont;    //执行内容
//	uint8_t SceneState = 0x00;
	
	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;        //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;          //调光存在计数
	
	Expand_And_Dimm_Action_Get2(DevActionInfo,expand_type,dimm_type,0x02);
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{

				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"PWM调光 群控控制开始地址:%d，回路标志:%08X 场景名:%s ",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, dimm_type[j].DimmReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
			}
		}
	}
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{

			if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行没有继电器
			{
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case DEV_RS485_STRIP:            //RGB调光
					case Dev_Rs485_PB20:
					case DEV_Virtual_ColorTemp:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
							uint32_t inputaddr = 0;
							RS485_SWI_INFO RotaryInfo;       //开关局部变量
							inputaddr = Find_AllDevice_List_Information2(Active_Port,DevActionInfo->DevActionInput.DevType,DevActionInfo->DevActionInput.DevAddr);
							if(inputaddr != NULL)
							{
								SRAM_DMA_Read_Buff((uint8_t *)&RotaryInfo,sizeof(RS485_SWI_INFO),inputaddr+Dev_Privately);
							}
									
							
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
//								uint16_t LedState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop); 
								
//								if(((0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag)&&(((CFG_Dev_CtrlWay_Is_Dim_Down == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(LEDLIGHTMINLIMIT < LedState))||((CFG_Dev_CtrlWay_Is_Dim_Up == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(0x00 != LedState))))
//									||(0x00 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag))  
								{
									DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0xff;
									if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType == DEV_Virtual_ColorTemp)
									{
										if((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x01) \
											|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x02)\
											|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x30))
										{
											DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[0] << 8);
										}
										else if((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x03) \
											|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x40))
										{
											DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[3] << 8);
										}
										
									}
									else
									{
										DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[0] << 8);
									}
									
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
								}
							}
							else
							{
								DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0xff;
								if(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType == DEV_Virtual_ColorTemp)
								{
									if((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x01) \
										|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x02)\
										|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x30))
									{
										DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[0] << 8);
									}
									else if((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x03) \
										|| (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState == 0x40))
									{
										DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[3] << 8);
									}
									
								}
								else
								{
									DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState += (RotaryInfo.RotaryValue[0] << 8);
								}
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
							}
						}
						break;
				}
			}
			else if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
			}			
		}
	}
}


/**
*@name 扩展灯光类设备控制函数  或者场景   
*@para 
* DevActionInfo   当前设备动作
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数
*     2022-09-03
*/
void DevAction_ExpandLightOpen(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;    //地址相同计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	
	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;        //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;          //调光存在计数
	
	
	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x01);


	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控控制开始，回路标志:%08X 场景名:%s ", expand_type[j].ExpandReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"PWM调光状态群控控制开始地址:%d，回路标志:%08X 场景名:%s ",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, dimm_type[j].DimmReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif
			}
		}
	}
	
	
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{
			if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行没有继电器
			{
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case Dev_Host_Invalid:   //场景
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"2025-10-11取消 设备输出场景控制,场景地址:%08X 状态%d", DevActionInfo->DevActionOutput[i].DevActionOutAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
						//DevAction_DevAddr_Ctrl(DevActionInfo->DevActionOutput[i].DevActionOutAddr, 0x01, NOR_MODE_CTRL, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  
						break;
//					case DEV_RS485_SWT:       //485开关 
//					case DEV_RS485_WxLock:    //微信锁
//					case Dev_Host_Service:
//					case Dev_Host_HVout:   //继电器立即控制走群控
					case Dev_Host_LVoutput:
//					case Dev_NodeCurtain:
//					case DEV_RS485_IR_SEND:
//					case DEV_RS485_TEMP:
					case Dev_Rs485_PB20:
					case Dev_Rs485_PB20_LD:
					case Dev_Rs485_PB20_LS:
					case Dev_Rs485_PB20_Relay:
					case Dev_Scene_Restore:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
							}
						}
						break;
//					case DEV_RS485_PWM:              //PWM调光
					case DEV_RS485_STRIP:            //RGB调光
					case DEV_Virtual_ColorTemp:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								uint16_t LedState = BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop); 
								
//								if(((0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag)&&(((CFG_Dev_CtrlWay_Is_Dim_Down == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(LEDLIGHTMINLIMIT < LedState))||((CFG_Dev_CtrlWay_Is_Dim_Up == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))&&(0x00 != LedState))))
//									||(0x00 == DevActionInfo->DevActionCond.DevActionU64Cond.LightFlag))  
								{
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		//服务信息状态赋值
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
								}
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
							}
						}
						break;				
				}
			}
			else if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器
			{
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)   //灯光类才参与延时执行
				{
//					case DEV_RS485_SWT:       //485开关 
					case Dev_Host_HVout:          //继电器延时控制仍然走延时控制
					case Dev_Host_LVoutput:					
					case DEV_RS485_PWM:              //PWM调光延时控制
					case DEV_RS485_STRIP:            //RGB调光
					case DEV_Virtual_ColorTemp:
					case Dev_Scene_Restore:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
						DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
						break;
				}
			}			
		}
	}
}


/**
*@name 扩展场景状态控制函数  立即执行的设备才执行  所有设备都关闭
*@para 
* DevActionInfo   当前设备动作
* ModeCtrl        0x01  普通场景关闭  0x02  睡眠场景关闭
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数
*     2022-09-03
*/
void DevAction_ExpandLightClose(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;    //地址相同计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
//	uint8_t DevCtrlWay;     //执行方式
//	uint8_t DevCtrlCont;    //执行内容
//	uint8_t SceneState = 0x00;
	
	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;        //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;          //调光存在计数
	
	
	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x00);


	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控控制开始，回路标志:%08X 场景名:%s ", expand_type[j].ExpandReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;								
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"PWM调光状态群控控制开始地址:%d，回路标志:%08X 场景名:%s ",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, dimm_type[j].DimmReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif
			}
		}
	}
	
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{
			if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行没有继电器
			{
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case Dev_Host_Invalid:   //场景
						
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"2025-10-11取消 设备输出场景控制,场景地址:%08X 状态%d", DevActionInfo->DevActionOutput[i].DevActionOutAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
						//DevAction_DevAddr_Ctrl(DevActionInfo->DevActionOutput[i].DevActionOutAddr, 0x01, NOR_MODE_CTRL, DEV_CTRLWAY_CLOSE);  
						break;
//					case DEV_RS485_SWT:       //485开关 
//					case DEV_RS485_WxLock:    //微信锁
//					case Dev_Host_Service:
//					case Dev_Host_HVout:
					case Dev_Host_LVoutput:
//					case Dev_NodeCurtain:
//					case DEV_RS485_IR_SEND:
//					case DEV_RS485_TEMP:
//					case DEV_RS485_PWM:              //PWM调光
					case DEV_RS485_STRIP:            //RGB调光	
					case Dev_Rs485_PB20_Relay:
					case DEV_Virtual_ColorTemp:
					case Dev_Scene_Restore:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);						
							}
						}
						break;
					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_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);						
							}
						}
						break;
				
				}
			}
			else if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
			}			
		}
	}
}


/**
*@name 扩展场景状态控制函数  立即执行的设备才执行  所有设备都关闭
*@para 
* DevActionInfo   当前设备动作
* ModeCtrl        0x01  普通场景关闭  0x02  睡眠场景关闭
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数
*     2022-09-03
*/
void DevAction_ExpandClose(DEV_ACTION_INFO *DevActionInfo, uint8_t ModeCtrl)
{
	uint8_t i;//,j;
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用

	EXPAND_TYPE_G expand_type[30]={0};

	DIMM_TYPE_G dimm_type[30]={0};

	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x00);

	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控控制开始，回路标志:%08X 场景名:%s ", expand_type[j].ExpandReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;	
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl)   //非空
									{
										BUS_Public.DevFunInfo.Dev_Output_Group_Ctrl(NULL, NULL, DevAddrOut, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState);
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"PWM调光状态群控控制开始地址:%d，回路标志:%08X 场景名:%s ",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, dimm_type[j].DimmReadFlag, DevActionInfo->DevActionCore.DevActionName);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif
			}
		}
	}
	

	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)
	{
		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)   //地址非空
		{
			if(0x00 == DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行没有继电器
			{
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//清延时执行标志位
				switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
				{
					case Dev_Host_Invalid:   //场景
						
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"2025-10-11取消 设备输出场景控制,场景地址:%08X 状态%d ", DevActionInfo->DevActionOutput[i].DevActionOutAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);						
						
						//DevAction_DevAddr_Ctrl(DevActionInfo->DevActionOutput[i].DevActionOutAddr, 0x01, NOR_MODE_CTRL, DEV_CTRLWAY_CLOSE);  
					
						break;
					case DEV_RS485_SWT:       //485开关 
//					case DEV_RS485_WxLock:    //微信锁
//					case Dev_Host_Service:
//					case Dev_Host_HVout:
					case Dev_Host_LVoutput:
//					case Dev_NodeCurtain:
//					case DEV_RS485_IR_SEND:
//					case DEV_RS485_TEMP:
//					case DEV_RS485_PWM:              //PWM调光
					case DEV_RS485_STRIP:            //RGB调光		
					case Dev_Rs485_PB20_Relay:
					case DEV_Virtual_ColorTemp:
					case Dev_Scene_Restore:
                    case Dev_Virtual_GlobalSet:  //2025-07-15,YYW,全局设置 
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);						
							}
						}
						break;
					#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_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0012);						
							}
						}
						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_Ctrl)
						{
							switch(ModeCtrl)
							{
								case NOR_MODE_CTRL:     //普通模式 窗帘控制
									switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)
									{
										case DEV_CTRLWAY_OPEN:           //开
										case DEV_CTRLWAY_CLOSE:	         //关
										case CFG_Dev_CtrlWay_Is_TOGGLE:  //互切
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_STOP);
											break;
										case 0x15:  //延时控制开
										case 0x16:  //延时控制关 - 场景可关闭时，延时控制关闭状态为0x17
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x17);
											break;
										case DEV_CTRLWAY_STOP:
											break;
									}
									break;
								case SLEEP_MODE_CTRL:   //睡眠模式 窗帘控制 
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									break;
							}
						}
						break;
						
					case DEV_RS485_CURTAIN:	  //窗帘开取反为窗帘停  窗帘关取反为窗帘停  窗帘停取反为窗帘开或关
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)
						{
							switch(ModeCtrl)
							{
								case NOR_MODE_CTRL:     //普通模式 窗帘控制
									switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff)
									{
										case DEV_CTRLWAY_OPEN:           //开
										case DEV_CTRLWAY_CLOSE:	         //关
										case CFG_Dev_CtrlWay_Is_TOGGLE:  //互切
										case 0x05:
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_STOP);
											Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"485窗帘场景关闭控制 state:%4X\n\r",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
											break;
//										case 0x15:  //延时控制开
//										case 0x16:  //延时控制关 - 场景可关闭时，延时控制关闭状态为0x17
//											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x17);
//											break;

										case DEV_CTRLWAY_STOP:
											break;
									}
									break;
								case SLEEP_MODE_CTRL:   //睡眠模式 窗帘控制 
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									break;
							}
						}
						break;	
						
					case Dev_Host_Service:    //睡眠控制服务信息
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)
						{
							switch(ModeCtrl)
							{
								case NOR_MODE_CTRL:     //普通模式 服务信息控制
									switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)
									{
										case DEV_CTRLWAY_OPEN:           //开
										case DEV_CTRLWAY_CLOSE:	         //关
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);
											break;
									}
									break;
								case SLEEP_MODE_CTRL:   //睡眠模式 服务信息控制 
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									break;
							}
						}							
						break;
					case DEV_RS485_MUSIC:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
							DEV_MUSIC_CTRLSTATE DevMusicCtrlState;    //背景音乐控制状态

							BLV_Music_CtrlState_Get(&DevMusicCtrlState,DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
							if(BUS_Public.Protocol == 0x06)
							{
								if((NULL != DevActionInfo) && (DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect == 0x00) && (DevMusicCtrlState.DevMusicCtrlWay.CtrlDir == 0x01 || DevMusicCtrlState.DevMusicCtrlWay.CtrlDir == 0x02))   //传入的控制状态为播放或者暂停
								{
									
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0020);	     //关播放
								}
								else
								{
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行华尔思音乐控制，状态: %04X", DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);		
								}
							}
							else
							{
								#if LOGIC_FILE_EN							
								if((CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音
								#else
								if((CondIsPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WarningFlag, DevActionInfo->DevActionCond.DevActionU64Cond.WarningState, DevActionGlobal.DevActionU64Cond.WarningState)))  //配置的静音							
								#endif							
								{
									#if LOGIC_FILE_EN
										if((0x04 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect)||(SLEEP_MODE_CTRL == ModeCtrl))
										{
											Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐关播放，状态: %04X", DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);				
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行关场景指定播放			
										}
										else if((DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect == 0x00) && (DevMusicCtrlState.DevMusicCtrlWay.CtrlDir == 0x01 || DevMusicCtrlState.DevMusicCtrlWay.CtrlDir == 0x02))
										{
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0020);	     //关播放
										}
									#else
									if((0x00 != DevMusicCtrlState.DevMusicCtrlWay.CtrlDir) &&
										((0x02 == DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect)||(SLEEP_MODE_CTRL == ModeCtrl))  //睡眠执行开场景播放
									)  //关场景指定播放
									{		
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备执行背景音乐关播放，状态: %04X", DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);				
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);  //执行关场景指定播放
									}
									#endif
								}
							}
						}
						break;
					case Dev_485_BLE_Music:
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)  //非空
						{
																	
							if((NULL != DevActionInfo) && (NULL != DevActionInfo->DevActionState.DevAddrIn))   //
							{
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"输入设备地址:%04X 设备类型:%d 地址:%04X %d路 控制状态: %04X",DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);		//服务信息状态赋值
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(DevActionInfo->DevActionState.DevAddrIn, DevActionInfo->DevActionInput.inAddr, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0301);   //指定播放停止	
							}
							else
							{
								BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, 0x0301);		  //指定播放停止				
							}
						}
						break;
				}
			}
			else if((0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) && (NULL != DevActionInfo->DevActionOutput[i].DevDlyAddr))       //延时执行不为0   且延时设备不为0 包括继电器  把延时取消
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"准备延时设备执行置位，设备类型:%d  %d路 内容: %d,时间：%d单位：%d",DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight);		//继电器状态赋值		
				DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//置延时执行标志位
			}			
		}
	}
}




/*根据场景编号得到动作的地址*/
uint32_t DevAction_No_Get(uint16_t DevActionNo)
{
	uint16_t i;  //用于遍历所有动作
	uint32_t list_addr = NULL;   //动作的地址
	DEV_ACTION_INFO DevActionInfo;

	for(i = 0; i < DevActionGlobal.DevActionNum; i++)
	{
		list_addr = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
		SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), list_addr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
		if(DevActionNo == DevActionInfo.DevActionCore.ActionNo)
		{
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"遍历所有动作，找到相应的场景编号:%d 场景名%s", DevActionNo, DevActionInfo.DevActionCore.DevActionName);						
			return list_addr;   //返回当前动作的地址
		}
	}
	return NULL;
}

/**
*@name 场景模式控制
*@para 
*   DevActionInfo  动作地址
*   ModeCtrl        1为场景控制  2位灯光控制
*   SceneMode      NOR_MODE_CTRL 0x01 普通模式控制 SLEEP_MODE_CTRL 0x02 睡眠场景控制
*   CtrlState   控制状态 1开 2关
*@ret  无
*@attention 
*/
void DevAction_Mode_Ctrl(DEV_ACTION_INFO *DevActionInfo, uint8_t Mode, uint8_t SceneMode, uint16_t CtrlState)
{
	switch(CtrlState)
	{
		case DEV_CTRLWAY_OPEN:
			switch(Mode)
			{
				case SCENE_MODE_CTRL:
					DevAction_ExpandCtrl(DevActionInfo);
					break;
				case LIGHT_MODE_CTRL:
					DevAction_ExpandLightOpen(DevActionInfo);
					break;
			}
			break;
		case DEV_CTRLWAY_CLOSE:
			switch(Mode)
			{
				case SCENE_MODE_CTRL:
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"普通场景控制关闭，场景号:%d", DevActionInfo->DevActionCore.ActionNo);
					DevAction_ExpandClose(DevActionInfo, SceneMode);
					break;
				case LIGHT_MODE_CTRL:
					DevAction_ExpandLightClose(DevActionInfo);
					break;
			}
			break;
		case DEV_CTRLWAY_INVALID:    //控制方式无效，就是取消所有的延时执行
			DevAction_ExpandDlyClear(DevActionInfo);
			break;
	}	
}

/**
*@name 根据动作编号去控制输出  即场景控制
*@para 
*   DevActionNo  场景的下标
*   Mode        1为场景控制  2位灯光控制
*   CtrlState   控制状态 1开 2关
*@ret  无
*@attention 需要遍历所有的动作，然后找出相应的下标，再执行输出
*/
void DevAction_No_Ctrl(uint16_t DevActionNo, uint8_t Mode, uint16_t CtrlState)
{
	uint16_t i;  //用于遍历所有动作
	uint32_t list_addr;   //动作的地址
	DEV_ACTION_INFO DevActionInfo;
	Dev_Dly_Value Temp_Dly;
	if(NULL == DevActionNo)  //为空
	{
		return ;   //返回
	}
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"遍历所有动作，准备执行场景编号:%d", DevActionNo);						
	
	for(i = 0; i < DevActionGlobal.DevActionNum; i++)
	{
		list_addr = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
		SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), list_addr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
		if(DevActionNo == DevActionInfo.DevActionCore.ActionNo)
		{
//			if(0x00 == UINT16DATACONVER(DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevDlyValue))     //延时执行为0，立即执行
			{
//				DevDly_InfoSet(DevActionInfo.DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevCtrlState, UINT16DATACONVER(DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevDlyValue));//清延时执行标志位
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"遍历所有动作，找到相应的场景编号:%d 场景名%s，场景存储地址:%08X,立即执行，并清延时执行标志", DevActionNo, DevActionInfo.DevActionCore.DevActionName, list_addr);						
				    
					Temp_Dly.DelayCont = 0x00;
					Temp_Dly.DelayWeight = 0x00;
					DevDly_InfoSet(DevDlyAddr_Get(list_addr, DevActionNo), 0x00, 0x00, Temp_Dly, 0x00);//置延时执行标志位  先拿到延时节点的地址
					if((NeightModeNo == DevActionNo) || (DevActionInfo.DevActionCond.SceneExcute == LIGHT_SCENE_SLEEP))    //2024-05-27  避免配置睡眠场景号对不上
					{
						DevAction_Mode_Ctrl(&DevActionInfo, Mode, SLEEP_MODE_CTRL, CtrlState);
					}
					else
					{
						DevAction_Mode_Ctrl(&DevActionInfo, Mode, NOR_MODE_CTRL, CtrlState);
					}
				}
			}
//			else   //不为0
//			{
//				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"遍历所有动作，找到相应的场景编号:%d 场景名%s 场景延时执行", DevActionNo, DevActionInfo.DevActionCore.DevActionName);						
//				DevDly_InfoSet(DevActionInfo.DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevCtrlState, UINT16DATACONVER(DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevDlyValue));//置延时执行标志位
//			}
			if(DevActionGlobal.ServerCtrl == 0x01)
			{
				DevActionGlobal.ServerCtrl = 0x00;
				if(DevActionInfo.DevActionCond.SceneExcute == LIGHT_SCENE_SLEEP)
				{
					if(0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)  //与夜灯有关  且夜灯存在
					{
						if(NightModeStart != DevActionGlobal.DevActionU64Cond.NeightState)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeStart;     //进入起夜
						}
					}
					
					DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
					DevActionGlobal.SleepLight_State = 0x00;				//熄灭背光，关背光   2025-09-05
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景");
				}
				else
				{
					if(0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)  //与夜灯有关  且夜灯存在
					{
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;     
					}
					DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景");
				}
			}
			break;   //找到就跳出 也不用保存
		}
	}
}

/**
*@name 根据动作的绝对地址去控制输出  即场景控制
*@para 
*   DevActionAddr  场景的下标
*   Mode        1为场景控制  2位灯光控制
*   SceneMode      NOR_MODE_CTRL 0x01 普通模式控制 SLEEP_MODE_CTRL 0x02 睡眠场景控制
*   CtrlState   控制状态 1开 2关
*@ret  无
*@attention 根据动作的地址直接执行输出
*@loop   唯有本地按键调用  因为本地事先知道睡眠的地址
*/
void DevAction_DevAddr_Ctrl(uint32_t DevActionAddr, uint8_t Mode, uint8_t SceneMode, uint16_t CtrlState)
{
	DEV_ACTION_INFO DevActionInfo;     //设备动作全部信息  
	
		
	if((DevActionAddr < SRAM_DevAction_List_Start_Addr) || (DevActionAddr >= SRAM_DevAction_List_End_Addr))
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景地址无效:%08X",DevActionAddr);
		return ;
	}
	
	SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), DevActionAddr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景控制，场景地址有效:%08X，场景号:%d",DevActionAddr, DevActionInfo.DevActionCore.ActionNo);
	
	if(NeightModeNo == DevActionInfo.DevActionCore.ActionNo)  //控制场景时，如果是睡眠场景，就进入睡眠模式
	{
		if(0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)   //夜灯存在
		{
			if(NightModeStart != DevActionGlobal.DevActionU64Cond.NeightState)
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"设备输出场景控制，有场景控制睡眠，进入起夜");    //有场景控制
				DevActionGlobal.DevActionU64Cond.NeightState = NightModeStart;     //进入起夜  
			}
		}
		DevAction_Mode_Ctrl(&DevActionInfo, LIGHT_MODE_CTRL, SLEEP_MODE_CTRL, DEV_CTRLWAY_CLOSE);  //关闭所有灯不播放词条  DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState
	}
	else
	{
		DevAction_Mode_Ctrl(&DevActionInfo, Mode, SceneMode, CtrlState);
	}
}

/**
*@name 设备动作输出执行
*@para 
* DevActionInfo   当前设备动作
*@Ret  无
*/
void DevAction_Output(DEV_ACTION_INFO *DevActionInfo)
{
	switch(DevActionInfo->DevActionCond.SceneExcute)
	{
		case LIGHT_SCENE_ONE:            //场景不可关闭，执行相应动作
		case LIGHT_SCENE_MULTI:
			if((0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag) && (0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag))  //与夜灯有关
			{
				switch(DevActionGlobal.DevActionU64Cond.NeightState)
				{
					case NightModeStart:
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景不可关闭  准备执行打开夜灯:");						
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
						DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_OPEN);//打开夜灯
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
							Logic_Music_Ctrl(NULL, NULL, Find_Device_List_Information(0x15,0x01), 0x00, 0x0020);  //起夜关音乐
							
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -1");
						}
						break;
					case NightModeClose:
					case NightModeOpen:	
						if(NightModeOpen == DevActionGlobal.DevActionU64Cond.NeightState)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
							DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_CLOSE);//关闭夜灯
						}
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景不可关闭开始对所有设备输出状态进行赋值:");						
						DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景

						break;
				}
			}
			else          //与夜灯无关
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 场景不可关闭开始对所有设备输出状态进行赋值:");
				DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
				if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
				{
					DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
					
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -2");
				}
			}
			break;
		case LIGHT_SCENE_TWO:            //场景可关闭，执行相应动作
			if((0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag) && (0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag))  //与夜灯有关
			{
				switch(DevActionGlobal.DevActionU64Cond.NeightState)
				{
					case NightModeStart:
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
						DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_OPEN);    //打开夜灯
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
							Logic_Music_Ctrl(NULL, NULL, Find_Device_List_Information(0x15,0x01), 0x00, 0x0020);  //起夜关音乐
						}
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -3");
						break;
					case NightModeClose:
					case NightModeOpen:	
						if(NightModeOpen == DevActionGlobal.DevActionU64Cond.NeightState)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
							DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_CLOSE); //关闭夜灯
						}
						if(DEV_STATE_CLOSE == DevActionInfo->DevActionState.SceneState)   //当前场景为关
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景开");		
							DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
						}
						else if(DEV_STATE_OPEN == DevActionInfo->DevActionState.SceneState)
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景关");
							DevAction_ExpandClose(DevActionInfo, NOR_MODE_CTRL);     //执行当前场景								
						}
						break;
				}				
			}
			else          //与夜灯无关
			{
				if(DEV_STATE_CLOSE == DevActionInfo->DevActionState.SceneState)   //当前场景为关
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景开");
					DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
				}
				else if(DEV_STATE_OPEN == DevActionInfo->DevActionState.SceneState)   //当前场景为开
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景关");
					DevAction_ExpandClose(DevActionInfo, NOR_MODE_CTRL);     //执行当前场景				
				}
				if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
				{
					DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
					
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -4");
				}
			}
			break;
		case LIGHT_SCENE_MAINSWITCH:    //总开关
			if((0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag) && (0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag))  //与夜灯有关
			{
				switch(DevActionGlobal.DevActionU64Cond.NeightState)
				{
					case NightModeStart:
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
						DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_OPEN);    //打开夜灯
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
							Logic_Music_Ctrl(NULL, NULL, Find_Device_List_Information(0x15,0x01), 0x00, 0x0020);  //起夜关音乐
						}
						break;
					case NightModeClose:
					case NightModeOpen:	
						if(NightModeOpen == DevActionGlobal.DevActionU64Cond.NeightState)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
							DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_CLOSE); //关闭夜灯
						}
						if(DEV_STATE_CLOSE == DevActionInfo->DevActionState.SceneState)   //当前场景为关
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景开");		
							DevAction_ExpandLightOpen(DevActionInfo);     //打开当前场景的灯光
						}
						else if(DEV_STATE_OPEN == DevActionInfo->DevActionState.SceneState)
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景关");
							DevAction_ExpandClose(DevActionInfo, SLEEP_MODE_CTRL);     //执行当前场景，灯光类设备关闭								
						}
						break;
				}				
			}
			else          //与夜灯无关
			{
				if(DEV_STATE_CLOSE == DevActionInfo->DevActionState.SceneState)   //当前场景为关
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景开");
					DevAction_ExpandLightOpen(DevActionInfo);     //打开当前场景的灯光
				}
				else if(DEV_STATE_OPEN == DevActionInfo->DevActionState.SceneState)   //当前场景为开
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 场景可关闭开始对所有设备输出状态进行赋值:准备执行场景关");
					DevAction_ExpandClose(DevActionInfo, SLEEP_MODE_CTRL);     //执行当前场景				
				}
				if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
				{
					DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
				}
			}
			break;			
		case LIGHT_SCENE_SLEEP:          //睡眠模式 ，全部关才算开，有一个开就算关。
			if(0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)  //与夜灯有关  且夜灯存在
			{
				if(NightModeStart != DevActionGlobal.DevActionU64Cond.NeightState)
				{
					DevActionGlobal.DevActionU64Cond.NeightState = NightModeStart;     //进入起夜
					DevAction_ExpandClose(DevActionInfo, SLEEP_MODE_CTRL);     //睡眠场景为开 但是得关闭所有灯  并播放相应词条 
					DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
					DevActionGlobal.SleepLight_State = 0x00; 				//熄灭   2025-09-05
					
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景 1");
				}
				else
				{
					DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
					DevAction_ExpandLightOpen(DevActionInfo); 	//打开夜灯
					DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
					Logic_Music_Ctrl(NULL, NULL, Find_Device_List_Information(0x15,0x01), 0x00, 0x0020);  //起夜关音乐
					
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 1");
				}
			}
			else
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 睡眠场景开始对所有设备输出状态进行赋值:");						
				DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
				DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式关   2025-09-05
				DevActionGlobal.SleepLight_State = 0x00; 				//熄灭   2025-09-05
				
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景 2");
			}
			break;
		case LIGHT_SCENE_HELPSLEEP:  //助眠模式   按下打开夜灯开启标志。此时按下普通按键，就能关闭夜灯，并取消睡眠倒计时
			if((0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)&& (0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag))  //与夜灯有关  且夜灯存在
			{
				switch(DevActionGlobal.DevActionU64Cond.NeightState)
				{
					case NightModeStart:
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景助眠  准备执行打开夜灯:");						
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
						DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_OPEN);//打开夜灯  并取消睡眠倒计时
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
						}
						Logic_Music_Ctrl(NULL, NULL, Find_Device_List_Information(0x15,0x01), 0x00, 0x0020);  //起夜关音乐
						break;
					case NightModeClose:
					case NightModeOpen:	
						if(NightModeOpen == DevActionGlobal.DevActionU64Cond.NeightState)   //夜灯标志开启
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景助眠将夜灯标志关闭");											
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
							DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_CLOSE);//关闭夜灯
						}
//						else if(NightModeClose == DevActionGlobal.DevActionU64Cond.NeightState)  //夜灯标志关闭
//						{
//							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景助眠将夜灯标志打开");						
//							
//							DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;   //夜灯标志开启
//						}
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 场景助眠开始对所有设备输出状态进行赋值:");						
						DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeStart;     //进入起夜
							DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
							DevActionGlobal.SleepLight_State = 0x00; 				//熄灭   2025-09-05
							
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景 3");
						}
						
						break;
				}
			}
			else
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 助眠场景开始对所有设备输出状态进行赋值:");						
				DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
				if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
				{
					DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
					DevActionGlobal.SleepLight_State = 0x00; 				//熄灭   2025-09-05
					
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景 4");
				}
			}			
			break;
		#if RS485_Switch_Rotary_Flag
		case LIGHT_SCENE_Rotary:          //旋转场景
			if((0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag) && (0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag))  //与夜灯有关
			{
				switch(DevActionGlobal.DevActionU64Cond.NeightState)
				{
					case NightModeStart:
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 旋钮场景  准备执行打开夜灯:");						
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeOpen;
						DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_OPEN);//打开夜灯
						if(DevActionInfo->DevActionInput.DevType == DEV_RS485_SWT)
						{
							DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
						}
						break;
					case NightModeClose:
					case NightModeOpen:	
						if(NightModeOpen == DevActionGlobal.DevActionU64Cond.NeightState)
						{
							DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
							DevAction_No_Ctrl(DevActionGlobal.SleepActionNo, 0x02, DEV_CTRLWAY_CLOSE);//关闭夜灯
						}
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯有关 旋钮场景 开始对所有设备输出状态进行赋值:");						
						DevAction_RotaryCtrl(DevActionInfo);
						break;
				}
			}
			else
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 旋钮场景开始对所有设备输出状态进行赋值:");		
				DevAction_RotaryCtrl(DevActionInfo);
			}
			break;
		#endif
		case LIGHT_SCENE_SLEEP_UNRELATED:
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"与夜灯无关 无卡取电-任意按键  准备执行打开夜灯:");			
			DevAction_ExpandCtrl(DevActionInfo);     //执行当前场景
			break;
		default:
			
			break;
	}
	
	if(DevActionGlobal.DevActionU64Cond.NeightState != DevActionGlobal.Last_NeightState){   //2025-09-11
//		DevActionGlobal.Last_NeightState2 = DevActionGlobal.DevActionU64Cond.NeightState;
		DevActionGlobal.Last_NeightState = DevActionGlobal.DevActionU64Cond.NeightState;
	}
	
}

/**
*@name 设备动作反馈灯输出执行
*@para 
* DevActionInfo   当前设备动作
*@Ret  无
*/
void DevAction_IndicateCtrl(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	uint8_t CtrlWay;
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景状态改变准备执行反馈灯控制：场景名:%s，控制状态：%d,设备数量:%d",DevActionInfo->DevActionCore.DevActionName, DevActionInfo->DevActionState.SceneState, DevActionInfo->DevCtrlNum);
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)      //
	{		
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"设备下标：%d，设备地址:%08X", i, DevAddrOut);

		if(NULL != DevAddrOut)
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType) //能作为反馈灯的设备类型
			{
				case DEV_SWI_TYPE:         //开关类型
				case Dev_Host_LVoutput:    //弱电输出
					CtrlWay = DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff;  //执行方式
					switch(CtrlWay)
					{
						case DEV_CTRLWAY_RELATESCENE:
							switch(DevActionInfo->DevActionState.SceneState)
							{
								case DEV_STATE_OPEN:
								case DEV_STATE_CLOSE:
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"反馈灯控制顺便清延时执行,设备类型: %d 地址:%d，回路:%d，状态:%d",BUS_Public.type, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionState.SceneState);
									DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x00, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x00);//关闪烁 关延时					
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)
									{
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionState.SceneState);   //根据场景状态去控制反馈灯
									}
									break;
							}
							break;
						case CFG_Dev_CtrlWay_Is_RelateBlink:
							if(0x00 != DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)  //立即执行
							{
								switch(DevActionInfo->DevActionState.SceneState)
								{
									case DEV_STATE_OPEN:   //开启闪烁  应先开指示灯
										SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据							
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"开启闪烁,状态:%04X",CFG_Dev_CtrlWay_Is_TOGGLE |(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0xff00));
										DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, CFG_Dev_CtrlWay_Is_TOGGLE |(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0xff00), DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x01);//
										if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)
										{
											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_OPEN|(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0xff00));   //先开
										}
										break;
									case DEV_STATE_CLOSE:  //关闭闪烁  应后关指示灯
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"关闭闪烁");
										DevDly_InfoSet(DevActionInfo->DevActionOutput[i].DevDlyAddr, 0x01, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevDlyValue, 0x02);//
//											BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DEV_CTRLWAY_CLOSE);   //根据场景状态去控制反馈灯
										break;
								}
							}							
							break;
					}
					break;
				case Dev_NodeCurtain:
					if(DEV_CTRLWAY_RELATESCENE == (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff)) //对应场景//当前场景为开  且输入类型为开关停
					{
						if(DEV_STATE_OPEN == DevActionInfo->DevActionState.SceneState)  //当前场景为开
						{
							switch(DevActionInfo->DevActionInput.inType)  //输入类型为
							{
								case DEV_CTRLWAY_OPEN:  //开
								case DEV_CTRLWAY_CLOSE: //关
								case DEV_CTRLWAY_STOP:  //停
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
//									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"反馈灯控制,设备类型: %d 地址:%d，回路:%d，状态:%d",BUS_Public.type, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionState.SceneState);
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"反馈灯控制顺便清延时执行,设备类型: %d 地址:%d，回路:%d，状态:%d",BUS_Public.type, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionState.SceneState);
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Ctrl)
									{
										BUS_Public.DevFunInfo.Dev_Output_Ctrl(NULL, NULL, DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop, DevActionInfo->DevActionInput.inType);   //根据输入类型去控制窗帘状态
									}
									break;
							}
						}
					}
					break;
			}
		}
	}
}




#if 1 
/**
*@name 扩展场景状态得到函数
*@para 
* DevActionInfo   当前设备动作
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数
*     2022-09-03
*/
void Expand_State_Get(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;   //相同地址计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	uint8_t DevCtrlWay;     //执行方式
	uint8_t DevCtrlCont;    //执行内容
	uint8_t SceneState = 0x00;
	uint8_t SceneType = 0x01;

	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;   //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;     //调光存在计数

	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x01);

	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr)   //非空
									{
										if(DEV_STATE_CLOSE == BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr(DevAddrOut, SceneType, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState))
										{
											SceneState = DEV_STATE_CLOSE;   //只赋值关
										}
//										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控读取开始，回路标志:%08X 场景名:%s 场景状态:%d", expand_type[j].ExpandReadFlag, DevActionInfo->DevActionCore.DevActionName, SceneState);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;								
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr)   //非空
									{
										if(DEV_STATE_CLOSE == BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr(DevAddrOut, SceneType, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState))
										{
											SceneState = DEV_STATE_CLOSE;
										}
		//								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光3状态群控读取开始0，回路标志:%08X 场景名:%s 场景状态:%d", C12DimmingReadFlag3, DevActionInfo->DevActionCore.DevActionName, SceneState);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif
			}
		}
	}	
	


	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第3次遍历  除了继电器和调光 其他的设备
	{
		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_SWT:
					case Dev_Host_Service:  //服务信息	
//					case DEV_C5MUSIC_Type:
//					case Dev_NodeCurtain:
					case Dev_Scene_Restore:
						if(DevActionInfo->DevActionCond.SceneExcute != LIGHT_SCENE_SLEEP)
						{
							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(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
									{
			//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
										break;            //跳出switch循环
									}
								}
							}
						}
						break;
					#if RS485_PB20_Relay_Flag
					case Dev_Rs485_PB20_Relay:
						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(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
								{
		//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
									SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
									break;            //跳出switch循环
								}
							}
						}
						break;
					#endif
					case Dev_NodeCurtain:     //窗帘
					case DEV_RS485_CURTAIN:
						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(DevActionInfo->DevActionCond.SceneExcute != LIGHT_SCENE_SLEEP)      //202404-13
							{
								if((DEV_CTRLWAY_OPEN == DevCtrlWay)
								||(DEV_CTRLWAY_CLOSE == DevCtrlWay)
								||(DEV_CTRLWAY_STOP == DevCtrlWay)
								||(0x15 == DevCtrlWay)
								||(0x16 == DevCtrlWay))   //且控制状态 为开和关
								{
									if(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
									{
			//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
										break;            //跳出switch循环
									}
								}
								else if((CFG_Dev_CtrlWay_Is_TOGGLE == DevCtrlWay)
									   ||(0x05 == DevCtrlWay))    //配置的窗帘取反  控制百分比
								{
									if(DEV_CTRLWAY_STOP == BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))  //为停就判为场景关
									{
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
										break;            //跳出switch循环									
									}
								}
							}
						}
						break;
	//				case DEV_RS485_PWM:   //PWM调光
					case DEV_RS485_STRIP:            //RGB调光
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据					
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							DevCtrlCont = ((DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState)>>8)&0x00ff;  //高字节
							if(DevCtrlCont != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
							{
								SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
								break;
							}
						}
						break;
					#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;  //高字节
							/*2025-07-11 色温加入开关状态 判断需根据开关状态处理*/
//							if((DevCtrlWay == 0x01) || (DevCtrlWay == 0x02) ){
//								if(DevCtrlCont != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
//								{
//									SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
//									break;
//								}
//							}
							
							if(DevCtrlWay == 0x01)
							{
								DevCtrlCont |= 0x80;
								if(DevCtrlCont != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
								{
                                 //   Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"YYW111 DevCtrlCont:%d,light:%d", DevCtrlCont,BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop));
									SceneState = DEV_STATE_CLOSE;	//只要有一个状态不满足就跳出 此时场景状态为关	
									break;
								}
							}else if(DevCtrlWay == 0x02){
								/*关状态下 - 只判断最高位*/
								if((DevCtrlCont & 0x80) != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80) ) 
								{
                                //    Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"YYW222 DevCtrlCont:%d,light:%d", DevCtrlCont,BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop));
									SceneState = DEV_STATE_CLOSE;	//只要有一个状态不满足就跳出 此时场景状态为关	
									break;
								}
							}
							
						}
						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(0x80 == (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80))
									{
										if(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)) 
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									break;
								case PB20_Strip_OnlySwitch:
									if(DevCtrlCont == 0x02)
									{
										DevCtrlCont = 0x00;
									}
									if(DevCtrlCont != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) 
									{
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
										break;
									}
									break;
								case PB20_Strip_LIGHT_OPEN:
								case PB20_Strip_LIGHT_CLOSE:
									if(CtrlWay == 0x01)
									{
										if((CtrlWay != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) ||
											(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)))
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									else if(CtrlWay == 0x02)
									{
										CtrlWay = 0x00;
										if((CtrlWay != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) ||
											(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)))
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									break;
								default:break;
							}
							
						}
						break;
					#endif
					case DEV_C5MUSIC_Type:     //2023-02-28
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							if(DevActionInfo->DevActionCond.SceneExcute != LIGHT_SCENE_SLEEP)     //2024-04-29
							{
								if(BUS_Public.Protocol == 0x01)
								{
									DEV_MUSIC_CTRLSTATE DevMusicCtrlState;
									BLV_Music_CtrlState_Get(&DevMusicCtrlState,DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									if(DevMusicCtrlState.DevMusicCtrlWay.CtrlDirect == 0x00)
									{
										DevCtrlWay = DevMusicCtrlState.DevMusicCtrlWay.CtrlDir;
										if((0x01 == DevCtrlWay)    
											||(0x02 == DevCtrlWay)
											) 
										{    
											if(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
											{
												SceneState = DEV_STATE_CLOSE;     
												break;           
											}
										}
									}
								}
								else if((BUS_Public.Protocol == 0x02) || (BUS_Public.Protocol == 0x06))
								{
									RS485_MUSIC_INFO Rs485Music;
									BLV_Music_CtrlState_Get(&Rs485Music.DevMusicCtrlState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop],DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState);
									if(Rs485Music.DevMusicCtrlState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop].DevMusicCtrlWay.CtrlDirect == 0x00)
									{
										DevCtrlWay = Rs485Music.DevMusicCtrlState[DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop].DevMusicCtrlWay.CtrlDir;
										if((0x01 == DevCtrlWay)    
											||(0x02 == DevCtrlWay)
											) 
										{    
											if(DevCtrlWay != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)>>8)&0x0F))
											{
												SceneState = DEV_STATE_CLOSE;     
												break;           
											}
										}
									}
								}
							}
							
							

						}
						break;
					#if Dev_485_BLE_Music_Flag
					case Dev_485_BLE_Music:
						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)&0x0f;        
							DevCtrlCont = (DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevCtrlState >> 4)&0x0f;
							
							if(DevCtrlWay == 0x03)    //指定播放文件
							{
								if((DevCtrlCont == 0x01) || (DevCtrlCont == 0x02))    //播放文件夹
								{
									if(DevCtrlCont != ( (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) >> 8) & 0xff) )    //与当前播放的文件夹不同
									{
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
										break;
									}
									else
									{
										if( (0x01 == ( BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0xff) ) \
										||(0x02 == ( BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0xff) ))       //与当前播放文件夹相同但播放停止
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
								}
							}
						}
						break;
					#endif
					#if Dev_Nor_Carbon_Flag
					case DEV_Carbon_Saved:
						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(0x01 == DevCtrlWay)   //且控制节能状态 开和关
							{
								if(DevCtrlCont != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
								{
		//						    Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
									SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
									break;            //跳出switch循环
								}
							}
						}
						break;
					#endif
				}
			}
			if(DEV_STATE_CLOSE == SceneState) break;   //跳出for循环
		}
	}
	if(00 == SceneState)
	{
		SceneState = DEV_STATE_OPEN;       //场景状态为开
	}
	
	if(SceneState != DevActionInfo->DevActionState.SceneState)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit," 当前场景名:%d 场景状态:%d", DevActionInfo->DevActionCore.ActionNo, SceneState);
		DevActionInfo->DevActionState.SceneState = SceneState;   //1开 2关  0未初始化 
	}
	
}
#endif

void Sleep_State_Get(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;   //相同地址计数
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	uint8_t DevCtrlWay;     //执行方式
	uint8_t DevCtrlCont;    //执行内容
	uint8_t SceneState = 0x00;
//	uint8_t SceneType = 0x01;

	EXPAND_TYPE_G expand_type[30]={0};
//	uint8_t expandexnum=0;   //继电器存在计数
	
	DIMM_TYPE_G dimm_type[30]={0};
//	uint8_t dimmexnum=0;     //调光存在计数


	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x01);

	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
						if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get)   //非空
						{
							if(DEV_STATE_OPEN == BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
							{
								SceneState = DEV_STATE_CLOSE;   //只赋值关
								break;
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_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)   //非空
						{
							if(0x00 != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
							{
								SceneState = DEV_STATE_CLOSE;
								break;
							}
						}
						break;
				#endif
			}
		}
	}	
	


	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第3次遍历  除了继电器和调光 其他的设备
	{
		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_SWT:
//					case Dev_Host_Service:  //服务信息	
////					case DEV_C5MUSIC_Type:
////					case Dev_NodeCurtain:
//						if(DevActionInfo->DevActionCond.SceneExcute != LIGHT_SCENE_SLEEP)
//						{
//							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(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
//									{
//			//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
//										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
//										break;            //跳出switch循环
//									}
//								}
//							}
//						}
//						break;
					#if C8_TYPE
					case Dev_Rs485_PB20_Relay:
						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(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
								{
		//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
									SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
									break;            //跳出switch循环
								}
							}
						}
						break;
					#endif
//					case Dev_NodeCurtain:     //窗帘
//					case DEV_RS485_CURTAIN:
//						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(DevActionInfo->DevActionCond.SceneExcute != LIGHT_SCENE_SLEEP)     //2024-04-10
//							{
//								if((DEV_CTRLWAY_OPEN == DevCtrlWay)
//								||(DEV_CTRLWAY_CLOSE == DevCtrlWay)
//								||(DEV_CTRLWAY_STOP == DevCtrlWay)
//								||(0x15 == DevCtrlWay)
//								||(0x16 == DevCtrlWay))   //且控制状态 为开和关
//								{
//									if(DevCtrlWay != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))
//									{
//			//												Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，有扩展设备不满足场景:类型:%d 回路:%d",DevActionInfo->DevActionCore.ActionNo, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);		//	
//										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
//										break;            //跳出switch循环
//									}
//								}
//								else if(CFG_Dev_CtrlWay_Is_TOGGLE == DevCtrlWay)    //配置的窗帘取反
//								{
//									if(DEV_CTRLWAY_STOP == BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop))  //为停就判为场景关
//									{
//										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关
//										break;            //跳出switch循环									
//									}
//								}
//							}
//							
//						}
//						break;
	//				case DEV_RS485_PWM:   //PWM调光
//					case DEV_RS485_STRIP:            //RGB调光
					#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(0x80 == (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80))
									{
										if(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)) 
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									break;
								case PB20_Strip_OnlySwitch:
									if(DevCtrlCont == 0x02)
									{
										DevCtrlCont = 0x00;
									}
									if(DevCtrlCont != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) 
									{
										SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
										break;
									}
									break;
								case PB20_Strip_LIGHT_OPEN:
								case PB20_Strip_LIGHT_CLOSE:
									if(CtrlWay == 0x01)
									{
										if((CtrlWay != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) ||
											(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)))
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									else if(CtrlWay == 0x02)
									{
										CtrlWay = 0x00;
										if((CtrlWay != ((BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x80)>>7)) ||
											(DevCtrlCont != (BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop) & 0x7f)))
										{
											SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
											break;
										}
									}
									break;
								default:break;
							}
							
						}
						break;
					#endif
					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(DevCtrlCont != BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
								{
									SceneState = DEV_STATE_CLOSE;     //只要有一个状态不满足就跳出 此时场景状态为关												
									break;
								}
							}
						}
						break;

				}
			}
			if(DEV_STATE_CLOSE == SceneState) break;   //跳出for循环
		}
	}
	
	
	
	if(00 == SceneState)
	{
		SceneState = DEV_STATE_OPEN;       //场景状态为开
	}
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit," 当前场景名:%s 场景状态:%d", DevActionInfo->DevActionCore.DevActionName, SceneState);
	
//	if(DevActionInfo->DevActionCond.SceneExcute == LIGHT_SCENE_SLEEP)     //2024-04-10
//	{
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit," 当前场景号:%d 场景状态:%d", DevActionInfo->DevActionCore.ActionNo, SceneState);
//	}
	
	DevActionInfo->DevActionState.SceneState = SceneState;   //1开 2关  0未初始化 
}


/**
*@name 总开关扩展场景状态得到函数
*@para 
* DevActionInfo   当前设备动作
*@Ret  1 为开  2为关
*@brief 遍历所有的设备，把同类的设备转换成数组，然后通过数组去调用组得到函数
*			继电器和C12调光用群控函数  
*@attention 注意总开关场景，仅判断开的灯，有一个灯开，场景状态为开。全关才为关。
*     2022-09-03
*/
void MainSwitch_Expand_State_Get(DEV_ACTION_INFO *DevActionInfo)
{
	uint8_t i;//,j;
//	uint8_t TNum=0;
	uint32_t DevAddrOut;  //设备地址局部变量
	Device_Public_Information_G BUS_Public;   //共用
	uint8_t DevCtrlWay;     //执行方式
	uint8_t DevCtrlCont;    //执行内容
	uint8_t SceneState = 0x00;
	uint8_t SceneType = 0x02;
	
	EXPAND_TYPE_G expand_type[30]={0};
	
	DIMM_TYPE_G dimm_type[30]={0};

	Expand_And_Dimm_Action_Get(DevActionInfo,expand_type,dimm_type,0x01);
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)   //第二次遍历，优先处理群控设备，每种群控处理一次就好
	{
		DevAddrOut = DevActionInfo->DevActionOutput[i].DevActionOutAddr;//
		if(NULL != DevAddrOut)   
		{
			switch(DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevType)
			{
				case Dev_Host_HVout:  //扩展板
						for(uint8_t j=0;j<30;j++)
						{
							if(expand_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=expand_type[j].ExpandReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr)   //非空
									{
										if(DEV_STATE_OPEN == BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr(DevAddrOut, SceneType, expand_type[j].ExpandReadFlag, HVoutNumMAX, expand_type[j].ExpandReadState))
										{
											SceneState = DEV_STATE_OPEN;   //只赋值开
										}
				//						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"继电器状态群控读取开始0，回路标志:%08X 场景名:%s 场景状态:%d", ExpandReadFlag0, DevActionInfo->DevActionCore.DevActionName, SceneState);
									}
									expand_type[j].ExpandReadFlag=0x00;
								}
								break;								
							}
						}
						break;
				#if RS485_LED_Flag
				case DEV_RS485_PWM:
						for(uint8_t j=0;j<30;j++)
						{
							if(dimm_type[j].Addr==DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevAddr)
							{
								if(0x00!=dimm_type[j].DimmReadFlag)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAddrOut);	//拷贝所有共有数据
									if(NULL != BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr)   //非空
									{
										if(DEV_STATE_OPEN == BUS_Public.DevFunInfo.Dev_Output_Loop_Group_State_Get_ptr(DevAddrOut, SceneType, dimm_type[j].DimmReadFlag, LED_OUT_CH_MAX, dimm_type[j].DimmReadState))
										{
											SceneState = DEV_STATE_OPEN;
										}
		//								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"调光3状态群控读取开始0，回路标志:%08X 场景名:%s 场景状态:%d", C12DimmingReadFlag3, DevActionInfo->DevActionCore.DevActionName, SceneState);
									}
									dimm_type[j].DimmReadFlag = 0x00;
								}
								break;
							}
						}
						break;
				#endif
			}
		}
	}
	
	
	for(i = 0; i < DevActionInfo->DevCtrlNum; i++)        //第3次遍历，除继电器和调光的其他设备
	{
		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_RS485_PWM:   //PWM调光
					case DEV_RS485_STRIP:            //RGB调光
					case Dev_Rs485_PB20:
					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(0x01 == DevCtrlWay)
							{
								if(DevCtrlCont == BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
								{
									SceneState = DEV_STATE_OPEN;     //只要有一个状态满足就跳出 此时场景状态为开												
									break;
								}
							}
						}
						break;
					case Dev_Scene_Restore:
						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((0x01 == DevCtrlWay) || (0x02 == DevCtrlWay))
							{
								if(DevCtrlWay == BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get(DevAddrOut, DevActionInfo->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)) 
								{
									SceneState = DEV_STATE_OPEN;     //只要有一个状态满足就跳出 此时场景状态为开												
									break;
								}
							}
						}
						break;
				}
			}
			if(DEV_STATE_OPEN == SceneState) break;   //跳出for循环
		}
	}
	if(00 == SceneState)
	{
		SceneState = DEV_STATE_CLOSE;       //场景状态为关
	}
	
//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit," 当前场景名:%s 场景状态:%d", DevActionInfo->DevActionCore.DevActionName, SceneState);
	
	DevActionInfo->DevActionState.SceneState = SceneState;   //1开 2关  0未初始化 
}

/**
	*@name 设备动作状态得到
	*@para 
	* DevActionInfo   当前设备动作
	*@ret  无
	*@brief  状态 1开 2关  0未初始化
	*/
void DevAction_State_Get(DEV_ACTION_INFO *DevActionInfo)
{
//	uint8_t i;
//	uint32_t DevAddrOut;  //设备地址局部变量
//	uint8_t SceneState = 0;   //场景状态 对于普通场景，只要有一个灯不满足，就算关
	
	switch(DevActionInfo->DevActionCond.SceneExcute)
	{
		case LIGHT_SCENE_SLEEP:  //睡眠模式
			if(0x01 == DevActionGlobal.DevActionU64Cond.NeightFlag)    //夜灯存在
			{
				if(NightModeStart == DevActionGlobal.DevActionU64Cond.NeightState)   //进入起夜 场景状态为开
				{
					DevActionInfo->DevActionState.SceneState = DEV_STATE_OPEN;   //为开
					if( DevActionGlobal.SleepLight_State != 0x01 )
					{
						DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
						
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"进入睡眠场景 5");
					}
				}
				else
				{
//					if(NightModeClose == DevActionGlobal.DevActionU64Cond.NeightState)
//					{
//						Sleep_State_Get(DevActionInfo); 
////						Dbg_Println(DBG_BIT_SYS_STATUS_bit,"------DevAction_State_Get:%d  %d---------\r\n",\
//						DevActionInfo->DevActionState.SceneState,DevActionInfo->DevActionState.SceneStateLast);
//						if(DevActionInfo->DevActionState.SceneState == DEV_STATE_OPEN)
//						{
//							DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
//							DevActionGlobal.DevActionU64Cond.NeightState = NightModeStart;
//						}
//					}
				}
				
				if(DevActionGlobal.CardInFlag == 0x01)
				{
					Sleep_State_Get(DevActionInfo); 
					if(DevActionInfo->DevActionState.SceneState == DEV_STATE_CLOSE)
					{
						DevActionGlobal.CardInFlag = 0x00;
						DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
						DevActionGlobal.DevActionU64Cond.NeightState = NightModeClose;
						
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -5");
					}
				}
				break;  //带夜灯  直接跳出
			}
			else 
			{
				Expand_State_Get(DevActionInfo); 
				if(DevActionInfo->DevActionState.SceneState==DEV_STATE_OPEN)
				{
//					DevActionGlobal.SleepMode_State = 0x01;					//睡眠模式开   2025-09-05
//					DevActionGlobal.SleepLight_State = 0x00; 
				}
				else if(DevActionInfo->DevActionState.SceneState == DEV_STATE_CLOSE)
				{
					if(DevActionGlobal.CardInFlag == 0x01)
					{
						DevActionGlobal.CardInFlag = 0x00;
						DevActionGlobal.SleepMode_State = 0x00;					//睡眠模式关   2025-09-05
						
						Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"退出睡眠场景 -6");
					}
				}
			}
		case LIGHT_SCENE_ONE:  //不可关闭
		case LIGHT_SCENE_TWO:  //可关闭	
		case LIGHT_SCENE_HELPSLEEP:  //助眠场景
			Expand_State_Get(DevActionInfo); 			        //场景状态得到
			break;
		case LIGHT_SCENE_MAINSWITCH:  //总开关
			MainSwitch_Expand_State_Get(DevActionInfo);   //场景状态得到
			break;
	}
	
	if(DevActionGlobal.DevActionU64Cond.NeightState != DevActionGlobal.Last_NeightState){   //2025-09-11
//		DevActionGlobal.Last_NeightState2 = DevActionGlobal.DevActionU64Cond.NeightState;
		DevActionGlobal.Last_NeightState = DevActionGlobal.DevActionU64Cond.NeightState;
	}
	
	
}

#if LOGIC_FILE_EN
/**
	*@name  条件判断  
	*@para
	*@ret
  *@brief 状态1有效 且状态1和2一样，返回通过  或者 状态1无效 直接返回通过
	*/
uint8_t CondJudge(uint8_t State1, uint8_t State2)
{
	if((0x00 == State1) || ((0x00 != State1)&&(State1 == State2)))
	{
		return CondIsPass;
	}
	else
	{
		return CondIsNotPass;  
	}

}
#else

/*单个条件比较函数*/
uint8_t CondJudge(uint8_t Flag, uint8_t State1, uint8_t State2)
{
	if((0x01 == Flag) && (State1 != State2))
	{
		return CondIsNotPass;  
	}
	else
	{
		return CondIsPass;
	}

}
#endif

/**
	*@name RCU锁定状态扫描
	*@para 无
	*@Ret  无
  *@brief 从正常到授权，取电服务会关闭
	*/
void RcuLockState_Scan(void)
{
	uint8_t LockState;

	LockState = Get_Authorize_Lock_Status();   //拿到RCU的锁状态  1，锁定  0，正常
	if(DevActionGlobal.DevActionU64Cond.RcuLockState != LockState)  //锁状态变了
	{
		DevActionGlobal.DevActionU64Cond.RcuLockState = LockState; //同步
		switch(DevActionGlobal.DevActionU64Cond.RcuLockState)
		{
			case 0x01:   //锁定
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"RCU已锁定，导致取电服务关闭");
				Ele_Ctrl_OpenClose(0x02);   //断电
				break;
			case 0x00:  //正常
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"RCU已解锁，欢迎正常使用");
				break;
		}
	}  	
}

#if LOGIC_FILE_EN
/*******************************************************************************
* @Function Name  : BLV_DevAction_Cond_Judge 
* @Description    : 设备动作条件判断函数
* @Input          : 
*		DevActionAddr	: 设备动作地址
* @Ret            1条件满足  0条件不满足  主要两种条件 全局条件有8位 普通条件56位
* @Attention      : 判断8个字节的条件，满足就返回1，不满足就返回0
*******************************************************************************/
uint8_t BLV_DevAction_Cond_Judge(DEV_ACTION_INFO *DevActionInfo)
{	
	
	if(0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.DevActionOutFlag)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作已锁定");
		return CondIsNotPass;     //锁定直接返回
	}
             
	
	/*普通条件判断开始*/
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.RoomState, DevActionGlobal.DevActionU64Cond.RoomState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"房态未判断通过"); return CondIsNotPass; }    //房态
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.EleState, DevActionGlobal.DevActionU64Cond.EleState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"取电未判断通过"); return CondIsNotPass; }    //取电
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.DndState, DevActionGlobal.DevActionU64Cond.DndState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"勿扰未判断通过"); return CondIsNotPass; }     //勿扰
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CleanState, DevActionGlobal.DevActionU64Cond.CleanState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"清理未判断通过"); return CondIsNotPass; }  //清理
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CallState, DevActionGlobal.DevActionU64Cond.CallState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"呼叫未判断通过"); return CondIsNotPass; }  //呼叫
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WashState, DevActionGlobal.DevActionU64Cond.WashState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"洗衣未判断通过"); return CondIsNotPass; }   //洗衣
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CheckOutState, DevActionGlobal.DevActionU64Cond.CheckOutState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"退房未判断通过"); return CondIsNotPass; }   //退房
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WaitState, DevActionGlobal.DevActionU64Cond.WaitState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"稍后未判断通过"); return CondIsNotPass; }  //稍后
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.SosState, DevActionGlobal.DevActionU64Cond.SosState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"SOS未判断通过"); return CondIsNotPass; }   //SOS
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.RentState, DevActionGlobal.DevActionU64Cond.RentState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"预约待租未判断通过"); return CondIsNotPass; }   //预约待租
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.LockState, DevActionGlobal.DevActionU64Cond.LockState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"开锁未判断通过"); return CondIsNotPass; }  //开锁
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.LuggageState, DevActionGlobal.DevActionU64Cond.LuggageState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"行李未判断通过"); return CondIsNotPass; }   //行李
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.StrongState, DevActionGlobal.DevActionU64Cond.StrongState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"保险箱未判断通过"); return CondIsNotPass; }  //保险箱
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.DoorState, DevActionGlobal.DevActionU64Cond.DoorState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"门磁未判断通过"); return CondIsNotPass; }  //门磁
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.SeasonState, DevActionGlobal.DevActionU64Cond.SeasonState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"季节未判断通过"); return CondIsNotPass; }  //季节
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.TimeState, DevActionGlobal.DevActionU64Cond.TimeState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"时间未判断通过"); return CondIsNotPass; }  //时间
//	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag, DevActionInfo->DevActionCond.DevActionU64Cond.NeightState, DevActionGlobal.DevActionU64Cond.NeightState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"起夜未判断通过"); return CondIsNotPass; }  //起夜
//	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockState, DevActionGlobal.DevActionU64Cond.RcuLockState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"授权条件未判断通过,场景名:%s",DevActionInfo->DevActionCore.DevActionName); return CondIsNotPass; } //锁定     DevActionGlobal.DevActionU64Cond.RcuLockState
	
	if((0x00 != DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockState)&&
		(((0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockState)&&(0x00 == DevActionGlobal.DevActionU64Cond.RcuLockState))
	||((0x02 == DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockState)&&(0x01 == DevActionGlobal.DevActionU64Cond.RcuLockState)))
	)
	{Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"授权条件未判断通过,场景名:%s",DevActionInfo->DevActionCore.DevActionName); return CondIsNotPass; } //锁定 
	
		
	/*普通条件判断开始*/
	
	return CondIsPass;
}
#else
/*******************************************************************************
* @Function Name  : BLV_DevAction_Cond_Judge 
* @Description    : 设备动作条件判断函数
* @Input          : 
*		DevActionAddr	: 设备动作地址
* @Ret            1条件满足  0条件不满足  主要两种条件 全局条件有8位 普通条件56位
* @Attention      : 判断8个字节的条件，满足就返回1，不满足就返回0
*******************************************************************************/
uint8_t BLV_DevAction_Cond_Judge(DEV_ACTION_INFO *DevActionInfo)
{	
	
	if(0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.DevActionOutFlag)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作已锁定");
		return CondIsNotPass;     //锁定直接返回
	}
	if(0x01 == DevActionInfo->DevActionCond.DevActionU64Cond.RoomFlag)  //房态关联置位
	{
		if(DevActionGlobal.DevActionU64Cond.RoomState != DevActionInfo->DevActionCond.DevActionU64Cond.RoomState)  //房态对不上直接返回
		{
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"房态未判断通过");
			return CondIsNotPass;
		}
	}
             
	
	/*普通条件判断开始*/
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.EleFlag, DevActionInfo->DevActionCond.DevActionU64Cond.EleState, DevActionGlobal.DevActionU64Cond.EleState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"取电未判断通过"); return CondIsNotPass; }    //取电
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.DndFlag, DevActionInfo->DevActionCond.DevActionU64Cond.DndState, DevActionGlobal.DevActionU64Cond.DndState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"勿扰未判断通过"); return CondIsNotPass; }     //勿扰
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CleanFlag, DevActionInfo->DevActionCond.DevActionU64Cond.CleanState, DevActionGlobal.DevActionU64Cond.CleanState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"清理未判断通过"); return CondIsNotPass; }  //清理
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CallFlag, DevActionInfo->DevActionCond.DevActionU64Cond.CallState, DevActionGlobal.DevActionU64Cond.CallState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"呼叫未判断通过"); return CondIsNotPass; }  //呼叫
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WashFlag, DevActionInfo->DevActionCond.DevActionU64Cond.WashState, DevActionGlobal.DevActionU64Cond.WashState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"洗衣未判断通过"); return CondIsNotPass; }   //洗衣
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.CheckOutFlag, DevActionInfo->DevActionCond.DevActionU64Cond.CheckOutState, DevActionGlobal.DevActionU64Cond.CheckOutState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"退房未判断通过"); return CondIsNotPass; }   //退房
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.WaitFlag, DevActionInfo->DevActionCond.DevActionU64Cond.WaitState, DevActionGlobal.DevActionU64Cond.WaitState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"稍后未判断通过"); return CondIsNotPass; }  //稍后
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.SosFlag, DevActionInfo->DevActionCond.DevActionU64Cond.SosState, DevActionGlobal.DevActionU64Cond.SosState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"SOS未判断通过"); return CondIsNotPass; }   //SOS
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.RentFlag, DevActionInfo->DevActionCond.DevActionU64Cond.RentState, DevActionGlobal.DevActionU64Cond.RentState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"预约待租未判断通过"); return CondIsNotPass; }   //预约待租
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.LockFlag, DevActionInfo->DevActionCond.DevActionU64Cond.LockState, DevActionGlobal.DevActionU64Cond.LockState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"开锁未判断通过"); return CondIsNotPass; }  //开锁
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.LuggageFlag, DevActionInfo->DevActionCond.DevActionU64Cond.LuggageState, DevActionGlobal.DevActionU64Cond.LuggageState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"行李未判断通过"); return CondIsNotPass; }   //行李
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.StrongFlag, DevActionInfo->DevActionCond.DevActionU64Cond.StrongState, DevActionGlobal.DevActionU64Cond.StrongState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"保险箱未判断通过"); return CondIsNotPass; }  //保险箱
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.DoorFlag, DevActionInfo->DevActionCond.DevActionU64Cond.DoorState, DevActionGlobal.DevActionU64Cond.DoorState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"门磁未判断通过"); return CondIsNotPass; }  //门磁
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.SeaSonFlag, DevActionInfo->DevActionCond.DevActionU64Cond.SeasonState, DevActionGlobal.DevActionU64Cond.SeasonState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"季节未判断通过"); return CondIsNotPass; }  //季节
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.TimeFlag, DevActionInfo->DevActionCond.DevActionU64Cond.TimeState, DevActionGlobal.DevActionU64Cond.TimeState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"时间未判断通过"); return CondIsNotPass; }  //时间
//	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.NeightFlag, DevActionInfo->DevActionCond.DevActionU64Cond.NeightState, DevActionGlobal.DevActionU64Cond.NeightState)){Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"起夜未判断通过"); return CondIsNotPass; }  //起夜
	if(CondIsNotPass == CondJudge(DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockFlag, DevActionInfo->DevActionCond.DevActionU64Cond.RcuLockState, DevActionGlobal.DevActionU64Cond.RcuLockState)) {Dbg_Println(DBG_BIT_ActCond_STATUS_bit,"授权条件未判断通过,场景名:%s",DevActionInfo->DevActionCore.DevActionName); return CondIsNotPass; } //锁定     DevActionGlobal.DevActionU64Cond.RcuLockState
		
		
	/*普通条件判断开始*/
	
	return CondIsPass;
}
#endif

/*******************************************************************************
* @name  : BLV_DevAction_Cycle 
* @para  :
    Dev_processing_addr   设备地址
		BUS_Public    公共属性
* @ret   :无
* @brief :遍历所有的动作，相同输入触发节点的动作一起扫描   这些动作的ActionCoord 值一样 
*******************************************************************************/
void BLV_DevAction_Cycle(uint32_t Dev_processing_addr, Device_Public_Information_G *BUS_Public)
{
	DEV_ACTION_INFO DevActionInfo;     //设备动作全部信息  
	uint32_t DevActionAddr;      //用于遍历所有动作存在
	uint16_t j;   //用于遍历动作存在
	uint8_t BreakFlag = 0x00;   //跳出循环标志   有设备控制执行  

	for(j = BUS_Public->ActionCoord; j < DevActionGlobal.DevActionNum; j++)   //从相应的动作开始遍历
	{
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作下标遍历:%d", j);  //
		
		DevActionAddr = SRAM_DevAction_List_Start_Addr + j*SRAM_DevAction_List_Size;
		if(SRAM_Read_DW(DevActionAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)-4) == Dev_processing_addr) //拥有相同的输入触发节点    DevActionInfo.DevActionState.DevAddrIn
		{
//			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作下标判断:%d", j);  //

			SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), DevActionAddr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
			if(0x00 != CheckSum((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO)))   //不为0
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作参数校验未通过:%d");
				continue ;
			}						
			RcuLockState_Scan(); 
//			if(0x01 == DevActionInfo.DevActionState.SceneTypeFlag)   //需要判断场景
			{
				DevAction_State_Get(&DevActionInfo);//当前场景状态更新   结合所有设备输出去判断
			}

			if(0x00 == DevActionInfo.DevActionCond.DevActionU64Cond.DevActionOutFlag)   //动作启用了
			{
//					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前场景号:%d，当前设备检测函数指针:%04X",DevActionInfo.DevActionCore.ActionNo, BUS_Public.DevFunInfo.Dev_Input_Type_Get);		//	
				if(0x00 == DevActionInfo.DevActionState.SceneReuseFlag)  //没有复用标志
				{
					if(
						(NULL != BUS_Public->DevFunInfo.Dev_Input_Type_Get) 
						&&(CtrlValid == BUS_Public->DevFunInfo.Dev_Input_Type_Get(DevActionInfo.DevActionState.DevAddrIn, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionInput.inType))
//							&&(CondIsPass == BLV_DevAction_Cond_Judge(&DevActionInfo))   //条件判断通过
						)
					{
						if(CondIsPass == BLV_DevAction_Cond_Judge(&DevActionInfo))    //条件也判断通过
						{
							BreakFlag = 0x01;
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"设备类型:%d 设备地址%d 输入地址:%d 地址编号:%d 动作地址:%08X通过", DevActionInfo.DevActionInput.DevType,DevActionInfo.DevActionInput.DevAddr, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionCore.ActionNo, DevActionAddr);
							DevAction_Output(&DevActionInfo);  //执行输出控制	
						}
						else if(0x01 == DevActionInfo.DevActionCond.DevActionU64Cond.EleCtrlFlag)    //条件未判断通过，但是该动作控制取电开被置位
						{
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"设备类型:%d 设备地址%d 输入地址:%d 地址编号:%d 动作地址:%08X未通过，但是有控取电开标志", DevActionInfo.DevActionInput.DevType,DevActionInfo.DevActionInput.DevAddr, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionCore.ActionNo, DevActionAddr);							
							if(0x00 == Get_Authorize_Lock_Status())  //授权锁定判断
							{
								BreakFlag = 0x01;
								Ele_Ctrl_OpenClose(0x01);   //控制取电服务打开
							}
						}
					}
				}
				else if(0x01 == DevActionInfo.DevActionState.SceneReuseFlag)    //存在复用标志
				{
					if((DevActionInfo.DevActionCond.SceneExcute == LIGHT_SCENE_MULTI) && (DevActionInfo.DevActionInput.DevType == DEV_RS485_SWT))
					{
						if(
						(CondIsPass == BLV_DevAction_Cond_Judge(&DevActionInfo))   //条件判断通过					
						&&(NULL != BUS_Public->DevFunInfo.Dev_Input_Type_Get) 
						)
						{
							uint8_t ret = BUS_Public->DevFunInfo.Dev_Input_Type_Get(DevActionInfo.DevActionState.DevAddrIn, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionInput.inType);
							if(CtrlValid == (ret&0x01))
							{
								if(DevActionInfo.DevActionState.MultiNumber == (ret >> 0x01))       //当前动作多联下标和开关触发多联下标相等
								{
									BreakFlag = 0x01;
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"多联场景别名:%s,设备类型复用:%d 设备地址%d 输入地址:%d 动作编号:%d 动作地址:%08X通过",DevActionInfo.DevActionCore.DevActionName, DevActionInfo.DevActionInput.DevType,DevActionInfo.DevActionInput.DevAddr, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionCore.ActionNo, DevActionAddr);
									DevAction_Output(&DevActionInfo);  //执行输出控制
								}
								else 
								{
									
									//当前动作多联下标和开关触发多联下标不相等，重新寻找动作地址
									uint32_t TempAddr = 0x00;     
									for(uint8_t i = 0; i < DevActionGlobal.DevActionNum; i++)
									{
										TempAddr = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
										if(SRAM_Read_DW(TempAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)-4) == Dev_processing_addr)
										{
											if(SRAM_Read_Byte(TempAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)-4) == DevActionInfo.DevActionInput.inAddr)		//多联开关控制增加回路判断 - 2026-01-09
											{
												if(SRAM_Read_Byte(TempAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)-7) == (ret >> 0x01))
												{
													Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"找到多联编号:%d 动作地址:%08X",\
													SRAM_Read_Byte(TempAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)-7),TempAddr);
													break;
												}
											}
										}
									}
									
									if((TempAddr != NULL) && (SRAM_Read_DW(TempAddr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)-4) == Dev_processing_addr)) //拥有相同的输入触发节点
									{
										SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), TempAddr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
										if(0x00 != CheckSum((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO)))   //不为0
										{
											Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作参数校验未通过:%d");
											continue ;
										}
										
										BreakFlag = 0x01;
										Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"多联场景别名:%s,设备类型复用:%d 设备地址%d 输入地址:%d 动作编号:%d 动作地址:%08X通过",DevActionInfo.DevActionCore.DevActionName, DevActionInfo.DevActionInput.DevType,DevActionInfo.DevActionInput.DevAddr, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionCore.ActionNo, DevActionAddr);
										DevAction_Output(&DevActionInfo);  //执行输出控制
										
									}
								}
							}
						}	
					}
					else
					{
						if(
						(CondIsPass == BLV_DevAction_Cond_Judge(&DevActionInfo))   //条件判断通过					
						&&(NULL != BUS_Public->DevFunInfo.Dev_Input_Type_Get) 
						&&(CtrlValid == BUS_Public->DevFunInfo.Dev_Input_Type_Get(DevActionInfo.DevActionState.DevAddrIn, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionInput.inType))
						)
						{
							BreakFlag = 0x01;
							Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"场景别名:%s,设备类型复用:%d 设备地址%d 输入地址:%d 动作编号:%d 动作地址:%08X通过",DevActionInfo.DevActionCore.DevActionName, DevActionInfo.DevActionInput.DevType,DevActionInfo.DevActionInput.DevAddr, DevActionInfo.DevActionInput.inAddr, DevActionInfo.DevActionCore.ActionNo, DevActionAddr);
							DevAction_Output(&DevActionInfo);  //执行输出控制	
						}	
					}
					
				}	
			}					
	
//			if(0x01 == DevActionInfo.DevActionState.SceneTypeFlag)   //需要判断场景
			{
				if(0x01 == BreakFlag)   //本地产生事件，就立即刷新场景状态
				{
					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), DevActionAddr); 
					
				}
			}
			if(0x01 == BreakFlag)
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作下标:%d", j);  
				break;
				
			}
			
		}
	}   //for结束 当前设备存在下 动作遍历结束

	 

}



/**
* @name  为复用动作复用标志得到
* @para 无
* @ret  无
* @attention  每个动作遍历所有的动作 相同的输入节点和回路，该动作的复用标志就置一。置一后，扫描动作时会先判断
*/
void DevAction_ReuseFlag_Get(void)
{
	uint16_t i;  //用于遍历所有动作
	uint16_t j;  //用于重新遍历所有动作
	uint16_t k;  //用于遍历所有扩展属性 以及遍历外部SRAM
	DEV_ACTION_INFO DevActionInfoi;     //当前设备动作全部信息  
	DEV_ACTION_INFO DevActionInfoj;     //当前设备动作全部信息  
	uint32_t list_addri;   //当前动作地址
	uint32_t list_addrj;   //遍历所有动作的地址
	
	for(i = 0; i < DevActionGlobal.DevActionNum; i++) 
	{
		list_addri = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
		SRAM_Read_Buff((uint8_t *)&DevActionInfoi, sizeof(DEV_ACTION_INFO), list_addri);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
		DevActionInfoi.DevActionState.DevAddrIn = Find_AllDevice_List_Information(DevActionInfoi.DevActionInput.DevType, DevActionInfoi.DevActionInput.DevAddr);   //动作触发设备得到
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作设备数量:%d，设备输入类型:%d，设备输入地址:%d,设备输入地址:%04x", DevActionInfoi.DevCtrlNum, DevActionInfoi.DevActionInput.DevType, DevActionInfoi.DevActionInput.DevAddr, DevActionInfoi.DevActionState.DevAddrIn);
		
		Dbg_Print_Buff(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据打印:",(uint8_t *)&DevActionInfoi,sizeof(Dev_Action_Core) + sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State));

		for(j = 0;( j < DevActionGlobal.DevActionNum); j++)  //遍历所有动作  找到相同的  
		{
			if(j != i )
			{
				list_addrj = SRAM_DevAction_List_Start_Addr + j*SRAM_DevAction_List_Size;
				SRAM_Read_Buff((uint8_t *)&DevActionInfoj, sizeof(DEV_ACTION_INFO), list_addrj);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
				if(
					(0x00 == DevActionInfoi.DevActionCond.DevActionU64Cond.DevActionOutFlag)    //正常
					&&(0x00 == DevActionInfoj.DevActionCond.DevActionU64Cond.DevActionOutFlag)   //正常
					&&(DevActionInfoi.DevActionInput.DevType == DevActionInfoj.DevActionInput.DevType) //类型 地址 输入地址都一样
					&&(DevActionInfoi.DevActionInput.DevAddr == DevActionInfoj.DevActionInput.DevAddr)
				 &&(DevActionInfoi.DevActionInput.inAddr == DevActionInfoj.DevActionInput.inAddr)
				 &&(DevActionInfoi.DevActionInput.inType == DevActionInfoj.DevActionInput.inType)
				 )
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作地址:%08X，之前动作地址:%08X", list_addri, list_addrj);
					DevActionInfoi.DevActionState.SceneReuseFlag = 0x01;     //
					if((DevActionInfoi.DevActionInput.DevType == DEV_RS485_SWT) && (DevActionInfoi.DevActionCond.SceneExcute == LIGHT_SCENE_MULTI)\
						&& (DevActionInfoj.DevActionInput.DevType == DEV_RS485_SWT) && (DevActionInfoj.DevActionCond.SceneExcute == LIGHT_SCENE_MULTI))
					{
						if(j > i)
						{
							if((DevActionInfoi.DevActionState.MultiValidNo == 0x00)  && (DevActionInfoi.DevActionState.MultiSetFlag == 0x00))
							{
								DevActionInfoi.DevActionState.MultiSetFlag = 0x01;
								DevActionInfoi.DevActionState.MultiNumber = 0x01;
								DevActionInfoi.DevActionState.MultiValidNo++;
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"开关:%d  回路:%d 多联起始地址:%08X 多联下标:%d",\
								DevActionInfoi.DevActionInput.DevAddr,DevActionInfoi.DevActionInput.inAddr,list_addri,DevActionInfoi.DevActionState.MultiNumber);
							}
							
							if(DevActionInfoj.DevActionState.MultiSetFlag == 0x00)
							{
								DevActionInfoi.DevActionState.MultiValidNo++;
								DevActionInfoj.DevActionState.MultiNumber = DevActionInfoi.DevActionState.MultiValidNo;
								DevActionInfoj.DevActionState.MultiSetFlag = 0x01;
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"开关:%d 回路:%d 多联当前地址:%08X 多联下标:%d",\
								DevActionInfoj.DevActionInput.DevAddr,DevActionInfoj.DevActionInput.inAddr,list_addrj,DevActionInfoj.DevActionState.MultiNumber);
								
								
								/*当前动作重新写入开始*/
								/*清空数据*/
								for(uint16_t k = 0;k<SRAM_DevAction_List_Size;k++)
								{
									SRAM_Write_Byte(0x00,list_addrj+k);	
								}
								Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"因为多联下标置位准备重新保存,地址:%08X", list_addrj);
								DevActionInfoj.CheckVal = 0x00;     //校验清0，再写入
								SRAM_DMA_Write_Buff((uint8_t *)&DevActionInfoj, DevActionInfoj.data_len, list_addrj);      //写入数据

								DevActionInfoj.CheckVal = DevAction_CheckSum(list_addrj,DevActionInfoj.data_len);     //计算整包校验
								
								SRAM_Write_Byte(DevActionInfoj.CheckVal,list_addrj+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State));
								//校验值重新写入
								/*当前动作重新写入结束*/	
								
								Device_Public_Information_G BUS_Public;   //共用	
								RS485_SWI_INFO Rs485SwiInfo;       //开关局部变量
								uint32_t DevAdd = 0x00;
								DevAdd = Find_AllDevice_List_Information2(Active_Port, DevActionInfoi.DevActionInput.DevType, DevActionInfoi.DevActionInput.DevAddr);
								if(DevAdd != NULL)
								{
									SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);
									SRAM_DMA_Read_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);
									if(DevActionInfoi.DevActionState.MultiValidNo <= 127)
									{
										Rs485SwiInfo.MultiValidNo[DevActionInfoi.DevActionInput.inAddr] = DevActionInfoi.DevActionState.MultiValidNo;
									}
									
									BUS_Public.check = 0x00;
									BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485SwiInfo, sizeof(RS485_SWI_INFO));
									SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
									SRAM_DMA_Write_Buff((uint8_t *)&Rs485SwiInfo,sizeof(RS485_SWI_INFO),DevAdd+Dev_Privately);
									
									Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"%d多联开关,回路:%d 有效联数:%d",DevActionInfoi.DevActionInput.DevAddr,\
									DevActionInfoi.DevActionInput.inAddr,Rs485SwiInfo.MultiValidNo[DevActionInfoi.DevActionInput.inAddr]);
								}
								
							}
						}
					}
					else
					{
						break;
					}
					
				}
			}
		}
		for(k = 0; k < DevActionInfoi.DevCtrlNum; k++)   //遍历当前动作的所有扩展属性
		{
//			memcpy(&DevActionInfoi->DevActionOutput[i].DevActionOutCfg, &DevCtrlBuf[i*DEVACTIONOUTCFGLEN], DEVACTIONOUTCFGLEN);   //每次拷贝8个字节  配置设备信息DevAction_Info->DevCtrlNum*
//	//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备个数:%d", DevAction_Info->DevCtrlNum);
//			Dbg_Print_Buff(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备数据:",&DevCtrlBuf[i*DEVACTIONOUTCFGLEN],DEVACTIONOUTCFGLEN);
			if(Dev_Host_Invalid == DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevType)  //唯有场景
			{
				DevActionInfoi.DevActionOutput[k].DevActionOutAddr = DevAction_No_Get(DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop);
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作包含场景,地址:%08X 场景地址:%08X 下标:%d 回路:%d",list_addri,DevActionInfoi.DevActionOutput[k].DevActionOutAddr, i,  DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop);					
			}
			else
			{
				DevActionInfoi.DevActionOutput[k].DevActionOutAddr = Find_AllDevice_List_Information(DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevType, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevAddr);
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"扩展设备输入类型:%d，扩展设备输入地址:%d,扩展设备回路地址:%d,扩展设备存储地址:%04x", DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevType, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevAddr, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop, DevActionInfoi.DevActionOutput[k].DevActionOutAddr);
			}
			if(0x00 != DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevDlyValue.DelayCont)   //延时执行参数不为0
			{
				DevActionInfoi.DevActionOutput[k].DevDlyAddr = Add_DevDly_To_List(DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevType, DevActionInfoi.DevActionOutput[k].DevActionOutAddr, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop);//添加当前设备到延时设备链表，如果需要当前动作挂起，需要保存当前扩展设备执行的下标。正常的动作由输入加条件去执行扩展，挂起的动作，可以无视输入和条件，直接执行
				
				if(Dev_Host_Invalid != DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevType)
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作包含延时设备准备重新保存,地址:%08X 下标:%d,延时节点:%08X 有涉及到延时设备地址:%08X, 回路:%d",list_addri, i, DevActionInfoi.DevActionOutput[k].DevDlyAddr, DevActionInfoi.DevActionOutput[k].DevActionOutAddr, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop);										
				}
				else
				{
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作包含延时场景准备重新保存,地址:%08X 下标:%d,延时节点:%08X 有涉及到延时设备地址:%08X, 回路:%d",list_addri, i, DevActionInfoi.DevActionOutput[k].DevDlyAddr, DevActionInfoi.DevActionOutput[k].DevActionOutAddr, DevActionInfoi.DevActionOutput[k].DevActionOutCfg.DevOutputLoop);					
					
				}
				
			}
			else   //延时节点为0
			{
				DevActionInfoi.DevActionOutput[k].DevDlyAddr = 0x00;    //控制扩展设备未延时的，先清空延时节点。后面再重新遍历，再赋值延时设备信息
			}			
		}
		
//		if(0x01 == DevActionInfoi.DevActionState.SceneReuseFlag) //保存当前动作
		{
			/*当前动作重新写入开始*/
				/*清空数据*/
			for(uint16_t k = 0;k<SRAM_DevAction_List_Size;k++)
			{
				SRAM_Write_Byte(0x00,list_addri+k);	
			}
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作因为复用标志置位准备重新保存,地址:%08X", list_addri);
			DevActionInfoi.CheckVal = 0x00;     //校验清0，再写入
			SRAM_DMA_Write_Buff((uint8_t *)&DevActionInfoi, DevActionInfoi.data_len, list_addri);      //写入数据

			DevActionInfoi.CheckVal = DevAction_CheckSum(list_addri,DevActionInfoi.data_len);     //计算整包校验
			
			SRAM_Write_Byte(DevActionInfoi.CheckVal,list_addri+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State));		//校验值重新写入
			/*当前动作重新写入结束*/			
		}
	}
}

/**
* @name  为控制场景的设备进行地址得到
* @para 无
* @ret  无
* @attention  当动作初始化，以及延时链表完成之后，重新遍历动作链表，每个动作中的每个扩展设备，进行赋值
*/
void Expand_Scene_Get(void)
{
	uint16_t i;  //用于遍历所有动作
	uint16_t j;  //用于遍历所有扩展设备
	DEV_ACTION_INFO DevActionInfo;     //当前设备动作全部信息  
	uint32_t list_addr;
	uint8_t KeepFlag = 0x00;   //
	uint8_t CtrlWay;
	
	for(i = 0; i < DevActionGlobal.DevActionNum; i++) 
	{
		KeepFlag = 0x00;  //当前动作默认不用重新保存
		list_addr = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
		SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), list_addr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
		for(j = 0; j < DevActionInfo.DevCtrlNum; j++)
		{
			if(Dev_Host_Invalid == DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevType)  //唯有场景
			{
				DevActionInfo.DevActionOutput[j].DevActionOutAddr = DevAction_No_Get(DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevOutputLoop);
				if(NULL != DevActionInfo.DevActionOutput[j].DevActionOutAddr)
				{
					KeepFlag = 0x01;  //当前动作需要重新保存				
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作包含场景，准备重新保存,地址:%08X 场景地址:%08X 下标:%d 回路:%d",list_addr,DevActionInfo.DevActionOutput[j].DevActionOutAddr, i,  DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevOutputLoop);					
				}
			}
			switch(DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevType) //能作为反馈灯的设备类型
			{
				case DEV_SWI_TYPE:         //开关类型
				case Dev_Host_LVoutput:    //弱电输出
					CtrlWay = DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff;  //执行方式
					switch(CtrlWay)
					{
						case DEV_CTRLWAY_RELATESCENE:   //对应场景
						case CFG_Dev_CtrlWay_Is_RelateBlink: //对应闪烁
							DevActionInfo.DevActionState.SceneTypeFlag = 0x01;
							KeepFlag = 0x01;  //当前动作需要重新保存				
							break;
					}
				case Dev_NodeCurtain:
					if(DEV_CTRLWAY_RELATESCENE == (DevActionInfo.DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))
					{
						KeepFlag = 0x01;  //当前动作需要重新保存				
						DevActionInfo.DevActionState.SceneTypeFlag = 0x01;
					}
					break;
			}
			switch(DevActionInfo.DevActionCond.SceneExcute)
			{
				case LIGHT_SCENE_TWO:
				case LIGHT_SCENE_SLEEP:
				case LIGHT_SCENE_MAINSWITCH:
				case LIGHT_SCENE_HELPSLEEP:
					KeepFlag = 0x01;  //当前动作需要重新保存				
					DevActionInfo.DevActionState.SceneTypeFlag = 0x01;					
					break;
			}
		}
		
		if(0x01 == KeepFlag)       // 重新保存
		{
			/*当前动作重新写入开始*/
				/*清空数据*/
			for(uint16_t k = 0;k<SRAM_DevAction_List_Size;k++)
			{
				SRAM_Write_Byte(0x00,list_addr+k);	
			}
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作准备重新保存,地址:%08X", list_addr);
			DevActionInfo.CheckVal = 0x00;     //校验清0，再写入
			SRAM_DMA_Write_Buff((uint8_t *)&DevActionInfo, DevActionInfo.data_len, list_addr);      //写入数据

			DevActionInfo.CheckVal = DevAction_CheckSum(list_addr,DevActionInfo.data_len);     //计算整包校验
			
			SRAM_Write_Byte(DevActionInfo.CheckVal,list_addr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State));		//校验值重新写入
			/*当前动作重新写入结束*/
		}
	}	
}
/**
* @name 为不带延时的的扩展设备进行延时节点赋值，为带延时的场景，进行地址赋值。  为控制场景的设备进行地址得到
* @para 无
* @ret  无
* @attention  当动作初始化，以及延时链表完成之后，重新遍历动作链表，每个动作中的每个扩展设备，进行赋值
*/
void Expand_DevDly_Get(void)
{
	uint16_t i;  //用于遍历所有动作
	uint16_t j;  //用于遍历所有扩展设备
	DEV_ACTION_INFO DevActionInfo;     //当前设备动作全部信息  
	uint32_t list_addr;
	uint8_t KeepFlag = 0x00;   //
//	uint16_t data_len;
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"开始遍历所有的动作 动作个数:%d, 动作的起始地址:%08X",DevActionGlobal.DevActionNum, SRAM_DevAction_List_Start_Addr);


	
	for(i = 0; i < DevActionGlobal.DevActionNum; i++) 
	{
		KeepFlag = 0x00;  //当前动作默认不用重新保存
		list_addr = SRAM_DevAction_List_Start_Addr + i*SRAM_DevAction_List_Size;
		SRAM_Read_Buff((uint8_t *)&DevActionInfo, sizeof(DEV_ACTION_INFO), list_addr);   //完整拷贝设备动作信息 根据设备输出数量去执行控制 
		for(j = 0; j < DevActionInfo.DevCtrlNum; j++)
		{
			if(0x00 == DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevDlyValue.DelayCont)  //当前扩展设备不带延时，拿到可能涉及到的延时设备 
			{

				DevActionInfo.DevActionOutput[j].DevDlyAddr = DevDlyAddr_Get(DevActionInfo.DevActionOutput[j].DevActionOutAddr, DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevOutputLoop);//找到延时节点
				if(NULL != DevActionInfo.DevActionOutput[j].DevDlyAddr)
				{
					KeepFlag = 0x01;  //当前动作需要重新保存
					Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作准备重新保存,地址:%08X 下标:%d,延时节点:%08X 有涉及到延时设备地址:%08X, 回路:%d",list_addr, i, DevActionInfo.DevActionOutput[j].DevDlyAddr, DevActionInfo.DevActionOutput[j].DevActionOutAddr, DevActionInfo.DevActionOutput[j].DevActionOutCfg.DevOutputLoop);					
				}
			}

		}
		
		if(0x01 == KeepFlag)       // 重新保存
		{
			/*当前动作重新写入开始*/
				/*清空数据*/
			for(uint16_t k = 0;k<SRAM_DevAction_List_Size;k++)
			{
				SRAM_Write_Byte(0x00,list_addr+k);	
			}
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作准备重新保存,地址:%08X", list_addr);
			DevActionInfo.CheckVal = 0x00;     //校验清0，再写入
			SRAM_DMA_Write_Buff((uint8_t *)&DevActionInfo, DevActionInfo.data_len, list_addr);      //写入数据

			DevActionInfo.CheckVal = DevAction_CheckSum(list_addr,DevActionInfo.data_len);     //计算整包校验
			
			SRAM_Write_Byte(DevActionInfo.CheckVal,list_addr+sizeof(Dev_Action_Core)+sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State));		//校验值重新写入
			/*当前动作重新写入结束*/
		}
	}
}

#if LOGIC_FILE_EN
 /*配置数据动作输出数据得到*/
void Logic_Action_Output_DataGet(DEV_ACTION_INFO *DevAction_Info, uint8_t *DevCtrlBuf)
{
	uint8_t i;        //用于扫描所有的扩展设备
	uint8_t NeightLight = 0x00;
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备个数:%d", DevAction_Info->DevCtrlNum);

	for(i = 0; i < DevAction_Info->DevCtrlNum; i++)
	{
		memcpy(&DevAction_Info->DevActionOutput[i].DevActionOutCfg, &DevCtrlBuf[i*DEVACTIONOUTCFGLEN], DEVACTIONOUTCFGLEN);   //每次拷贝8个字节  配置设备信息DevAction_Info->DevCtrlNum*
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备个数:%d", DevAction_Info->DevCtrlNum);

					
		if(Dev_Host_Invalid != DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType)   //类型不为场景
		{
			if(0x00 != DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevOutputLoop)  //且回路不为0
			{
				DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevOutputLoop--;
			}
		}
//		if((DEV_CTRLWAY_RELATESCENE == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))    //对应场景，目前仅有弱电输出 开关和窗帘
//			||(CFG_Dev_CtrlWay_Is_RelateBlink == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))) //对应闪烁 目前仅有弱电输出 开关
//		{ 
//			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0x00ff;  //高字节清0
//			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState |= 0x6400;  //高字节赋值
//		}
		if( ( (DEV_CTRLWAY_RELATESCENE == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))    				//对应场景，目前仅有弱电输出 开关和窗帘
			|| ( (CFG_Dev_CtrlWay_Is_RelateBlink == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff)) && (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != DEV_RS485_TEMP) ) )	//对应闪烁 目前仅有弱电输出 开关
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != DEV_RS485_HEATER)
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != DEV_Virtual_ColorTemp)
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != Dev_485_BLE_Music)
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != DEV_Carbon_Saved) 
		    && (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != Dev_Scene_Restore)
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != Dev_Energy_Monitor)
			&& (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType != Dev_Host_Service) )	//并且动作输出类型不是地暖类型
		{
			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState &= 0x00ff;  //高字节清0
			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState |= 0x6400;  //高字节赋值
		}
		if(0x00 == DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont)   //内容为0
		{
			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont = 0x00;  //内容和单位都清0
			DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayWeight = 0x00;  //内容和单位都清0
		}
		
		Dbg_Print_Buff(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备数据:",(uint8_t *)&DevAction_Info->DevActionOutput[i].DevActionOutCfg, DEVACTIONOUTCFGLEN);
		
//		DevAction_Info->DevActionOutput[i].DevActionOutAddr = Find_AllDevice_List_Information(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType, DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevAddr);
		
		if(DEV_CTRLWAY_OPEN == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))  //控制为开
		{
			switch(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType)  //当前设备类型
			{
				case Dev_Host_HVout:
				case DEV_RS485_PWM:
				case DEV_RS485_STRIP:
				case Dev_Rs485_PB20:
				case Dev_Rs485_PB20_LD:
				case Dev_Rs485_PB20_LS:
				case Dev_Rs485_PB20_Relay:
				case DEV_Virtual_ColorTemp:
					NeightLight = 0x01;
					break;
			}
		}
		
		if(0x12 == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))    //只控制亮度
		{
			switch(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType)  //当前设备类型
			{
				case Dev_Rs485_PB20:
				case Dev_Rs485_PB20_LD:
				case Dev_Rs485_PB20_LS:
					NeightLight = 0x01;
					break;
			}
		}
	}
	if((LIGHT_SCENE_SLEEP == DevAction_Info->DevActionCond.SceneExcute)&&(0x01 == NeightLight)) //
	{
		DevActionGlobal.DevActionU64Cond.NeightFlag = 0x01;  //存在夜灯 即为1
	}
}
#endif

 /*动作输出数据得到*/
void Dev_Action_Output_DataGet(DEV_ACTION_INFO *DevAction_Info, uint8_t *DevCtrlBuf)
{
	uint8_t i;        //用于扫描所有的扩展设备
	uint8_t NeightLight = 0x00;
	
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备个数:%d", DevAction_Info->DevCtrlNum);

	for(i = 0; i < DevAction_Info->DevCtrlNum; i++)
	{
		memcpy(&DevAction_Info->DevActionOutput[i].DevActionOutCfg, &DevCtrlBuf[i*DEVACTIONOUTCFGLEN], DEVACTIONOUTCFGLEN);   //每次拷贝8个字节  配置设备信息DevAction_Info->DevCtrlNum*
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备个数:%d", DevAction_Info->DevCtrlNum);
		Dbg_Print_Buff(DBG_BIT_LOGIC_STATUS_bit,"当前扩展设备数据:",&DevCtrlBuf[i*DEVACTIONOUTCFGLEN],DEVACTIONOUTCFGLEN);
		
//		DevAction_Info->DevActionOutput[i].DevActionOutAddr = Find_AllDevice_List_Information(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType, DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevAddr);
		
		if(DEV_CTRLWAY_OPEN == (DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevCtrlState&0x00ff))  //控制为开
		{
			switch(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType)  //当前设备类型
			{
				case Dev_Host_HVout:
				case DEV_RS485_PWM:
				case DEV_RS485_STRIP:
				case DEV_Virtual_ColorTemp:
					NeightLight = 0x01;
					break;
			}
		}
	}
	if((LIGHT_SCENE_SLEEP == DevAction_Info->DevActionCond.SceneExcute)&&(0x01 == NeightLight)) //
	{
		DevActionGlobal.DevActionU64Cond.NeightFlag = 0x01;  //存在夜灯 即为1
	}
}


#if LOGIC_FILE_EN
/*******************************************************************************
* Function Name  : BLV_DevAction_Add
* Description    : 设备动作1添加  将动作的结构体填满，然后保存到外部SRAM
* data  动作参数
* len   动作长度
*******************************************************************************/
void Logic_DevAction_Add(uint8_t *data,uint16_t len)
{
	DEV_ACTION_INFO DevAction_Info;  
//	uint8_t InputBuf[9] = {0x00, };
//	uint8_t DevNameLen;
	
	memset(&DevAction_Info,0,sizeof(DEV_ACTION_INFO));   //动作全部参数清空
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据清空");

	//memcpy((uint8_t *)&DevAction_Info.DevActionCore.ActionNo, &data[2], sizeof(uint16_t));    	//拷贝动作编号  
	memcpy((uint8_t *)&DevAction_Info.DevActionCore.ActionNo, &data[81], sizeof(uint16_t));    	//拷贝场景编号 
	memcpy((uint8_t *)&DevAction_Info.DevActionCore.DevActionName, &data[49], 32); 				//填充别名

	DevAction_Info.DevActionInput.DevType = data[0];        //设备类型
	DevAction_Info.DevActionInput.DevAddr = data[1];		//设备地址
	DevAction_Info.DevActionInput.inAddr = data[4] + (data[5]<<8);  //输入回路
	if(0x00 != DevAction_Info.DevActionInput.inAddr)
	{
		DevAction_Info.DevActionInput.inAddr--;       //转换到配置
	}
	DevAction_Info.DevActionInput.inType = data[6] + (data[7]<<8);
	
	memcpy(&DevAction_Info.DevActionCond.DevActionU64Cond, &data[8], sizeof(Dev_Action_U64Cond));     //动作条件拷贝
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:动作输出使能 DevAction_Info.DevActionCond.DevActionU64Cond.DevActionOutFlag: %d", DevAction_Info.DevActionCond.DevActionU64Cond.DevActionOutFlag);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:房态         DevAction_Info.DevActionCond.DevActionU64Cond.RoomState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.RoomState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:取电服务控制 DevAction_Info.DevActionCond.DevActionU64Cond.EleCtrlFlag:      %d", DevAction_Info.DevActionCond.DevActionU64Cond.EleCtrlFlag);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:取电状态     DevAction_Info.DevActionCond.DevActionU64Cond.EleState:         %d", DevAction_Info.DevActionCond.DevActionU64Cond.EleState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:勿扰状态     DevAction_Info.DevActionCond.DevActionU64Cond.DndState:         %d", DevAction_Info.DevActionCond.DevActionU64Cond.DndState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:清理状态     DevAction_Info.DevActionCond.DevActionU64Cond.CleanState:       %d", DevAction_Info.DevActionCond.DevActionU64Cond.CleanState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:呼叫状态     DevAction_Info.DevActionCond.DevActionU64Cond.CallState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.CallState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:洗衣状态     DevAction_Info.DevActionCond.DevActionU64Cond.WashState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.WashState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:退房状态     DevAction_Info.DevActionCond.DevActionU64Cond.CheckOutState:    %d", DevAction_Info.DevActionCond.DevActionU64Cond.CheckOutState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:稍后状态     DevAction_Info.DevActionCond.DevActionU64Cond.WaitState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.WaitState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:SOS状态      DevAction_Info.DevActionCond.DevActionU64Cond.SosState:         %d", DevAction_Info.DevActionCond.DevActionU64Cond.SosState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:预约待租状态 DevAction_Info.DevActionCond.DevActionU64Cond.RentState:		%d", DevAction_Info.DevActionCond.DevActionU64Cond.RentState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:开锁状态     DevAction_Info.DevActionCond.DevActionU64Cond.LockState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.LockState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:行李状态     DevAction_Info.DevActionCond.DevActionU64Cond.LuggageState:     %d", DevAction_Info.DevActionCond.DevActionU64Cond.LuggageState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:保险箱状态   DevAction_Info.DevActionCond.DevActionU64Cond.StrongState:      %d", DevAction_Info.DevActionCond.DevActionU64Cond.StrongState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:门磁状态     DevAction_Info.DevActionCond.DevActionU64Cond.DoorState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.DoorState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:提示音状态   DevAction_Info.DevActionCond.DevActionU64Cond.WarningState:     %d", DevAction_Info.DevActionCond.DevActionU64Cond.WarningState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:背光状态     DevAction_Info.DevActionCond.DevActionU64Cond.BacklightState:   %d", DevAction_Info.DevActionCond.DevActionU64Cond.BacklightState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:季节         DevAction_Info.DevActionCond.DevActionU64Cond.SeasonState:      %d", DevAction_Info.DevActionCond.DevActionU64Cond.SeasonState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:时间         DevAction_Info.DevActionCond.DevActionU64Cond.TimeState:        %d", DevAction_Info.DevActionCond.DevActionU64Cond.TimeState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:与夜灯有关   DevAction_Info.DevActionCond.DevActionU64Cond.NeightFlag:       %d", DevAction_Info.DevActionCond.DevActionU64Cond.NeightFlag);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:起夜状态     DevAction_Info.DevActionCond.DevActionU64Cond.NeightState:      %d", DevAction_Info.DevActionCond.DevActionU64Cond.NeightState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:RCU锁定      DevAction_Info.DevActionCond.DevActionU64Cond.RcuLockState:     %d", DevAction_Info.DevActionCond.DevActionU64Cond.RcuLockState);
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作条件:保留2位      DevAction_Info.DevActionCond.DevActionU64Cond.Reserve1:         %d", DevAction_Info.DevActionCond.DevActionU64Cond.Reserve1);
	
	
	DevAction_Info.DevActionCond.SceneExcute = data[48];   //动作执行方式
	if((LIGHT_SCENE_SLEEP == DevAction_Info.DevActionCond.SceneExcute) && (NULL == DevActionGlobal.SleepActionNo)) //场景执行方式为睡眠模式 未保存过睡眠编号
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"增加睡眠动作，动作编号:%d", DevAction_Info.DevActionCore.ActionNo);
		DevActionGlobal.SleepActionNo = DevAction_Info.DevActionCore.ActionNo;      //保存睡眠场景编号
		
	}
	
//	DevAction_Info.DevActionState.DevAddrIn = Find_AllDevice_List_Information(DevAction_Info.DevActionInput.DevType, DevAction_Info.DevActionInput.DevAddr);   //动作触发设备得到
	
	if(data[115] > DevCtrlNumMax)
	{
		DevAction_Info.DevCtrlNum = DevCtrlNumMax;   //最多
	}
	else
	{
		DevAction_Info.DevCtrlNum = data[115];  //动作数量拷贝
	}
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作设备数量:%d，设备输入类型:%d，设备输入地址:%d,设备存储地址:%04x,设备输入事件:%04X 动作执行方式:%d",\
	DevAction_Info.DevCtrlNum, DevAction_Info.DevActionInput.DevType, DevAction_Info.DevActionInput.DevAddr, DevAction_Info.DevActionState.DevAddrIn, DevAction_Info.DevActionInput.inType, DevAction_Info.DevActionCond.SceneExcute);
	
	Logic_Action_Output_DataGet(&DevAction_Info, &data[116]); //动作输出拷贝，以及设备节点得到
	
	DevAction_Info.data_len = sizeof(Dev_Action_Core) + sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State) + DevAction_Info.DevCtrlNum*sizeof(Dev_Action_Output) + 4;//计算总长度        
	Add_DevAction_To_List(&DevAction_Info); //3个结构体 再加四个字节
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"添加设备结束");
	
}
#endif
/*******************************************************************************
* Function Name  : BLV_DevAction_Add
* Description    : 设备动作1添加  将动作的结构体填满，然后保存到外部SRAM
*******************************************************************************/
void BLV_DevAction_Add(uint8_t *DevCoreBuf, char *DevName, uint8_t *DevInputBuf, uint8_t *DevCondBuf, uint8_t DevCtrlNum, uint8_t *DevCtrlBuf)
{
	DEV_ACTION_INFO DevAction_Info;  
//	uint8_t InputBuf[9] = {0x00, };
	uint8_t DevNameLen;
	
	memset(&DevAction_Info,0,sizeof(DEV_ACTION_INFO));   //动作全部参数清空
	 	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据清空");

	memcpy((uint8_t *)&DevAction_Info.DevActionCore.ActionNo, DevCoreBuf, sizeof(uint16_t));    //拷贝核心信息  
	DevNameLen = strlen(DevName);

	if(DevNameLen <= DevActionNameLenMax)  //范围有效
	{
		memcpy(DevAction_Info.DevActionCore.DevActionName, DevName, DevNameLen);       //拷贝名称
	}	
	memcpy(&DevAction_Info.DevActionInput, DevInputBuf, sizeof(Dev_Action_Input));   //动作输入拷贝
	memcpy(&DevAction_Info.DevActionCond, DevCondBuf, sizeof(Dev_Action_Cond));     //动作条件拷贝
	if((LIGHT_SCENE_SLEEP == DevAction_Info.DevActionCond.SceneExcute) && (NULL == DevActionGlobal.SleepActionNo)) //场景执行方式为睡眠模式 未保存过睡眠编号
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"增加睡眠动作，动作编号:%d", DevAction_Info.DevActionCore.ActionNo);
		DevActionGlobal.SleepActionNo = DevAction_Info.DevActionCore.ActionNo;      //保存睡眠场景编号
		
	}
	
//	DevAction_Info.DevActionState.DevAddrIn = Find_AllDevice_List_Information(DevAction_Info.DevActionInput.DevType, DevAction_Info.DevActionInput.DevAddr);   //动作触发设备得到
	
	if(DevCtrlNum > DevCtrlNumMax)
	{
		DevCtrlNum = DevCtrlNumMax;   //最多
	}
	DevAction_Info.DevCtrlNum = DevCtrlNum;  //数量拷贝
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作设备数量:%d，设备输入类型:%d，设备输入地址:%d,设备输入地址:%04x", DevAction_Info.DevCtrlNum, DevAction_Info.DevActionInput.DevType, DevAction_Info.DevActionInput.DevAddr, DevAction_Info.DevActionState.DevAddrIn);
	
	Dev_Action_Output_DataGet(&DevAction_Info, DevCtrlBuf); //动作输出拷贝，以及设备节点得到

	DevDly_Add(&DevAction_Info);    /*遍历所有的扩展设备，带延时的，需要新增到设备链表，为带延时的扩展设备进行延时节点赋值*/
	
	
	DevAction_Info.data_len = sizeof(Dev_Action_Core) + sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State) + DevCtrlNum*sizeof(Dev_Action_Output) + 4;//计算总长度        
	Add_DevAction_To_List(&DevAction_Info); //3个结构体 再加四个字节
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"添加设备结束");
	
}


/*将设备动作信息添加到链表*/
void Add_DevAction_To_List(DEV_ACTION_INFO *DevAction_Info)
{
	
	uint32_t list_addr = SRAM_DevAction_List_Start_Addr + DevActionGlobal.DevActionNum*SRAM_DevAction_List_Size;//找到当前位置 //SRAM_Read_DW(SRAM_DevAction_List_Addr);	//获取设备信息保存地址
	
	if(DevActionGlobal.DevActionNum >= DevActionNumMax)      //设备总数超过范围就返回
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作添加超过范围 动作上限: %d", DevActionNumMax);		//	
		return ;
	}
	DevActionGlobal.DevActionNum++;  
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"动作添加成功，当前动作个数：%d 当前动作地址: %08X", DevActionGlobal.DevActionNum, list_addr);		//		

//	if((list_addr < SRAM_DevAction_List_Start_Addr) || (list_addr >= SRAM_DevAction_List_End_Addr))	list_addr = SRAM_DevAction_List_Start_Addr;
	
	/*清空数据*/
	for(uint16_t i = 0;i<SRAM_DevAction_List_Size;i++)
	{
		SRAM_Write_Byte(0x00,list_addr+i);	
	}
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据长度：%d", DevAction_Info->data_len);		//		
	
	SRAM_DMA_Write_Buff((uint8_t *)DevAction_Info, DevAction_Info->data_len, list_addr);      //写入数据

	DevAction_Info->CheckVal = DevAction_CheckSum(list_addr,DevAction_Info->data_len);     //计算整包校验
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"计算校验：%d", DevAction_Info->CheckVal);		//		

	SRAM_Write_Byte(DevAction_Info->CheckVal,list_addr+sizeof(Dev_Action_Core) + sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond) + sizeof(Dev_Action_State));		//校验值重新写入
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"写入校验：%d", DevAction_Info->CheckVal);		//		
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据长度：%d", DevAction_Info->data_len);		//		

		/*设备添加完毕,设备链表地址偏移*/
//	list_addr += SRAM_DevAction_List_Size;
//	SRAM_Write_DW(list_addr,SRAM_DevAction_List_Addr);
	
}

/**
* @name 延时执行，信息直接赋值
* @para
*    DevDlyAddr   延时链表的节点地址
*    DlyExcuteFlag 延时执行标志
*    DevOutputType 执行方式
*    DevDelayTime  执行时间
* @attention  一定会进行写入操作
*/
void DevDly_InfoSet(uint32_t DevDlyAddr, uint8_t DlyExcuteFlag, uint16_t DevOutputType, Dev_Dly_Value DevDelayTime, uint8_t DlyBlinkFlag)
{
	Struct_Dev_Dly DevDlyInfo;
	Dev_Dly_Value DevDlyValue;
	uint32_t DlyExcuteTime;
	uint8_t KeepFlag = 0x00;
	
	if(NULL == DevDlyAddr)
	{
//		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时节点数据地址为无效，地址:%08X", DevDlyAddr);
		return ;
	}
	
	DevDlyValue.DelayCont = DevDelayTime.DelayCont;
	DevDlyValue.DelayWeight = DevDelayTime.DelayWeight;
	
	switch(DevDlyValue.DelayWeight)
	{
		case NULL:   //单位为0，可能准备清延时
			DlyExcuteTime = 0x00;
			break;
		case  DELAY_TIME_MS:              //0x01      //毫秒
			DlyExcuteTime = SysTick_1ms + DevDlyValue.DelayCont;
			break;
		case  DELAY_TIME_S:               //0x02      //秒
			DlyExcuteTime = SysTick_1ms + DevDlyValue.DelayCont*1000;			
			break;
		case  DELAY_TIME_MIN:              //0x03      //分钟
			DlyExcuteTime = SysTick_1ms + DevDlyValue.DelayCont*1000*60;			
			break;
		case  DELAY_TIME_HOUR:			       //0x04      //小时
			DlyExcuteTime = SysTick_1ms + DevDlyValue.DelayCont*1000*60*60;
			break;
		default:
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时单位为无效:", DevDlyValue.DelayWeight);
			return;  //其他情况直接返回
	}
	
	SRAM_Read_Buff((uint8_t *)&DevDlyInfo, sizeof(Struct_Dev_Dly), DevDlyAddr);  //把状态读取出来
	
	if( ( DevDlyInfo.DlyExcuteTime != DlyExcuteTime )
		|| ( DevDlyInfo.DlyExcuteFlag != DlyExcuteFlag )
		|| ( DevDlyInfo.DevOutputType != DevOutputType )
		|| ( DevDlyInfo.DlyBlinkFlag != DlyBlinkFlag )
		|| ( DevDlyInfo.DlyBlinkTime.DelayCont != DevDelayTime.DelayCont )
		|| ( DevDlyInfo.DlyBlinkTime.DelayWeight != DevDelayTime.DelayWeight )
		)
	{
		KeepFlag = 0x01;
		DevDlyInfo.DlyExcuteFlag = DlyExcuteFlag;
		DevDlyInfo.DevOutputType = DevOutputType;
		switch(DlyBlinkFlag)
		{
			case 0x01:   //开启闪烁
				DevDlyInfo.DlyBlinkFlag = DlyBlinkFlag;	
  			DevDlyInfo.DlyExcuteTime = DlyExcuteTime;

				break;
			case 0x02:   //关闭闪烁  不重新赋值倒计时时间
				if(0x01 == DevDlyInfo.DlyBlinkFlag) //之前是开启闪烁状态
				{
					DevDlyInfo.DlyBlinkFlag = DlyBlinkFlag;
				}
				break;
			default:	
				DevDlyInfo.DlyBlinkFlag = DlyBlinkFlag;
			  DevDlyInfo.DlyExcuteTime = DlyExcuteTime;
				break;

		}
//		if((0x02 == DlyBlinkFlag)&&(0x01 == DevDlyInfo.DlyBlinkFlag)) //当前控制为关闪烁  当前闪烁状态为1
//		{
//			DevDlyInfo.DlyBlinkFlag = DlyBlinkFlag;
//		}
//		else   //其他情况直接赋值
//		{
//			DevDlyInfo.DlyBlinkFlag = DlyBlinkFlag;
//		}

		DevDlyInfo.DlyBlinkTime.DelayCont = DevDelayTime.DelayCont;
		DevDlyInfo.DlyBlinkTime.DelayWeight = DevDelayTime.DelayWeight;
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时节点赋值，节点地址:%08X 执行标志:%d 时间:%02x%02x, 执行方式:%04X 闪烁标志:%d", DevDlyAddr, DlyExcuteFlag, DevDlyValue.DelayCont,DevDlyValue.DelayWeight, DevOutputType, DevDlyInfo.DlyBlinkFlag);		//	

	}
	
	if(0x01 == KeepFlag)
	{
		SRAM_DMA_Write_Buff((uint8_t *)&DevDlyInfo, sizeof(Struct_Dev_Dly), DevDlyAddr);  //把状态读取出来
	}
}

/*遍历所有的扩展设备，将带延时的设备添加到延时设备链表*/
void DevDly_Add(DEV_ACTION_INFO *DevAction_Info)
{
	uint8_t i; //用于遍历扩展设备
	
	for(i = 0; i < DevAction_Info->DevCtrlNum; i++)
	{
		if( (0x00 != DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevDlyValue.DelayCont) &&(Dev_Host_Invalid != DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType))   //延时执行参数不为0
		{
			DevAction_Info->DevActionOutput[i].DevDlyAddr = Add_DevDly_To_List(DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevType, DevAction_Info->DevActionOutput[i].DevActionOutAddr, DevAction_Info->DevActionOutput[i].DevActionOutCfg.DevOutputLoop);//添加当前设备到延时设备链表，如果需要当前动作挂起，需要保存当前扩展设备执行的下标。正常的动作由输入加条件去执行扩展，挂起的动作，可以无视输入和条件，直接执行
		}
		else   //延时节点为0
		{
			DevAction_Info->DevActionOutput[i].DevDlyAddr = 0x00;    //控制扩展设备未延时的，先清空延时节点。后面再重新遍历，再赋值延时设备信息
		}
	}
}
/**
*@name 将延时设备信息添加到链表
*@para  
*  DevType       设备类型
*  DevDlyAddr    设备节点地址
*  DevOutputLoop 回路地址
*@brief 将需要延时的节点添加到链表，如果是新节点，就返回新的地址，如果是旧节点，就返回旧地址
*/
uint32_t Add_DevDly_To_List(uint8_t DevType, uint32_t DevDlyAddr, uint16_t DevOutputLoop)
{
	uint32_t list_addr;// = SRAM_DevDly_List_Start_Addr + DevActionGlobal.DevDlyNum*DevDlyStructLen;//找到当前位置 //获取设备信息保存地址
	Struct_Dev_Dly_Core DevDlyCore;    //延时设备局部变量
	
	if(DevActionGlobal.DevActionNum >= DevDlyNumMax)      //延时设备总数超过范围就返回
	{ 
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时设备添加超过范围 延时设备上限: %d", DevDlyNumMax);		//	
		return NULL;  //添加失败
	}
	list_addr = DevDlyAddr_Get(DevDlyAddr, DevOutputLoop);  //遍历当前所有延时节点
	if(NULL != list_addr)  //如果不为空 即已存在该节点
	{
		return list_addr;  //就直接将地址返回
	}
	
	
	DevDlyCore.DevType = DevType;
	DevDlyCore.DevDlyAddr = DevDlyAddr;
	DevDlyCore.DevOutputLoop = DevOutputLoop;//填充数据
	list_addr = SRAM_DevDly_List_Start_Addr + DevActionGlobal.DevDlyNum*DevDlyStructLen;   //拿到新地址
	//新增延时设备
	SRAM_DMA_Write_Buff((uint8_t *)&DevDlyCore, sizeof(Struct_Dev_Dly_Core), list_addr);      //接着写入数据
	DevActionGlobal.DevDlyNum++;    //延时节点计数增加

	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"延时设备添加成功当前延时节点地址:%08X 当前延时设备计数:%d 延时设备地址: %08X 延时设备回路：%d",list_addr ,DevActionGlobal.DevDlyNum, DevDlyCore.DevDlyAddr, DevDlyCore.DevOutputLoop);		//	
	
	return list_addr;   //返回有效的地址
	/*遍历当前所有的延时设备，存在过的，就不添加，不存在的就往后添加*/
	
}

/*根据设备信息和回路，来得到延时节点*/
uint32_t DevDlyAddr_Get(uint32_t DevDlyAddr, uint16_t DevOutputLoop)
{
	uint16_t i;
	uint32_t list_addr = NULL;
	Struct_Dev_Dly_Core  DevDlyCore;
	
	for(i = 0; i < DevActionGlobal.DevDlyNum; i++)
	{
		list_addr = SRAM_DevDly_List_Start_Addr + i*DevDlyStructLen;  //
		SRAM_Read_Buff((uint8_t *)&DevDlyCore, sizeof(Struct_Dev_Dly_Core), list_addr);   //拿到延时设备的核心信息
		
		if((DevDlyCore.DevDlyAddr == DevDlyAddr) && (DevDlyCore.DevOutputLoop == DevOutputLoop)) 
		{
			return list_addr;  //已存在该节点，就直接返回
		}
	}
	return NULL;  //没找到就返回空
}

//extern uint8_t check_temp_buff[SRAM_Device_List_Size];

/*******************************************************************************
* Function Name  : DevAction_Data_Check 
* Description    : 设备动作链表数据校验
*******************************************************************************/
uint8_t DeAction_Data_Check(uint32_t sram_addr)
{
	uint16_t data_len = SRAM_Read_Word(sram_addr + sizeof(Dev_Action_Core) + sizeof(Dev_Action_Input)+sizeof(Dev_Action_Cond)+sizeof(Dev_Action_State)+1);
	uint8_t data_sum = 0;
	
	uint8_t check_temp_buff[SRAM_DevAction_List_Size] = {0};

//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"校验时，存储的长度，%d", data_len);

	if(data_len > SRAM_DevAction_List_Size)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据校验错误1，当前地址:%08X 存储的长度，%04X",sram_addr, data_len);
		return 1;
	}
	memset(check_temp_buff,0,SRAM_DevAction_List_Size);
	
	SRAM_Read_Buff(check_temp_buff,data_len,sram_addr);
	
	for(uint16_t i = 0;i<data_len;i++)
	{
		data_sum += check_temp_buff[i];
	}
	return ~data_sum;
}



/*******************************************************************************
* Function Name  : Dev_CheckSum 
* Description    : 和校验取反，数据内容从SRAM中读取
*******************************************************************************/
uint8_t DevAction_CheckSum(uint32_t addr,uint16_t len)
{
	uint8_t data_sum = 0;
	
	uint8_t check_temp_buff[SRAM_DevAction_List_Size];// = {0};
	if(len > SRAM_DevAction_List_Size)
	{
		Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前动作数据校验错误2，当前地址:%08X 存储的长度，%04X",addr, len);
		return 1;
	}
	
	memset(check_temp_buff,0,SRAM_DevAction_List_Size);
	SRAM_Read_Buff(check_temp_buff,len,addr);
	
	for(uint16_t i = 0;i<len;i++)
	{
		data_sum += check_temp_buff[i];
	}
	return ~data_sum;
}


/*查找所有设备，包括普通设备*/
uint32_t Find_AllDevice_List_Information(uint8_t dev_type,uint8_t addr)
{
	uint32_t read_addr = SRAM_Device_List_Start_Addr;
	uint32_t end_addr = SRAM_Read_DW(SRAM_NORMAL_Device_List_Addr);   
	if((end_addr < SRAM_Device_List_Start_Addr) || (end_addr > SRAM_Device_List_End_Addr))	end_addr = SRAM_Device_List_End_Addr;
	
	for(uint32_t i=SRAM_Device_List_Start_Addr;i<end_addr;)
	{
		if((SRAM_Read_Byte(read_addr + Dev_Type) == dev_type) && (SRAM_Read_Byte(read_addr + Dev_Addr) == addr))
		{
			if(Device_Data_Check(read_addr) == 0)
			{
				
				return read_addr;
			}
		}
		read_addr += SRAM_Device_List_Size;
		i+= SRAM_Device_List_Size;
		if(read_addr >= end_addr)	
		{
			return 0x00;
		}
	}
	
	return 0x00;
}

/**
*@name  查找所有设备，包括普通设备
*@para
*  dev_type 设备类型
*  addr     设备地址
*@ret   返回设备地址
*@attention   如果未添加完设备时，需要查找设备用此函数
*/
uint32_t Find_AllDevice_List_Information2(uint8_t Port, uint8_t dev_type,uint8_t addr)
{
	uint16_t i = 0;
	uint32_t read_addr = 0x00;
	
	switch(Port)
	{
		case Active_Port:
			i = BUS485_Info.device_num + Poll485_Info.device_num;
			break;
		case Polling_Port:
			i = BUS485_Info.device_num;
			break;
		case Bus_port:
			i = 0;
			break;
	}
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"未添加完设备时，需要查找设备总数:%d，下标:%d", (BUS485_Info.device_num+Poll485_Info.device_num+Act485_Info.device_num), i);		
	
	for(; i < (BUS485_Info.device_num+Poll485_Info.device_num+Act485_Info.device_num); i++)
	{
		read_addr = SRAM_Device_List_Start_Addr + i*SRAM_Device_List_Size;
		if((SRAM_Read_Byte(read_addr + Dev_Type) == dev_type) && (SRAM_Read_Byte(read_addr + Dev_Addr) == addr))
		{
			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"找到当前设备");		

//			if(Device_Data_Check(read_addr) == 0)
			{
				Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"当前设备校验通过%04x", read_addr);	
                
				return read_addr;
			}
		}
	}
	
	return 0x00;        //未找到设备，返回空指针
}
