/**
  ******************************************************************************
  * @file    BLV_485_Dev_CJiaLockFun.c
  * @author  BLW RCU  development Team	林开锐
  * @version V1.0.0
  * @date    2022年7月8日
  * @brief   创佳门锁
	*          此驱动直接跟利尔达主从一体模组进行通讯。
	*  创佳门锁控制原理
			1.主动端口下发控制创佳开锁（需要从特征通道发送，1分钟创佳锁的密码会自己更改一次）
			2.查询创佳锁的状态（创佳和锁的连接，开锁）
			3.支持设置命令
  ******************************************************************************
  */

#include "includes.h"

#include "BLV_485_Dev_ChuangJiaLockFun.h"

/*******************************************************************************
  * @brief      添加设备到链表 - 主动设备
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	None
*******************************************************************************/
void ChuangJia_RS485_WxLockFun_Init(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFO *Rs485WxLockInfo)
{
	BUS_Public->polling_cf = (uint32_t)&ChuangJia_WxLock_Polling_Ctrl;	//创佳微信锁轮询控制函数（用于发送命令控制）
	BUS_Public->processing_cf = (uint32_t)&ChuangJia_WxLock_Data_Processing;	//创佳微信锁接收处理函数
	
	Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"添加创佳微信锁设备");
}

/*******************************************************************************
  * @brief      创佳微信锁轮询控制函数（用于发送命令控制，根据BUS_Public.wait_time的时间运行程序）
  * @param  
  *		dev_addr		设备信息地址
  * @retval     RS485OCCUPYTIME--485发送函数会占用时间
  * @attention	None
*******************************************************************************/
uint8_t ChuangJia_WxLock_Polling_Ctrl(uint32_t dev_addr)
{
	uint8_t i, temp = 0, flag = 0;	//循环查询命令次数、控制命令标志位（以位算）、发送标志
	Device_Public_Information_G BUS_Public;	//声明共有数据结构体
	RS485_WxLock_INFO Rs485WxLockInfo;	//声明门锁私有结构体
	
	SRAM_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);	//读取门锁地址的共有数据
	SRAM_Read_Buff((uint8_t *)&Rs485WxLockInfo, sizeof(RS485_WxLock_INFO), dev_addr+Dev_Privately);	//读取门锁地址的私有数据
	if( Rs485WxLockInfo.WeixinCtrlFlag == 0x01 )	//如果创佳锁控制标志位为1
	{
		if(SysTick_1ms >= Rs485WxLockInfo.WeixinCycleCnt)  //如果当前时间超过微信锁轮询计数，才执行下一次发送（超过5s没收到回复数据，才进行下一次发送）
		{
			Rs485WxLockInfo.WeixinCycleCnt = SysTick_1ms + CJ_LOCKCYCLEWAITTIMEOUT;	//下一次轮询次数的时间=当前时间+5s
			if(Rs485WxLockInfo.WeixinCtrlSendCnt != 0x00)	//发送次数不为0
			{
				Rs485WxLockInfo.WeixinCtrlSendCnt--;   //发送次数递减
			}
			else if(Rs485WxLockInfo.WeixinCtrlSendCnt == 0x00)	//发送次数为0
			{
				Rs485WxLockInfo.WeixinCtrlFlag = 0;	//关闭创佳锁控制标志位
			}
			if(Rs485WxLockInfo.WeixinCtrlState == 0x01)	//控制微信锁开（逻辑开）
			{
				Rs485WxLockInfo.CJ_control_flag |= CJ_UNLOCKING_FLAG;	//发送开锁命令
			}
			else if(Rs485WxLockInfo.WeixinCtrlState == 0x02)	//控制微信锁关（逻辑关）
			{
				Rs485WxLockInfo.CJ_control_flag |= CJ_QUERY_STATUS_FLAG;	//查询命令
			}
			for(i = 0; i < CJ_COMMAND_MAX; i++)	//查询命令
			{
				temp = 1 << i;	//每一位代表一个控制命令
				if(Rs485WxLockInfo.CJ_control_flag & temp)	//创佳微信锁控制命令返回处理
					break;
			}
			switch(temp)
			{
				case CJ_QUERY_STATUS_FLAG:	//查询状态
					ChuangJia_Query_Status(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_UNLOCKING_FLAG:		//开锁
					ChuangJia_Ctrl_Unlock(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_SET_CLOCK_FLAG:		//设置时钟
					ChuangJia_Set_Clock(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_LOCK_TIMER_FLAG:	//读取锁的时间
					ChuangJia_Lock_Timer(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_SET_CONNECT_FLAG:	//控制连接
					ChuangJia_Set_Connect(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_READ_ROOM_FLAG:		//读取房号
					ChuangJia_Read_Room(&BUS_Public,&Rs485WxLockInfo);
					break;
				case CJ_READ_GATEWAY_FLAG:	//读取网关版本
					ChuangJia_Read_Gateway(&BUS_Public,&Rs485WxLockInfo);
					break;
			}
			flag = 1;	//进入下一步
		}
	}
	if(flag == 1)
	{
		BLV_Communication_Record(&Rs485WxLockInfo.comm_record,0x01,0x00);	//通讯统计
		if(Rs485WxLockInfo.DevSendCnt > WxLockCtrlSendMax)	//发送次数大于重发，并且不处于离线
		{
			if(Rs485WxLockInfo.DevOffline != DEV_IS_OFFLINE)
			{
				Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁离线！");
				LOG_Device_Online_Record(BUS_Public.type, BUS_Public.addr, LogInfo_Device_Offline);	//记录设备离线
			}
			Rs485WxLockInfo.DevOffline = DEV_IS_OFFLINE;	//判为离线
			if(Rs485WxLockInfo.DevOffline != Rs485WxLockInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
			{
				Rs485WxLockInfo.DevOfflineLast = Rs485WxLockInfo.DevOffline;	//更新上一次在线状态
				Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_OFFLINE);	//保存设备在线状态到SRAM
			}
		}
		else 
		{
			Rs485WxLockInfo.DevSendCnt++;	//发送次数累加
		}
		BUS_Public.check = 0x00;	//校验和先置0
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485WxLockInfo, 
												sizeof(RS485_WxLock_INFO));	//两个数组和校验取反
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);	//保存门锁地址共有数据
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO),dev_addr+Dev_Privately);	//保存门锁地址私有数据
	}
	return RS485OCCUPYTIME;
}

