/*
 * Main.c
 *
 *  Created on: 2019年8月6日
 *      Author: 7564
 */


#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <linux/wireless.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>      /*標準輸入輸出定義*/
#include <stdlib.h>     /*標準函數庫定義*/
#include <stdint.h>
#include <unistd.h>     /*Unix 標準函數定義*/
#include <fcntl.h>      /*檔控制定義*/
#include <termios.h>    /*PPSIX 終端控制定義*/
#include <errno.h>      /*錯誤號定義*/
#include <errno.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <ifaddrs.h>
#include <math.h>
#include <stdbool.h>

#include "./ShareMemory/shmMem.h"
#include "./Define/define.h"
#include "./SelectGun/SelectGun.h"
#include "Config.h"

//------------------------------------------------------------------------------
#define CMD_KEY_WAIT                                (1)
#define CMD_KEY_DONT_WAIT                           (0)

#define DEFAULT_AC_INDEX                            (2)

#define AUTORUN_STEP1_TIME_START                    (140)             // Minutes
#define AUTORUN_STEP1_TIME_END                      (150)
#define AUTORUN_STEP2_TIME_START                    (210)
#define AUTORUN_STEP2_TIME_END                      (410)
#define AUTORUN_END_TIME                            (480)
#define AUTORUN_CYCLE_COUNT                         (30)

#define TTY_PATH                                    "/dev/tty"
#define STTY_US                                     "stty raw -echo -F "
#define STTY_DEF                                    "stty -raw echo -F "

//------------------------------------------------------------------------------
uint8_t _curAutoRunCount = 0;
uint8_t _usingAutoRun = 0;
struct timeval _autoTime;

static struct SysConfigData *pSysConfig = NULL;
static struct SysInfoData *pSysInfo = NULL;
static struct WARNING_CODE_INFO *pSysWarning = NULL;

static struct AlarmCodeData *pAlarmCode = NULL;

static struct PrimaryMcuData *ShmPrimaryMcuData = NULL;
static struct CHAdeMOData *ShmCHAdeMOData = NULL;
static struct CcsData *ShmCcsData = NULL;
static struct GBTData *ShmGBTData = NULL;
static struct FanModuleData *ShmFanModuleData = NULL;
static struct RelayModuleData *ShmRelayModuleData = NULL;
static struct LedModuleData *ShmLedModuleData = NULL;
static struct PsuData *ShmPsuData = NULL;
static struct OCPP16Data *ShmOCPP16Data = NULL;
static SelectGunInfo *ShmSelectGunInfo = NULL;
static DcCommonInfo *ShmDcCommonData = NULL;

static struct ChargingInfoData *pDcChargingInfo = NULL;
static struct ChargingInfoData *pAcChargingInfo = NULL;

static char newString[8][16] = {0};

//------------------------------------------------------------------------------
static int DiffTimeb(struct timeb ST, struct timeb ET)
{
    //return milli-second
    unsigned int StartTime, StopTime;

    StartTime = (unsigned int)ST.time;
    StopTime = (unsigned int)ET.time;

    return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm;
}

static void get_char(char *word)
{
    fd_set rfds;
    struct timeval tv;

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    tv.tv_sec = 0;
    tv.tv_usec = 10; //wait input timout time

    //if input
    if (select(1, &rfds, NULL, NULL, &tv) > 0) {
        fgets(word, 128, stdin);
    }
}

static uint8_t helpCmd(void)
{
    if (strcmp(newString[0], "?") == 0 ||
            strcmp(newString[0], "help") == 0 ||
            strcmp(newString[0], "h") == 0) {
        return YES;
    }

    return NO;
}

static uint8_t exitCmd(void)
{
    if (strcmp(newString[0], "c") == EQUAL ||
            strcmp(newString[0], "C") == EQUAL ||
            strncmp(&newString[0][0], "exit", 4) == EQUAL
       ) {
        return YES;
    }

    return NO;
}

static uint8_t readCmdKey(uint8_t state)
{
    char word[128] = {0};
    int i = 0, j = 0, ctr = 0;

    memset(word, 0, sizeof(word));
    if (state == CMD_KEY_WAIT) {
        fgets(word, sizeof(word), stdin);
    } else if (state == CMD_KEY_DONT_WAIT) {
        get_char(word);

        if (strlen(word) == 0) {
            //usleep(50000);
            return NO;
        }
    }

    memset(newString, 0, sizeof(newString));

    strcpy(newString[1], "-1");
    strcpy(newString[2], "-1");
    for (i = 0; i <= (strlen(word)); i++) {
        if (word[i] == ' ' ||
                word[i] == '\0' ||
                word[i] == '\r' ||
                word[i] == '\n' ||
                word[i] == 10) {
            newString[ctr][j] = '\0';
            ctr++;
            j = 0;
        } else {
            newString[ctr][j] = word[i];
            j++;
        }
    }

    return YES;
}

unsigned long GetTimeoutValue(struct timeval _sour_time)
{
    struct timeval _end_time;
    gettimeofday(&_end_time, NULL);

    return (_end_time.tv_sec - _sour_time.tv_sec);
}

