

/**
  ******************************************************************************
  * @file    BLV_Dev_Action.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2021年11月03日
  * @brief  能够调用所有设备的驱动
  * 根据配置信息，将四张设备链表填满，将动作链表和延时链表填满。设备添加时，他的技能也同时添加进来。	
	* 每个设备至少有四个函数指针，没有的可以不填 。后面可能还会增加，可以预留20个函数指针的位置
	* 1，设备输入检测     typedef uint8_t (*Dev_Input_Detect_ptr)(CFG_Dev_AddP CfgDevAddIn, uint16_t DevInputLoop, uint8_t DevInputType);  遍历动作时调用
	* 2，设备输出控制     typedef void (*Dev_Output_Ctrl_ptr)(CFG_Dev_AddP CfgDevAddIn, uint16_t DevInputAddr, CFG_Dev_AddP CfgDevAddOut, uint16_t DevOutputLoop, uint16_t DevOutputType);
	* 3，设备状态读取     typedef uint16_t (*Dev_Output_Loop_State_Get_ptr)(CFG_Dev_AddP CfgDevAddOut, uint16_t DevOutputLoop);										//设备输出回路状态得到。
	
	* 4, 普通设备输入输出得到 typedef void (*Dev_InOutGet_ptr)(CFG_Dev_AddP CfgDevAdd);     //设备输出控制函数，或者输入检测函数 定期调用
	* 5, 485数据发送
	* 6, 485数据接收
	*1,2,3 由动作遍历时调用     4,5,6 定期调用
  ******************************************************************************
  */

#include "includes.h"   
#include "BLV_All_Dev_Init.h"

#include "BLV_Nor_DevFun.h"
#include "BLV_Logic_Edit.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"
#include "BLV_Nor_Dev_CurtainFun.h"
#include "BLV_485_Dev_AirDetectFun.h"
#include "BLV_485_Dev_AirRevealFun.h"
#include "BLV_485_Dev_IN_CH6.h"


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




