



#include "BLV_485_Dev_C7TFun.h"
#include "check_fun.h"
#include "SPI_SRAM.h"
#include "usart.h"
#include "string.h"
#include "DBG.h"
#include "rw_logging.h"
#include "BLV_NET_Function.h"
#include "rtc.h"
#include "Log_api.h"
#include "includes.h"

  
#define Dev_C7T_RecvData_Len_Max	7
#define REPEATSENDTIMEMAX         0x03  //重发次数上限

/**/
uint8_t BLV_RS485_C7T_TempCycleCtrl(uint32_t DevAdd);   
uint8_t BLW_Rs485_C7T_Temp_Check(uint32_t DevAdd ,uint32_t Data_addr, uint16_t DataLen);

/**/
/*******************************************************************************
* Function Name  : BLV_RS485_C7T_Data_Init 
* Description    : C7T设备初始化函数
C7T设备描述：
	C7T是一个混合型设备，有温控器设备功能，按键设备功能，滑动条设备功能；并且使用
功能的协议和原设备功能协议相同，也就是说温控器数据上报使用的是温控器协议，按键上报
数据使用的是T1开关协议，滑动条上报数据使用的是滑动条协议(调光)协议。
	因此C7T设备驱动对于设备链表而言是3个设备：温控器、按键、滑动条。
* Input          : 
	Devaddr	: 设备地址
	DevSwiselect	: 设备开关键数
		日志: 202205091000   SongHan   0x16指令也会赋值温控器的状态，测试
		

*******************************************************************************/
void BLV_RS485_C7T_Data_Init(Device_Public_Information_G *BUS_Public, RS485_TEMP_INFO *Rs485TempT1)
{

	
	BUS_Public->polling_cf = (uint32_t)&BLV_RS485_C7T_TempCycleCtrl;		
	BUS_Public->processing_cf = (uint32_t)&BLW_Rs485_C7T_Temp_Check;
	
	Rs485TempT1->ValveSameFlag = 0x01;      //冷热阀一致   2023-06-27
	
	
}


/*******************************************************************************
* Function Name  : RS485_C7T_TempControl
* Description    : C7T温控器控制数据发送函数
*******************************************************************************/
void RS485_C7T_TempControl(Device_Public_Information_G *BUS_Public,RS485_TEMP_INFO *C7T_Info, uint8_t CtrlWay)
{
	uint8_t CtrlSend[5];// = {0x01, 0x16, 0x00, 0x00, 0x00};
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"%s",__func__); 

	CtrlSend[0] = BUS_Public->addr;// SRAM_Read_Byte(DevAdd+Dev_Addr);
	CtrlSend[1] = 0x16;                    
	
	CtrlSend[2] = C7T_Info->TemStateCtrl.set_t;//设置温度

	CtrlSend[3] = ((C7T_Temp_Switch_To_Judge(C7T_Info->TemStateCtrl.on_off)&0x03)<<6)+((C7T_Info->TemStateCtrl.mode&0x03)<<4)+((C7T_Info->TemStateCtrl.fan&0x03)<<2)+((C7T_Info->TemState.valve&0x03)<<0);   //阀门的状态发过去了，也不会判断
	
	CtrlSend[4] = SOR_CRC(CtrlSend,4);
	
	MCU485_SendString(BUS_Public->port,CtrlSend,5);
	
	/*日志记录*/
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port,BUS_Public->baud,CtrlSend,5);
}





/*******************************************************************************
* Function Name  : BLWC43_tempRecAsk 
* Description    : C7T温控器主动上报数据回复函数
*******************************************************************************/
void BLWC43_tempRecAsk(Device_Public_Information_G* BUS_Public, uint8_t *data, uint16_t DataLen, RS485_TEMP_INFO *Rs485Tem)
{
//	uint8_t Senddata[5];
//	uint8_t port = SRAM_Read_Byte(DevAdd+Dev_port);  

//	SRAM_Read_Buff(Senddata,5,Data_addr);

	MCU485_SendString(BUS_Public->port,data,DataLen);
}