void RunStatusProc(char *v1, char *v2)
{
    printf("OrderCharging = %d \n", pSysInfo->OrderCharging);
    printf("WaitForPlugit = %d \n", pSysInfo->WaitForPlugit);
    if (strcmp(v1, "ac") == 0) {
        pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
        //if (!FindAcChargingInfoData(0, &ac_chargingInfo[0])) {
        //    printf("FindChargingInfoData (AC) false \n");
        //}
        printf("AC Status = %d \n", pAcChargingInfo->ConnectorPlugIn);
        return;
    }

    int _index = atoi(v1);

    if (_index <= 1) {
        //if (!FindChargingInfoData(_index, &_chargingData[0])) {
        //    printf ("FindChargingInfoData error\n");
        //    return;
        //}
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
            // get
            printf ("index = %x, status = %x (%d)\n",
                    _index,
                    pDcChargingInfo->SystemStatus,
                    pDcChargingInfo->IsAvailable);
            printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
                    pSysInfo->SystemTimeoutFlag, pSysInfo->PageIndex);
        } else {
            // set
            pDcChargingInfo->SystemStatus = atoi(v2);
        }
    } else {
        //if (!FindAcChargingInfoData(0, &ac_chargingInfo[0])) {
        //    printf("FindChargingInfoData (AC) false \n");
        //}
        pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);

        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
            // get
            printf ("AC Type, status = %x (%d)\n",
                    pAcChargingInfo->SystemStatus,
                    pAcChargingInfo->IsAvailable);
        } else {
            // set
            pAcChargingInfo->SystemStatus = atoi(v2);
        }
    }
}

void RunCardProc(char *v1, char *v2)
{
    if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0) {
        if (pSysInfo->WaitForPlugit) {
            pSysInfo->WaitForPlugit = 0x00;
            printf ("SysInfo.WaitForPlugit = %x \n", pSysInfo->WaitForPlugit);
        } else {
            pSysInfo->WaitForPlugit = 0x01;
            printf ("SysInfo.WaitForPlugit = %x \n", pSysInfo->WaitForPlugit);
        }
    } else {
        strcpy((char *)pSysConfig->UserId, "");
        memcpy((char *)pSysConfig->UserId, v1, strlen(v1));
        pSysConfig->UserId[strlen(v1)] = '\0';
        printf("StartUserId = %s \n", pSysConfig->UserId);
    }
}

void RunGunPlugitProc(char *v1, char *v2)
{
    if (strcmp(v1, "ac") == 0) {
        //if (!FindAcChargingInfoData(0, &ac_chargingInfo[0])) {
        //    printf("FindChargingInfoData (AC) false \n");
        //}
        pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);

        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
            // get
            printf("ConnectorPlugIn = %d \n", pAcChargingInfo->ConnectorPlugIn);
        } else {
            // set
            pAcChargingInfo->ConnectorPlugIn = atoi(v2);
        }
        return;
    }

    int _index = atoi(v1);
    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0) {
        // get
        printf("index = %x, plug it = %x\n",
               _index,
               pDcChargingInfo->ConnectorPlugIn);
    } else {
        // set
        pDcChargingInfo->ConnectorPlugIn = atoi(v2);
    }
}

void GetGunLockStatusProc(char *v1, char *v2)
{
    int _index = atoi(v1);
    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    if (strcmp(v2, "-1") != 0 && strcmp(v2, "") != 0) {
        pDcChargingInfo->GunLocked = atoi(v2);
    }

    printf("Gun Locked Status = %d \n", pDcChargingInfo->GunLocked);
}

void SetSystemIDProc()
{
    char *systemId = "Alston_Test";
    memcpy(&pSysConfig->SystemId, systemId, strlen(systemId));
}

void RunSelfProc()
{
    printf("self test status = %x\n", pSysInfo->SelfTestSeq);
}

void GetFwVerProc(void)
{
    int _index = 0;
    int isContinue = 1;
    char *usageMsg = "Usage:\n"
                     "      model\n"
                     "      407\n"
                     "      conn index, ex: conn 0 | 1\n"
                     "      relay\n"
                     "      fan\n"
                     "      dc\n"
                     "      led\n"
                     "      ac\n"
                     "      exit | c | C\n"
                     "      help | ? | h\n";

    while (isContinue) {
        if (readCmdKey(CMD_KEY_WAIT) == NO) {
            continue;
        }

        if (strcmp(newString[0], "407") == 0) {
            printf("407 FW Version = %s\n", ShmPrimaryMcuData->version);
        } else if (strcmp(newString[0], "model") == 0) {
            printf("ModelName = %s\r\n", pSysConfig->ModelName);
        } else if (strcmp(newString[0], "conn") == 0) {
            if (strcmp(newString[1], "-1") == 0  ||
                    strcmp(newString[1], "") == 0 ||
                    atoi(newString[1]) >= pSysConfig->TotalConnectorCount
               ) {
                printf("index over flow\r\n");
                continue;
            }

            _index = atoi(newString[1]);

            if (_index == 0) {
                printf("Gun 0 FW Version = %s \n", pSysInfo->Connector1FwRev);
            } else if (_index == 1) {
                printf("Gun 1 FW Version = %s \n", pSysInfo->Connector2FwRev);
            }
        } else if (strcmp(newString[0], "relay") == 0) {
            printf("RB Version = %s \n", pSysInfo->RelayModuleFwRev);
        } else if (strcmp(newString[0], "fan") == 0) {
            printf("FAN Version = %s \n", pSysInfo->FanModuleFwRev);
        } else if (strcmp(newString[0], "dc") == 0) {
            printf("DC Main Version = %s \n", pSysInfo->CsuRootFsFwRev);
        } else if (strcmp(newString[0], "led") == 0) {
            printf("LED Version = %s \n", pSysInfo->LedModuleFwRev);
        } else if (strcmp(newString[0], "ac") == 0) {
            pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);

            printf("AC Version = %s \n", pAcChargingInfo->version);
        } else if (exitCmd() == YES) {
            return;
        } else if (helpCmd() == YES) {
            printf ("%s\n", usageMsg);
        }

    }//while
}

