/*
 * Module_DcMeter.c
 *
 *  Created on: 2021/5/31
 *      Author: foluswen
 */
#include "Module_DcMeter.h"
#include "meterComm.h"
#include "Module_RatedCurrent.h"

/**
 * Initial share memory
 * @return
 */
int InitShareMemory()
{
	int result = PASS;
	int MeterSMId;

	//Initialize ShmSysConfigAndInfo
	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
    {
		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
		result = FAIL;
	}
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
    	result = FAIL;
   	 }
    else
    {}

   	//Initialize ShmStatusCodeData
   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
    {
   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
   		result = FAIL;
	}
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
    	result = FAIL;
   	}
    else
    {}

    return result;
}

//==========================================
// Main loop
//==========================================
int main(void)
{
	ParsingRatedCur modelnameInfo = {0};
	Meter_Info meter_info = {0};
	uint8_t pollingIndex = 0;
	uint8_t	meterIndex = 0;
	uint8_t failCount = 0;

#ifndef DEBUG_STANDALONG
	// Initialize share memory
	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
		}
		sleep(5);
		return -1;
	}

	RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo);
#endif//DEBUG_STANDALONG

	// Initialize DC meter model
	/*
	 *	TODO:
	 *		1. Maybe need to parse configuration by model name
	 */
	meterInitialize(METER_MODEL_LEM_L18005A);

	// Main loop
	for(;;)
	{
		for(uint8_t gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++)
		{
			if(gun_index == 0)
				meterIndex = 0;

			if(modelnameInfo.ParsingInfo[gun_index].GunType != Gun_Type_AC)
			{
				meterApiAssign(meterIndex);
				switch(pollingIndex)
				{
					case 0:
						if(readCurrent(&meter_info))
						{
							#ifndef DEBUG_STANDALONG
							/*
							 *	TODO:
							 *		1. Synchronize data to share memory
							 */
							#else
							DEBUG_INFO("Output current: %.3f A\n", meter_info.presentCurrent);
							#endif//DEBUG_STANDALONG
							pollingIndex++;
							failCount = 0;
						}
						else
						{
							if(failCount < 10)
								failCount++;
						}
						break;
					case 1:
						if(readVoltage(&meter_info))
						{
							#ifndef DEBUG_STANDALONG
							/*
							 *	TODO:
							 *		1. Synchronize data to share memory
							 */
							#else
							DEBUG_INFO("Output voltage: %.3f V\n", meter_info.presetVoltage);
							#endif//DEBUG_STANDALONG
							pollingIndex++;
							failCount = 0;
						}
						else
						{
							if(failCount < 10)
								failCount++;
						}
						break;
					case 2:
						if(readPower(&meter_info))
						{
							#ifndef DEBUG_STANDALONG
							/*
							 *	TODO:
							 *		1. Synchronize data to share memory
							 */
							#else
							DEBUG_INFO("Output power: %.3f kw\n", meter_info.presentPower);
							#endif//DEBUG_STANDALONG
							pollingIndex++;
							failCount = 0;
						}
						else
						{
							if(failCount < 10)
								failCount++;
						}
						break;
					case 3:
						if(readEnergy(&meter_info))
						{
							#ifndef DEBUG_STANDALONG
							/*
							 *	TODO:
							 *		1. Synchronize data to share memory
							 */
							#else
							DEBUG_INFO("Totalize import energy: %.3f kwh\n", meter_info.totlizeImportEnergy);
							DEBUG_INFO("Totalize export energy: %.3f kwh\n", meter_info.totlizeExportEnergy);
							#endif//DEBUG_STANDALONG
							pollingIndex++;
							failCount = 0;
						}
						else
						{
							if(failCount < 10)
								failCount++;
						}
						break;
					default:
						pollingIndex = 0;
						break;
				}

				meterIndex++;
			}

			if(failCount >= 10)
			{
				#ifndef DEBUG_STANDALONG
				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout)
				{
					DEBUG_ERROR("Meter communication timeout");
					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout = ON;
				}
				#endif//DEBUG_STANDALONG
			}
			else
			{
				#ifndef DEBUG_STANDALONG
				ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout = OFF;
				#endif//DEBUG_STANDALONG
			}
			usleep(500000);
		}
	}



	return -1;
}