/*******************************************************************************
  * @brief      创佳微信锁接收处理函数
  * @param  
  *		dev_addr		设备信息地址
  *		data_addr		485数据包地址
  *		DataLen			数据包长度
  * @retval     0-是创佳锁数据，1-不是创佳锁数据
  * @attention	None
*******************************************************************************/
uint8_t ChuangJia_WxLock_Data_Processing(uint32_t dev_addr,uint32_t data_addr,uint16_t len)
{
	uint8_t i,data[CJ_RECEIVE_MAX_LEN];	//局部变量  接收的数据中间变量（最多接收到42字节）
	
	Device_Public_Information_G BUS_Public;	//共有数据结构体
	RS485_WxLock_INFO Rs485WxLockInfo;		//微信锁私有数据结构体
	
	SRAM_Read_Buff(data, len, data_addr);   //将485数据读取出来 
	SRAM_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), dev_addr);			//读取门锁地址的共有数据
	SRAM_Read_Buff((uint8_t *)&Rs485WxLockInfo, sizeof(RS485_WxLock_INFO), dev_addr+Dev_Privately);	//读取门锁地址的私有数据
	if(Rs485WxLockInfo.DevOffline != DEV_IS_ONLINE)
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁在线！");
		LOG_Device_Online_Record(BUS_Public.type, BUS_Public.addr,LogInfo_Device_Online);	//记录设备在线
	}
	Rs485WxLockInfo.DevSendCnt = 0x00;	//进入数据回复，清发送次数
	Rs485WxLockInfo.DevOffline = DEV_IS_ONLINE;    //设备在线
	if(Rs485WxLockInfo.DevOffline != Rs485WxLockInfo.DevOfflineLast)	//当前在线状态不等于上一次在线状态
	{
		Rs485WxLockInfo.DevOfflineLast = Rs485WxLockInfo.DevOffline;	//更新上一次在线状态
		Write_Device_Fault_State(BUS_Public.type,BUS_Public.addr,In_ErrFun_LineState,DEV_IS_ONLINE);	//保存设备在线状态到SRAM
	}
	BLV_Communication_Record(&Rs485WxLockInfo.comm_record,0x02,0x01);		//记录通讯成功
	if(Dev_CheckSum(data_addr,len) != 0x00)	//数据校验不对
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁数据校验不对");
		return 1;
	}
	if(len > CJ_RECEIVE_MAX_LEN)	//接收的数据长度不对
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁数据长度不对");
		return 1;
	}
	if(data[CJ_OUR_ADD] != 0x01)	//发送地址不对
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁发送地址不对");
		return 1;
	}
	if(data[CJ_DEVICE_TYPE] != CJ_TYPE)		//创佳锁设备类型不对！
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁设备类型不对");
		return 1;
	}
	if(data[CJ_RECE_ADD] != 0x00)	//接收地址不对
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳锁接收地址不对");
		return 1;
	}
	if(Rs485WxLockInfo.DevOffline == DEV_IS_OFFLINE)	//创佳锁离线（如果接收到数据了标记在线）
	{
		Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"创佳微信锁离线");
		LOG_Device_Online_Record(BUS_Public.type, BUS_Public.addr,LogInfo_Device_Offline);	//记录设备离线
	}
	switch(data[CJ_COMMAND])	//对于不同命令回复数据
	{
		case CJ_QUERY_STATUS:	//查询状态
			Rs485WxLockInfo.CJ_connection_status = data[7];	//保存创佳锁与E92连接状态
			Rs485WxLockInfo.CJ_reality_lock = data[8];	//保存创佳锁实际开锁状态
			Rs485WxLockInfo.CJ_status = data[9];	//保存创佳锁状态
			Rs485WxLockInfo.CJ_kwh = data[10];	//保存创佳锁电量
			Rs485WxLockInfo.CJ_signal = data[11];	//保存创佳锁信号强度
			for(i = 0; i < 6; i++)	//保存创佳锁MAC（小端）
			{
				Rs485WxLockInfo.CJ_lock_mac[i] = data[i+12];
			}
			for(i = 0; i < 23; i++)	//保存创佳锁固件版本（小端模式）
			{
				Rs485WxLockInfo.CJ_firmware_version[i] = data[i+18];
			}
			Rs485WxLockInfo.CJ_identity = data[41];	//保存创佳锁开锁身份
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_QUERY_STATUS_FLAG);	//清除控制标志位
			break;
		case CJ_UNLOCKING:		//开锁
			Rs485WxLockInfo.CJ_connection_status = data[7];	//保存创佳锁与E92连接状态
			Rs485WxLockInfo.CJ_reality_lock = data[8];	//保存创佳锁实际开锁状态
			Rs485WxLockInfo.CJ_status = data[9];	//保存创佳锁状态
			Rs485WxLockInfo.CJ_kwh = data[10];	//保存创佳锁电量
			Rs485WxLockInfo.CJ_signal = data[11];	//保存创佳锁信号强度
			for(i = 0; i < 6; i++)	//保存创佳锁MAC（小端）
			{
				Rs485WxLockInfo.CJ_lock_mac[i] = data[i+12];
			}
			for(i = 0; i < 23; i++)	//保存创佳锁固件版本（小端模式）
			{
				Rs485WxLockInfo.CJ_firmware_version[i] = data[i+18];
			}
			Rs485WxLockInfo.CJ_identity = data[41];	//保存创佳锁开锁身份
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_UNLOCKING_FLAG);	//清除控制标志位
			break;
		case CJ_SET_CLOCK:		//设置时钟
			Rs485WxLockInfo.CJ_clock_flag = data[7];	//保存创佳锁设置时钟状态
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_SET_CLOCK_FLAG);	//清除控制标志位
			break;
		case CJ_LOCK_TIMER:		//读取锁的时间
			Rs485WxLockInfo.CJ_year = (uint16_t)(data[7]<<8)|data[8];	//年
			Rs485WxLockInfo.CJ_month = data[9];	//月
			Rs485WxLockInfo.CJ_day = data[10];	//日
			Rs485WxLockInfo.CJ_hour = data[11];	//时
			Rs485WxLockInfo.CJ_min = data[12];	//分
			Rs485WxLockInfo.CJ_sec = data[13];	//秒
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_LOCK_TIMER_FLAG);	//清除控制标志位
			break;
		case CJ_SET_CONNECT:	//控制连接
			Rs485WxLockInfo.CJ_connect_flag = data[7];	//保存创佳锁控制配对连接状态
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_SET_CONNECT_FLAG);	//清除控制标志位
			break;
		case CJ_READ_ROOM:		//读取房号
			for(i = 0; i < 4; i++)
			{
				Rs485WxLockInfo.CJ_room[i] = data[i+7];	//保存创佳锁房间
			}
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_READ_ROOM_FLAG);	//清除控制标志位
			break;
		case CJ_READ_GATEWAY:	//读取网关版本
			for(i = 0; i < 14; i++)
			{
				Rs485WxLockInfo.CJ_read_gateway[i] = data[i+7];	//保存创佳锁读取网关版本信息
			}
			Rs485WxLockInfo.CJ_control_flag &= ~(CJ_READ_GATEWAY_FLAG);	//清除控制标志位
			break;
		case CJ_CARD_UNLOCKING:	//卡开锁
			Rs485WxLockInfo.CJ_connection_status = data[7];	//保存创佳锁与E92连接状态
			Rs485WxLockInfo.CJ_reality_lock = data[8];	//保存创佳锁实际开锁状态
			Rs485WxLockInfo.CJ_status = data[9];	//保存创佳锁状态
			Rs485WxLockInfo.CJ_kwh = data[10];	//保存创佳锁电量
			Rs485WxLockInfo.CJ_signal = data[11];	//保存创佳锁信号强度
			for(i = 0; i < 6; i++)	//保存创佳锁MAC（小端）
			{
				Rs485WxLockInfo.CJ_lock_mac[i] = data[i+12];
			}
			for(i = 0; i < 23; i++)	//保存创佳锁固件版本（小端模式）
			{
				Rs485WxLockInfo.CJ_firmware_version[i] = data[i+18];
			}
			Rs485WxLockInfo.CJ_identity = data[41];	//保存创佳锁开锁身份
			LOG_Device_COMM_Send_Control_Record(BUS_Public.port, BUS_Public.baud, data, 42);	//记录卡开锁日志
			break;
	}
	if(data[CJ_COMMAND] == CJ_CARD_UNLOCKING)	//只有卡开锁才需要主机主动发送回复命令
	{
		i = data[CJ_OUR_ADD];	//己方地址保存到中间变量
		data[CJ_OUR_ADD] = data[CJ_RECE_ADD];	//己方地址和收方地址中的数据互换
		data[CJ_RECE_ADD] = i;	//中间变量保存到收方地址
		data[CJ_DATA_LEN] = 7;	//回复创佳锁数据固定为7
		data[CJ_CHECK] = 0x00;	//校验和先置0
		data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
		MCU485_SendString(BUS_Public.port, data, 7);	//RCU通用485发送函数
	}
	Rs485WxLockInfo.WeixinCtrlFlag = 0;   //收到回复进行清0
	Rs485WxLockInfo.WeixinCycleCnt = 0;   //收到回复清计数，方便下次发命令，能及时回复数据
	BUS_Public.check = 0x00;	//校验和先置0
	BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485WxLockInfo, 
											sizeof(RS485_WxLock_INFO));	//计算检验和
	SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),dev_addr);	//将共有数据保存
	SRAM_DMA_Write_Buff((uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO),dev_addr+Dev_Privately);	//将私有数据保存
	return 0;
}

