#include "GY39Controller.h"
#include "ZZ_Types.h"
using namespace ZZ_MISCDEF;

GY39Controller::GY39Controller(QObject* parent /*= nullptr*/)
{
	m_pSerialPort = new QSerialPort;
	m_iBaudRate = 9600;
}

GY39Controller::~GY39Controller()
{
	if (m_pSerialPort != NULL)
	{
		delete m_pSerialPort;
	}
}

int GY39Controller::SendCommand(QByteArray qbCommand)
{
	qint64 qi64Write = m_pSerialPort->write(qbCommand);
	m_pSerialPort->waitForBytesWritten(5000);
	if (qi64Write != qbCommand.size())
	{
		qDebug() << "Err:write Failed.Exit Code:1" << qi64Write;
		return 1;
	}

	return 0;
}

int GY39Controller::RecvHumitureData(QByteArray &qbData)
{
	qbData.clear();
	qbData = m_pSerialPort->readAll();

	int iCounter = 0;
	while (qbData.size() < 15)
	{
		m_pSerialPort->waitForReadyRead(5000);
		QByteArray qbTemp = m_pSerialPort->readAll();
		qbData.append(qbTemp);

		if (iCounter > 10)
		{
			qDebug() << "Err:RecvHumitureData Failed,Not Enough Data.Exit Code:1" << qbData.size();
			return 1;
		}
		iCounter++;
	}
	return 0;
}

int GY39Controller::ParseHumitureData(QByteArray &qbData)
{
	ZZ_U8 cTempH8, cTempL8, cHumH8, cHumL8;

	cTempH8 = qbData[4];
	cTempL8 = qbData[5];

	cHumH8 = qbData[10];
	cHumL8 = qbData[11];

	float fTemp = (cTempH8 << 8) | cTempL8;
	fTemp = fTemp / 100;
	float fHum = (cHumH8 << 8) | cHumL8;
	fHum = fHum / 100;

	m_fTemperature = fTemp;
	m_fHumidity = fHum;
	return 0;
}

int GY39Controller::Initialize(std::string ucPortName, bool bAuto15/*=false*/, bool bAuto45/*=false*/)
{
	QString qstrPortName = QString::fromStdString(ucPortName);

	m_pSerialPort->setPortName(qstrPortName);
	m_pSerialPort->setReadBufferSize(512);
	bool bRes = m_pSerialPort->setBaudRate(m_iBaudRate);
	if (!bRes)
	{
		qDebug() << "Err:setBaudRate Failed.Exit Code:1";
		//std::cout << "Err.setBaudRate Failed" << std::endl;
		return 1;
	}

	bRes = m_pSerialPort->open(QIODevice::ReadWrite);
	if (!bRes)
	{
		qDebug() << "Err:open Failed.Exit Code:2";
		//std::cout << "Err.open Failed" << std::endl;
		return 2;
	}

	QByteArray qbSend;

	if (bAuto15==false && bAuto45==false)
	{
		qbSend.resize(3);
		qbSend[0] = (ZZ_U8)0xA5;
		qbSend[1] = (ZZ_U8)0x00;
		qbSend[2] = (ZZ_U8)0xA5;
	}

	if (bAuto15 == true && bAuto45 == true)
	{
		qbSend.resize(3);
		qbSend[0] = (ZZ_U8)0xA5;
		qbSend[1] = (ZZ_U8)0x03;
		qbSend[2] = (ZZ_U8)0xA8;
	}
	SendCommand(qbSend);
	return 0;
}

int GY39Controller::GetHumiture(float &fTemp, float &fHum)
{
	QByteArray qbSend,qbRecv;

	qbSend.resize(3);
	qbSend[0] = (ZZ_U8)0xA5;
	qbSend[1] = (ZZ_U8)0x52;
	qbSend[2] = (ZZ_U8)0xF7;

	int iRes = SendCommand(qbSend);
	if (iRes)
	{
		return iRes;
	}

	iRes = RecvHumitureData(qbRecv);
	if (iRes)
	{
		return iRes;
	}

	ParseHumitureData(qbRecv);
	fTemp = m_fTemperature;
	fHum  = m_fHumidity;
	return 0;
}

int GY39Controller::GetHumiture_retry(float &fTemp, float &fHum)
{
	int iCount = 0;
	while (iCount<3)
	{
		if (GetHumiture(fTemp, fHum) == 0)
		{
			return 0;
		}
		else
		{
			iCount++;
		}
	}
	return 1;
	
}
