/**
  ******************************************************************************
  * @file    BLV_485_Dev_CLEDFreshAirFun.c
  * @author  BLW RCU  development Team	YHF
  * @version V1.0.0
  * @date    2023年7月27日
  * @brief   CLED新风
  ******************************************************************************
  */

#include "includes.h"
#include "BLV_485_Dev_CLEDFreshAirFun.h"

#define CLED_FRESHAIR_MAX_SEND_CNT				0x03	//CLED新风设备最大重发次数
#define CLED_FRESHAIR_RECEIVE_MAX_DATA_LEN		0x0A	//CLED新风设备最大数据长度

/*函数声明开始*/
void CLED_FreshAir_Control(Device_Public_Information_G *BUS_Public,RS485_FreshAir_INFO *FreshAir_Info);      
void CLED_FreshAir_Change_Data(Device_Public_Information_G *BUS_Public,RS485_FreshAir_INFO *FreshAir_Info,uint8_t *data);
/*函数声明结束*/

/*******************************************************************************
  * @brief      添加CLED新风设备到链表 - 主动设备
  * @param  
  *		BUS_Public		设备共有属性指针
  *		FreshAir_Info	485新风设备私有属性指针
  * @retval     None
  * @attention	None
*******************************************************************************/
void BLW_RS485_CLEDFreshAir_Init(Device_Public_Information_G *BUS_Public,RS485_FreshAir_INFO *FreshAir_Info)
{
	BUS_Public->polling_cf = (uint32_t)&CLED_FreshAir_Polling_Ctrl;	        //CLED新风控制函数
	BUS_Public->processing_cf = (uint32_t)&CLED_FreshAir_Data_Processing;	//CLED新风接收处理函数
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"添加CLED新风设备 %d 地址",BUS_Public->addr);
}

/*******************************************************************************
  * @brief      CLED新风控制函数
  * @param  
  *		dev_addr	设备信息地址
  * @retval     RS485OCCUPYTIME - 485发送函数会占用时间
				RS485OCCUPYNOTIME - 485发送函数不会占用时间
  * @attention	None
*******************************************************************************/
uint8_t CLED_FreshAir_Polling_Ctrl(uint32_t dev_addr)
{
	uint8_t send_time = RS485OCCUPYNOTIME;	//发送时间（默认发送不占用时间）
	Device_Public_Information_G BUS_Public;	//新风设备共有属性
	RS485_FreshAir_INFO FreshAir_Info;	//新风设备私有属性
	
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);	       //读取共有属性
	SRAM_DMA_Read_Buff((uint8_t *)&FreshAir_Info,sizeof(RS485_FreshAir_INFO), dev_addr+Dev_Privately);	//读取私有属性
	
	if((FreshAir_Info.ctrl_flag.on_off == 0x01) &&(FreshAir_Info.ctrl_flag.wind_velocity == 0x01))	//控制标志置1	
	{
		if(FreshAir_Info.ctrl_cnt.on_off != 0x00)	//开关机控制次数不为0
		{
			FreshAir_Info.ctrl_cnt.on_off--;	//控制次数减1
		}
		else	//开关机控制次数为0
		{
			FreshAir_Info.ctrl_flag.on_off = 0x00;	//控制开关机标志清0
		}
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CLED新风 开关机状态%d 风速状态:%d",\
		FreshAir_Info.ctrl_content.on_off,FreshAir_Info.ctrl_content.wind_velocity);
		CLED_FreshAir_Control(&BUS_Public,&FreshAir_Info);	//新风控制
		send_time = RS485OCCUPYTIME;	//发送占用时间
	}
	
	
	if(send_time == RS485OCCUPYTIME)	//如果发送占用时间
	{
		if(FreshAir_Info.DevSendCnt > CLED_FRESHAIR_MAX_SEND_CNT)	//发送次数大于重发次数
		{
			if(FreshAir_Info.DevOffline != DEV_IS_OFFLINE)	//设备当前不是离线
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CLED新风 %d 地址离线！！！",BUS_Public.addr);
				LOG_Device_Online_Record(DEV_RS485_FreshAir, BUS_Public.addr, LogInfo_Device_Offline);	//记录设备离线
			}
			FreshAir_Info.DevOffline = DEV_IS_OFFLINE;	//设备离线
			if(FreshAir_Info.DevOffline != FreshAir_Info.DevOfflineLast)	//当前在线状态不等于上一次在线状态
			{
				FreshAir_Info.DevOfflineLast = FreshAir_Info.DevOffline;	//更新上一次在线状态
				Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
			}
		}
		else	//发送次数小于等于重发
		{
			FreshAir_Info.DevSendCnt++;	//发送次数增加
		}
		BLV_Communication_Record(&FreshAir_Info.comm_record, 0x01, 0x00);	//通讯统计
		FreshAir_Info.inquire_tick = SysTick_1ms;	//更新轮询时间戳
		
		BUS_Public.check = 0x00;	//检验清0
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&FreshAir_Info, sizeof(RS485_FreshAir_INFO));	//计算校验
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);	//保存共有数据
		SRAM_DMA_Write_Buff((uint8_t *)&FreshAir_Info, sizeof(RS485_FreshAir_INFO), dev_addr+Dev_Privately);	//保存新风私有数据
	}
	return send_time;
}