/*******************************************************************************
  * @brief      创佳微信锁查询状态函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责查询创佳锁状态
*******************************************************************************/
void ChuangJia_Query_Status(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[7];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x07;	//数据长度
	data[CJ_COMMAND] = CJ_QUERY_STATUS;	//查询状态命令
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 7);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 7);	//记录查询状态日志
}

/*******************************************************************************
  * @brief      创佳微信锁控制开锁函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责下发创佳锁开锁
*******************************************************************************/
void ChuangJia_Ctrl_Unlock(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[7];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x07;	//数据长度
	data[CJ_COMMAND] = CJ_UNLOCKING;	//开锁命令
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 7);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 7);	//记录控制开锁日志
}

uint8_t CJ_Set_Timer[7];	//创佳锁设置时间
/*******************************************************************************
  * @brief      创佳微信锁设置时钟函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责设置创佳锁时钟（需要设置CJ_Set_Timer数组）
*******************************************************************************/
void ChuangJia_Set_Clock(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[14];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else	//重发
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x0E;	//数据长度
	data[CJ_COMMAND] = CJ_SET_CLOCK;	//设置时钟命令
	data[CJ_PARAM] = CJ_Set_Timer[0];	//取年份前两位数（十进制）
	data[CJ_PARAM+1] = CJ_Set_Timer[1];	//取年份后两位数（十进制）
	data[CJ_PARAM+2] = CJ_Set_Timer[2];	//月
	data[CJ_PARAM+3] = CJ_Set_Timer[3];	//日
	data[CJ_PARAM+4] = CJ_Set_Timer[4];	//时
	data[CJ_PARAM+5] = CJ_Set_Timer[5];	//分
	data[CJ_PARAM+6] = CJ_Set_Timer[6];	//秒
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 14);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 14);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 14);	//记录设置时钟日志
}