void CreateOneError(char *v1)
{
    int value = atoi(v1);

    pAlarmCode->AlarmEvents.bits.SystemL1InputOVP = value;
    pSysConfig->BillingData.isBilling = value;
}

void GetAuthorizeFlag(char *v1)
{
    if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0) {
        printf("AuthorizeFlag = %d \n", pSysInfo->AuthorizeFlag);
    } else {
        pSysInfo->AuthorizeFlag = atoi(v1);
    }
}

void GetRelayStatus(char *v1)
{
    int _index = atoi(v1);
    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    printf("RelayK1K2Status = %d \n", pDcChargingInfo->RelayK1K2Status);
    printf("RelayKPK2Status = %d \n", pDcChargingInfo->RelayKPK2Status);
}

void FwUpdateFlagProc()
{
    pSysInfo->FirmwareUpdate = 0x01;
}

void CheckAcStatus(char *v1)
{
    if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0) {
        printf("AC Status = %d \n", pSysInfo->AcContactorStatus);
    }
}

void SetCableChkStatus(char *v1, char *v2)
{
    int _index = atoi(v1);
    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf ("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    pDcChargingInfo->GroundFaultStatus = atoi(v2);
}

void SetChargingInfoCCID(char *v1, char *v2)
{
    int _index = atoi(v1);
    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf ("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    memcpy(pDcChargingInfo->EVCCID, v2, 8);
    pDcChargingInfo->EVCCID[8] = '\0';
}

void SetPowerValue(char *v1, char *v2)
{
    int _index = atoi(v1);
    float _Current = atof(v2);

    //if (!FindChargingInfoData(_index, &_chargingData[0])) {
    //    printf ("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);

    // 盲沖的時候才允許使用~
    if (pDcChargingInfo->Type != 9) {
        return;
    }

    pDcChargingInfo->EvBatterytargetCurrent = _Current;
}

void GetSystemInfo()
{
    printf ("ModelName = %s \n", pSysConfig->ModelName);
    printf ("SerialNumber = %s \n", pSysConfig->SerialNumber);
    printf ("InternetConn = %d \n", pSysInfo->InternetConn);

    printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
            pSysConfig->MaxChargingPower,
            pSysConfig->MaxChargingCurrent);
}

void ChangeGunNum()
{
    if (pSysInfo->CurGunSelected + 1 < pSysConfig->TotalConnectorCount) {
        pSysInfo->CurGunSelected += 1;
        pSysInfo->CurGunSelectedByAc = NO_DEFINE;
    } else if (pSysConfig->AcConnectorCount > 0 &&
               pSysInfo->CurGunSelectedByAc == NO_DEFINE) {
        pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX;
    } else {
        pSysInfo->CurGunSelected = 0;
        pSysInfo->CurGunSelectedByAc = NO_DEFINE;
    }
}

void GetGunSelectedNum(char *v1)
{
    if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0) {
        if (AC_QUANTITY > 0 &&
                pSysInfo->CurGunSelectedByAc != NO_DEFINE) {
            printf("connector select changed = AC \n");
        } else {
            printf("connector selected = %d \n", pSysInfo->CurGunSelected);
        }
    } else {
        int _index = atoi(v1);
        if (_index <= 1) {
            pSysInfo->CurGunSelected = _index;
            pSysInfo->CurGunSelectedByAc = NO_DEFINE;
            printf("connector select changed = %d \n", _index);
        } else if (AC_QUANTITY > 0) {
            pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX;
            printf("connector select changed = AC \n");
        }
    }
}

void SetFanSpeed(char *v1)
{
    int speed = atoi(v1);

    ShmFanModuleData->TestFanSpeed = speed;
}

void GetFanSpeed()
{
    printf("ShmFanModuleData->PresentFan1Speed = %d \n", ShmFanModuleData->PresentFan1Speed);
    printf("ShmFanModuleData->PresentFan2Speed = %d \n", ShmFanModuleData->PresentFan2Speed);
    printf("ShmFanModuleData->PresentFan3Speed = %d \n", ShmFanModuleData->PresentFan3Speed);
    printf("ShmFanModuleData->PresentFan4Speed = %d \n", ShmFanModuleData->PresentFan4Speed);
}

void SetDebugMode(char *v1)
{
    int mode = atoi(v1);

    pSysConfig->SwitchDebugFlag = mode;
}

void SetGFDMode(char *v1)
{
    int mode = atoi(v1);

    pSysConfig->AlwaysGfdFlag = mode;
}

void GetPsuTemp()
{
    for (uint8_t index = 0; index < ShmPsuData->GroupCount; index++) {
        for (uint8_t count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) {
            printf("PSU Temp = %d \n", ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp);
        }
    }
}

void GetAcInputVol()
{
    printf("L1N_L12 = %f, L2N_L23 = %f, L3N_L31 = %f \n",
           pSysInfo->InputVoltageR,
           pSysInfo->InputVoltageS,
           pSysInfo->InputVoltageT);
}

