#include "modbus.h"
#include "main.h"
#include "usart.h"
#include "OCPP.h"
#include "w25qxx.h"
//#include "settings.h"

volatile OCPP_States OCPP_State_ACType2;
 char wifi_connected;
unsigned char modbus_device_addr;
unsigned char modbus_cmd;
unsigned short int modbus_addr;
short int modbus_dat;
unsigned short int modbus_length;
unsigned short int modbus_crc16;
unsigned short int cal_crc;
 uint8_t rxmsg[100];//,hmi[25];
 extern char Send_meter;
 extern uint8_t update_variable;
 //unsigned char txmsg[70];
//float power_factor;
//uint32_t current=32,power;
volatile uint32_t energy,energy2,energy3,ocpp_energy;
extern uint8_t gun_3,gun_2,gun_1,gun,RCD2_stop,RCD1_stop,RCD3_stop;
uint16_t temp;
//uint32_t consume_energy;
extern uint8_t ALARM_FLAG;

#if defined(NAYARA)
extern unsigned char ALARM_CHARGING_STATUS;
uint16_t GasDetection,ALARM_GAS;
extern
#endif

unsigned char meterquerycntr=0;
uint16_t enrgyread1_timouttick=5000,enrgyread2_timouttick=5000,enrgyread3_timouttick=5000;
uint8_t energymeter_err[3];

extern uint8_t meter_failed;

union
{
	unsigned short int word;
	uint32_t dword;
	float dfloat;
	unsigned char byte[4];
}split_int;	

#define M1_IV 0
#define M2_IV 1
#define M1_KW 2
#define M2_KW 3
#define M1_KWH 4
#define M2_KWH 5