/*******************************************************************************
  * @brief      创佳微信锁读取时间函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责读取创佳锁时间
*******************************************************************************/
void ChuangJia_Lock_Timer(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[7];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else	//重发
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x07;	//数据长度
	data[CJ_COMMAND] = CJ_LOCK_TIMER;	//读取锁的时间
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 7);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 7);	//记录读取时间日志
}

uint8_t CJ_Set_Connect;	//创佳锁配对控制参数
/*******************************************************************************
  * @brief      创佳微信锁控制配对连接函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责创佳锁控制连接
*******************************************************************************/
void ChuangJia_Set_Connect(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[8];	//命令固定8字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else	//重发
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x08;	//数据长度
	data[CJ_COMMAND] = CJ_SET_CONNECT;	//控制连接
	data[CJ_PARAM] = CJ_Set_Connect;	//配对控制参数
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 8);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 8);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 8);	//记录创佳锁控制开锁命令日志
}

/*******************************************************************************
  * @brief      创佳微信锁读取房号函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责创佳锁读取房号
*******************************************************************************/
void ChuangJia_Read_Room(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[7];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else	//重发
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x07;	//数据长度
	data[CJ_COMMAND] = CJ_READ_ROOM;	//读取房号
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 7);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 7);	//记录读取房号日志
}