/*******************************************************************************
* Function Name  : BLWC43_tempRecAsk 
* Description    : C7T温控器主动上报数据处理函数
*******************************************************************************/
void BLWC43_TempCtrDataProc(Device_Public_Information_G* BUS_Public, uint8_t *Data, RS485_TEMP_INFO *C7T_Temp_Info)
{
	RS485_TEMP_BASIC  Rs485TemRecBuf;  
//	RS485_TEM_BASIC set_temp;
	
	uint16_t TemState;
//	uint8_t temp = 0;
	
//	temp = SRAM_Read_Byte(Data_addr + 1);
	switch(Data[1])
	{
		case 0x13:
			TemState = Data[2] + (Data[3]<<8);//SRAM_Read_Word(Data_addr + 2);
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"温控器状态：");
			switch((TemState&0x8000)>>15)   //最高位
			{
				case 0x01:
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"开机");
					Rs485TemRecBuf.TemState.on_off = TEMP_STATE_ON;	
					break;
				case 0x00:
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"关机");
					Rs485TemRecBuf.TemState.on_off = TEMP_STATE_OFF; 
					break;
			}
			switch((TemState&0x6000)>>13)
			{
				case 1: 	//制冷
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"制冷");
					Rs485TemRecBuf.TemState.mode = TEMP_COLD; 
					break;  
				case 2: 	//制热
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"制热");
					Rs485TemRecBuf.TemState.mode = TEMP_HOT;  
					break;  
				case 3: 	//送风
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"送风");
					Rs485TemRecBuf.TemState.mode = TEMP_WIND; 
					break;  
				case 0: 	//模式自动
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"模式自动");
					Rs485TemRecBuf.TemState.mode = TEMP_MODEAUTO; 
					break;  
			}
			switch((TemState&0x1800)>>11)
			{
				case 1: 	//高速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"高速");
					Rs485TemRecBuf.TemState.fan	= TEMP_LOW; 
					break; 
				case 2: 	//中速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"中速");
					Rs485TemRecBuf.TemState.fan	= TEMP_MID; 
					break; 
				case 3: 	//低速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"低速");
					Rs485TemRecBuf.TemState.fan	= TEMP_HIGH; 
					break; 
				case 0: 	//自动
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"自动");
					Rs485TemRecBuf.TemState.fan	= TEMP_FANAUTO; 
					break; 
			}
			if((TEMP_STATE_ON == Rs485TemRecBuf.TemState.on_off)&&(TemState & 0x0400))   //如果阀开
			{
				Rs485TemRecBuf.TemState.valve = TEMP_VALVE_OPEN;
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"阀开");
			}
			else
			{
				Rs485TemRecBuf.TemState.valve = TEMP_VALVE_CLOSE; //阀关
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"阀关");
			}
			
			Rs485TemRecBuf.TemState.set_t = ((TemState&0x03E0)>>5);  //拿到温度，0即32度
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"设置温度：%d",Rs485TemRecBuf.TemState.set_t);
			
			Rs485TemRecBuf.TemState.indoor_t = (TemState&0x001F);    //拿到温度，0即32度
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"室内温度：%d",Rs485TemRecBuf.TemState.indoor_t);

			if((Rs485TemRecBuf.TemState.on_off != C7T_Temp_Info->TemState.on_off) || (Rs485TemRecBuf.TemState.mode != C7T_Temp_Info->TemState.mode)  ||
				(Rs485TemRecBuf.TemState.fan != C7T_Temp_Info->TemState.fan) || (Rs485TemRecBuf.TemState.valve != C7T_Temp_Info->TemState.valve)||
				 (Rs485TemRecBuf.TemState.set_t != C7T_Temp_Info->TemState.set_t) || (Rs485TemRecBuf.TemState.indoor_t != C7T_Temp_Info->TemState.indoor_t))//开关机 模式 温度 风速 室内温度与储存的不一样
			{
				
				if(C7T_Temp_Info->TemState.on_off == C7T_Temp_Info->control_start)		//本地控制状态，控制成功清楚标志位
				{
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"C7T_Temp_Info 清楚控制状态标志");
					C7T_Temp_Info->control_start = 0xFF;
				}
				
				Temp_Action_Set(&Rs485TemRecBuf, C7T_Temp_Info);  //同步状态，并产生动作
				
//				C7T_Temp_Info->TemState.on_off = Rs485TemRecBuf.TemState.on_off;
//				C7T_Temp_Info->TemState.mode = Rs485TemRecBuf.TemState.mode;
//				C7T_Temp_Info->TemState.fan = Rs485TemRecBuf.TemState.fan;
//				C7T_Temp_Info->TemState.set_t = Rs485TemRecBuf.TemState.set_t;
//				C7T_Temp_Info->TemState.valve = Rs485TemRecBuf.TemState.valve;
//				
//				
//				
//				C7T_Temp_Info->TemDataChangeFlag = 0x01;    //空调控制继电器标志		
			}
