// ==========================================================================
// sensor_shtc3.c
// (c) 2020, Aurel Dumitru
//
// Description:
// Sensor SHTC3 operations
// =========================================================================

#include <string.h>
#include "sensor_shtc3.h"
#include "main.h"
#include "rtc.h"
#include "file.h"
#include "sensor_nfc.h"
#include "config.h"
#include "utils.h"
#include "devstatus.h"


#define SENSOR_SHTC3_I2C_ADDRESS			0x70

HAL_StatusTypeDef Sensor_Shtc3_Status;
const uint8_t Sensor_Shtc3_ResetCmd[]		= {0x80, 0x5D};
const uint8_t Sensor_Shtc3_SleepCmd[]		= {0xB0, 0x98};
const uint8_t Sensor_Shtc3_WakeupCmd[]		= {0x35, 0x17};
const uint8_t Sensor_Shtc3_ReadTempHumCmd[]	= {0x78, 0x66};

uint32_t Sensor_Shtc3_TimeStamp;
char	Sensor_Shtc3_ReturnValues[128];
char	Sensor_Shtc3_ReturnOldValues[32];
char	Sensor_Shtc3_SmsMessage[128];


int32_t Sensor_Shtc3_EvaluateFrostAlarm(int32_t Temperature, uint32_t Humidity)
{
	uint8_t Tmp8;
	int32_t Factor;
	int32_t TempAbsReturn;
	char* Dest = Sensor_Shtc3_SmsMessage;
	//	-5.0	-2.5	-1.5	-1.0	0.0		1.0		2.0		3.0		4.0		5.0
	//	0.22	0.24	0.25	0.27    0.29	0.30	0.31	0.32	0.33	0.34
	if (Temperature < -50) Factor = 210;
	else
		if (Temperature >  50)	Factor = 350;
		else
			if (Temperature >=  0) Factor = 290 + Temperature;
		 	else
		 	{
		 		double TemperatureFloat = (double)Temperature;
		 		Factor = (int32_t)(0.0271475*TemperatureFloat*TemperatureFloat + 2.76773*TemperatureFloat + 290.623); // https://www.dcode.fr/function-equation-finder
		 	}

	int32_t TemperatureAbs = Temperature - (((1000 - Humidity)*Factor)/(50*100));
	TempAbsReturn = TemperatureAbs;
	if ((TemperatureAbs-Config_FreezeThreshold) <= 10)
	{
		if ((TemperatureAbs-Config_FreezeThreshold) <= 0)	Dest = Utils_CopyString("Active freeze on Dev", Dest);
		else												Dest = Utils_CopyString("Almost freeze on Dev", Dest);
		char* Device = Sensor_Nfc_GetDevSN();
		Dest = Utils_CopyString(Device + strlen(Device) - 6, Dest);
		Dest = Utils_CopyString(" Trf:", Dest);
		if (TemperatureAbs < 0)		{TemperatureAbs = -TemperatureAbs; *Dest++ = '-';}
		Tmp8 = (uint8_t)(TemperatureAbs/10);
		if (Tmp8 >= 10)
			*Dest++ = (char)(Tmp8/10) + '0';
		*Dest++ = (char)(Tmp8%10) + '0'; *Dest++ = '.'; *Dest++ = (char)(TemperatureAbs%10) + '0';
		Dest = Utils_CopyString("C (T:", Dest);
		if (Temperature < 0)		{Temperature = -Temperature; *Dest++ = '-';}
		Tmp8 = (uint8_t)(Temperature/10);
		if (Tmp8 >= 10)
			*Dest++ = (char)(Tmp8/10) + '0';
		*Dest++ = (char)(Tmp8%10) + '0'; *Dest++ = '.'; *Dest++ = (char)(Temperature%10) + '0';
		Dest = Utils_CopyString("C, RH:", Dest);
		Humidity = (Humidity+5)/10;
		if (Humidity >= 100)	Dest = Utils_CopyString("100", Dest);
		else					{*Dest++ = (char)(Humidity/10) + '0'; *Dest++ = (char)(Humidity%10) + '0';}
		Dest = Utils_CopyString("%)", Dest);
		*Dest++ = (char)0x1A;
		*Dest = '\0';
	}
	return TempAbsReturn;
}

char* Sensor_Shtc3_GetFrostAlarm(void)
{
	return Sensor_Shtc3_SmsMessage;
}


void Sensor_Shtc3_Init(void)
{
	DevStatus[DEVSTATUS_TEMPHUMID_STATUS_IDX] = DEVSTATUS_TEMPHUMID_OK;
	Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_WakeupCmd, 2, 10);
	if (Sensor_Shtc3_Status == HAL_OK)
	{
		Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_ResetCmd, 2, 10);
		Utils_DelayMicroseconds(240);
		Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_ReadTempHumCmd, 2, 10);
	}
	if (Sensor_Shtc3_Status != HAL_OK)
		DevStatus[DEVSTATUS_TEMPHUMID_STATUS_IDX] = DEVSTATUS_TEMPHUMID_FAIL;
}