/*******************************************************************************
  * @brief      创佳微信锁读取网关版本函数
  * @param  
  *		BUS_Public		设备共有数据结构体
  *		Rs485WxLockInfo	微信锁私有数据结构体
  * @retval     None
  * @attention	负责创佳锁读取网关版本
*******************************************************************************/
void ChuangJia_Read_Gateway(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFOP Rs485WxLockInfo)
{
	uint8_t data[7];	//命令固定7字节
	memset(data,0,sizeof(data));	//初始化为0
	/*参数设置*/
	data[CJ_OUR_ADD] = 0x00;	//己方地址
	if(Rs485WxLockInfo->DevSendCnt == 0x00)	//首发
	{
		Rs485WxLockInfo->CJ_send_sn++;	//发送序号递增
		if(Rs485WxLockInfo->CJ_send_sn > 15) Rs485WxLockInfo->CJ_send_sn = 1;
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
	}
	else	//重发
	{
		data[CJ_SEND_TYPE] |= (Rs485WxLockInfo->CJ_send_sn & 0x0F);	//发送类型
		data[CJ_SEND_TYPE] |= CJ_RETRY_FLAG;
	}
	data[CJ_DEVICE_TYPE] = 0x06;	//设备类型
	data[CJ_RECE_ADD] = 0x01;	//收方地址
	data[CJ_DATA_LEN] = 0x07;	//数据长度
	data[CJ_COMMAND] = CJ_READ_GATEWAY;	//读取网关版本
	data[CJ_CHECK] = 0x00;	//和校验取反（将检验和带进去就算后，再赋值）
	data[CJ_CHECK] = CheckSum(data, 7);	//计算检验和
	MCU485_SendString(BUS_Public->port, data, 7);	//RCU通用485发送函数
	LOG_Device_COMM_Send_Control_Record(BUS_Public->port, BUS_Public->baud, data, 7);	//记录读取网关版本日志
}