void GetPsuInformation(char *v1, char *v2, char *v3)
{
    printf("**********************AC Contact needed*************************\n");
    if (strcmp(v1, "count") == 0) {
        for (int i = 0; i < 4; i++) {
            printf("Group Index = %d, Module Count = %d \n",
                   i,
                   ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity);
        }
    } else if (strcmp(v1, "ver") == 0) {
        for (int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++) {
            printf("Psu Index = %d, PriVersion = %s, SecVersion = %s \n",
                   i, ShmPsuData->PsuVersion[i].FwPrimaryVersion,
                   ShmPsuData->PsuVersion[i].FwSecondVersion);
        }

        for (int i = 0; i < ShmPsuData->GroupCount; i++) {
            for (int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++) {
                printf("Group Index = %d, Psu Index = %d, Version = %s \n",
                       i,
                       j,
                       ShmPsuData->PsuGroup[i].PsuModule[j].FwVersion);
            }
        }
    } else if (strcmp(v1, "cap") == 0) {
        for (int i = 0; i < ShmPsuData->GroupCount; i++) {
            printf("Group Index = %d, MaxCur = %d, Power = %d \n",
                   i,
                   ShmPsuData->PsuGroup[i].GroupAvailableCurrent,
                   ShmPsuData->PsuGroup[i].GroupAvailablePower);
        }
    } else if (strcmp(v1, "input") == 0) {
        for (int i = 0; i < ShmPsuData->GroupCount; i++) {
            for (uint8_t count = 0; count < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; count++) {
                printf("gp = %d, Index = %d, volR = %d, volS = %d, volT = %d \n",
                       i,
                       count,
                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL1,
                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL2,
                       ShmPsuData->PsuGroup[i].PsuModule[count].InputVoltageL3);
            }
        }
    } else if (strcmp(v1, "output") == 0) {
        for (int i = 0; i < ShmPsuData->GroupCount; i++) {
            printf("Group Index = %d, OutputV = %d, OutputC = %d \n",
                   i,
                   ShmPsuData->PsuGroup[i].GroupPresentOutputVoltage,
                   ShmPsuData->PsuGroup[i].GroupPresentOutputCurrent);
        }

        for (int i = 0; i < pSysConfig->TotalConnectorCount; i++) {
            //if (!FindChargingInfoData(i, &_chargingData[0])) {
            //    printf ("FindChargingInfoData error\n");
            //    continue;
            //}
            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);

            printf("Form RB : Group Index = %d, OutputV = %f \n",
                   i,
                   pDcChargingInfo->FireChargingVoltage);
        }
    } else if (strcmp(v1, "test") == 0) {
        int mode = atoi(v2);

        if (mode >= _TEST_MODE && mode <= _TEST_MODE) {
            ShmPsuData->Work_Step = mode;
        }
    } else if (strcmp(v1, "out") == 0) {
        float vol = atof(v2);
        float cur = atof(v3);

        if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
            //if (!FindChargingInfoData(0, &_chargingData[0])) {
            //    printf ("FindChargingInfoData error\n");
            //    return;
            //}
            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(0);

            pDcChargingInfo->EvBatterytargetVoltage = vol;
            pDcChargingInfo->EvBatterytargetCurrent = cur;
        }
    }
    printf("*************************************************\n");
}

void GetConnectorCapInfo(char *v1)
{
    int _GunIndex = atoi(v1);

    //if (!FindChargingInfoData(_GunIndex, &_chargingData[0])) {
    //    printf ("FindChargingInfoData error\n");
    //    return;
    //}
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

    printf ("Charger Max Current = %d, Max Power = %d \n",
            pSysConfig->MaxChargingCurrent * 10,
            pSysConfig->MaxChargingPower * 10);

    printf ("Index = %d, MaxPow = %f, MaxVol = %f, MaxCur = %f\n",
            _GunIndex,
            pDcChargingInfo->RealMaxPower,
            pDcChargingInfo->RealMaxVoltage,
            pDcChargingInfo->RealMaxCurrent);
}

static void setConfirmSelGun(uint8_t selGun)
{
    if (selGun == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_RELEASE) {
        ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_CONFIRM;
        //printf("confirmSelGun left\r\n");
    } else if (selGun == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_RELEASE) {
        ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_CONFIRM;
        //printf("confirmSelGun right\r\n");
    }
}