//			if(Rs485TemRecBuf.TemState.indoor_t != C7T_Temp_Info->TemState.indoor_t)
//			{
//				C7T_Temp_Info->TemState.indoor_t = Rs485TemRecBuf.TemState.indoor_t;
//				if(C7T_Temp_Info->TempType == TEMP_TYPE_VALVE)   //温控器类型为电磁阀类型
//				{
//					C7T_Temp_Info->TemDataChangeFlag = 0x01;
//				}
//			}	

			
//			C7T_Temp_Info->ControlFlag = 0x00;
			break;
		case 0x16:
			
			C7T_Temp_Info->TemStateCtrlFlag.TemOnOffCtrlVar = 0x00;
			C7T_Temp_Info->TemStateCtrlFlag.TemModeCtrlVar = 0x00;
			C7T_Temp_Info->TemStateCtrlFlag.TemFanCtrlVar = 0x00;
			C7T_Temp_Info->TemStateCtrlFlag.TemIndoorCtrlVar = 0x00;
			C7T_Temp_Info->TemStateCtrlFlag.TemSetTCtrlVar = 0x00;
			C7T_Temp_Info->TemStateCtrlFlag.TemValveCtrlVar = 0x00;
			
			TemState = Data[2] + (Data[3]<<8);//SRAM_Read_Word(Data_addr + 2);
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"控制回复指令，温控器状态:");
			switch((TemState&0xC000)>>14)   //Bit14~15
			{
				case 0x01:
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"开机");
					Rs485TemRecBuf.TemState.on_off = TEMP_STATE_ON;	
					break;
				case 0x02:
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"关机");
					Rs485TemRecBuf.TemState.on_off = TEMP_STATE_OFF; 
					break;
			}
			switch((TemState&0x3000)>>12)     //Bit12~13
			{
				case 1: 	//制冷
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"制冷");
					Rs485TemRecBuf.TemState.mode = TEMP_COLD; 
					break;  
				case 2: 	//制热
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"制热");
					Rs485TemRecBuf.TemState.mode = TEMP_HOT;  
					break;  
				case 3: 	//送风
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"送风");
					Rs485TemRecBuf.TemState.mode = TEMP_WIND; 
					break;  
				case 0: 	//模式自动
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"模式自动");
					Rs485TemRecBuf.TemState.mode = TEMP_MODEAUTO; 
					break;  
			}
			switch((TemState&0x0C00)>>10)   //Bit10~11
			{
				case 1: 	//高速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"高速");
					Rs485TemRecBuf.TemState.fan	= TEMP_LOW; 
					break; 
				case 2: 	//中速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"中速");
					Rs485TemRecBuf.TemState.fan	= TEMP_MID; 
					break; 
				case 3: 	//低速
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"低速");
					Rs485TemRecBuf.TemState.fan	= TEMP_HIGH; 
					break; 
				case 0: 	//自动
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"自动");
					Rs485TemRecBuf.TemState.fan	= TEMP_FANAUTO; 
					break; 
			}
