#include "main.h"
#include "sensor.h"
#include "string.h"
#include "sht3x.h"
#include "usart_user.h"

//PM2.5命令
const uint8_t cmd_pm25_duqu[7] 					= {0x42,0x4D,0xE2,0x00,0x00,0x01,0x71};//主动读取数据
const uint8_t cmd_pm25_beidong[7]		  	= {0x42,0x4D,0xE1,0x00,0x00,0x01,0x70};//设置传感器为应答模式
const uint8_t cmd_pm25_zhudong[7] 			= {0x42,0x4D,0xE1,0x00,0x01,0x01,0x71};//设置传感器为主动上传模式
const uint8_t cmd_pm25_daiji[7]					= {0x42,0x4D,0xE4,0x00,0x00,0x01,0x73};//设置传感器进入待机模式
const uint8_t cmd_pm25_zhengchang[7] 		= {0x42,0x4D,0xE4,0x00,0x01,0x01,0x74};//设置传感器进入正常模式
	
//CO2命令
const uint8_t cmd_co2_duqu[9]      			= {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_co2_liangcheng2[9] 	  = {0xFF,0x01,0x99,0x00,0x00,0x00,0x07,0xD0,0x8F};//设置二氧化碳量程为0-2000ppm
const uint8_t cmd_co2_liangcheng5[9] 		= {0xFF,0x01,0x99,0x00,0x00,0x00,0x13,0x88,0xCB};//设置二氧化碳量程为0-5000ppm
const uint8_t cmd_co2_liangcheng10[9] 	= {0xFF,0x01,0x99,0x00,0x00,0x00,0x27,0x10,0x2F};//设置二氧化碳量程为0-10000ppm

//NH3/H2S命令
const uint8_t cmd_nh3_h2s_duqu[9]  			= {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_nh3_h2s_beidong[9]  	= {0xFF,0x01,0x78,0x04,0x00,0x00,0x00,0x00,0x83};//设置传感器为应答模式
const uint8_t cmd_nh3_h2s_zhudong[9]  	= {0xFF,0x01,0x86,0x03,0x00,0x00,0x00,0x00,0x84};//设置传感器为主动上传模式

//CH2O命令
const uint8_t cmd_CH2O_duqu[9]      		= {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_CH2O_beidong[9] 		  = {0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//设置传感器为应答模式
const uint8_t cmd_CH2O_zhudong[9] 			= {0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//设置传感器为主动上传模式

//O3命令
const uint8_t cmd_O3_duqu[9]      		= {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_O3_beidong[9] 		  = {0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//设置传感器为应答模式
const uint8_t cmd_O3_zhudong[9] 			= {0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//设置传感器为主动上传模式


sensor_parse_ctrl_t nh3;
sensor_parse_ctrl_t h2s;
sensor_parse_ctrl_t co2;
sensor_parse_ctrl_t pm25;
sensor_parse_ctrl_t ch2o;
sensor_parse_ctrl_t o3;

SensorDataTypeDef sensorData;

void InitSonsorData(SensorDataTypeDef *sensorData)
{
	sensorData->temperature = 26.00;
	sensorData->humidity = 50.00;
	sensorData->nh3 = 1.00;
	sensorData->h2s = 0.01;
	sensorData->ch2o = 0.01;
	sensorData->co2 = 400;
	sensorData->tvoc = 0;
	sensorData->pm25 = 20;
	sensorData->pm10 = 25;
	
	sensorData->temperature1 = 25;
	sensorData->temperature2 = 55;
	sensorData->humidity1 = 43;
	sensorData->humidity2 = 46;
	sensorData->nh31 = 5;
	sensorData->nh32 = 4;
	sensorData->h2s1 = 7;
	sensorData->h2s2 = 18;
	sensorData->ch2o1 = 4;
	sensorData->ch2o2 = 78;
		
	sensorData->co21 = 4;
	sensorData->co22 = 112;
	
	sensorData->o31 = 0;
	sensorData->o32 = 0;
		
	sensorData->tvoca = 1;
	sensorData->tvocb = 1;
		
	sensorData->pm251 = 2;
	sensorData->pm252 = 45;
		
	sensorData->pm101 = 5;
	sensorData->pm102 = 45;
}

//初始化结构体
void InitSonsorCtrlData(sensor_parse_ctrl_t *sensor_parse_ctrl, uint8_t data_length, uint8_t type)
{
	sensor_parse_ctrl->type = type;
	
	RingBuff_Init(&sensor_parse_ctrl->recvRingBuff);
	
	sensor_parse_ctrl->data_length = data_length;
	
	sensor_parse_ctrl->function = NULL;
}

void SensorModeInitSet(void)
{
	//PM25设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(PM25_USART,cmd_pm25_beidong,sizeof(cmd_pm25_beidong));

	//CH2O设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(CH2O_USART,cmd_CH2O_beidong,sizeof(cmd_CH2O_beidong));

	//H2S设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(H2S_USART,cmd_nh3_h2s_beidong,sizeof(cmd_nh3_h2s_beidong));

	//NH3设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(NH3_USART,cmd_nh3_h2s_beidong,sizeof(cmd_nh3_h2s_beidong));

	//CO2设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(CO2_USART,cmd_co2_liangcheng2,sizeof(cmd_co2_liangcheng2));
	
	
	//O3设置为应答模式
	LL_mDelay(50);
	UsartxSendDataStr(O3_USART,cmd_O3_beidong,sizeof(cmd_O3_beidong));
	
	//init sht3x sensor
	LL_mDelay(50);
	SHT3X_Init(0x44);
	LL_mDelay(50);
}

void GetSensorData(void)
{
	
	//PM2.5发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(USART4, cmd_pm25_duqu, sizeof(cmd_pm25_duqu));
		
	//CO2发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(CO2_USART, cmd_co2_duqu, sizeof(cmd_co2_duqu));

	//O3发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(O3_USART, cmd_O3_duqu, sizeof(cmd_O3_duqu));
	
	//CH2O发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(CH2O_USART,cmd_CH2O_duqu,sizeof(cmd_CH2O_duqu));
	
	//H2S发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(H2S_USART,cmd_nh3_h2s_duqu,sizeof(cmd_nh3_h2s_duqu));

	//NH3发送获取数据命令
	LL_mDelay(50);
	UsartxSendDataStr(NH3_USART,cmd_nh3_h2s_duqu,sizeof(cmd_nh3_h2s_duqu));
	
	//获取温湿度数据
	LL_mDelay(50);
	SHT3X_GetTempAndHumi(&sensorData.temperature, &sensorData.humidity, REPEATAB_HIGH, MODE_POLLING, 50);
	if(sensorData.temperature >= 0)
	{
		sensorData.symbol = 1&0xFF;
	}
	else
	{
		sensorData.symbol = 0&0xFF;
	}
	sensorData.temperature1 = ((int)sensorData.temperature)&0xFF;
	sensorData.temperature2 = ((int)((sensorData.temperature)*100)%100)&0xFF;
	sensorData.humidity1 = ((int)sensorData.humidity)&0xFF;
	sensorData.humidity2 = ((int)((sensorData.humidity)*100)%100)&0xFF;
	
	sensorData.tvoca = LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_10);
	sensorData.tvocb =	LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_10);
	if(sensorData.tvoca == 0 & sensorData.tvocb == 0)
		sensorData.tvoc = 0;
	if(sensorData.tvoca == 0 & sensorData.tvocb == 1)
		sensorData.tvoc = 1;
	if(sensorData.tvoca == 1 & sensorData.tvocb == 0)
		sensorData.tvoc = 2;
	if(sensorData.tvoca == 1 & sensorData.tvocb == 1)
		sensorData.tvoc = 3;
	
}

void ReadSensorData(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
	uint8_t recdata[1];
	uint32_t data_length = 0;
	
	if(Read_Length_RingBuff(&sensor_parse_ctrl->recvRingBuff) < sensor_parse_ctrl->data_length)
	{
		while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata)){};
	}
	
	else
	{
		while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata))
		{
			sensor_parse_ctrl->sensorData[data_length] = recdata[0];
			data_length++;
			if(data_length >= sensor_parse_ctrl->data_length)
			{
				while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata)){};
			}
		}
	}
}