void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
{
    int _GunIndex;
    uint8_t gunIndex = 0;
    uint8_t stopChg = 0;
    uint8_t curGun = 0;
    int isContinue = 1;
    float _Voltage;
    float _Current;
    uint8_t PreviousSystemStatus[2] = {0xff};
    char *usageMsg = "Usage:\n"
                     "       strchg <index> <voltage> <current>    ex: strchg 0 150 2\n"
                     "       chg    <voltage> <current>            ex: chg 500 100\n"
                     "       c      <index>                        ex: c 0\n"
                     "       help | ? | h\n"
                     "\r\n";

    if (strcmp(v1, "auto") == EQUAL) {
        _usingAutoRun = 0x01;
        _GunIndex = 0;
        _Voltage = 500;
        _Current = (pSysConfig->MaxChargingPower * 1000) / _Voltage;
    } else {
        _usingAutoRun = 0x00;
        _GunIndex = atoi(v1);
        _Voltage = atof(v2);
        _Current = atof(v3);
    }

    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

    printf("Power = %d, ReqVoltage = %f, ReqCurrent = %f\n",
           pSysConfig->MaxChargingPower,
           _Voltage,
           _Current);

    if (_Voltage > 1000 || _Voltage < 50) {
        printf ("Input Voltage over range\n");
        return;
    }

    //kill ev task
    system("killall Module_EvComm");

    pSysInfo->CurGunSelected = _GunIndex;

    while (isContinue) {

        curGun = pSysInfo->CurGunSelected;
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);

        //fix gun 1
        switch (pDcChargingInfo->SystemStatus) {
        case S_IDLE:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;
#if defined DD360Audi
                setConfirmSelGun(curGun);
#endif //defined DD360Audi

                strcpy((char *)pSysConfig->UserId, "AutoStartCharging");
                pDcChargingInfo->ConnectorPlugIn = 1;
                printf ("[UnconditionalCharge - S_IDLE]\n");
                pDcChargingInfo->Type = 9;

            }
            if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf == 1) {
                pSysInfo->StartToChargingFlag = 0x01;
                pDcChargingInfo->SystemStatus = S_PREPARNING;
            }
            break;

        case S_PREPARNING:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                printf ("[UnconditionalCharge - S_PREPARNIN]\n");

                //等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
                printf ("wait find module\n");

            }
            //main 會在此階段判斷以下資料跳到下一個 state
            //用來得知 AC 是否有搭上 (搭上模組的資訊才會出來) 因為每次  AC_Contactor
            //ShmPsuData->SystemPresentPsuQuantity;
            //ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity;
            //ShmPsuData->PsuGroup[gun_index].GroupAvailablePower;
            //_chargingData[gun_index]->AvailableChargingPower;

            //等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
            //sleep(10);

            //清除 main timeout 機制
            pDcChargingInfo->TimeoutFlag = 0;
            //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
            pDcChargingInfo->Type = 9;
            break;

        case S_PREPARING_FOR_EV:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                printf ("[UnconditionalCharge - S_PREPARING_FOR_EV]\n");
                printf ("ReqVoltage = %f, ReqCurrent = %f \n", _Voltage * 10, _Current * 10);

            }
            //清除 main timeout 機制
            pDcChargingInfo->TimeoutFlag = 0;
            //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
            pDcChargingInfo->Type = 9;

            //充電電壓電流
            pDcChargingInfo->EvBatterySoc             = 50;
            pDcChargingInfo->EvBatterytargetVoltage   = 500;
            pDcChargingInfo->EvBatterytargetCurrent   = 2;
            pDcChargingInfo->AvailableChargingCurrent = 1000;

            //****** 注意~此行為是防止 K1K2 先開導到無法升壓 ( Relay Board 在此 state 還未搭上 K1K2 )
            //確定模組己升壓完成
            //if(pDcChargingInfo->PresentChargingVoltage <=  (3000+500) &&
            //  pDcChargingInfo->PresentChargingVoltage >=  (3000-500) )
            {
                printf ("Precharge Done = %f \n",
                        pDcChargingInfo->PresentChargingVoltage);
                //EV done
                pDcChargingInfo->SystemStatus = S_PREPARING_FOR_EVSE;
            }
            break;

        case S_PREPARING_FOR_EVSE:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                printf ("[UnconditionalCharge - S_PREPARING_FOR_EVSE]\n");

            }
            //printf ("tar vol = %d \n", _Voltage);
            //printf ("tar cur = %d \n", _Current);

            //清除 main timeout 機制
            pDcChargingInfo->TimeoutFlag = 0;
            //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
            pDcChargingInfo->Type = 9;

            //充電電壓電流
            pDcChargingInfo->EvBatterySoc = 50;
            pDcChargingInfo->EvBatterytargetVoltage = 500;
            pDcChargingInfo->EvBatterytargetCurrent = 2;
            pDcChargingInfo->AvailableChargingCurrent = 1000;

            //printf ("tar vol_ = %d \n", pDcChargingInfo->EvBatterytargetVoltage);
            // printf ("tar cur_ = %d \n", pDcChargingInfo->EvBatterytargetCurrent);

            //****** 注意~此行為是防止 K1K2 先開導到無法升壓 ( Relay Board 在此 state 還未搭上 K1K2 )
            //確定模組己升壓完成
            if (pDcChargingInfo->GroundFaultStatus == 0x01 ||
                    pDcChargingInfo->GroundFaultStatus == 0x03) {
                printf ("First Ground Fault State (%d)\n",
                        pDcChargingInfo->GroundFaultStatus);
                printf ("Wait K1K2 = %f \n", pDcChargingInfo->PresentChargingVoltage);
                sleep(5);
                //EV done
                pDcChargingInfo->SystemStatus = S_CHARGING;
            } else if (pDcChargingInfo->GroundFaultStatus > 0x02) {
                printf ("First Ground Fault check Fail (%d)\n",
                        pDcChargingInfo->GroundFaultStatus);
                pDcChargingInfo->SystemStatus = S_TERMINATING;
            }
            break;

        case S_CHARGING:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                if (_usingAutoRun == 0x00) {
                    //充電電壓電流
                    pDcChargingInfo->EvBatterytargetVoltage = _Voltage;
                    pDcChargingInfo->EvBatterytargetCurrent = _Current;
                } else {
                    _curAutoRunCount = 0;
                    gettimeofday(&_autoTime, NULL);
                }

                pDcChargingInfo->EvBatterySoc = 50;
                pDcChargingInfo->AvailableChargingCurrent = 1000;

                printf ("[UnconditionalCharge - S_CHARGING]\n");
            }

            if (_usingAutoRun == 0x01) {
                if (((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP1_TIME_START * 60 &&
                        (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP1_TIME_END * 60) ||
                        ((GetTimeoutValue(_autoTime)) >= AUTORUN_STEP2_TIME_START * 60 &&
                         (GetTimeoutValue(_autoTime)) <= AUTORUN_STEP2_TIME_END * 60)
                   ) {
                    pDcChargingInfo->EvBatterytargetVoltage = _Voltage;
                    pDcChargingInfo->EvBatterytargetCurrent = _Current;
                } else if ((GetTimeoutValue(_autoTime)) >= AUTORUN_END_TIME * 60) {
                    _curAutoRunCount++;
                    if (_curAutoRunCount >= AUTORUN_CYCLE_COUNT) {
                        pDcChargingInfo->SystemStatus = S_TERMINATING;
                    } else {
                        gettimeofday(&_autoTime, NULL);
                    }
                } else {
                    pDcChargingInfo->EvBatterytargetVoltage = 0;
                    pDcChargingInfo->EvBatterytargetCurrent = 0;
                }
            }

//              printf("out : vol = %f, cur = %f \n",
//                      pDcChargingInfo->EvBatterytargetVoltage,
//                      pDcChargingInfo->EvBatterytargetCurrent);
            //ev task do this
            pDcChargingInfo->PresentChargingPower =
                ((float)((pDcChargingInfo->PresentChargingVoltage) *
                         (pDcChargingInfo->PresentChargingCurrent)) / 1000);

            if (pDcChargingInfo->GroundFaultStatus == 0x02) {
                printf ("Charging Ground Fault check Fail (%d)\n",
                        pDcChargingInfo->GroundFaultStatus);
                pDcChargingInfo->SystemStatus = S_TERMINATING;
            }
            break;

        case S_TERMINATING:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                printf ("[UnconditionalCharge - S_TERMINATING]\n");
                //無阻塞偵測 keybaord 結束
                system(STTY_DEF TTY_PATH);
            }

            pDcChargingInfo->SystemStatus = S_COMPLETE;
            break;

        case S_COMPLETE:
            if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;

                printf ("[UnconditionalCharge - S_COMPLETE]\n");
            }

            PreviousSystemStatus[curGun] = 0xFF;
            stopChg = 0;
            for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
                if (PreviousSystemStatus[gunIndex] == 0xFF) {
                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);
                    pDcChargingInfo->SystemStatus = S_IDLE;
                } else {
                    pSysInfo->CurGunSelected = gunIndex;
                }

                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
                if (pDcChargingInfo->SystemStatus == S_IDLE) {
                    stopChg++;
                }
            }

            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);
            pDcChargingInfo->PresentChargingPower = 0;

            if (stopChg == pSysConfig->TotalConnectorCount) {
                system("/root/Module_EvComm &");
                sleep(3);

                for (_GunIndex = 0; _GunIndex < pSysConfig->TotalConnectorCount; _GunIndex++) {
                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

                    pDcChargingInfo->SystemStatus = S_IDLE;
                }
                return;
            }
            break;
        }

        if (readCmdKey(CMD_KEY_DONT_WAIT) == NO) {
            continue;
        }

        if (strcmp(newString[0], "strchg") == 0) {
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0 ||
                    strcmp(newString[2], "-1") == 0 ||
                    strcmp(newString[2], "") == 0
               ) {
                printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
                continue;
            }

            if (atoi(newString[1]) == pSysInfo->CurGunSelected) {
                continue;
            }

            _GunIndex = atoi((char *)newString[1]);
            _Voltage = atof((char *)newString[2]);
            _Current = atof((char *)newString[3]);

            printf ("Power = %d, ReqVoltage = %f, ReqCurrent = %f\n",
                    pSysConfig->MaxChargingPower,
                    _Voltage,
                    _Current);

            if (_Voltage > 1000 || _Voltage < 50) {
                _Voltage = 200;
                printf ("Input Voltage over range\n");
                continue;
            }

            pSysInfo->CurGunSelected = _GunIndex;
            strcpy((char *)pSysConfig->UserId, "");
        } else if (strcmp(newString[0], "chg") == 0) {
            if (strcmp(newString[1], "-1") == 0) {
                continue;
            }

            if (strcmp(newString[2], "-1") == 0 ||
                    strcmp(newString[2], "") == 0) {
                continue;
            }

            if (strcmp(newString[3], "-1") == 0 ||
                    strcmp(newString[3], "") == 0) {
                continue;
            }

            _GunIndex = atoi((char *)newString[1]);
            float _vol = atof(newString[2]);
            float _cur = atof(newString[3]);

            if (_cur <= 0 || _cur <= 0) {
                continue;
            }

            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

            printf("reset vol = %f, cur = %f \n", _vol, _cur);
            pDcChargingInfo->EvBatterytargetVoltage = _vol;
            pDcChargingInfo->EvBatterytargetCurrent = _cur;
        } else if (strcmp(newString[0], "c") == 0) {
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0) {
                printf("argc 1 is error parameter\r\n");
                continue;
            }

            if (atoi((char *)newString[1]) != -1) {
                pSysInfo->CurGunSelected = atoi((char *)newString[1]);
            }
            printf("stop \n\r");

            pSysInfo->StartToChargingFlag = 0x00;

            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData( pSysInfo->CurGunSelected);

            pDcChargingInfo->SystemStatus = S_TERMINATING;
        } else if (helpCmd() == YES) {
            printf("%s\n", usageMsg);
        }

        usleep(100000);
    }
}