Struct_Dev_Data_Get DevDataGetGather[] = //所有的设备类型，与相应的驱动。同类型的设备拥有相同的驱动接口 
{
	Dev_Host_Invalid,    			NULL   											   ,           //场景
	Dev_Host_HVout, 					NULL, //HVOut_Data_Get		 						 ,           //继电器   
	Dev_Host_LVinput,  				NULL, //LVInput_Data_Get		 				   ,           //弱电输入
	Dev_Host_LVoutput,   			NULL, //LVOut_Data_Get								 ,           //弱电输出
	Dev_Host_Service, 			  NULL, //Service_Data_Get		 				   ,           //服务信息

	Dev_NodeCurtain,     			NULL, //NodeCurtain_Data_Get           ,   		     //干节点窗帘
	
	DEV_RS485_SWT,       			NULL, //Rs485_Swt_Data_Get             ,           //Rs485开关
	DEV_RS485_TEMP,			NULL, //Rs485_Tem_Data_Get	           ,	 	       //温控器
	
	DEV_RS485_INFRARED,			  NULL, //Rs485_Infrared_Data_Get		   ,		         //红外感应
	DEV_RS485_AirDetect, 			NULL, //Rs485_AirDetect_Data_Get	    ,		         //空气质量检测     
	DEV_RS485_CARD,						NULL, //Rs485_Card_Data_Get	 		      ,		         //插卡取电
	DEV_RS485_HEATER,					NULL, //Rs485_Heater_Data_Get		       ,		       //地暖温控器 
	Dev_RCU_NET ,			       	NULL, //RCU_Net_Data_Get		          ,		         //网络设备
	DEV_RS485_CURTAIN,			  NULL, //RS485Curtain_Data_Get		      ,		         //窗帘动作数组控制
	DEV_RS485_RELAY,				  NULL, //Rs485_Relay_Expand_Data_Get	    ,		   //继电器扩展板控制
	DEV_RS485_IR_SEND,				NULL, //Rs485_IR_Data_Get		 			      ,		   //红外发送控制  
	DEV_RS485_DIMMING,				NULL, //Rs485_Dim_Data_Get		 		     ,		              //调光控制
	DEV_RS485_TRAIC,		  		NULL, //Rs485_Traic_Data_Get   		     ,		              //可控硅调光数组控制
	DEV_RS485_STRIP,     			NULL, //Rs485_Strip_Data_Get   		    ,     //设备灯带调光
	DEV_RS485_CoreCtrl,  			NULL, //Rs485_CoreCtrl_Data_Get       , //中控数组控制    NULL               
	DEV_RS485_WxLock,    			NULL, //Rs485_WxLockCtrl_Data_Get  ,            //微信锁数组控制 
	DEV_RS485_MUSIC,     			NULL, //Rs485_Music_Data_Get    			,         //背景音乐	数组控制
	DEV_NET_ROOMSTATE,   			NULL, //Udp_RoomState_Data_Init          ,      //房态下发     
	Dev_Host_PWMLight,   			NULL, //A3_Traic_Data_Get               ,      //自带PWM调光控制	

	DEV_RS485_PWM,       			NULL, //Rs485_PWM_Data_Get                ,     //调光扩展板
	DEV_PB_LED,          			NULL, //Rs485_PBLED_Data_Get         ,          //PBLED
	DEV_RCU_POWER,            NULL     ,	   //电源控制接口    
	DEV_RS485_RFGatewayCycle, NULL, //BLW_Rs485_RF_GatewayCycle_Data_Get   , //无线网关轮询接口
	DEV_RS485_RFGatewayHost,  NULL, //BLW_Rs485_RF_GatewayHost_Data_Get    , //无线网关主动接口
	DEV_RS485_RFGatewayDoor,  NULL, //BLW_Rs485_RFGatewayDoor_Data_Get ,     //无线门磁
	DEV_RS485_AirReveal,      NULL, //Rs485_AirReveal_Data_Get,           
	Dev_Host_TimeCtrl,        NULL, //BLW_Rs485_TimeCtrl_Data_Get     ,      //时间同步
	Dev_Rs458_MonitorCtrl,    NULL, //BLW_Rs485_MonitorCtrl_Data_Get  ,                //监控控制
	Dev_Rs458_RotaryCtrl,     NULL, //Rs485_Rot_Data_Get  ,                //监控控制
  DEV_C5IO_Type,            NULL,                                       //弱电输入输出，继电器服务函数
};



#define DEVINFOTYPENUM  (sizeof(DevDataGetGather)/sizeof(Struct_Dev_Data_Get))

/*所有设备数据,函数指针得到函数*/
void Dev_Info_Get(CFG_Dev_AddP CfgDevAdd)
{
	uint16_t i;
	
	for(i = 0; i < DEVINFOTYPENUM; i++)
	{
		if(CfgDevAdd->BUS_Public.type == DevDataGetGather[i].DevType)  //找到设备类型
		{
			if(NULL != DevDataGetGather[i].DevNodeDataInit)     //驱动存在
			{
				DevDataGetGather[i].DevNodeDataInit(CfgDevAdd); //执行相应的得到函数
			}
		}
	}
}

/**
  * @name  			MQTT获取设备地址列表
  * @param  
  *    buf      用于装设备列表的缓存buf
  * @retval     设备个数
  * @attention  
  */
