#include "IDIBUS_3Thermo1HT.h"

IdiBusDevice *IdiBus_3Thermo1HT::getDevice(uint8_t Num)
{
 switch (Num)
	{
	 case ( IDIBUS_3Thermo1HT_THERMO_DEV ) :  { return &this->THERMO_DEV; }
	 //case ( IDIBUS_INPV_CNTRL_DEV ) : { return &this->INPV_DEV; }
	 default :                        { return NULL; }
	}
}

IdiBus_3Thermo1HT_ThermoChannel::IdiBus_3Thermo1HT_ThermoChannel(void) : IdiBusChannel()
{ 
 this->Temperature = 0;
 this->CJTemperature = 0;
 this->MMES_Error = (1<<2);
 /*Bit error list
	0 - Sensor fault
	1 - over/under voltage
	2 - no data error
	6 - TC out of range
	7 - CJ out of range
	*/
}

IdiBusChannel *IdiBus_3Thermo1HT_ThermoDevice::getChannel(uint8_t Num)
{
 if ( Num < IDIBUS_3Thermo1HT_Thermo_CH_COUNT ) { return &this->CH[Num]; }
 else                             { return NULL; }
}

IdiBus_3Thermo1HT_ThermoChannel IdiBus_3Thermo1HT_ThermoDevice::getChData(uint8_t ChNum){
	if ( ChNum < IDIBUS_3Thermo1HT_Thermo_CH_COUNT ) { return this->CH[ChNum]; }
	else								{ IdiBus_3Thermo1HT_ThermoChannel NewData; return NewData; }
}

uint8_t IdiBus_3Thermo1HT_ThermoDevice::startOneShotConversion(uint8_t ChNum)
{
	if (ChNum >= IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { return IDIERMST_INVALID_CHN_NUM; }
		
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.CHNL.NUM   = ChNum;
	MMES.ComFunc    = 0x02;	//Start one shot conversion 
	
	uint8_t ChDataSize = 0;	//None
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	
	if      ( RequestError   != IDIER_NOPE )          { this->CH[ChNum].MMES_Error = RequestError;   }
	else if ( MMES.RxDataLength == 1 )                { this->CH[ChNum].MMES_Error = MMES.RxData[0]; }
	else if ( MMES.RxDataLength != (ChDataSize + 1) ) { this->CH[ChNum].MMES_Error = IDIERMST_INVALID_RX_REQUEST_FORMAT; }
	else {
		this->CH[ChNum].MMES_Error = MMES.RxData[0];
	}
	return this->CH[ChNum].MMES_Error;
} //

void IdiBus_3Thermo1HT_ThermoDevice::startAllOneShotConversions()
{
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.DEV.ALLCH     = 1;
	MMES.ComFunc       = 0x02;//Set automatic conversion
	uint8_t ChDataSize = 0;		//None
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError != IDIER_NOPE )            { this->setAllChErr(RequestError); return; }
	else if (MMES.RxDataLength < IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return; }
	else {
		uint8_t ExpDataLength = IDIBUS_3Thermo1HT_Thermo_CH_COUNT; // Errors
		for (uint8_t I=0; I<IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++) {  if ( MMES.RxData[I] == IDIER_NOPE ) { ExpDataLength = (uint16_t)(ExpDataLength + ChDataSize); }  }
		if ( ExpDataLength != MMES.RxDataLength )     {  this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return;  }
	}
	uint8_t ErrorPos = 0;
	uint8_t DataPos  = ErrorPos + IDIBUS_3Thermo1HT_Thermo_CH_COUNT;
	for (uint8_t I = 0; I < IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = MMES.RxData[ErrorPos];
		ErrorPos = (uint8_t)(ErrorPos + 1);
	}
}