int printTimeMsg(const char *fmt, ...)
{
    char Buf[4096 + 256] = {0};
    char buffer[4096] = {0};
    int rc = -1;
    va_list args;
    struct timeb  SeqEndTime;
    struct tm *tm;
    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();

    va_start(args, fmt);
    rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);

    ftime(&SeqEndTime);
    SeqEndTime.time = time(NULL);
    tm = localtime(&SeqEndTime.time);

    sprintf(Buf, "%02d:%02d:%02d:%03d - %s",
            tm->tm_hour,
            tm->tm_min,
            tm->tm_sec,
            SeqEndTime.millitm,
            buffer);
    printf("%s", Buf);

    return rc;
}

static void resdGunAndChillerTemp(void)
{
    int isContinue = 1;
    uint8_t i = 0;
    uint32_t sleepTime = 500000;
    uint32_t loopTime = 1000;
    struct timeb showTime;
    struct timeb nowTime;

    char *usageMsg = "Usage:\n"
                     "       t <index>: loop time, ex: t 1\n"
                     "       exit | c | C: exit test\n"
                     "       h | help | ?: show usage message\n"
                     "\r\n";

    ftime(&showTime);

    while (isContinue) {
        ftime(&nowTime);

        if (DiffTimeb(showTime, nowTime) > loopTime ||
                DiffTimeb(showTime, nowTime) < 0) {
            for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {

                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);

                printTimeMsg("get %d gun temp = %d, chiller temp = %d\r\n",
                             i,
                             pDcChargingInfo->ConnectorTemp,
                             pDcChargingInfo->ChillerTemp);
            }//for
            ftime(&showTime);
        }

        if (readCmdKey(CMD_KEY_DONT_WAIT) == NO) {
            usleep(sleepTime);
            continue;
        }

        if (strcmp(newString[0], "t") == 0) {
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0 ||
                    atoi((char *)newString[1]) > 255
               ) {
                printf("argc 1 is error parameter\r\n");
                continue;
            }

            loopTime = ((atoi((char *)newString[1])) * 1000);
            printf("loopTime = %d\r\n", loopTime);
            ftime(&showTime);
            continue;
        } else if (exitCmd() == YES) {
            return;
        } else if (helpCmd() == YES) {
            printf ("%s\n", usageMsg);
        }

        usleep(sleepTime);
    }//while
}