uint16_t MQTT_DevList_Get(uint8_t* buf)
{
	uint16_t DevSum = 0;    //SRAM_Read_Byte(SRAM_MQTT_DEVICE_LIST_START);
#if MQTT_EN	
//	if(num > CFG_Dev_Freego_Map_MAX)   num = CFG_Dev_Freego_Map_MAX;
//	if(buf == NULL)
//	{
//		buf = malloc(num*Struct_CFG_Dev_Freego_Map_LEN + DeviceID_LEN + UTCTime_LEN + 5);
//		if(buf == NULL)  return 0;
//	}
//	SRAM_Read_Buff(&buf[1+DeviceID_LEN+UTCTime_LEN], num*Struct_CFG_Dev_Freego_Map_LEN, SRAM_MQTT_DEVICE_LIST_START+1);
	uint16_t i;  //用于遍历所有动作
	uint16_t j;  //用于遍历数组
	DEV_ACTION_INFO DevActionInfo;     //当前设备动作全部信息  
	uint32_t list_addr;
	uint8_t KeepFlag = 0x00;   //

/*所有场景遍历开始*/
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT场景上报遍历总数:%d", DevActionGlobal.DevActionNum);
	for(i = 0; i < DevActionGlobal.DevActionNum; i++) 
	{
		KeepFlag = 0x01;  //当前动作默认保存
		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 LOGIC_FILE_EN		
		if((0x00 != DevActionInfo.DevActionCore.ActionNo) && (DevSum < CFG_Dev_Freego_Map_MAX)&&(0x00 == DevActionInfo.DevActionInput.DevType))   //非0，个数限制  //增加使用配置时只上传0地址设备场景  2022-07-07
		{
			for(j = 0; j < DevSum; j++)  
			{
				if(((buf[j*Struct_CFG_Dev_Freego_Map_LEN+2])+(buf[j*Struct_CFG_Dev_Freego_Map_LEN+3]<<8)) == DevActionInfo.DevActionCore.ActionNo)
				{
					KeepFlag = 0x00;
				}
			}
			if(0x01 == KeepFlag)
			{
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = Dev_Host_Invalid;
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = 0x00;
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2] = DevActionInfo.DevActionCore.ActionNo;    //当前回路地址低字节
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+3] = 0x00;   //当前回路地址高字节	
				memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+4], (uint8_t *)&DevActionInfo.DevActionCore.DevActionName, DevActionNameLenMax);  
				DevSum++;		
				Dbg_Println(DBG_BIT_NET_STATUS_bit,"A7上报设备数:%d 场景名称：%s", DevSum,DevActionInfo.DevActionCore.DevActionName);
			}
		}

#else		
		if((0x00 != DevActionInfo.DevActionCore.ActionNo) && (DevSum < CFG_Dev_Freego_Map_MAX))   //非0，个数限制
		{
			for(j = 0; j < DevSum; j++)  
			{
				if(((buf[j*Struct_CFG_Dev_Freego_Map_LEN+2])+(buf[j*Struct_CFG_Dev_Freego_Map_LEN+3]<<8)) == DevActionInfo.DevActionCore.ActionNo)
				{
					KeepFlag = 0x00;
				}
			}
			if(0x01 == KeepFlag)
			{
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = Dev_Host_Invalid;
				buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = 0x00;
				memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2], (uint8_t *)&DevActionInfo.DevActionCore.ActionNo, Struct_CFG_Dev_Freego_Name_Len+2);  //拷贝22个字节
				DevSum++;		
				Dbg_Println(DBG_BIT_NET_STATUS_bit,"A7上报设备数:%d", DevSum);
			}
		}
#endif
  }