/*******************************************************************************
  * @brief      CLED新风接收处理函数
  * @param  
  *		dev_addr		设备信息地址
  *		data_addr		485数据包地址
  *		DataLen			数据包长度
  * @retval     0-是CLED新风数据，1-不是CLED新风数据
  * @attention	None
*******************************************************************************/
uint8_t CLED_FreshAir_Data_Processing(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t rec = 0x01, data[CLED_FRESHAIR_RECEIVE_MAX_DATA_LEN];	//返回值（默认不是宝来威新风数据），接收的数据中间变量
	uint8_t temp_flag = 0x00;
	Device_Public_Information_G BUS_Public;	//新风设备共有属性
	RS485_FreshAir_INFO FreshAir_Info;	//新风设备私有属性
	
	
	if(len!=5)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"接收数据长度和CLED新风不符!!");
		return rec;
	}
	
	SRAM_DMA_Read_Buff(data, len, data_addr);	//读取新风设备的485数据
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);	//读取共有属性
	
	if(data[4]!=SOR_CRC(data,4))
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CLED新风和校验错误!!");
		return rec;
	}
	
	if(data[0]!=BUS_Public.addr)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"与CLED新风地址不符!!");
		return rec;
	}
	
	if((data[1]!=0x93) && (data[1]!=0x96))
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"与CLED新风命令字不符!!");
		return rec;
	}
	
	rec = 0x00;
	
	SRAM_DMA_Read_Buff((uint8_t *)&FreshAir_Info,sizeof(RS485_FreshAir_INFO), dev_addr+Dev_Privately);	//读取私有属性
	
	if(FreshAir_Info.DevOffline != DEV_IS_ONLINE)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CLED新风 %d 地址在线",BUS_Public.addr);
		LOG_Device_Online_Record(DEV_RS485_FreshAir, BUS_Public.addr, LogInfo_Device_Online);	//记录设备在线
	}
	FreshAir_Info.DevSendCnt = 0x00;	//计数清0
	FreshAir_Info.DevOffline = DEV_IS_ONLINE;	//轮询回复，设备在线
	if(FreshAir_Info.DevOffline != FreshAir_Info.DevOfflineLast)	//当前在线状态不等于上一次在线状态
	{
		FreshAir_Info.DevOfflineLast = FreshAir_Info.DevOffline;	//更新上一次在线状态
		Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
	}
	BLV_Communication_Record(&FreshAir_Info.comm_record,0x02,0x01);	//记录通讯成功
	
	switch(data[1])
	{
		case 0x93:
			CLED_FreshAir_Change_Data(&BUS_Public,&FreshAir_Info,data);
			temp_flag = 0x01;
			break;
		case 0x96:
			FreshAir_Info.ctrl_flag.on_off = 0x00;	//控制开关机清0
			FreshAir_Info.ctrl_flag.wind_velocity = 0x00;	//控制风速清0
			FreshAir_Info.ctrl_cnt.on_off = 0x03;
			FreshAir_Info.ctrl_cnt.wind_velocity = 0x03;		
			temp_flag = 0x01;
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"CLED新风 %d 地址设备收到控制回复，清开控制标志", BUS_Public.addr);
			break;
		default:
			break;
	}
	
	
	
	if(temp_flag)
	{
		BUS_Public.check = 0x00;	//检验清0
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&FreshAir_Info, sizeof(RS485_FreshAir_INFO));	//计算校验
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);	//保存共有数据
		SRAM_DMA_Write_Buff((uint8_t *)&FreshAir_Info, sizeof(RS485_FreshAir_INFO), dev_addr+Dev_Privately);	//保存新风私有数据
	}
		
	return rec;
}

/*******************************************************************************
  * @brief      CLED新风控制函数
  * @param  
  *		BUS_Public		设备共有属性指针
  *		function		功能控制
  *		control			控制内容
  * @retval     None
  * @attention	None
*******************************************************************************/
void CLED_FreshAir_Control(Device_Public_Information_G *BUS_Public,RS485_FreshAir_INFO *FreshAir_Info)
{
	uint8_t data[5] = {0};	//要发送的数据
	
	data[0] = BUS_Public->addr;	//设备地址赋值
	data[1] = 0x96;
	data[2] = 0x00;
	data[3] |= (FreshAir_Info->ctrl_content.wind_velocity<<2);
	
	if(FreshAir_Info->ctrl_content.on_off==0x01)
	{
		data[3] |= (0x01<<6);
	}
	else if(FreshAir_Info->ctrl_content.on_off==0x00)
	{
		data[3] |= (0x02<<6);
	}
	
	
	data[4] = SOR_CRC(data,4);
	
	MCU485_SendString(BUS_Public->port, data, 5);	//使用485发送
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 5);	//日志记录
}


/*******************************************************************************
  * @brief      宝来威新风数据变化函数
  * @param  
  *		FreshAir_Info	485新风设备私有属性指针
  *		data			接收数据指针
  * @retval     0 - 数据没变化
				1 - 数据有变化
  * @attention	None
*******************************************************************************/
void CLED_FreshAir_Change_Data(Device_Public_Information_G *BUS_Public,RS485_FreshAir_INFO *FreshAir_Info,uint8_t *data)
{

	FreshAir_Info->new_state.on_off = (data[3]&0x80)>>7;	//收到回复，当前开关机状态保存
	FreshAir_Info->new_state.wind_velocity = (data[3]&0x18)>>3;	//收到回复，当前风速状态保存
	if(FreshAir_Info->ctrl_content.on_off != FreshAir_Info->ctrl_content_last.on_off)	//开关控制状态同步
	{
		FreshAir_Info->ctrl_content_last.on_off = FreshAir_Info->ctrl_content.on_off;
	}
	if(FreshAir_Info->ctrl_content.wind_velocity != FreshAir_Info->ctrl_content_last.wind_velocity)	//风速控制状态同步
	{
		FreshAir_Info->ctrl_content_last.wind_velocity = FreshAir_Info->ctrl_content.wind_velocity;
	}
	
	MCU485_SendString(BUS_Public->port, data, 5);	//使用485发送
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 10);	//日志记录
	
}