static void writeGunAndChillerTemp(void)
{
    uint8_t _GunIndex = 0;
    int isContinue = 1;
    uint32_t sleepTime = 500000;
    char *usageMsg = "Usage:\n"
                     "       conn    <index> <temp>, ex: conn 0 150\n"
                     "       chiller <index> <temp>, ex: chiller 0 150\n"
                     "       tempR\n"
                     "       exit | c | C\n"
                     "       help | ? | h\n"
                     "\r\n";

    ShmDcCommonData->TestTemperature = YES;

    while (isContinue) {
        if (readCmdKey(CMD_KEY_WAIT) == NO) {
            sleep(sleepTime);
            continue;
        }

        if (helpCmd() == YES) {
            printf ("%s\n", usageMsg);
            continue;
        } else if (exitCmd() == YES) {
            ShmDcCommonData->TestTemperature = NO;
            sleep(1);
            return;
        } else if (strcmp(newString[0], "tempR") == 0) {
            resdGunAndChillerTemp();
        }

        if ((strcmp(newString[0], "chiller") != 0) &&
                (strcmp(newString[1], "-1") == 0 ||
                 strcmp(newString[1], "") == 0)
           ) {
            printf("argc 1 is error parameter\r\n");
            continue;
        }

        if (atoi(newString[2]) > 255 ||
                atoi(newString[2]) == -1) {
            printf("temperature value overflow\r\n");
            continue;
        }

        _GunIndex = atoi((char *)newString[1]);

        if (_GunIndex >= pSysConfig->TotalConnectorCount) {
            printf("gun index over total connector\r\n");
            continue;
        }

        if (strcmp(newString[0], "chiller") == 0) {//修改水冷機溫度值
            if (_GunIndex >= 1) {
                _GunIndex = 0; //只會有一個水冷機
            }

            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);
            pDcChargingInfo->ChillerTemp = atoi(newString[2]);
            printf("set %d chiller temperature = %d\r\n",
                   _GunIndex,
                   pDcChargingInfo->ChillerTemp);
        } else if (strcmp(newString[0], "conn") == 0) {//修改槍頭溫度值
            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

            pDcChargingInfo->ConnectorTemp = atoi(newString[2]);
            printf("set %d connector temp = %d\r\n",
                   _GunIndex,
                   pDcChargingInfo->ConnectorTemp);
        }

        usleep(sleepTime);
    }//while
}