/*所有场景遍历结束*/	
/*所有设备遍历开始*/	
#if 1
	{
		uint32_t List_addr;
		Device_Public_Information_G BUS_Public;   //共用
		
		Dbg_Println(DBG_BIT_NET_STATUS_bit,"MQTT设备上报遍历总数:%d", DevActionGlobal.DevNum);

		for(i = 0; i < DevActionGlobal.DevNum; i++)   
		{
			List_addr = SRAM_Device_List_Start_Addr + i*SRAM_Device_List_Size;
			SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),List_addr);	//拷贝所有的函数指针
			Dbg_Println(DBG_BIT_NET_STATUS_bit,"第%d个设备，设备类型:%d",i, BUS_Public.type);
			
			switch(BUS_Public.type)
			{
				case Dev_Host_HVout:
					{
						NOR_HVOUT_INFO DevHVoutInfo;
						
						SRAM_DMA_Read_Buff((uint8_t *)&DevHVoutInfo,sizeof(NOR_HVOUT_INFO),List_addr+Dev_Privately);
						
						for(j = 0; j < DevHVoutInfo.HVoutLoopValidNum; j++)
						{		
							if((DevSum < CFG_Dev_Freego_Map_MAX)&&(0x00 != DevHVoutInfo.DevNameStruct[j].DevName[0]))   //别名存在且没有超出范围
							{
								{
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = BUS_Public.type;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = BUS_Public.addr;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2] = j+1;    //当前回路地址低字节
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+3] = 0x00;   //当前回路地址高字节									
									memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+4], (uint8_t *)&DevHVoutInfo.DevNameStruct[j].DevName[0], DEVNAMELENMAX);  //拷贝16个字节，继电器名称长度限制
									DevSum++;		
									Dbg_Println(DBG_BIT_NET_STATUS_bit,"继电器添加，A7上报设备数:%d", DevSum);
								}
							}
						}
					}
					break;
				case Dev_Host_Service:
					{
						NOR_SERVICE_INFO DevServiceInfo;       //服务信息局部变量
						
						SRAM_DMA_Read_Buff((uint8_t *)&DevServiceInfo,sizeof(NOR_SERVICE_INFO),List_addr+Dev_Privately);
						
						for(j = 0; j < DevServiceInfo.ServiceLoopValidNum; j++)
						{		
							if((DevSum < CFG_Dev_Freego_Map_MAX)&&(0x00 != DevServiceInfo.DevNameStruct[j].DevName[0]))   //别名存在且没有超出范围
							{
								{
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = BUS_Public.type;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = BUS_Public.addr;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2] = j+1;    //当前回路地址低字节
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+3] = 0x00;   //当前回路地址高字节									
									memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+4], (uint8_t *)&DevServiceInfo.DevNameStruct[j].DevName[0], DEVNAMELENMAX);  //拷贝16个字节，继电器名称长度限制
									DevSum++;		
									Dbg_Println(DBG_BIT_NET_STATUS_bit,"服务信息添加 A7上报设备数:%d", DevSum);
								}
							}
						}
					}
					break;	
				case Dev_NodeCurtain:
					{
						NOR_CURTAIN_INFO DevCurtainInfo;       //窗帘局部变量
						
						SRAM_DMA_Read_Buff((uint8_t *)&DevCurtainInfo,sizeof(NOR_CURTAIN_INFO),List_addr+Dev_Privately);
						
//						for(j = 0; j < DevCurtainInfo.ServiceLoopValidNum; j++)
						{		
							if((DevSum < CFG_Dev_Freego_Map_MAX)&&(0x00 != DevCurtainInfo.DevNameStruct.DevName[0]))   //别名存在且没有超出范围
							{
								{
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = BUS_Public.type;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = BUS_Public.addr;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2] = 0x00;    //当前回路地址低字节
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+3] = 0x00;   //当前回路地址高字节									
									memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+4], (uint8_t *)&DevCurtainInfo.DevNameStruct.DevName[0], DEVNAMELENMAX);  //拷贝16个字节，继电器名称长度限制
									DevSum++;		
									Dbg_Println(DBG_BIT_NET_STATUS_bit,"窗帘添加 A7上报设备数:%d", DevSum);
								}
							}
						}
					}
					break;	
				case DEV_RS485_TEMP:
					{
						RS485_TEMP_INFO Rs485TempT1;       //温控器局部变量
						
						SRAM_DMA_Read_Buff((uint8_t *)&Rs485TempT1,sizeof(RS485_TEMP_INFO),List_addr+Dev_Privately);
						
//						for(j = 0; j < Rs485TempT1.ServiceLoopValidNum; j++)
						{		
							if((DevSum < CFG_Dev_Freego_Map_MAX)&&(0x00 != Rs485TempT1.DevNameStruct.DevName[0]))   //别名存在且没有超出范围
							{
								{
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+0] = BUS_Public.type;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+1] = BUS_Public.addr;
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+2] = 0x00;    //当前回路地址低字节
									buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+3] = 0x00;   //当前回路地址高字节									
									memcpy(&buf[DevSum*Struct_CFG_Dev_Freego_Map_LEN+4], (uint8_t *)&Rs485TempT1.DevNameStruct.DevName[0], DEVNAMELENMAX);  //拷贝16个字节，继电器名称长度限制
									DevSum++;		
									Dbg_Println(DBG_BIT_NET_STATUS_bit,"温控器添加 A7上报设备数:%d", DevSum);
								}
							}
						}
					}
					break;						
			}
		}
	}
#endif	
/*所有设备遍历结束*/	
#endif	
	return DevSum * Struct_CFG_Dev_Freego_Map_LEN;

}