//			if((TEMP_STATE_ON == Rs485TemRecBuf.TemState.on_off)&&
//				(TEMP_COLD == Rs485TemRecBuf.TemState.mode)&&())   //如果阀开
//			{
//				Rs485TemRecBuf.TemState.valve = TEMP_VALVE_OPEN;
//				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"阀开 ");
//			}
//			else
//			{
//				Rs485TemRecBuf.TemState.valve = TEMP_VALVE_CLOSE; //阀关
//				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"阀关 ");
//			}
			Rs485TemRecBuf.TemState.valve = C7T_Temp_Info->TemState.valve;
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"获取RCU之前存储的阀门状态：%d ",Rs485TemRecBuf.TemState.valve);
			
			Rs485TemRecBuf.TemState.set_t = (TemState&0x00ff);  //拿到温度，0即32度
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"设置温度：%d ",Rs485TemRecBuf.TemState.set_t);
			
			Rs485TemRecBuf.TemState.indoor_t = TEMTEMPCONVER(C7T_Temp_Info->TemState.indoor_t);  //(TemState&0x001F);    //拿到温度，0即32度
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"获取RCU之前存储的室内温度：%d ",Rs485TemRecBuf.TemState.indoor_t);

			if((Rs485TemRecBuf.TemState.on_off != C7T_Temp_Info->TemState.on_off) || (Rs485TemRecBuf.TemState.mode != C7T_Temp_Info->TemState.mode)  ||
				(Rs485TemRecBuf.TemState.fan != C7T_Temp_Info->TemState.fan) || (Rs485TemRecBuf.TemState.valve != C7T_Temp_Info->TemState.valve)||
				 (Rs485TemRecBuf.TemState.set_t != C7T_Temp_Info->TemState.set_t) || (Rs485TemRecBuf.TemState.indoor_t != C7T_Temp_Info->TemState.indoor_t))//开关机 模式 温度 风速 室内温度与储存的不一样
			{
				
				if(C7T_Temp_Info->TemState.on_off == C7T_Temp_Info->control_start)		//本地控制状态，控制成功清楚标志位
				{
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"C7T_Temp_Info 清楚控制状态标志");
					C7T_Temp_Info->control_start = 0xFF;
				}
				
				Temp_Action_Set(&Rs485TemRecBuf, C7T_Temp_Info);  //同步状态，并产生动作
			}		
			break;
	}
	
	//Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"C7T 没有小数位");
	C7T_Temp_Info->indoor_dec_temp = 0x00;
	
	/*比对服务器上报状态 - 是否写入日志
		2025-10-13 修改
			1、只针对用户操作状态变化进行上报，室内温度变化，不会进行数据上报
			2、温控器操作停止后30S后，再进行数据上报
	*/
	if( (C7T_Temp_Info->TemStateLast.on_off != C7T_Temp_Info->TemState.on_off) 	
		||	(C7T_Temp_Info->TemStateLast.mode != C7T_Temp_Info->TemState.mode) 
		||	(C7T_Temp_Info->TemStateLast.fan != C7T_Temp_Info->TemState.fan)
		||	(C7T_Temp_Info->TemStateLast.valve != C7T_Temp_Info->TemState.valve)
		||	(C7T_Temp_Info->TemStateLast.set_t != C7T_Temp_Info->TemState.set_t)
		||	(C7T_Temp_Info->TemStateLast.indoor_t != C7T_Temp_Info->TemState.indoor_t) )			
	{
		Dev_Temp_State_Sync(&C7T_Temp_Info->TemStateLast,&C7T_Temp_Info->TemState);
		
		if( (C7T_Temp_Info->TemStateLast.on_off != C7T_Temp_Info->TemState.on_off) 	
			||	(C7T_Temp_Info->TemStateLast.mode != C7T_Temp_Info->TemState.mode) 
			||	(C7T_Temp_Info->TemStateLast.fan != C7T_Temp_Info->TemState.fan)
			||	(C7T_Temp_Info->TemStateLast.valve != C7T_Temp_Info->TemState.valve)
			||	(C7T_Temp_Info->TemStateLast.set_t != C7T_Temp_Info->TemState.set_t) )			
		{
			
			
			C7T_Temp_Info->udp_flag = 0x01;
			C7T_Temp_Info->udp_tick = SysTick_1ms;

		}

	}
	
	
	
	if(C7T_Temp_Info->udp_flag == 0x01)
	{
		if( SysTick_1ms - C7T_Temp_Info->udp_tick >= 2000)
		{
			C7T_Temp_Info->udp_tick = SysTick_1ms;
			C7T_Temp_Info->udp_flag = 0x00;
			
			//写入日志
			Udp_Addtion_Roomstate(DEV_RS485_TEMP,BUS_Public->addr,0x0000,Dev_Temp_State_Data(C7T_Temp_Info->TemState));
		}
	}

}


/*******************************************************************************
* Function Name  : BLV_RS485_C7T_TempCycleCtrl 
* Description    : C7T温控器数据发送处理函数，包括重发

* Return         : 
	0x01：有数据需要发送
	0x00：没有数据需要发送
*******************************************************************************/
uint8_t BLV_RS485_C7T_TempCycleCtrl(uint32_t DevAdd)
{
	return TemGlobalJudge(DevAdd, RS485_C7T_TempControl, NULL);

	
}



#define RECDATALENMAX 5