static void general_data_check(sensor_parse_ctrl_t *sensor_parse_ctrl)
{	
	if((sensor_parse_ctrl->sensorData[0] != 0xFF) || (sensor_parse_ctrl->sensorData[1] != 0x86))
	{
		return;
	}
	
	uint8_t temp = 0x00;
	
	for(int i = 1; i<sensor_parse_ctrl->data_length-1; i++)
	{
		temp += sensor_parse_ctrl->sensorData[i];
	}
	
	temp = (~temp)+1;
	
	if((temp&0xFF) == sensor_parse_ctrl->sensorData[sensor_parse_ctrl->data_length-1])
	{
		
		switch (sensor_parse_ctrl->type)
		{
			case CO2_TYPE:
				sensorData.co2 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3]);
				sensorData.co21 = ((sensorData.co2)>>8)&0xFF;
				sensorData.co22 = (sensorData.co2)&0xFF;
				break;
			case O3_TYPE:
				sensorData.o3 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3]);
				sensorData.o31 = ((sensorData.o3)>>8)&0xFF;
				sensorData.o32 = (sensorData.o3)&0xFF;
				break;

			case CH2O_TYPE:
				sensorData.ch2o = (sensor_parse_ctrl->sensorData[6]*256+sensor_parse_ctrl->sensorData[7])/1000.00;
				sensorData.ch2o1 = ((int)sensorData.ch2o)&0xFF;
				sensorData.ch2o2 = ((int)((sensorData.ch2o)*100)%100)&0xFF;
				break;
			case NH3_TYPE:
				sensorData.nh3 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3])/100.00;
				sensorData.nh31 = ((int)sensorData.nh3)&0xFF;
				sensorData.nh32 = ((int)((sensorData.nh3)*100)%100)&0xFF;
				break;
			case H2S_TYPE:
				sensorData.h2s = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3])/100.00;
				sensorData.h2s1 = ((int)sensorData.h2s)&0xFF;
				sensorData.h2s2 = ((int)((sensorData.h2s)*100)%100)&0xFF;
				break;
			default:
				break;	
		}
	}
	
	memset(sensor_parse_ctrl->sensorData, 0, sizeof(sensor_parse_ctrl->sensorData));
	
}