uint8_t IdiBus_3Thermo1HT_ThermoDevice::changeAutomatiocConversionState(uint8_t ChNum)
{
	if (ChNum >= IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { return IDIERMST_INVALID_CHN_NUM; }
		
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.CHNL.NUM   = ChNum;
	MMES.ComFunc    = 0x01;	//Set automatic conversion
	
	uint8_t ChDataSize = 1;	//uint8_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	
	if      ( RequestError   != IDIER_NOPE )          { this->CH[ChNum].MMES_Error = RequestError;   }
	else if ( MMES.RxDataLength == 1 )                { this->CH[ChNum].MMES_Error = MMES.RxData[0]; }
	else if ( MMES.RxDataLength != (ChDataSize + 1) ) { this->CH[ChNum].MMES_Error = IDIERMST_INVALID_RX_REQUEST_FORMAT; }
	else {
		this->CH[ChNum].MMES_Error = MMES.RxData[0];
		//if ( this->CH[ChNum].MMES_Error == IDIER_NOPE )
		//{
			//Ignoring return value
		//}
	}
	return this->CH[ChNum].MMES_Error;

}

void IdiBus_3Thermo1HT_ThermoDevice::changeAllAutomatiocConversionStates(void)
{
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.DEV.ALLCH     = 1;
	MMES.ComFunc       = 0x01;//Set automatic conversion
	uint8_t ChDataSize = 1;		//uint8_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError != IDIER_NOPE )            { this->setAllChErr(RequestError); return; }
	else if (MMES.RxDataLength < IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return; }
	else {
		uint8_t ExpDataLength = IDIBUS_3Thermo1HT_Thermo_CH_COUNT; // Errors
		for (uint8_t I=0; I<IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++) {  if ( MMES.RxData[I] == IDIER_NOPE ) { ExpDataLength = (uint16_t)(ExpDataLength + ChDataSize); }  }
		if ( ExpDataLength != MMES.RxDataLength )     {  this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return;  }
	}
	uint8_t ErrorPos = 0;
	uint8_t DataPos  = ErrorPos + IDIBUS_3Thermo1HT_Thermo_CH_COUNT;
	for (uint8_t I = 0; I < IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = MMES.RxData[ErrorPos];
		ErrorPos = (uint8_t)(ErrorPos + 1);
		//if ( this->CH[I].MMES_Error == IDIER_NOPE )
		//{
		//}
	}

}

uint8_t IdiBus_3Thermo1HT_ThermoDevice::getTemperature(uint8_t ChNum)
{
	if (ChNum >= IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { return IDIERMST_INVALID_CHN_NUM; }
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.CHNL.NUM   = ChNum;
	MMES.ComFunc    = 0x03;	//Get Value
	uint8_t ChDataSize = 3;	//int24_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError   != IDIER_NOPE )          { this->CH[ChNum].MMES_Error = RequestError;   }
	else if ( MMES.RxDataLength == 1 )                { this->CH[ChNum].MMES_Error = MMES.RxData[0]; }
	else if ( MMES.RxDataLength != (ChDataSize + 1) ) { this->CH[ChNum].MMES_Error = IDIERMST_INVALID_RX_REQUEST_FORMAT; }
	else {
		this->CH[ChNum].MMES_Error = MMES.RxData[0];
		if ( this->CH[ChNum].MMES_Error == IDIER_NOPE )
		{
			this->CH[ChNum].Temperature = (int32_t) (	((int32_t)MMES.RxData[1]<<16) |
														((int32_t)MMES.RxData[2]<<8) |
														((int32_t)MMES.RxData[3]));
		}
	}
	return this->CH[ChNum].MMES_Error;

}

void IdiBus_3Thermo1HT_ThermoDevice::getAllChTemperature(void)
{
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.DEV.ALLCH     = 1;
	MMES.ComFunc       = 0x03;
	uint8_t ChDataSize = 3;		//int24_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError != IDIER_NOPE )            { this->setAllChErr(RequestError); return; }
	else if (MMES.RxDataLength < IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return; }
	else {
		uint8_t ExpDataLength = IDIBUS_3Thermo1HT_Thermo_CH_COUNT; // Errors
		for (uint8_t I=0; I<IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++) {  if ( MMES.RxData[I] == IDIER_NOPE ) { ExpDataLength = (uint16_t)(ExpDataLength + ChDataSize); }  }
		if ( ExpDataLength != MMES.RxDataLength )     {  this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return;  }
	}
	uint8_t ErrorPos = 0;
	uint8_t DataPos  = ErrorPos + IDIBUS_3Thermo1HT_Thermo_CH_COUNT;
	for (uint8_t I = 0; I < IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = MMES.RxData[ErrorPos];
		ErrorPos = (uint8_t)(ErrorPos + 1);
		if ( this->CH[I].MMES_Error == IDIER_NOPE )
		{
			this->CH[I].Temperature = (int32_t) (	((int32_t)MMES.RxData[DataPos]<<16) |
														((int32_t)MMES.RxData[DataPos+1]<<8) |
														((int32_t)MMES.RxData[DataPos+2]));
			DataPos  = (uint8_t)(DataPos  + ChDataSize);
		}
	}
}

uint8_t IdiBus_3Thermo1HT_ThermoDevice::getCJTemperature(uint8_t ChNum)
{
	if (ChNum >= IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { return IDIERMST_INVALID_CHN_NUM; }
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.CHNL.NUM   = ChNum;
	MMES.ComFunc    = 0x04;	//Get Value
	uint8_t ChDataSize = 2;	//int16_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError   != IDIER_NOPE )          { this->CH[ChNum].MMES_Error = RequestError;   }
	else if ( MMES.RxDataLength == 1 )                { this->CH[ChNum].MMES_Error = MMES.RxData[0]; }
	else if ( MMES.RxDataLength != (ChDataSize + 1) ) { this->CH[ChNum].MMES_Error = IDIERMST_INVALID_RX_REQUEST_FORMAT; }
	else {
		this->CH[ChNum].MMES_Error = MMES.RxData[0];
		if ( this->CH[ChNum].MMES_Error == IDIER_NOPE )
		{
			this->CH[ChNum].Temperature = (int16_t) (	((int16_t)MMES.RxData[1]<<8) |
														((int16_t)MMES.RxData[2]) );
		}
	}
	return this->CH[ChNum].MMES_Error;

}

void IdiBus_3Thermo1HT_ThermoDevice::getAllChCJTemperature(void)
{
	IdiBusMMES MMES(static_cast<IdiBusSlave*>(this->Module)->getAddress());
	MMES.DEV.NUM	= IDIBUS_3Thermo1HT_THERMO_DEV;
	MMES.DEV.ALLCH     = 1;
	MMES.ComFunc       = 0x04;
	uint8_t ChDataSize = 2;		//int24_t
	uint8_t RequestError = static_cast<IdiBusSlave*>(this->Module)->SendRequestMMES(&MMES);
	if      ( RequestError != IDIER_NOPE )            { this->setAllChErr(RequestError); return; }
	else if (MMES.RxDataLength < IDIBUS_3Thermo1HT_Thermo_CH_COUNT) { this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return; }
	else {
		uint8_t ExpDataLength = IDIBUS_3Thermo1HT_Thermo_CH_COUNT; // Errors
		for (uint8_t I=0; I<IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++) {  if ( MMES.RxData[I] == IDIER_NOPE ) { ExpDataLength = (uint16_t)(ExpDataLength + ChDataSize); }  }
		if ( ExpDataLength != MMES.RxDataLength )     {  this->setAllChErr(IDIERMST_INVALID_RX_REQUEST_FORMAT); return;  }
	}
	uint8_t ErrorPos = 0;
	uint8_t DataPos  = ErrorPos + IDIBUS_3Thermo1HT_Thermo_CH_COUNT;
	for (uint8_t I = 0; I < IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = MMES.RxData[ErrorPos];
		ErrorPos = (uint8_t)(ErrorPos + 1);
		if ( this->CH[I].MMES_Error == IDIER_NOPE )
		{
			this->CH[I].Temperature = (int16_t) (	((int16_t)MMES.RxData[DataPos]<<8) |
														((int16_t)MMES.RxData[DataPos+1])  ); 
			DataPos  = (uint8_t)(DataPos  + ChDataSize);
		}
	}
}

void IdiBus_3Thermo1HT_ThermoDevice::setAllChErr(uint8_t ErrCode)
{
	for (uint8_t I=0; I<IDIBUS_3Thermo1HT_Thermo_CH_COUNT; I++) { this->CH[I].MMES_Error = ErrCode; }
}