/*******************************************************************************
* Function Name  : BLW_Rs485_C7T_Temp_Check 
* Description    : C7T温控器数据解析函数
* Return         : 
	0x01：数据处理失败
	0x00：数据处理成功
*******************************************************************************/
uint8_t BLW_Rs485_C7T_Temp_Check(uint32_t DevAdd ,uint32_t Data_addr, uint16_t DataLen) 
{
	uint8_t rev = 0x01;
//	uint16_t temp = 0;
	uint8_t data[RECDATALENMAX];
	Device_Public_Information_G BUS_Public;
	RS485_TEMP_INFO C7T_Temp_Info;       //温控器变量
	
	if((DataLen > RECDATALENMAX) || (0x00 == DevAdd))
	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"C7T温控器接收数据长度超出范围!!\r\n");
		return rev;     //长度
	}			
	
	SRAM_DMA_Read_Buff(data,DataLen,Data_addr);   //拷贝485数据
		
//	if(DevAdd == 0x00)	return 0x01;
//	temp = SRAM_Read_Byte(Data_addr);
	if((DataLen != 0x05)|| ((data[1] != 0x13)&&(data[1] != 0x16))||(data[DataLen - 1] != SOR_CRC(data, DataLen-1))||(data[0] != SRAM_Read_Byte(DevAdd+Dev_Addr)))	
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"C7T温控器未判断通过 len:%d",DataLen);
		return 0x01;
	}
	SRAM_DMA_Read_Buff((uint8_t *)&BUS_Public,sizeof(Device_Public_Information_G),DevAdd);		
	
	Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"BLW_Rs485_C7T_Temp_Check %d",BUS_Public.addr);
	
//	uint16_t deal_len = DataLen;
//	if(deal_len > Dev_C7T_RecvData_Len_Max)
//	{
//		Dbg_Print(DBG_BIT_DEVICE_STATUS_bit,"Dev_C7T_Temp Check_Len Fail! \r\n");
//		return rev;
//	}
//	uint8_t deal_buff[deal_len+2];
//	memset(deal_buff,0,sizeof(deal_buff));
//	SRAM_DMA_Read_Buff(deal_buff,deal_len,Data_addr);	
	
//	if()   //校验通过
	{
//		uint16_t val_check = 0;
//		uint16_t dev_datalen = SRAM_Read_Word(DevAdd+Dev_DataLen);
		
		/*拷贝设备私有信息*/
		SRAM_DMA_Read_Buff((uint8_t *)&C7T_Temp_Info,sizeof(RS485_TEMP_INFO),DevAdd+Dev_Privately);

//	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"增加C7T温控器设备发送函数2 地址: %4X 发送函数地址:%4X",BUS_Public.polling_cf, (uint32_t)&BLV_RS485_C7T_TempCycleCtrl);																 
		
		
		switch(data[1])
		{
//			case 0x07:		//设置温差回复
			case 0x13:		//主动上报
			case 0x16:		//控制回复
				if(C7T_Temp_Info.DevOffline != DEV_IS_ONLINE)  //不在线
				{
					Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"Dev_C7T_Temp %d LogInfo_Device_Online...........", data[0]);
					LOG_Device_Online_Record(BUS_Public.type, BUS_Public.addr, LogInfo_Device_Online);	//记录设备在线
				}
				BLV_Communication_Record(&C7T_Temp_Info.comm_record,0x02,0x01);		//记录通讯成功
				C7T_Temp_Info.DevSendCnt = 0x00;
				C7T_Temp_Info.DevOffline = DEV_IS_ONLINE;    //设备在线	
				if(C7T_Temp_Info.DevOffline != C7T_Temp_Info.DevOfflineLast)	//当前在线状态不等于上一次在线状态
				{
					C7T_Temp_Info.DevOfflineLast = C7T_Temp_Info.DevOffline;	//更新上一次在线状态
					Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
				}
				break;
		}
		
		switch(data[1])
		{
			case 0x13:		//主动上报
				BLWC43_tempRecAsk(&BUS_Public,data,DataLen, &C7T_Temp_Info);
			case 0x16:		//控制回复
				BLWC43_TempCtrDataProc(&BUS_Public,data, &C7T_Temp_Info);
				break;
		}
		
		/*日志记录*/
		LOG_Device_COMM_Control_Reply_Record(BUS_Public.port,BUS_Public.baud,data,DataLen);
		
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&C7T_Temp_Info, sizeof(RS485_TEMP_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),DevAdd);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&C7T_Temp_Info,sizeof(RS485_TEMP_INFO),DevAdd+Dev_Privately);
				
		rev = 0x00;
	}
	return rev;
}