unsigned short int CRC16 (unsigned char *nData, unsigned short int wLength)
{
static const unsigned short int wCRCTable[] = {
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

unsigned char nTemp;
unsigned short int wCRCWord = 0xFFFF;

   while (wLength--)
   {
      nTemp = *nData++ ^ wCRCWord;
      wCRCWord >>= 8;
      wCRCWord ^= wCRCTable[nTemp];
   }
   return wCRCWord;
}
uint16_t ModCRC(uint8_t buf[], int len);
uint16_t ModCRC(uint8_t buf[], int len)
{
	uint16_t crc = 0xFFFF;

  for (int pos = 0; pos < len; pos++) {
    crc ^= (uint16_t)buf[pos];          // XOR byte into least sig. byte of crc

    for (int i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return crc;
}
void modbus_check(void)
{
	char i=0;
	enrgyread1_timouttick=20000;
	modbus_device_addr=rxmsg[0];
	uint16_t lclCRCchk=0;
	unsigned short TEMP=0;
	uint8_t temparray[2];

#if defined(selecdual)
		if(modbus_device_addr==0x01 && meterquerycntr == 0)
	{
	split_int.byte[3] = /* charger_status_G1.hmi[6] */ rxmsg[3];
	split_int.byte[2] = /* charger_status_G1.hmi[7] */ rxmsg[4];
	split_int.byte[1] = /* cha-rger_status_G1.hmi[8] */ rxmsg[5];
	split_int.byte[0] = /* charger_status_G1.hmi[9] */rxmsg[6]; //VOLTAGE
	charger_status_G1.voltage =  (uint16_t)split_int.dfloat;//;/10000;

	split_int.byte[3] = /* charger_status_G2.hmi[10] = */rxmsg[19];
	split_int.byte[2] = /* charger_status_G2.hmi[11] = */rxmsg[20];
	split_int.byte[1] = /* charger_status_G2.hmi[12] = */rxmsg[21];
	split_int.byte[0] = /* charger_status_G2.hmi[13] = */rxmsg[22]; //CURRENT
	charger_status_G1.current = split_int.dfloat;///10000;
	if(OCPP.under_voltage > charger_status_G1.voltage)
				{
					charger_status_G1.error = UnderVoltage;
				}
			else if(OCPP.over_voltage < charger_status_G1.voltage)
			{
				charger_status_G1.error = OverVoltage;
			}
			else if(OCPP.over_current_AC02 < charger_status_G1.current)
			{
				charger_status_G1.error = OverCurrentFailure;
			}
			else{
					if(charger_status_G1.error == UnderVoltage || charger_status_G1.error == OverVoltage )
					{
						charger_status_G1.error = NoError_ChargerPoint;
					}
			}
			///////////////////////////////////////////////////////////////////////////////////////



			if(charger_status_G1.error == UnderVoltage)
			{

			}
			else if(charger_status_G1.error == OverVoltage)
			{

			}
			else if(charger_status_G1.error == OverCurrentFailure)
			{

			}
			else if(charger_status_G1.error == GroundFailure)
			{

			}
			else if(charger_status_G1.error == InternalError)
			{

			}
			else
			{
				//////////////////////////////////////V3.3.1///////////////////////////////
				if(charger_status_G1.stop == Error || charger_status_G1.charging_status == Faulted_ChargerPoint )
				{
					charger_status_G1.stop = Stoped;
					enQueue(G1_StatusNotification);
					gun_1 = G_NoError;

					if(Ocpp_Setting.Operative[1] == Available_ChargerPoint)
					  {
						 charger_status_G1.charging_status = Available_ChargerPoint;
					  }
					  else if(Ocpp_Setting.Operative[1] == Unavailable_ChargerPoint)
					  {
						  charger_status_G1.charging_status = Unavailable_ChargerPoint;
					  }

				}
				charger_status_G1.error = NoError_ChargerPoint;
			}

			if((charger_status_G1.error == UnderVoltage) || (charger_status_G1.error == OverVoltage) || (charger_status_G1.error == OverCurrentFailure) || (charger_status_G1.error == InternalError) || (charger_status_G1.error == GroundFailure ))
			{
				if(charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					gun_1 = G_Discharging;
				}
				else if(charger_status_G1.charging_status != Faulted_ChargerPoint)
				{
					gun_1 = G_Error;
					enQueue(G1_StatusNotification);
				}

				charger_status_G1.stop =Error;
				charger_status_G1.charging_status = Faulted_ChargerPoint;
				if(charger_status_G1.error != PowerSwitchFailure)			//V4.x.8
				{
				charger_status_G1.reson= Other;
				}
			}

			meterquerycntr =1;

			charger_status_G1.hmi[0] = 0x5a;
				charger_status_G1.hmi[1] = 0xa5;
				charger_status_G1.hmi[2] = 19;
				charger_status_G1.hmi[3] = 0x82;
				charger_status_G1.hmi[4] = 0x10;
				charger_status_G1.hmi[5] = 0x00;

				split_int.dword = (charger_status_G1.voltage*10000);

				charger_status_G1.hmi[6] = split_int.byte[3];
				charger_status_G1.hmi[7] = split_int.byte[2];
				charger_status_G1.hmi[8] = split_int.byte[1];
				charger_status_G1.hmi[9] = split_int.byte[0]; //Voltage

				split_int.dword = (charger_status_G1.current*10000);
				charger_status_G1.hmi[10] = split_int.byte[3];
				charger_status_G1.hmi[11] = split_int.byte[2];
				charger_status_G1.hmi[12] = split_int.byte[1];
				charger_status_G1.hmi[13] = split_int.byte[0]; //current

			}
		else if(modbus_device_addr==0x02 && meterquerycntr == 1)
		{
			split_int.byte[3] = /* charger_status_G1.hmi[6] */ rxmsg[3];
			split_int.byte[2] = /* charger_status_G1.hmi[7] */ rxmsg[4];
			split_int.byte[1] = /* cha-rger_status_G1.hmi[8] */ rxmsg[5];
			split_int.byte[0] = /* charger_status_G1.hmi[9] */rxmsg[6]; //VOLTAGE
			charger_status_G2.voltage =  (uint16_t)split_int.dfloat;//;/10000;

			split_int.byte[3] = /* charger_status_G2.hmi[10] = */rxmsg[19];
			split_int.byte[2] = /* charger_status_G2.hmi[11] = */rxmsg[20];
			split_int.byte[1] = /* charger_status_G2.hmi[12] = */rxmsg[21];
			split_int.byte[0] = /* charger_status_G2.hmi[13] = */rxmsg[22]; //CURRENT
			charger_status_G2.current = split_int.dfloat;///10000;

			if(OCPP.under_voltage > charger_status_G2.voltage && (ALARM_FLAG != ALARM_NO))
			{
				charger_status_G2.error = UnderVoltage;

			}
			else if(OCPP.over_voltage < charger_status_G2.voltage)
			{
				charger_status_G2.error = OverVoltage;

			}
			else if(OCPP.over_current_AC02 < charger_status_G2.current)
			{
				charger_status_G2.error = OverCurrentFailure;

			}
			else if(charger_status_G2.error == GroundFailure)
			{

			}
			else if(charger_status_G2.error == PowerSwitchFailure)
			{

			}
			else if(charger_status_G2.error == InternalError)
			{

			}
			else
			{
				//////////////////////////////////////V3.3.1///////////////////////////////
				if(charger_status_G2.stop == Error ||  charger_status_G2.charging_status == Faulted_ChargerPoint)
				{
					charger_status_G2.stop = Stoped;
					enQueue(G2_StatusNotification);
					gun_2 = G_NoError;
					 if(Ocpp_Setting.Operative[2] == Available_ChargerPoint)
					  {
						 charger_status_G2.charging_status = Available_ChargerPoint;
					  }
					  else if(Ocpp_Setting.Operative[2] == Unavailable_ChargerPoint)
					  {
						  charger_status_G2.charging_status = Unavailable_ChargerPoint;
					  }
					//charger_status_G2.charging_status = Available_ChargerPoint;
				}
				charger_status_G2.error = NoError_ChargerPoint;
			}

			if((charger_status_G2.error == UnderVoltage) || (charger_status_G2.error == OverVoltage) || (charger_status_G2.error == OverCurrentFailure) || (charger_status_G2.error == GroundFailure) || (charger_status_G2.error == PowerSwitchFailure) || (charger_status_G2.error == InternalError)||(charger_status_G2.error == OtherError) || charger_status_G2.error == InternalError)
			{
				if(charger_status_G2.start == Started)
				{
					charger_status_G2.stop = Try_To_Stop;
					gun_2 = G_Discharging;
				}
				else if(charger_status_G2.charging_status != Faulted_ChargerPoint)
				{
					gun_2 = G_Error;
					enQueue(G2_StatusNotification);
				}

				charger_status_G2.stop =Error;
				charger_status_G2.charging_status = Faulted_ChargerPoint;
				if(charger_status_G2.error != PowerSwitchFailure)			//V4.x.8
				{
				charger_status_G2.reson= Other;
				}
			}
			///////////////////////////////////////////////////////////////////////////////////////


			charger_status_G2.hmi[0] = 0x5a;
			charger_status_G2.hmi[1] = 0xa5;
			charger_status_G2.hmi[2] = 19;
			charger_status_G2.hmi[3] = 0x82;
			charger_status_G2.hmi[4] = 0x10;
			charger_status_G2.hmi[5] = 0x00;

			split_int.dword = (charger_status_G2.voltage*10000);

			charger_status_G2.hmi[6] = split_int.byte[3];
			charger_status_G2.hmi[7] = split_int.byte[2];
			charger_status_G2.hmi[8] = split_int.byte[1];
			charger_status_G2.hmi[9] = split_int.byte[0]; //Voltage

			split_int.dword = (charger_status_G2.current*10000);
			charger_status_G2.hmi[10] = split_int.byte[3];
			charger_status_G2.hmi[11] = split_int.byte[2];
			charger_status_G2.hmi[12] = split_int.byte[1];
			charger_status_G2.hmi[13] = split_int.byte[0]; //current

			meterquerycntr=2;

		}
		else if(modbus_device_addr==0x01 && meterquerycntr == 2)
		{
			split_int.byte[3] =  rxmsg[3];
			split_int.byte[2] =  rxmsg[4];
			split_int.byte[1] =  rxmsg[5];
			split_int.byte[0] = rxmsg[6]; //KW
			charger_status_G1.power = (float)(split_int.dfloat*1000);///10000;

			split_int.dword = (charger_status_G1.power*10000);
			charger_status_G1.hmi[14] = split_int.byte[3];
			charger_status_G1.hmi[15] = split_int.byte[2];
			charger_status_G1.hmi[16] = split_int.byte[1];
			charger_status_G1.hmi[17] = split_int.byte[0]; //power

			meterquerycntr =3;
		}
		else if(modbus_device_addr==0x02 && meterquerycntr == 3)
		{
			split_int.byte[3] =  rxmsg[3];
			split_int.byte[2] =  rxmsg[4];
			split_int.byte[1] =  rxmsg[5];
			split_int.byte[0] = rxmsg[6]; //KW
			charger_status_G2.power = (float)(split_int.dfloat*1000);///10000;

			split_int.dword = (charger_status_G2.power*10000);
			charger_status_G2.hmi[14] = split_int.byte[3];
			charger_status_G2.hmi[15] = split_int.byte[2];
			charger_status_G2.hmi[16] = split_int.byte[1];
			charger_status_G2.hmi[17] = split_int.byte[0]; //power

			meterquerycntr =4;
		}

		else if(modbus_device_addr==0x01 && meterquerycntr == 4)
		{
			split_int.byte[3] /*= hmi[18]*/ =rxmsg[3];
			split_int.byte[2] /*= hmi[19]*/ =rxmsg[4];
			split_int.byte[1] /*= hmi[20]*/ =rxmsg[5];
			split_int.byte[0] /*= hmi[21]*/ =rxmsg[6]; //ENERGY

			energy = (uint32_t)(split_int.dfloat*100);///10;


			if(charger_status_G1.charging_status == Charging_ChargerPoint)
			{
				charger_status_G1.energy =  (unsigned long int)energy - (unsigned int)charger_status_G1.start_energy;
			}
			else
			{
				charger_status_G1.energy = 0;
			}

			split_int.dword = charger_status_G1.energy;
			charger_status_G1.hmi[18] = split_int.byte[3];
			charger_status_G1.hmi[19] = split_int.byte[2];
			charger_status_G1.hmi[20] = split_int.byte[1];
			charger_status_G1.hmi[21] = split_int.byte[0]; //KWh

			meterquerycntr =5;
		}
		else if(modbus_device_addr==0x02 && meterquerycntr == 5)
		{
			split_int.byte[3] /*= hmi[18]*/ =rxmsg[3];
			split_int.byte[2] /*= hmi[19]*/ =rxmsg[4];
			split_int.byte[1] /*= hmi[20]*/ =rxmsg[5];
			split_int.byte[0] /*= hmi[21]*/ =rxmsg[6]; //ENERGY

			energy2 = (uint32_t)(split_int.dfloat*100);///10;


			if(charger_status_G2.charging_status == Charging_ChargerPoint)
			{
				charger_status_G2.energy =  (unsigned long int)energy2 - (unsigned int)charger_status_G2.start_energy;
			}
			else
			{
				charger_status_G2.energy = 0;
			}

			split_int.dword = charger_status_G2.energy;
			charger_status_G2.hmi[18] = split_int.byte[3];
			charger_status_G2.hmi[19] = split_int.byte[2];
			charger_status_G2.hmi[20] = split_int.byte[1];
			charger_status_G2.hmi[21] = split_int.byte[0]; //KWh

			meterquerycntr =0;
		}
#else
#if meter == normal

	if(modbus_device_addr == 0x01)
	{
				lclCRCchk=ModCRC(rxmsg,35);
				TEMP=(lclCRCchk & 0X00FF);
				temparray[0] = (uint8_t)(TEMP);
				lclCRCchk>>=8;
				TEMP=0;
				TEMP=(lclCRCchk & 0X00FF);
				temparray[1] = (uint8_t)(TEMP);

			if((temparray[0] == rxmsg[35] ) &&  (temparray[1] == rxmsg[36]))
			{
					charger_status_G1.hmi[0] = 0x5a;
					charger_status_G1.hmi[1] = 0xa5;
					charger_status_G1.hmi[2] = 19;
					charger_status_G1.hmi[3] = 0x82;
					charger_status_G1.hmi[4] = 0x10;
					charger_status_G1.hmi[5] = 0x00;

					split_int.byte[3] = charger_status_G1.hmi[6] =rxmsg[3];
					split_int.byte[2] = charger_status_G1.hmi[7] =rxmsg[4];
					split_int.byte[1] = charger_status_G1.hmi[8] =rxmsg[5];
					split_int.byte[0] = charger_status_G1.hmi[9] =rxmsg[6]; //VOLTAGE
					charger_status_G1.voltage = split_int.dword/10000;

					split_int.byte[3] = charger_status_G1.hmi[10] =rxmsg[7];
					split_int.byte[2] = charger_status_G1.hmi[11] =rxmsg[8];
					split_int.byte[1] = charger_status_G1.hmi[12] =rxmsg[9];
					split_int.byte[0] = charger_status_G1.hmi[13] =rxmsg[10]; //CURRENT
					charger_status_G1.current = (float)split_int.dword/10000;

					split_int.byte[3] = charger_status_G1.hmi[14] =rxmsg[11];
					split_int.byte[2] = charger_status_G1.hmi[15] =rxmsg[12];
					split_int.byte[1] = charger_status_G1.hmi[16] =rxmsg[13];
					split_int.byte[0] = charger_status_G1.hmi[17] =rxmsg[14]; //KW
					charger_status_G1.power = (float)split_int.dword/10000;

					split_int.byte[3]  =rxmsg[15];
					split_int.byte[2]  =rxmsg[16];
					split_int.byte[1]  =rxmsg[17];
					split_int.byte[0]  =rxmsg[18]; //ENERGY
					energy = (uint32_t)split_int.dword/10;

					split_int.byte[3] =rxmsg[27];
					split_int.byte[2] =rxmsg[28];
					split_int.byte[1] =rxmsg[29];
					split_int.byte[0] =rxmsg[30]; //Tempreture
					charger_status_G1.Tempreture = split_int.dword/100;

	#ifdef OLD
					if(OCPP.under_voltage > charger_status_G1.voltage)
					{
						charger_status_G1.error = UnderVoltage;
					}
					else if(OCPP.over_voltage < charger_status_G1.voltage)
					{
						charger_status_G1.error = OverVoltage;
					}
					else if(OCPP.over_current_AC02 < charger_status_G1.current)
					{
						charger_status_G1.error = OverCurrentFailure;
					}
					else{
							if(charger_status_G1.error == UnderVoltage || charger_status_G1.error == OverVoltage )
							{
								charger_status_G1.error = NoError_ChargerPoint;
							}
					}
	#endif
				if(charger_status_G1.charging_status == Charging_ChargerPoint)
				{
					charger_status_G1.energy =  (unsigned long int)energy - (unsigned int)charger_status_G1.start_energy;
				}
				else
				{
					charger_status_G1.energy = 0;
				}

				split_int.dword = charger_status_G1.energy;
				charger_status_G1.hmi[18] = split_int.byte[3];
				charger_status_G1.hmi[19] = split_int.byte[2];
				charger_status_G1.hmi[20] = split_int.byte[1];
				charger_status_G1.hmi[21] = split_int.byte[0]; //KWh
		}
	}
#if defined(NAYARA)
	else if(modbus_device_addr == 2)
	{
		lclCRCchk=ModCRC(rxmsg,7);
		TEMP=(lclCRCchk & 0X00FF);
		temparray[0] = (uint8_t)(TEMP);
		lclCRCchk>>=8;
		TEMP=0;
		TEMP=(lclCRCchk & 0X00FF);
		temparray[1] = (uint8_t)(TEMP);

		if((temparray[0] == rxmsg[7] ) &&  (temparray[1] == rxmsg[8]))
		{
			split_int.byte[1] = rxmsg[3];
			split_int.byte[0] = rxmsg[4]; //Gas detection
			GasDetection = split_int.word;

			split_int.byte[1] = rxmsg[5];
			split_int.byte[0] = rxmsg[6]; //Gas ALARM
			ALARM_GAS = split_int.word;
			update_variable = 1;
		}
	}
#endif
#else
	if(modbus_device_addr==0x01)
	{
		lclCRCchk=ModCRC(rxmsg,95);
		TEMP=(lclCRCchk & 0X00FF);
		temparray[0] = (uint8_t)(TEMP);
		lclCRCchk>>=8;
		TEMP=0;
		TEMP=(lclCRCchk & 0X00FF);
		temparray[1] = (uint8_t)(TEMP );

		if((temparray[0] == rxmsg[95] ) &&  (temparray[1] == rxmsg[96]))
		{
		meter_failed=0;

		split_int.byte[3] = /* charger_status_G1.hmi[6] */ rxmsg[3];
		split_int.byte[2] = /* charger_status_G1.hmi[7] */ rxmsg[4];
		split_int.byte[1] = /* cha-rger_status_G1.hmi[8] */ rxmsg[5];
		split_int.byte[0] = /* charger_status_G1.hmi[9] */rxmsg[6]; //VOLTAGE
		charger_status_G1.voltage =  (uint16_t)split_int.dfloat;//;/10000;

		split_int.byte[3] = /* charger_status_G2.hmi[10] = */rxmsg[19];
		split_int.byte[2] = /* charger_status_G2.hmi[11] = */rxmsg[20];
		split_int.byte[1] = /* charger_status_G2.hmi[12] = */rxmsg[21];
		split_int.byte[0] = /* charger_status_G2.hmi[13] = */rxmsg[22]; //CURRENT
		charger_status_G1.current = split_int.dfloat;///10000;
		//charger_status_G1.current=3.125;

		split_int.byte[3] = /* charger_status_G2.hmi[14] = */ rxmsg[59];
		split_int.byte[2] = /* charger_status_G2.hmi[15] = */ rxmsg[60];
		split_int.byte[1] = /* charger_status_G2.hmi[16] = */ rxmsg[61];
		split_int.byte[0] = /* charger_status_G2.hmi[17] = */rxmsg[62]; //KW
		charger_status_G1.power = (float)(split_int.dfloat*1000);///10000;

		split_int.byte[3] /*= hmi[18]*/ =rxmsg[91];
		split_int.byte[2] /*= hmi[19]*/ =rxmsg[92];
		split_int.byte[1] /*= hmi[20]*/ =rxmsg[93];
		split_int.byte[0] /*= hmi[21]*/ =rxmsg[94]; //ENERGY

		energy = (uint32_t)(split_int.dfloat*100);///10;

		if(OCPP.under_voltage > charger_status_G1.voltage)
			{
				charger_status_G1.error = UnderVoltage;
			}
			else if(OCPP.over_voltage < charger_status_G1.voltage)
			{
				charger_status_G1.error = OverVoltage;
			}
			else if(OCPP.over_current_AC02 < charger_status_G1.current)
			{
				charger_status_G1.error = OverCurrentFailure;
			}
			else{
					if(charger_status_G1.error == UnderVoltage || charger_status_G1.error == OverVoltage )
					{
						charger_status_G1.error = NoError_ChargerPoint;
					}
			}

			if(charger_status_G1.charging_status == Charging_ChargerPoint)
			{
				charger_status_G1.energy =  (unsigned long int)energy - (unsigned int)charger_status_G1.start_energy;
			}
			else
			{
				charger_status_G1.energy = 0;
			}
		charger_status_G1.hmi[0] = 0x5a;
		charger_status_G1.hmi[1] = 0xa5;
		charger_status_G1.hmi[2] = 19;
		charger_status_G1.hmi[3] = 0x82;
		charger_status_G1.hmi[4] = 0x10;
		charger_status_G1.hmi[5] = 0x00;

		split_int.dword = (charger_status_G1.voltage*10000);

		charger_status_G1.hmi[6] = split_int.byte[3];
		charger_status_G1.hmi[7] = split_int.byte[2];
		charger_status_G1.hmi[8] = split_int.byte[1];
		charger_status_G1.hmi[9] = split_int.byte[0]; //Voltage

		split_int.dword = (charger_status_G1.current*10000);
		charger_status_G1.hmi[10] = split_int.byte[3];
		charger_status_G1.hmi[11] = split_int.byte[2];
		charger_status_G1.hmi[12] = split_int.byte[1];
		charger_status_G1.hmi[13] = split_int.byte[0]; //current


		split_int.dword = (charger_status_G1.power*10000);
		charger_status_G1.hmi[14] = split_int.byte[3];
		charger_status_G1.hmi[15] = split_int.byte[2];
		charger_status_G1.hmi[16] = split_int.byte[1];
		charger_status_G1.hmi[17] = split_int.byte[0]; //power

		split_int.dword = charger_status_G1.energy;
		charger_status_G1.hmi[18] = split_int.byte[3];
		charger_status_G1.hmi[19] = split_int.byte[2];
		charger_status_G1.hmi[20] = split_int.byte[1];
		charger_status_G1.hmi[21] = split_int.byte[0]; //KWh
		}

	}
#endif
	else if(modbus_device_addr==0x02)
		{
		if((temparray[0] == rxmsg[35] ) &&  (temparray[1] == rxmsg[36]))
			{
			enrgyread2_timouttick=5000;
			charger_status_G2.hmi[0] = 0x5a;
			charger_status_G2.hmi[1] = 0xa5;
			charger_status_G2.hmi[2] = 19;
			charger_status_G2.hmi[3] = 0x82;
			charger_status_G2.hmi[4] = 0x10;
			charger_status_G2.hmi[5] = 0x00;

			split_int.byte[3] = charger_status_G2.hmi[6] =rxmsg[3];
			split_int.byte[2] = charger_status_G2.hmi[7] =rxmsg[4];
			split_int.byte[1] = charger_status_G2.hmi[8] =rxmsg[5];
			split_int.byte[0] = charger_status_G2.hmi[9] =rxmsg[6]; //VOLTAGE
			charger_status_G2.voltage = split_int.dword/10000;

			split_int.byte[3] = charger_status_G2.hmi[10] =rxmsg[7];
			split_int.byte[2] = charger_status_G2.hmi[11] =rxmsg[8];
			split_int.byte[1] = charger_status_G2.hmi[12] =rxmsg[9];
			split_int.byte[0] = charger_status_G2.hmi[13] =rxmsg[10]; //CURRENT
			charger_status_G2.current = (float)split_int.dword/10000;

			split_int.byte[3] = charger_status_G2.hmi[14] =rxmsg[11];
			split_int.byte[2] = charger_status_G2.hmi[15] =rxmsg[12];
			split_int.byte[1] = charger_status_G2.hmi[16] =rxmsg[13];
			split_int.byte[0] = charger_status_G2.hmi[17] =rxmsg[14]; //KW
			charger_status_G2.power = (float)split_int.dword/10000;

			split_int.byte[3] /*= hmi[18]*/ =rxmsg[15];
			split_int.byte[2] /*= hmi[19]*/ =rxmsg[16];
			split_int.byte[1] /*= hmi[20]*/ =rxmsg[17];
			split_int.byte[0] /*= hmi[21]*/ =rxmsg[18]; //ENERGY

			energy2 = (uint32_t)split_int.dword/10;

			if(OCPP.under_voltage > charger_status_G2.voltage && (ALARM_FLAG!=5))
			{
				charger_status_G2.error = UnderVoltage;

			}
			else if(OCPP.over_voltage < charger_status_G2.voltage)
			{
				charger_status_G2.error = OverVoltage;

			}
			else if(OCPP.over_current_AC02 < charger_status_G2.current)
			{
				charger_status_G2.error = OverCurrentFailure;

			}
			else if(charger_status_G2.error == GroundFailure)
			{

			}
			else if(charger_status_G2.error == PowerSwitchFailure)
			{

			}
			else if(charger_status_G2.error == InternalError)
			{

			}
			else
			{
				//////////////////////////////////////V3.3.1///////////////////////////////
				if(charger_status_G2.stop == Error ||  charger_status_G2.charging_status == Faulted_ChargerPoint)
				{
					charger_status_G2.stop = Stoped;
					enQueue(G2_StatusNotification);
					gun_2 = G_NoError;
					 if(Ocpp_Setting.Operative[2] == Available_ChargerPoint)
					  {
						 charger_status_G2.charging_status = Available_ChargerPoint;
					  }
					  else if(Ocpp_Setting.Operative[2] == Unavailable_ChargerPoint)
					  {
						  charger_status_G2.charging_status = Unavailable_ChargerPoint;
					  }
				}
				charger_status_G2.error = NoError_ChargerPoint;
			}

			if((charger_status_G2.error == UnderVoltage) || (charger_status_G2.error == OverVoltage) || (charger_status_G2.error == OverCurrentFailure) || (charger_status_G2.error == GroundFailure) || (charger_status_G2.error == PowerSwitchFailure) || (charger_status_G2.error == InternalError)||(charger_status_G2.error == OtherError) || charger_status_G2.error == InternalError)
			{
				if(charger_status_G2.start == Started)
				{
					charger_status_G2.stop = Try_To_Stop;
					gun_2 = G_Discharging;
				}
				else if(charger_status_G2.charging_status != Faulted_ChargerPoint)
				{
					gun_2 = G_Error;
					enQueue(G2_StatusNotification);
				}

				charger_status_G2.stop =Error;
				charger_status_G2.charging_status = Faulted_ChargerPoint;
				if(charger_status_G2.error != PowerSwitchFailure)			//V4.x.8
				{
				charger_status_G2.reson= Other;
				}
			}
			///////////////////////////////////////////////////////////////////////////////////////

			if(charger_status_G2.charging_status == Charging_ChargerPoint)
			{
				charger_status_G2.energy =  (uint32_t)energy2 - charger_status_G2.start_energy;
			}
			else
			{
				charger_status_G2.energy = 0;
			}

			split_int.dword = charger_status_G2.energy;
			charger_status_G2.hmi[18] = split_int.byte[3];
			charger_status_G2.hmi[19] = split_int.byte[2];
			charger_status_G2.hmi[20] = split_int.byte[1];
			charger_status_G2.hmi[21] = split_int.byte[0]; //KWh
			}
		}
#ifdef GUN3
	else if(modbus_device_addr==0x03)
	{
		enrgyread3_timouttick=5000;				charger_status_G1.stop = Stoped;

		 energymeter_err[3] = 0;
		charger_status_G3.hmi[0] = 0x5a;
		charger_status_G3.hmi[1] = 0xa5;
		charger_status_G3.hmi[2] = 19;
		charger_status_G3.hmi[3] = 0x82;
		charger_status_G3.hmi[4] = 0x10;
		charger_status_G3.hmi[5] = 0x00;

		split_int.byte[3] = charger_status_G3.hmi[6] =rxmsg[3];
		split_int.byte[2] = charger_status_G3.hmi[7] =rxmsg[4];
		split_int.byte[1] = charger_status_G3.hmi[8] =rxmsg[5];
		split_int.byte[0] = charger_status_G3.hmi[9] =rxmsg[6]; //VOLTAGE
		charger_status_G3.voltage = split_int.dword/10000;

		split_int.byte[3] = charger_status_G3.hmi[10] =rxmsg[7];
		split_int.byte[2] = charger_status_G3.hmi[11] =rxmsg[8];
		split_int.byte[1] = charger_status_G3.hmi[12] =rxmsg[9];
		split_int.byte[0] = charger_status_G3.hmi[13] =rxmsg[10]; //CURRENT
		charger_status_G3.current = (float)split_int.dword/10000;

		split_int.byte[3] = charger_status_G3.hmi[14] =rxmsg[11];
		split_int.byte[2] = charger_status_G3.hmi[15] =rxmsg[12];
		split_int.byte[1] = charger_status_G3.hmi[16] =rxmsg[13];
		split_int.byte[0] = charger_status_G3.hmi[17] =rxmsg[14]; //KW
		charger_status_G3.power = (float)split_int.dword/10000;

		split_int.byte[3] /*= hmi[18]*/ =rxmsg[15];
		split_int.byte[2] /*= hmi[19]*/ =rxmsg[16];
		split_int.byte[1] /*= hmi[20]*/ =rxmsg[17];
		split_int.byte[0] /*= hmi[21]*/ =rxmsg[18]; //ENERGY

		energy3 = (uint32_t)split_int.dword/10;

		if(OCPP.under_voltage > charger_status_G3.voltage && (ALARM_FLAG!=5))
		{
			charger_status_G3.error = UnderVoltage;

		}
		else if(OCPP.over_voltage < charger_status_G3.voltage)
		{
			charger_status_G3.error = OverVoltage;

		}
		else if(OCPP.over_current_AC02 < charger_status_G3.current)
		{
			charger_status_G3.error = OverCurrentFailure;
		}
		else if((charger_status_G3.error == GroundFailure))
		{

		}
		else if(charger_status_G3.error == PowerSwitchFailure)
		{

		}
		else if(charger_status_G3.error == InternalError)
		{

		}
		else
		{
			//////////////////////////////////////V3.3.1///////////////////////////////
			if(charger_status_G3.stop == Error)
			{
				charger_status_G3.stop = Stoped;
				enQueue(G3_StatusNotification);
				gun_3 = G_NoError;

				//charger_status_G3.charging_status = Available_ChargerPoint;
				 if(Ocpp_Setting.Operative == Available_ChargerPoint)
				  {
					 charger_status_G3.charging_status = Available_ChargerPoint;
				  }
				  else if(Ocpp_Setting.Operative == Unavailable_ChargerPoint)
				  {
					  charger_status_G3.charging_status = Unavailable_ChargerPoint;
				  }
			}
			charger_status_G3.error = NoError_ChargerPoint;
		}

		if((charger_status_G3.error == UnderVoltage) || (charger_status_G3.error == OverVoltage) || (charger_status_G3.error == OverCurrentFailure) || (charger_status_G3.error == GroundFailure) || (charger_status_G3.error == PowerSwitchFailure) || (charger_status_G3.error == InternalError)||(charger_status_G3.error == OtherError) || charger_status_G3.error == InternalError)
		{
			if(charger_status_G3.start == Started)
			{
				charger_status_G3.stop = Try_To_Stop;
				gun_3 = G_Discharging;
			}
			else if(charger_status_G3.charging_status != Faulted_ChargerPoint)
			{
				gun_3 = G_Error;
				enQueue(G3_StatusNotification);
			}

			charger_status_G3.stop =Error;
			charger_status_G3.charging_status = Faulted_ChargerPoint;
			charger_status_G3.reson= Other;
		}
		///////////////////////////////////////////////////////////////////////////////////////
		if(charger_status_G3.charging_status == Charging_ChargerPoint)
		{
			charger_status_G3.energy =  (uint32_t)energy3 - charger_status_G3.start_energy;
		}
		else
		{
			charger_status_G3.energy = 0;
		}

		split_int.dword = charger_status_G3.energy;
		charger_status_G3.hmi[18] = split_int.byte[3];
		charger_status_G3.hmi[19] = split_int.byte[2];
		charger_status_G3.hmi[20] = split_int.byte[1];
		charger_status_G3.hmi[21] = split_int.byte[0]; //KWh
	}
#endif
	if(OCPP.under_voltage > charger_status_G1.voltage && (ALARM_FLAG != ALARM_POWERFAIL))
	{
		charger_status_G1.error = UnderVoltage;
		ALARM_FLAG = ALARM_UNDERVOLTAGE;
	}
	else if(OCPP.over_voltage < charger_status_G1.voltage)
	{
		charger_status_G1.error = OverVoltage;
		ALARM_FLAG = ALARM_OVERVOLTAGE;
	}
	else if(OCPP.over_current_AC02 < charger_status_G1.current)
	{
		charger_status_G1.error = OverCurrentFailure;
	}
	else if(OCPP.Over_Tempreture < charger_status_G1.Tempreture)
	{
		charger_status_G1.error = HighTemperature;
	}
	else if((OCPP.HC_LEL < GasDetection && ALARM_GAS > 4) || (charger_status_G1.error == OtherError))
	{
		charger_status_G1.error = OtherError;
	}
	else if(charger_status_G1.error == GroundFailure)
	{

	}
	else if(charger_status_G1.error == PowerSwitchFailure)
	{

	}
	else if(charger_status_G1.error == InternalError)
	{

	}

	else
		 {
			if(charger_status_G1.stop == Error || charger_status_G1.charging_status == Faulted_ChargerPoint )
			{
				charger_status_G1.stop = Stoped;
				enQueue(G1_StatusNotification);
				gun_1 = G_NoError;

				if(Ocpp_Setting.Operative[1] == Available_ChargerPoint)
				  {
					 charger_status_G1.charging_status = Available_ChargerPoint;
				  }
				  else if(Ocpp_Setting.Operative[1] == Unavailable_ChargerPoint)
				  {
					  charger_status_G1.charging_status = Unavailable_ChargerPoint;
				  }
			}
#if defined(NAYARA)
			if((Is_EvStatus() == STATE_B) && (ALARM_FLAG == ALARM_UNDERVOLTAGE || ALARM_FLAG == ALARM_OVERVOLTAGE) )  //NAYARA
		    {
				if(ALARM_CHARGING_STATUS == true)
				{
				   charger_status_G1.Authentication_done = PowerFailAuthorisation;
			       charger_status_G1.reson == Remote;
				}
		    }
			else if(ALARM_CHARGING_STATUS == true)
			{
				charger_status_G1.start = Started;
				charger_status_G1.stop = Try_To_Stop;
				charger_status_G1.timer = 0;
				charger_status_G1.charging_status = Finishing_ChargerPoint;
			}
#endif
			ALARM_FLAG = ALARM_NO;
			charger_status_G1.error = NoError_ChargerPoint;
		}

		if(charger_status_G1.error !=  NoError_ChargerPoint  /*(charger_status_G1.error == UnderVoltage) || (charger_status_G1.error == OverVoltage) || (charger_status_G1.error == OverCurrentFailure) || (charger_status_G1.error == InternalError) || (charger_status_G1.error == GroundFailure || charger_status_G1.error == PowerSwitchFailure || charger_status_G1.error == HighTemperature || charger_status_G1.error == OtherError )*/)
		{
			if(charger_status_G1.start == Started)
			{
				charger_status_G1.stop = Try_To_Stop;
				gun_1 = G_Discharging;
			}
			if(charger_status_G1.charging_status != Faulted_ChargerPoint)
			{
				gun_1 = G_Error;
				enQueue(G1_StatusNotification);
			}
			charger_status_G1.stop =Error;
			charger_status_G1.charging_status = Faulted_ChargerPoint;
			if(charger_status_G1.error != PowerSwitchFailure)			//V4.x.8
			{
				charger_status_G1.reson= Other;
			}
		}

		if(charger_status_G1.charging_status == Charging_ChargerPoint)
		{
			charger_status_G1.energy =  (unsigned long int)energy - (unsigned int)charger_status_G1.start_energy;
		}
		else
		{
			charger_status_G1.energy = 0;
		}
#endif
}
void Energy_MeterRead(char rw)
{
	uint8_t buff[12];//={0x5a,0xa5,0x05,0x82,0x00,0x0a,0x00,0x01,0x0a,0x0d};
#if meter == selec
	if(rw == 1)
	{	//for selec meter
		buff[0]=0x01;
		buff[1]=0x04;
		buff[2]=0x00;
		buff[3]=0x0E; // AVERAGE VOLTAGE //06 average voltage LN
		buff[4]=0x00;
		buff[5]=0x2E; // 2E FOR LL//0x02 // 36 FOR LN
		buff[6]=0x11; // 0x11 //90 // FOR LL
		buff[7]=0xD5;// 0xD5 // 1D // FOR LL

		HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
		// __HAL_UART_FLUSH_DRREGISTER(&huart1);
		//HAL_UART_Receive_DMA(&huart1,(uint8_t*)rxmsg,97); =
		Send_meter = 1;
		 meter_failed++;
	}
#elif meter == rishabh
	if(rw == 1)
		{	//for selec meter
			buff[0]=0x01;
			buff[1]=0x04;
			buff[2]=0x00;
			buff[3]=0x02; // AVERAGE VOLTAGE //06 average voltage LN
			buff[4]=0x00;
			buff[5]=0x02; // 2E FOR LL//0x02 // 36 FOR LN
			buff[6]=0xD0; // 0x11 //90 // FOR LL
			buff[7]=0x0B;// 0xD5 // 1D // FOR LL

			HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
			// __HAL_UART_FLUSH_DRREGISTER(&huart1);
			//HAL_UART_Receive_DMA(&huart1,(uint8_t*)rxmsg,97); =
			Send_meter = 1;
		}
#else
	if(rw == 1)
	{
		buff[0]=0x01;
		buff[1]=0x03;
		buff[2]=0x00;
		buff[3]=0x48; //write
		buff[4]=0x00;
		buff[5]=0x08;
		buff[6]=0xC4;
		buff[7]=0x1A;
		HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
		Send_meter = 1;
	}
#endif
#if defined(NAYARA)
	else if(rw == 2)
	{
		buff[0]=0x02;
		buff[1]=0x04;
		buff[2]=0x00;
		buff[3]=0x00; //write
		buff[4]=0x00;
		buff[5]=0x02;
		buff[6]=0x71;
		buff[7]=0xF8;
		HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
		Send_meter = 2;
	}
#else
	else if(rw == 2)
		{
			buff[0]=0x02;
			buff[1]=0x03;
			buff[2]=0x00;
			buff[3]=0x48; //write
			buff[4]=0x00;
			buff[5]=0x08;
			buff[6]=0xC4;
			buff[7]=0x29;
			HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
			Send_meter = 2;
		}
#endif

	else if(rw == 3)
	{
		buff[0]=0x03;
		buff[1]=0x03;
		buff[2]=0x00;
		buff[3]=0x48; //write
		buff[4]=0x00;
		buff[5]=0x08;
		buff[6]=0xC5;
		buff[7]=0xf8;
		HAL_UART_Transmit(&huart1, (uint8_t*)buff,8,0xffff);
	}
}
void Send_Meterquery(unsigned char M_send)
{
	switch(M_send)
	{
	case M1_IV :
					make_query(1,4,14,10);
					break;
	case M2_IV  :
					make_query(2,4,14,10);
					break;
	case M1_KW :
					make_query(1,4,42,2);
					break;
	case M2_KW  :
					make_query(2,4,42,2);
					break;
	case M1_KWH :
					make_query(1,4,88,2);
					break;
	case M2_KWH  :
					make_query(2,4,88,2);
					break;
	};

}
void make_query(unsigned char id,unsigned char FC,unsigned int addr,unsigned int n_byte)
{
	unsigned char msg[10] = {0};
	unsigned int lclCRCchk;

	msg[0] = id;
	msg[1] = FC;
	msg[2] = (addr >> 8);
	msg[3] = (uint8_t)addr;
	msg[4] = (n_byte >> 8);
	msg[5] = (uint8_t)(n_byte);
	lclCRCchk = ModCRC(msg,6);
	msg[6] = (uint8_t)lclCRCchk;
    msg[7] = (lclCRCchk >> 8);
    HAL_UART_Transmit(&huart1, (uint8_t*)msg,8,0xffff);
}
/*
void modbus_exemtion(unsigned char code)
{
	txmsg[0]=0x01; //Address
	txmsg[1]=modbus_cmd|0x80; //Command
	txmsg[2]=code; //Exception code
	split_int.word=CRC16(txmsg,3);
	txmsg[3]=split_int.byte[0];
	txmsg[4]=split_int.byte[1];
	HAL_UART_Transmit_DMA(&huart1, (uint8_t*)txmsg, 5);
}
*/