static void pm25_data_check(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
	//PM25数据校验
	uint16_t PM25_temp = 0x0000;
	
	if((sensor_parse_ctrl->sensorData[0] != 0x42) || (sensor_parse_ctrl->sensorData[1] != 0x4D))
	{
		return;
	}
	
	for(int i = 0; i < sensor_parse_ctrl->data_length-2; i++)
	{
		PM25_temp += sensor_parse_ctrl->sensorData[i];
	}
	if((PM25_temp>>8) == sensor_parse_ctrl->sensorData[30] && (PM25_temp&0xFF)==sensor_parse_ctrl->sensorData[31])
	{
		sensorData.pm25 = (sensor_parse_ctrl->sensorData[12]*256+sensor_parse_ctrl->sensorData[13]);
		sensorData.pm10 = (sensor_parse_ctrl->sensorData[14]*256+sensor_parse_ctrl->sensorData[15]);
		
		sensorData.pm251 = ((sensorData.pm25)>>8)&0xFF;
		sensorData.pm252 = ((sensorData.pm25))&0xFF;
	
		sensorData.pm101 = ((sensorData.pm10)>>8)&0xFF;
		sensorData.pm102 = (sensorData.pm10)&0xFF;
		
	}
	memset(sensor_parse_ctrl->sensorData, 0, sizeof(sensor_parse_ctrl->sensorData));
	
}

void AnalysisSensorData(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
	switch (sensor_parse_ctrl->type)
	{
		case H2S_TYPE:
		case CO2_TYPE:
		case O3_TYPE:
		case NH3_TYPE:
		case CH2O_TYPE:
			general_data_check(sensor_parse_ctrl);
			break;
		case PM25_TYPE:
			pm25_data_check(sensor_parse_ctrl);
			break;
	}
	
}