/*
 * HumitureSensors.cpp
 *
 *  Created on: 2024年4月15日
 *      Author: m
 */



#include "utils/I2CHelper.h"
#include "utils/CrcCheckUtil.h"
#include "HumitureSensors.h"
#include <unistd.h>
#include <string>
#include "base/strings.hpp"
#include "service/BusinessConfig.h"

// 测量湿度命令
#define DHT22_DATA 0x2C01;

static uint32_t DHT22_ADDR = 0x44;
static uint16_t HumA, HumB;
static I2CHelper i2c(0, DHT22_ADDR, 5 * 1000, 5);

//HumitureSenors::HumitureSenors() {
//}

HumitureSenors::~HumitureSenors() {
}

HumitureSenors* HumitureSenors::instance() {
	static HumitureSenors singleton;
	return &singleton;
}





void restartHumThread() {

}

void humThreadInit(){
	std::thread backend([](){
	    unsigned char humData[2];
	    uint8_t data[6];
	    uint8_t crcData[3];

	    // 触发温湿度测量
	    humData[0] = 0x2C;
		humData[1] = 0x10;
		if(!i2c.write(humData, sizeof(humData))) {
			LOGD("写入温湿度数据失败");
			return;
		}
		usleep(50 * 1000);

		if (!i2c.read(data, sizeof(data))) {
			LOGD("读取温湿度数据失败");
			return;
		}

	    std::string dataStr = "";
	    for (int i = 0; i < sizeof(data); i++) {
	    	dataStr = dataStr + base::format("0x%02x", data[i]) + " ";
	    }
//	    LOGD("data ============> %s", dataStr.c_str());

	    uint8_t temperatureCRC;
	    // 计算温度的CRC校验和
	    crcData[0] = data[0];
	    crcData[1] = data[1];
	    crcData[2] = data[2];
	    temperatureCRC = CrcCheckHelper::TemAndHumCheck(crcData, 2);
	    if (temperatureCRC != 0) {
	    	LOGD("CRC检验1失败");
	        return;
	    }

	    crcData[0] = data[3];
	    crcData[1] = data[4];
	    crcData[2] = data[5];
	    temperatureCRC = CrcCheckHelper::TemAndHumCheck(crcData, 2);
	    if (temperatureCRC != 0) {
	    	LOGD("CRC检验2失败");
	        return;
	    }

//	    LOGD("HumA %d ----- HumB %d", HumA, HumB);

	    int16_t TemBuf;
	    int CapBuf;
	    // 计算实际的湿度和温度值
	    TemBuf = (int16_t) data[0] << 8 | (data[1]); // 温度
//	    LOGD("TemBuf ==========> %d", TemBuf);//	    TemBuf = -3148;
	    TemBuf = 400 + TemBuf / 25.6;//*10 结果*10 倍 286 即 28.6℃

	    CapBuf = (int16_t) data [3] << 8 | (data[4]);
//	    LOGD("CapBuf ==========> %d", CapBuf);//	    CapBuf = 29884;
	    CapBuf = (CapBuf - HumB) * 600 / (HumA - HumB) + 300;
	    //20℃为 5 个湿度点 即 1℃为 0.25 个湿度点 0.1℃ 为 0.025
	    CapBuf = CapBuf + 25 * (TemBuf - 250) / 100;
	    if(CapBuf > 1000) {
	    	CapBuf = 999;
	    }
	    else if(CapBuf < 0) {
	    	CapBuf = 0;
	    }

	    LOGD("温度 =============> %d,   湿度 =============> %d", TemBuf, CapBuf);

	    sleep(10);
	    humThreadInit();
	});
	backend.detach();
	return;
}


bool setHumA() {
    unsigned char hum[2];
    hum[0] = 0xD2;
    hum[1] = 0x08;
    unsigned char humAdata[3];
    if (!i2c.transfer(hum, 2, humAdata, 3)) {
    	LOGD("请求 HumA 读写失败");
    	return false;
    }

    uint8_t humACRC = CrcCheckHelper::TemAndHumCheck(humAdata, 2);
    if (humACRC != 0) {
    	LOGD("HumA CRC校验失败 =======> 1");
    	return false;
    }


    hum[0] = 0xD2;
    hum[1] = 0x09;
    unsigned char humAdata2[5];
    if (!i2c.transfer(hum, 2, humAdata2, 5)) {
    	LOGD("请求 HumA2 读写失败");
    	return false;
    }

    uint8_t humA2CRC = CrcCheckHelper::TemAndHumCheck(humAdata2, 2);
    if (humA2CRC != 0) {
    	LOGD("HumA2 CRC校验失败");
    	return false;
    }
    HumA = (humAdata[0] << 8) | humAdata2[0];
    if (HumA < 10000) {
    	return false;
    }
    return true;
}


bool setHumB() {
    unsigned char hum[2];
    hum[0] = 0xD2;
    hum[1] = 0x0A;
    unsigned char humBdata[3];
    if (!i2c.transfer(hum, 2, humBdata, 3)) {
    	LOGD("请求 HumB 读写失败");
    	return false;
    }
    uint8_t humBCRC = CrcCheckHelper::TemAndHumCheck(humBdata, 2);
    if (humBCRC != 0) {
    	LOGD("HumB CRC校验失败");
    	return false;
    }

    hum[0] = 0xD2;
    hum[1] = 0x0B;
    unsigned char humBdata2[5];
    if (!i2c.transfer(hum, 2, humBdata2, 5)) {
    	LOGD("请求 HumB2 读写失败");
    	return false;
    }

    uint8_t humB2CRC = CrcCheckHelper::TemAndHumCheck(humBdata2, 2);
    if (humB2CRC != 0) {
    	LOGD("HumB2 CRC校验失败");
    }

    HumB = (humBdata[0] << 8) | humBdata2[0];
    if (HumB < 10000) {
    	return false;
    }
    return true;
}

bool setHum() {
	bool res = false;
	while (!res) {
		res = setHumA();
	}
	res = false;
	while (!res) {
		res = setHumB();
	}
    return true;
}


bool resetMD() {
    unsigned char cmd[2];
    // 复位
    cmd[0] = 0x30;
    cmd[1] = 0xA2;

    if (!i2c.write(cmd, 2)) {
		LOGD("复位失败");
		return false;
    }
    LOGD("复位成功");
    return true;
}

void HumitureSenors::DHT22Init() {
	LOGD("开始温湿度测量");
	bool res = resetMD();
	if (res) {
		if (setHum()) {
			humThreadInit();
		}
	}
}