void Sensor_Shtc3_StartMeasurement(void)
{
	DevStatus[DEVSTATUS_TEMPHUMID_STATUS_IDX] = DEVSTATUS_TEMPHUMID_OK;
	Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_WakeupCmd, 2, 10);
	if (Sensor_Shtc3_Status == HAL_OK)
	{
		Utils_DelayMicroseconds(240);
		Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_ReadTempHumCmd, 2, 10);
	}
	if (Sensor_Shtc3_Status != HAL_OK)
		DevStatus[DEVSTATUS_TEMPHUMID_STATUS_IDX] = DEVSTATUS_TEMPHUMID_FAIL;
	Sensor_Shtc3_TimeStamp = HAL_GetTick();
}

uint32_t Sensor_Shtc3_GetTemperatureHumidity(int32_t* Temperature, uint32_t* Humidity)
{
	uint8_t TempHum[6];
	uint32_t Val;

	Sensor_Shtc3_SmsMessage[0] = '\0';
	if (Sensor_Shtc3_Status == HAL_OK)
	{
		Sensor_Shtc3_Status = HAL_I2C_Master_Receive(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, TempHum, 6, 10);
		if (Sensor_Shtc3_Status == HAL_OK)
		{
			Sensor_Shtc3_Status = HAL_I2C_Master_Transmit(&hi2c2, SENSOR_SHTC3_I2C_ADDRESS<<1, (uint8_t*)Sensor_Shtc3_SleepCmd, 2, 10);
			Val = (((uint32_t)TempHum[0])<<8) + TempHum[1];
			*Temperature = (int32_t)((Val*1750)>>16) - 450;
			Val = (((uint32_t)TempHum[3])<<8) + TempHum[4];
			*Humidity =(Val*1000)>>16;
			return 1;
		}
	}

	*Temperature = 0;
	*Humidity = 0;
	DevStatus[DEVSTATUS_TEMPHUMID_STATUS_IDX] = DEVSTATUS_TEMPHUMID_FAIL;
	return 0;
}


uint32_t Sensor_Shtc3_GetMeasurementStatus(void)
{
	if ((HAL_GetTick() - Sensor_Shtc3_TimeStamp) > 20)
	{
		int32_t Temperature;
		int32_t TemperatureF;
		uint32_t Humidity;
		uint8_t  Tmp8;
		char* DestVal = Sensor_Shtc3_ReturnValues;

		Sensor_Shtc3_ReturnValues[0] = '\0';
		if (Sensor_Shtc3_GetTemperatureHumidity(&Temperature, &Humidity))
		{
			if (Config_FreezeAlert)
			{
				TemperatureF = Sensor_Shtc3_EvaluateFrostAlarm(Temperature, Humidity);
			    DestVal = Utils_CopyString("FreezeAirTemperature: ", DestVal);
				if (TemperatureF < 0)
				{
					TemperatureF = -TemperatureF;
					*DestVal++ = '-';
				}
				Tmp8 = (uint8_t)(TemperatureF/10);
				*DestVal++ = (char)(Tmp8/10) + '0';
				*DestVal++ = (char)(Tmp8%10) + '0';
				*DestVal++ = '.';
				*DestVal++ = (char)(TemperatureF%10) + '0';
				DestVal = Utils_CopyString("C\n", DestVal);
			}

		    DestVal = Utils_CopyString("AirTemperature: ", DestVal);
			if (Temperature < 0)
			{
				Temperature = -Temperature;
				*DestVal++ = '-';
			}
			Tmp8 = (uint8_t)(Temperature/10);
			*DestVal++ = (char)(Tmp8/10) + '0';
			*DestVal++ = (char)(Tmp8%10) + '0';
			*DestVal++ = '.';
			*DestVal++ = (char)(Temperature%10) + '0';
			DestVal = Utils_CopyString("C\n", DestVal);

			DestVal = Utils_CopyString("AirHumidity: ", DestVal);
			Tmp8 = (uint8_t)(Humidity/10);
			if (Tmp8 >= 100)
				DestVal = Utils_CopyString("100.0", DestVal);
			else
			{
				*DestVal++ = (char)(Tmp8/10) + '0';
				*DestVal++ = (char)(Tmp8%10) + '0';
				*DestVal++ = '.';
				Tmp8 = (uint8_t)(Humidity%10);
				*DestVal++ = (char)Tmp8 + '0';
			}
			*DestVal++ = '%'; *DestVal = '\0';
		}
		return 1;
	}
	return 0;
}

char* Sensor_Shtc3_GetValues(void)
{
	if (Sensor_Shtc3_ReturnValues[0] != '\0')
		return Sensor_Shtc3_ReturnValues;
	return NULL;
}