int main(void)
{
    uint8_t _GunIndex = 0;
    int isContinue = 1;
    char *usageMsg = "Usage:\n"
                     "       state <index>                     : get gun state\n"
                     "       card                              : scanning card (x)\n"
                     "       gun <index>                       : get gun plugit state\n"
                     "       lock <index>                      : get gun locked state\n"
                     "       sysid                             : test system ID\n"
                     "       self                              : self test state (x)\n"
                     "       version | v | -v                  : version of board (407 or relay or other)\n"
                     "       update                            : update firmware\n"
                     "       ac                                : get ac relay state (x) \n"
                     "       cable <index> <state>             : set ground fault state\n"
                     "       pow <index> <power>               : set power value\n"
                     "       model                             : get system information\n"
                     "       temp                              : get PSU temperature\n"
                     "       fan <speed>                       : set fan board speed\n"
                     "       strchg <auto>                     : auto test charging\n"
                     "       strchg <index> <voltage <current> : select gun test charging\n"
                     "       tempW                             : write connector header and Chiller temperature\r\n"
                     "       tempR                             : print connector header and chiller temperature\r\n"
                     "\r\n";

    if (CreateAllCsuShareMemory() == FAIL) {
        printf("create share memory error\r\n");
        return FAIL;
    }

    MappingGunChargingInfo("ReadCmdline Task");

    pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
    pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
    pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();

    pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();

    ShmCHAdeMOData = (struct CHAdeMOData *)GetShmCHAdeMOData();
    ShmGBTData = (struct GBTData *)GetShmGBTData();
    ShmCcsData = (struct CcsData *)GetShmCcsData();

    ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
    ShmRelayModuleData = (struct RelayModuleData *)GetShmRelayModuleData();
    ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
    ShmPsuData = (struct PsuData *)GetShmPsuData();
    ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
    ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
    ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();

    for (_GunIndex = 0; _GunIndex < pSysConfig->TotalConnectorCount; _GunIndex++) {
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);

        pDcChargingInfo->SystemStatus = S_IDLE;
    }

    while (isContinue) {
        if (readCmdKey(CMD_KEY_WAIT) == NO) {
            continue;
        }

        if (strcmp(newString[0], "state") == 0) {
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0) {
                continue;
            }

            // 槍狀態
            RunStatusProc(newString[1], newString[2]);
        } else if (strcmp(newString[0], "card") == 0) {
            // 刷卡狀態
            RunCardProc(newString[1], newString[2]);
        } else if (strcmp(newString[0], "gun") == 0) {
            if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0) {
                continue;
            }

            // 插槍狀態
            RunGunPlugitProc(newString[1], newString[2]);
        } else if (strcmp(newString[0], "lock") == 0) {
            if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0) {
                continue;
            }

            // 插槍狀態
            GetGunLockStatusProc(newString[1], newString[2]);
        } else if (strcmp(newString[0], "sysid") == 0) {
            // 測試 sys id
            SetSystemIDProc();
        } else if (strcmp(newString[0], "self") == 0) {
            // CSU 自我檢測狀態
            RunSelfProc(newString[1]);
        } else if (strcmp(newString[0], "version") == 0 ||
                   strcmp(newString[0], "v") == 0 ||
                   strcmp(newString[0], "-v") == 0) {
            //if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0) {
            //    continue;
            //}
            // 取 FW 版號
            GetFwVerProc();
        } else if (strcmp(newString[0], "update") == 0) {
            // 更新
            FwUpdateFlagProc(newString[1]);
        } else if (strcmp(newString[0], "ac") == 0) {
            // AC contactor 狀態
            CheckAcStatus(newString[1]);
        } else if (strcmp(newString[0], "cable") == 0) {
            if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0) {
                continue;
            }

            // cable check pass
            SetCableChkStatus(newString[1], newString[2]);
        } else if (strcmp(newString[0], "pow") == 0) {
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0) {
                continue;
            }
            // cable check pass
            SetPowerValue(newString[1], newString[2]);
        } else if (strcmp(newString[0], "model") == 0) {
            GetSystemInfo();
        } else if (strcmp(newString[0], "select") == 0) {
            // 取得 / 設定 當前選的槍號
            GetGunSelectedNum(newString[1]);
        } else if (strcmp(newString[0], "change") == 0) {
            // 模擬按鈕改變選槍
            ChangeGunNum();
        } else if (strcmp(newString[0], "fan") == 0) {
            // 設定風扇速度
            SetFanSpeed(newString[1]);
        } else if (strcmp(newString[0], "speed") == 0) {
            // 取得風扇速度
            GetFanSpeed();
        } else if (strcmp(newString[0], "debug") == 0) {
            // 設定 debug mode
            SetDebugMode(newString[1]);
        } else if (strcmp(newString[0], "gfd") == 0) {
            // 設定盲沖使用 GFD 功能
            SetGFDMode(newString[1]);
        } else if (strcmp(newString[0], "temp") == 0) {
            // 取得 PSU 溫度
            GetPsuTemp();
        } else if (strcmp(newString[0], "acin") == 0) {
            // 取得三向輸入電壓
            GetAcInputVol();
        } else if (strcmp(newString[0], "psu") == 0) {
            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
            if (strcmp(newString[1], "-1") == 0 ||
                    strcmp(newString[1], "") == 0) {
                printf ("PSU : Param fail..Please retry again......\n");
                continue;
            }
            // 取得 PSU 資訊
            GetPsuInformation(newString[1], newString[2], newString[3]);
        } else if (strcmp(newString[0], "cap") == 0) {
            GetConnectorCapInfo(newString[1]);
        } else if (strcmp(newString[0], "error") == 0) {
            CreateOneError(newString[1]);
        } else if (strcmp(newString[0], "auth") == 0) {
            GetAuthorizeFlag(newString[1]);
        } else if (strcmp(newString[0], "relay") == 0) {
            GetRelayStatus(newString[1]);
        } else if (strcmp(newString[0], "ccid") == 0) {
            if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 ||
                    strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0) {
                printf ("Input ccid fail.\n");
                continue;
            }
            SetChargingInfoCCID(newString[1], newString[2]);
        } else if (strcmp(newString[0], "strchg") == 0) {
            //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
            if (strcmp(newString[1], "auto") == 0) {
                newString[2][0] = 0;
                newString[3][0] = 0;
            } else if (strcmp(newString[1], "-1") == 0 ||
                       strcmp(newString[1], "") == 0   ||
                       strcmp(newString[2], "-1") == 0 ||
                       strcmp(newString[2], "") == 0) {
                printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
                continue;
            }

            // 槍狀態
            RunUnconditionalChargeIndex1(newString[1], newString[2], newString[3]);
        } else if (strcmp(newString[0], "tempW") == 0) { //測試槍頭和水冷機溫度
            writeGunAndChillerTemp();
        } else if (strcmp(newString[0], "tempR") == 0) { //讀取槍頭和水冷機溫度
            resdGunAndChillerTemp();
        } else {
            printf("%s\n", usageMsg);
        }

        sleep(1);
    }//while

    return 0;
}