Эх сурвалжийг харах

2022-12-06 / Simon Xue

Action:
1. [Fix] Modify DD360 for DD360Audi using.
2. [Modify] Gun Temperature average not include 255 degree.
3. [Modify] DD360Series Not using local policy.
4. [Modify] Power derating model name fix.
5. [Modify] IDLE and charing finish EV target current and voltage set 0.
6. [Modify] CSU not accept ev board error code when charging finish.
7. [Add] Model name 'P' using DC Meter function.
8. [Add] Tilt Sensor function.

Files
As the commit following history files.

Image Version: V1.24.1
Simon Xue 2 жил өмнө
parent
commit
868356d089
55 өөрчлөгдсөн 1634 нэмэгдсэн , 469 устгасан
  1. 21 133
      EVSE/Projects/DD360Audi/Apps/CSU/Primary.c
  2. 92 5
      EVSE/Projects/DD360Audi/Apps/CSU/RFID.c
  3. 3 3
      EVSE/Projects/DD360Audi/Apps/CSU/SelfTest.c
  4. 406 158
      EVSE/Projects/DD360Audi/Apps/CSU/main.c
  5. 4 1
      EVSE/Projects/DD360Audi/Apps/CSU/main.h
  6. 152 10
      EVSE/Projects/DD360Audi/Apps/Config.h
  7. 190 1
      EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.c
  8. 6 0
      EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.h
  9. 57 9
      EVSE/Projects/DD360Audi/Apps/Define/define.h
  10. 11 4
      EVSE/Projects/DD360Audi/Apps/Makefile
  11. 13 1
      EVSE/Projects/DD360Audi/Apps/ModuleChkSysTask/Module_ChkSysTask.c
  12. 2 0
      EVSE/Projects/DD360Audi/Apps/ModuleChkSysTask/Module_ChkSysTask.h
  13. 144 8
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c
  14. 7 0
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h
  15. 2 1
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCCS.c
  16. 2 1
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCHA.c
  17. 2 1
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalGBT.c
  18. 5 1
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c
  19. 36 24
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c
  20. 93 4
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c
  21. 27 9
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c
  22. 54 28
      EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c
  23. 169 29
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c
  24. 1 1
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.h
  25. 7 3
      EVSE/Projects/DD360Audi/Apps/ModuleUpdateFW/Module_UpdateFW.c
  26. BIN
      EVSE/Projects/DD360Audi/Apps/Module_ChkSysTask
  27. BIN
      EVSE/Projects/DD360Audi/Apps/Module_DoComm
  28. BIN
      EVSE/Projects/DD360Audi/Apps/Module_EvComm
  29. BIN
      EVSE/Projects/DD360Audi/Apps/Module_EventLogging
  30. BIN
      EVSE/Projects/DD360Audi/Apps/Module_InternalComm
  31. BIN
      EVSE/Projects/DD360Audi/Apps/Module_UpdateFW
  32. 80 24
      EVSE/Projects/DD360Audi/Apps/ReadCmdline.c
  33. 2 0
      EVSE/Projects/DD360Audi/Apps/Script/init.sh
  34. 2 0
      EVSE/Projects/DD360Audi/Apps/Script/kill.sh
  35. 0 4
      EVSE/Projects/DD360Audi/Apps/Script/replaceOtherDD360Project.sh
  36. 36 5
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c
  37. 1 1
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.h
  38. BIN
      EVSE/Projects/DD360Audi/Apps/UnsafetyOutputTask
  39. BIN
      EVSE/Projects/DD360Audi/Apps/main
  40. 3 0
      EVSE/Projects/DD360Audi/Apps/timeout.h
  41. BIN
      EVSE/Projects/DD360Audi/Images/ramdisk.gz
  42. BIN
      EVSE/Projects/DD360Audi/output/FactoryConfig
  43. BIN
      EVSE/Projects/DD360Audi/output/Module_ChkSysTask
  44. BIN
      EVSE/Projects/DD360Audi/output/Module_DoComm
  45. BIN
      EVSE/Projects/DD360Audi/output/Module_EvComm
  46. BIN
      EVSE/Projects/DD360Audi/output/Module_EventLogging
  47. BIN
      EVSE/Projects/DD360Audi/output/Module_InternalComm
  48. BIN
      EVSE/Projects/DD360Audi/output/Module_LcmControl
  49. BIN
      EVSE/Projects/DD360Audi/output/Module_PrimaryComm
  50. BIN
      EVSE/Projects/DD360Audi/output/Module_UpdateFW
  51. BIN
      EVSE/Projects/DD360Audi/output/ReadCmdline
  52. BIN
      EVSE/Projects/DD360Audi/output/UnsafetyOutputTask
  53. 2 0
      EVSE/Projects/DD360Audi/output/init.sh
  54. 2 0
      EVSE/Projects/DD360Audi/output/kill.sh
  55. BIN
      EVSE/Projects/DD360Audi/output/main

+ 21 - 133
EVSE/Projects/DD360Audi/Apps/CSU/Primary.c

@@ -272,54 +272,13 @@ static void checkChargingInfoByDC(uint8_t systemStatus)
     }
 }
 
-static void checkChargingInfoByAC(void)
-{
-    struct ChargingInfoData *pAcChargingInfo = NULL;
-    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-    struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
-
-    if (pSysInfo->CurGunSelectedByAc == NO_DEFINE) {
-        return;
-    }
-
-    pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
-
-    switch (pAcChargingInfo->SystemStatus) {
-    case S_IDLE:
-        if (isDetectPlugin(pSysInfo->CurGunSelected)) {
-            _DetectPlugInTimeout(pSysInfo->CurGunSelected);
-        }
-        break;
-
-    case S_REASSIGN_CHECK:
-    case S_REASSIGN:
-    case S_PREPARNING:
-    case S_PREPARING_FOR_EV:
-    case S_PREPARING_FOR_EVSE:
-    case S_CCS_PRECHARGE_ST0:
-    case S_CCS_PRECHARGE_ST1:
-        // 取消充電
-        AcChargingTerminalProcess();
-        break;
-
-    case S_CHARGING:
-        if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) {
-            // 停止充電
-            AcChargingTerminalProcess();
-        }
-        break;
-
-    case S_COMPLETE:
-        break;
-    }
-}
-
 void ChkPrimaryStatus(void)
 {
     static bool leftBtnPush = false;
     static bool rightBtnPush = false;
     uint8_t i = 0;
     uint8_t Rtn = 0;
+    uint8_t _setGun = 0;
     struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
     struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
@@ -464,93 +423,7 @@ void ChkPrimaryStatus(void)
             leftBtnPush = true;
             log_info("left btn down...............................%x",
                      pDcChargingInfo->SystemStatus);
-            checkChargingInfoByAC();
             checkChargingInfoByDC(pDcChargingInfo->SystemStatus);
-#if 0
-            if (pSysInfo->CurGunSelectedByAc != NO_DEFINE) {
-                pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0);
-
-                switch (pAcChargingInfo->SystemStatus) {
-                case S_IDLE:
-                    if (isDetectPlugin()) {
-                        _DetectPlugInTimeout();
-                        StopSystemTimeoutDet();
-                    }
-                    break;
-
-                case S_REASSIGN_CHECK:
-                case S_REASSIGN:
-                case S_PREPARNING:
-                case S_PREPARING_FOR_EV:
-                case S_PREPARING_FOR_EVSE:
-                case S_CCS_PRECHARGE_ST0:
-                case S_CCS_PRECHARGE_ST1:
-                    // 取消充電
-                    AcChargingTerminalProcess();
-                    break;
-
-                case S_CHARGING:
-                    if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) {
-                        // 停止充電
-                        AcChargingTerminalProcess();
-                    }
-                    break;
-
-                case S_COMPLETE:
-                    break;
-                }
-            }
-            switch (pDcChargingInfo->SystemStatus) {
-            case S_IDLE:
-                if (isDetectPlugin()) {
-                    _DetectPlugInTimeout();
-                    StopSystemTimeoutDet();
-                    destroySelGun(pSysInfo->CurGunSelected);
-                }             else {
-#if defined DD360Audi
-                    if (getConfirmSelectedGun(pSysInfo->CurGunSelected) == PASS) {
-                        //printf("destroy gun = %d", pSysInfo->CurGunSelected);
-                        destroySelGun(pSysInfo->CurGunSelected);
-                    } else {
-                        confirmSelGun(pSysInfo->CurGunSelected);
-                        log_info("confirm select gun ............................... %d ",
-                                 pSysInfo->CurGunSelected);
-                    }
-
-#endif //defined DD360Audi
-                }
-                break;
-
-            case S_REASSIGN_CHECK:
-            case S_REASSIGN:
-            case S_PREPARNING:
-            case S_PREPARING_FOR_EV:
-            case S_PREPARING_FOR_EVSE:
-            case S_CCS_PRECHARGE_ST0:
-            case S_CCS_PRECHARGE_ST1:
-                // 取消充電
-                if (pSysInfo->CurGunSelectedByAc != NO_DEFINE) {
-                    AcChargingTerminalProcess();
-                } else {
-                    ChargingTerminalProcess(pSysInfo->CurGunSelected);
-                }
-                break;
-
-            case S_CHARGING:
-                if (pSysConfig->StopChargingByButton == YES ||
-                        pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) {
-                    // 停止充電
-                    ChargingTerminalProcess(pSysInfo->CurGunSelected);
-                }
-                break;
-
-            case S_COMPLETE:
-                // 回 IDLE
-                //log_info("right btn down.................S_COMPLETE ");
-                //pDcChargingInfo->SystemStatus = S_IDLE;
-                break;
-            }
-#endif //0
         }
     } else if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_RELEASE) {
         if (leftBtnPush) {
@@ -558,24 +431,38 @@ void ChkPrimaryStatus(void)
             //log_info("left btn up............................... ");
         }
     }
+    bool isCharging = false;
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+
+        if (pDcChargingInfo->SystemStatus == S_IDLE) {
+            continue;
+        }
 
+        isCharging = true;
+        break;
+    }
     if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS &&
             !rightBtnPush &&
 #if defined DD360Audi
             pSysInfo->SystemPage != _LCM_IDLE &&
+            pSysInfo->SystemPage != _LCM_WAIT_FOR_PLUG &&
 #endif
             pSysInfo->SystemPage != _LCM_AUTHORIZING &&
             pSysInfo->SystemPage != _LCM_AUTHORIZ_COMP &&
-            pSysInfo->SystemPage != _LCM_AUTHORIZ_FAIL &&
-            pSysInfo->SystemPage != _LCM_WAIT_FOR_PLUG
+            pSysInfo->SystemPage != _LCM_AUTHORIZ_FAIL
        ) {
         if (!rightBtnPush) {
+            if (pSysInfo->SystemPage == _LCM_WAIT_FOR_PLUG && !isCharging) {
+                return;
+            }
             rightBtnPush = true;
-            //log_info("right btn down............................... %d ", pSysInfo->CurGunSelected);
+            log_info("right btn down............................... %d ", pSysInfo->CurGunSelected);
             if (pSysInfo->CurGunSelected + 1 < pSysConfig->TotalConnectorCount &&
                     pSysInfo->IsAlternatvieConf == NO) {
                 pSysInfo->CurGunSelected++;
                 ChangeGunSelectByIndex(pSysInfo->CurGunSelected);
+            /*
             } else if (pSysConfig->AcConnectorCount > 0 &&
                        pSysInfo->CurGunSelectedByAc == NO_DEFINE) {
                 pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX;
@@ -593,12 +480,13 @@ void ChkPrimaryStatus(void)
                 }
                 pSysInfo->CurGunSelected = 0;
                 ChangeGunSelectByIndex(pSysInfo->CurGunSelected);
+                */
             } else {
                 pSysInfo->CurGunSelected = 0;
                 ChangeGunSelectByIndex(pSysInfo->CurGunSelected);
             }
-            log_info("current select gun ............................... %d ",
-                     pSysInfo->CurGunSelected);
+            //log_info("current select gun ............................... %d ",
+            //         pSysInfo->CurGunSelected);
         }
 
     } else if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_RELEASE) {

+ 92 - 5
EVSE/Projects/DD360Audi/Apps/CSU/RFID.c

@@ -231,7 +231,7 @@ static void UserScanFunction(void)
         } else if ((pGunIndexInfo->AcGunIndex > 0 &&
                     pSysInfo->CurGunSelectedByAc == DEFAULT_AC_INDEX) ||
                    pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) {
-            log_info("// LCM => Authorizing");
+            log_info("// LCM => Authorizing ID:%s",(char *)pSysConfig->UserId);
 
             setSelGunWaitToAuthor(pSysInfo->CurGunSelected);
 
@@ -268,8 +268,11 @@ void ScannerCardProcess(void)
     struct WARNING_CODE_INFO *pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
     SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
     ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
-
+#if defined DD360Audi
     if (!isDetectPlugin(pSysInfo->CurGunSelected) &&
+#else
+    if ((!isDetectPlugin(LEFT_GUN_NUM) || !isDetectPlugin(RIGHT_GUN_NUM)) &&
+#endif
             !isCardScan &&
             pSysWarning->Level != WARN_LV_ER /*&&
             pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE*/) {
@@ -278,16 +281,18 @@ void ScannerCardProcess(void)
         UserScanFunction();
     }
 
-    if (pSysInfo->PageIndex == _LCM_AUTHORIZING) {
+    if (pSysInfo->SystemPage == _LCM_AUTHORIZING) {
         if(!isAuthorizedComplete())
             StartSystemTimeoutDet(Timeout_Authorizing);
 
         //printf("isAuthorizedComplete = %d, %f", isAuthorizedComplete(), ShmSelectGunInfo->PricesInfo[pSysInfo->CurGunSelected].Balance);
         // 確認驗證卡號完成沒
         if (isAuthorizedComplete()
+            /*
 #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
                 || pSysConfig->OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING
 #endif //!defined DD360 && !defined DD360Audi && !defined DD360ComBox
+*/
            ) {
                 //StopSystemTimeoutDet();
                 StartSystemTimeoutDet(Timeout_WaitBalance);
@@ -305,14 +310,14 @@ void ScannerCardProcess(void)
                 }
 
             } ClearAuthorizedFlag();
-        }/* else if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST) {
+        } /*else if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST) {
             // 白名單驗證
             for (i = 0; i < 10; i++) {
                 if (strcmp((char *)pSysConfig->LocalWhiteCard[i], "") == EQUAL) {
                     continue;
                 }
-
                 if (strcmp((char *)pSysConfig->LocalWhiteCard[i], (char *)pSysConfig->UserId) == EQUAL) {
+                    log_info("Local White Card [%d]:%s", i, pSysConfig->LocalWhiteCard[i]);
                     pSysInfo->SystemPage = _LCM_AUTHORIZ_COMP;
                     ClearAuthorizedFlag();
                     break;
@@ -393,6 +398,7 @@ void CreateRfidFork(void)
 
             if (pSysConfig->RfidCardNumEndian == RFID_ENDIAN_LITTLE) {
                 switch (rfid.snType) {
+#if defined DD360Audi
                 case RFID_SN_TYPE_6BYTE:
                     sprintf((char *) pSysConfig->UserId,
                             "%02X%02X%02X%02X%02X%02X",
@@ -423,9 +429,50 @@ void CreateRfidFork(void)
                             rfid.currentCard[0], rfid.currentCard[1],
                             rfid.currentCard[2], rfid.currentCard[3]);
                     break;
+#else
+                case RFID_SN_TYPE_6BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[5], rfid.currentCard[4],
+                        rfid.currentCard[3], rfid.currentCard[2],
+                        rfid.currentCard[1], rfid.currentCard[0]);
+                    break;
+                case RFID_SN_TYPE_7BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[6], rfid.currentCard[5],
+                        rfid.currentCard[4], rfid.currentCard[3],
+                        rfid.currentCard[2], rfid.currentCard[1],
+                        rfid.currentCard[0]);
+                    break;
+                case RFID_SN_TYPE_8BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[7], rfid.currentCard[6],
+                        rfid.currentCard[5], rfid.currentCard[4],
+                        rfid.currentCard[3], rfid.currentCard[2],
+                        rfid.currentCard[1], rfid.currentCard[0]);
+                    break;
+                case RFID_SN_TYPE_10BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[9], rfid.currentCard[8],
+                        rfid.currentCard[7], rfid.currentCard[6],
+                        rfid.currentCard[5], rfid.currentCard[4],
+                        rfid.currentCard[3], rfid.currentCard[2],
+                        rfid.currentCard[1], rfid.currentCard[0]);
+                    break;
+                case RFID_SN_TYPE_4BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X",
+                        rfid.currentCard[3], rfid.currentCard[2],
+                        rfid.currentCard[1], rfid.currentCard[0]);
+                    break;
+#endif
                 }
             } else if (pSysConfig->RfidCardNumEndian == RFID_ENDIAN_BIG) {
                 switch (rfid.snType) {
+#if defined DD360Audi
                 case RFID_SN_TYPE_6BYTE:
                     sprintf((char *) pSysConfig->UserId,
                             "%02X%02X%02X%02X%02X%02X",
@@ -456,6 +503,46 @@ void CreateRfidFork(void)
                             rfid.currentCard[3], rfid.currentCard[2],
                             rfid.currentCard[1], rfid.currentCard[0]);
                     break;
+#else
+                case RFID_SN_TYPE_6BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[0], rfid.currentCard[1],
+                        rfid.currentCard[2], rfid.currentCard[3],
+                        rfid.currentCard[4], rfid.currentCard[5]);
+                    break;
+                case RFID_SN_TYPE_7BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[0], rfid.currentCard[1],
+                        rfid.currentCard[2], rfid.currentCard[3],
+                        rfid.currentCard[4], rfid.currentCard[5],
+                        rfid.currentCard[6]);
+                    break;
+                case RFID_SN_TYPE_8BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[0], rfid.currentCard[1],
+                        rfid.currentCard[2], rfid.currentCard[3],
+                        rfid.currentCard[4], rfid.currentCard[5],
+                        rfid.currentCard[6], rfid.currentCard[7]);
+                    break;
+                case RFID_SN_TYPE_10BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+                        rfid.currentCard[0], rfid.currentCard[1],
+                        rfid.currentCard[2], rfid.currentCard[3],
+                        rfid.currentCard[4], rfid.currentCard[5],
+                        rfid.currentCard[6], rfid.currentCard[7],
+                        rfid.currentCard[8], rfid.currentCard[9]);
+                    break;
+                case RFID_SN_TYPE_4BYTE:
+                    sprintf((char*)pSysConfig->UserId,
+                        "%02X%02X%02X%02X",
+                        rfid.currentCard[0], rfid.currentCard[1],
+                        rfid.currentCard[2], rfid.currentCard[3]);
+                    break;
+#endif
                 }
             }
             log_info("card number = %s", pSysConfig->UserId);

+ 3 - 3
EVSE/Projects/DD360Audi/Apps/CSU/SelfTest.c

@@ -53,12 +53,12 @@ void SelfTestRun(void)
         }
         
         ChkPrimaryStatus(); //確認硬體有無錯誤,如急停按鈕或門有打開
-
+        /*
         if (pSysWarning->Level == WARN_LV_ER) {
             pSysInfo->SelfTestSeq = _STEST_FAIL;
             return;
         }
-
+        */
         if (pSysConfig->TotalConnectorCount <= 0) {
             pSysInfo->SelfTestSeq = _STEST_FAIL;
             return;
@@ -102,7 +102,7 @@ void SelfTestRun(void)
                     (ShmPrimaryMcuData->SelfTest_Comp != YES)
                ) {
                 //log_info("Primary FW Rev = %s", pSysInfo->CsuPrimFwRev);
-                ShmPrimaryMcuData->SelfTest_Comp = YES;
+                //ShmPrimaryMcuData->SelfTest_Comp = YES;
             }
 
             // EV 小板

+ 406 - 158
EVSE/Projects/DD360Audi/Apps/CSU/main.c

@@ -85,8 +85,8 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.23.00.0000.00"; // "V0.16.00.0000.00";
-char* DebugVersion = "V1.23.5";
+char *fwVersion = "V1.24.01.0000.00";
+char* DebugVersion = "V1.24.1";
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -398,7 +398,14 @@ static void GetFirmwareVersion(void)
         log_info("UL model");
     }
 }
-
+bool isCharging(uint8_t status)
+{
+    if ((status >= S_REASSIGN_CHECK && status <= S_CHARGING) ||
+        status == S_CCS_PRECHARGE_ST0 || status == S_CCS_PRECHARGE_ST1 ) {
+            return TRUE;
+    }
+    return FALSE;
+}
 static void checkGunOTPState(uint8_t gunIndex)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -409,29 +416,23 @@ static void checkGunOTPState(uint8_t gunIndex)
         if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
             // 單水冷機
             // Chiller OTP
-            if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
+            if (pDcChargingInfo->ChillerTemp == UNDEFINED_TEMP) {
                 // 溫度為255時判斷Sensor fail
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
             } else {
                 //判斷OTP
-                if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
+                if ((ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[0] != UNDEFINED_TEMP) ||
+                    (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[1] != UNDEFINED_TEMP)) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
                     RecordAlarmCode(gunIndex, "012323");
                 } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR &&
                     ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
                 }
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-            }
-            // Chiller Tube OTP
-            if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP || ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
-                // 溫度為255時判斷Sensor fail
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-            } else {
-                //判斷OTP
-                if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp || ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
+                //判斷Tube OTP
+                if ((ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[2] != UNDEFINED_TEMP)||
+                     (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[3] != UNDEFINED_TEMP)) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
                     RecordAlarmCode(gunIndex, "012332");
                 } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR &&
@@ -440,67 +441,28 @@ static void checkGunOTPState(uint8_t gunIndex)
                 }
                 ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
+
         } else {
             // 雙水冷機
-            if (gunIndex == LEFT_GUN_NUM) {
-                if (ShmDcCommonData->SystemTemp[0] == UNDEFINED_TEMP) {
-                    // 溫度為255時判斷Sensor fail
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-                } else {
-                    //判斷OTP
-                    if (ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
-                        RecordAlarmCode(gunIndex, "012323");
-                    } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-                    }
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-                }
-                if (ShmDcCommonData->SystemTemp[1] == UNDEFINED_TEMP) {
-                    // 溫度為255時判斷Sensor fail
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-                } else {
-                    //判斷OTP
-                    if (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
-                        RecordAlarmCode(gunIndex, "012332");
-                    } else if (ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
-                    }
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
-                }
+            if (pDcChargingInfo->ChillerTemp == UNDEFINED_TEMP) {
+                // 溫度為255時判斷Sensor fail
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
             } else {
-                if (ShmDcCommonData->SystemTemp[2] == UNDEFINED_TEMP) {
-                    // 溫度為255時判斷Sensor fail
+                //判斷OTP
+                if (ShmDcCommonData->SystemTemp[gunIndex*2] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[gunIndex*2] != UNDEFINED_TEMP) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                    RecordAlarmCode(gunIndex, "012323");
+                } else if (ShmDcCommonData->SystemTemp[gunIndex*2] != 0 && ShmDcCommonData->SystemTemp[gunIndex*2] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-                } else {
-                    //判斷OTP
-                    if (ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
-                        RecordAlarmCode(gunIndex, "012323");
-                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
-                    }
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
                 }
-                if (ShmDcCommonData->SystemTemp[3] == UNDEFINED_TEMP) {
-                    // 溫度為255時判斷Sensor fail
+                if (ShmDcCommonData->SystemTemp[gunIndex*2+1] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[gunIndex*2+1] != UNDEFINED_TEMP) {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
+                    RecordAlarmCode(gunIndex, "012332");
+                } else if (ShmDcCommonData->SystemTemp[gunIndex*2+1] != 0 && ShmDcCommonData->SystemTemp[gunIndex*2+1] < pSysInfo->OTPTempR) {
                     ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
-                } else {
-                    //判斷OTP
-                    if (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES;
-                        RecordAlarmCode(gunIndex, "012332");
-
-                    } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) {
-                        ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO;
-                    }
-                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
                 }
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
             }
         }
 
@@ -527,6 +489,7 @@ static void checkGunOTPState(uint8_t gunIndex)
             //ResetChargerAlarmCode(gunIndex, "012229");
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
+
             if  ((gunIndex == 0) &&
                     (strncmp((char *)&pSysConfig->ModelName[7], "J", 1) == 0)) {
             	ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
@@ -1394,11 +1357,7 @@ bool DisplaySelfTestFailReason()
         pAlarmCode->AlarmEvents.bits.AcContactStestFail = true;
         result = true;
 #endif // !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-    }
-    //else if (pAlarmCode->AlarmEvents.bits.PsuDipSwitchStestFail == YES) { //DS60-120 add
-    //    result = true;
-    //}
-    else if (ShmPsuData->SystemAvailablePower <= 0 &&
+    } else if (ShmPsuData->SystemAvailablePower <= 0 &&
              ShmPsuData->SystemAvailableCurrent <= 0) {
         // PSU 通訊問題
         pAlarmCode->AlarmEvents.bits.PsuModuleStestFail = true;
@@ -1712,6 +1671,8 @@ void _SelfTestTimeout(void)
     ShmPsuData->Work_Step = _NO_WORKING;
     pSysInfo->SelfTestSeq = _STEST_FAIL;
     log_info("Self test timeout. ");
+    sleep(3);
+    system("/usr/bin/run_evse_restart.sh");
 }
 
 void _AuthorizedTimeout(void)
@@ -2260,6 +2221,10 @@ void ReleaseEmsOccureByString(uint8_t index, char *code)
                pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES) {
         isTrigger = true;
         pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip = NO;
+    } else if (strncmp(code, "012348", 6) == 0 &&
+               pAlarmCode->AlarmEvents.bits.ChillerAlarmFail == YES) {
+        isTrigger = true;
+        pAlarmCode->AlarmEvents.bits.ChillerAlarmFail = NO;
     }
 
     if (isTrigger) {
@@ -2727,33 +2692,10 @@ int SpawnTask(void)
     system("/root/Module_InternalComm &");
     system("/root/Module_ProduceUtils &");
     system("/root/Module_UpdateFW &");
-
-    #if defined DD360 ||defined DD360Audi || defined DD360ComBox
+    if (pSysConfig->ModelName[3] == 'P')
+        system("/root/Module_DcMeter &");
     system("/root/Module_DoComm &");
 
-    return PASS;
-#endif //defined DD360 ||defined DD360Audi || defined DD360ComBox
-
-    system("/root/Module_PsuComm &");
-
-    if (strcmp((char *)pSysConfig->OcppServerURL, "") != EQUAL &&
-            strcmp((char *)pSysConfig->ChargeBoxId, "") != EQUAL) {
-        system("/root/OcppBackend &");
-    }
-
-    if (pSysConfig->ModelName[10] == 'T') {
-        system("/root/Module_4g &");
-    }
-
-    if (pSysConfig->ModelName[10] == 'W') {
-        system("/root/Module_Wifi &");
-    }
-
-    if (pSysConfig->ModelName[10] == 'D') {
-        system("/root/Module_4g &");
-        system("/root/Module_Wifi &");
-    }
-
     return PASS;
 }
 
@@ -2768,15 +2710,11 @@ void KillTask(void)
     system("killall Module_InternalComm");
     system("killall Module_UpdateFW");
     system("killall Module_ChkSysTask");
+    if (pSysConfig->ModelName[3] == 'P')
+        system("killall Module_DcMeter");
     //system("killall Module_DoComm");
-#if defined DD360 || defined DD360Audi || defined DD360ComBox
     return ;
-#endif //defined DD360 || defined DD360Audi || defined DD360ComBox
 
-    system("killall Module_PsuComm");
-    system("killall OcppBackend &");
-    system("killall Module_4g &");
-    system("killall Module_Wifi &");
 }
 
 void KillTaskExceptPrimary(void)
@@ -2785,7 +2723,8 @@ void KillTaskExceptPrimary(void)
 
     system("killall Module_EvComm");
     system("killall Module_InternalComm");
-
+    if (pSysConfig->ModelName[3] == 'P')
+        system("killall Module_DcMeter");
 #if defined DD360 || defined DD360Audi || defined DD360ComBox
     return;
 #endif //defined DD360 || defined DD360Audi || defined DD360ComBox
@@ -2806,7 +2745,8 @@ void KillAllTask(void)
     system("killall Module_InternalComm");
     system("killall Module_UpdateFW");
     system("killall Module_ChkSysTask");
-
+    if (pSysConfig->ModelName[3] == 'P')
+        system("killall Module_DcMeter");
 #if defined DD360 || defined DD360Audi || defined DD360ComBox
     system("killall Module_DoComm");
     return ;
@@ -2845,7 +2785,19 @@ void StartGunInfoTimeoutDet(uint8_t gunIndex, uint8_t flag)
         pDcChargingInfo->TimeoutFlag = flag;
     }
 }
-
+void checkLanguagePageTimeout(void)
+{
+    int is_idle = TRUE;
+    for (int i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+        pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i);
+        if (pDcChargingInfo->SystemStatus != S_IDLE)
+            is_idle = FALSE;
+    }
+    if (is_idle)
+        pSysInfo->SystemPage = _PAGE_VIEW;
+    else
+        pSysInfo->SystemPage = _PAGE_SELECT_PAY;
+}
 void StopGunInfoTimeoutDet(uint8_t gunIndex)
 {
 
@@ -2917,6 +2869,30 @@ void CreateTimeoutFork(void)
                     destroySelGun(DESTROY_ALL_SEL); //jerry add
                 }
                 break;
+            case Timeout_ReturnViewPage:
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_VIEWPAGE_TIMEOUT) {
+                    log_error("Timeout_ReturnViewPage");
+                    StopSystemTimeoutDet();
+                    pSysInfo->SystemPage = _PAGE_VIEW;
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
+                    if (pDcChargingInfo->SystemStatus == S_AUTHORIZING || pDcChargingInfo->SystemStatus == S_COMPLETE ||
+                        pDcChargingInfo->SystemStatus == S_ALARM) {
+                        setChargerMode(pSysInfo->CurGunSelected, MODE_IDLE);
+                    }
+                }
+            	break;
+            case Timeout_helpPage:
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= HELP_PAGE_TIMEOUT) {
+                    StopSystemTimeoutDet();
+                    pSysInfo->SystemPage = ShmDcCommonData->previousPage;
+                }
+                break;
+            case Timeout_LanguagePage:
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= LANGUAGE_PAGE_TIMEOUT) {
+                    StopSystemTimeoutDet();
+                    checkLanguagePageTimeout();
+                }
+                break;
             case Timeout_Authorizing:
                 if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) {
                     log_error("Authorizing Timeout");
@@ -3334,7 +3310,6 @@ void ChkOcppStatus(uint8_t gunIndex)
         ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowReq = NO;
         if (isReservationExpired(gunIndex)) {
             log_info("***************ChkOcppStatus : OcppReservedStatus******************** ");
-            log_error("***************ChkOcppStatus : OcppReservedStatus******************** ");
             pDcChargingInfo->ReservationId = ShmOCPP16Data->ReserveNow[gunIndex].ReservationId;
             pDcChargingInfo->SystemStatus = S_RESERVATION;
         }
@@ -3346,7 +3321,6 @@ void ChkOcppStatus(uint8_t gunIndex)
         ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationReq = NO;
         if (isReservationExpired(gunIndex)) {
             log_info("***************ChkOcppStatus : Cancel OcppReservedStatus******************** ");
-            log_error("***************ChkOcppStatus : Cancel OcppReservedStatus******************** ");
             pDcChargingInfo->ReservationId = 0;
             pDcChargingInfo->SystemStatus = S_IDLE;
         }
@@ -3355,7 +3329,6 @@ void ChkOcppStatus(uint8_t gunIndex)
 
     if (ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq == YES) {
         log_info("***************ChkOcppStatus : OcppChangeAvailability******************** ");
-        log_error("***************ChkOcppStatus : OcppChangeAvailability******************** ");
         ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq = NO;
         if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex].Type, "Operative") == EQUAL) {
             if (isDb_ready) {
@@ -3376,7 +3349,7 @@ void ChkOcppStatus(uint8_t gunIndex)
             pDcChargingInfo->IsAvailable = NO;
             if (pDcChargingInfo->SystemStatus == S_IDLE ||
                     pDcChargingInfo->SystemStatus == S_RESERVATION ||
-                    pDcChargingInfo->SystemStatus == S_MAINTAIN) {
+                    pDcChargingInfo->SystemStatus == S_MAINTAIN ) {
                 setChargerMode(gunIndex, MODE_MAINTAIN);
             }
         }
@@ -3934,6 +3907,7 @@ static void autoStartCharging(uint8_t gunIndex)
             confirmSelGun(gunIndex);
             pSysInfo->SystemPage = _LCM_AUTHORIZING;
             ShmDcCommonData->AuthroizeType = IdTokenType_NoAuthorization;
+            pDcChargingInfo->StartMethod = _CHARGING_START_AUTOSTART;
         }
         if (strcmp( (char *)pSysConfig->UserId , OldUseId ) != EQUAL) {
             strcpy((char *)OldUseId, (char *)pSysConfig->UserId);
@@ -4211,7 +4185,6 @@ void CheckTaskAlive()
             if( count != 1 ) {
                 system("pkill Module_ChkSysTask");
                 sleep(10);
-                log_info("Create Check System Task");
                 system("/root/Module_ChkSysTask &");
             }
         }
@@ -4483,6 +4456,16 @@ void SetCHAdeMoTypeSJOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
     deratingByConnOtp->deratingTargetCurrent[4] = 0;
 }
 
+void SetCHAdeMoTypeOOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    deratingByConnOtp->isNeedDerating = YES;
+    deratingByConnOtp->deratingTargetCurrent[0] = 3500;
+    deratingByConnOtp->deratingTargetCurrent[1] = 2000;
+    deratingByConnOtp->deratingTargetCurrent[2] = 2000;
+    deratingByConnOtp->deratingTargetCurrent[3] = 0;
+    deratingByConnOtp->deratingTargetCurrent[4] = 0;
+}
+
 static void SetGunTypeOTPValue(void)
 {
     //struct ChargingInfoData* chargingData_2 = NULL;
@@ -4496,17 +4479,19 @@ static void SetGunTypeOTPValue(void)
         Gun2Type = pSysConfig->ModelName[7];
 
         switch (Gun1Type) {
-
         case 'K':
             SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp);
             break;
         case 'S':
             SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
             break;
-        case 'T':
-        case 'D':
+        case 'I':
+        case 'Q':
             SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
             break;
+        case 'O':
+            SetCHAdeMoTypeOOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
             // 水冷
         case 'V':
         case 'F':
@@ -4546,10 +4531,13 @@ static void SetGunTypeOTPValue(void)
                 SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
                 break;
                 // 風冷300A
-            case 'T':
-            case 'D':
+            case 'I':
+            case 'Q':
                 SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
                 break;
+            case 'O':
+                SetCHAdeMoTypeOOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
                 // 水冷
             case 'V':
             case 'F':
@@ -4577,7 +4565,170 @@ static void SetGunTypeOTPValue(void)
         }
     }
 }
+bool checkGunTempFail(uint8_t gunIndex)
+{
+#ifndef DD360
+    return FALSE;
+#endif
+    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+    switch (pDcChargingInfo->Type) {
+        case _Type_Chademo:
+            if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail) {
+                if (isCharging(pDcChargingInfo->SystemStatus)) {
+                    RecordAlarmCode(gunIndex,"011018");
+                } else {
+                    setChargerMode(gunIndex,S_FAULT);
+                }
+                return TRUE;
+            }
+            break;
+        case _Type_CCS_2:
+            if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail) {
+                if (isCharging(pDcChargingInfo->SystemStatus)) {
+                    RecordAlarmCode(gunIndex,"011019");
+                } else {
+                    setChargerMode(gunIndex,S_FAULT);
+                }
+                return TRUE;
+            }
+            break;
+        case _Type_GB:
+            if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail) {
+                if (isCharging(pDcChargingInfo->SystemStatus)) {
+                    RecordAlarmCode(gunIndex,"011020");
+                } else {
+                    setChargerMode(gunIndex,S_FAULT);
+                }
+                return TRUE;
+            }
+            break;
+    }
+    return FALSE;
+}
+
+//==========================================
+// Ocmf
+//==========================================
 
+void ConfigOcmfInfo(uint8_t gun_index)
+{
+    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun_index);
+	strncpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.evseId,
+			(char *)pSysConfig->SerialNumber, ARRAY_SIZE(pSysConfig->SerialNumber));
+
+	char trId[32];
+	sprintf(trId, "%d", ShmSelectGunInfo->PricesInfo[gun_index].TransactionId);
+	memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.transactionId, trId,
+			sizeof(trId));
+
+	char clientId[32] = "DC_Charger";
+	memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.clientId, clientId,
+			sizeof(clientId));
+
+	pSysInfo->DcMeterTransactionAction[gun_index].head.tariffId = 0;
+	pSysInfo->DcMeterTransactionAction[gun_index].head.cableId = 2;
+
+	memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.userData,
+			(char *)pDcChargingInfo->StartUserId,
+			sizeof(pDcChargingInfo->StartUserId));
+}
+
+void ConfigOcmfInfo_Record(int _trID, uint8_t gun_index)
+{
+	strncpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.evseId,
+			(char *)pSysConfig->SerialNumber, ARRAY_SIZE(pSysConfig->SerialNumber));
+
+	char trId[32];
+	sprintf(trId, "%d", _trID);
+	strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.transactionId, trId);
+	strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.clientId, "DC_Charger");
+
+	pSysInfo->DcMeterReadTransactionRecord[gun_index].head.tariffId = 0;
+	pSysInfo->DcMeterReadTransactionRecord[gun_index].head.cableId = 2;
+
+	strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.userData, "Record");
+}
+void StoreOcmfFile(uint8_t gun_index,int trid,int isRecord)
+{
+    if (ShmDcCommonData->pGunInfo[gun_index].ConnectorID <= 0 || ShmDcCommonData->pGunInfo[gun_index].ConnectorID > 4) {
+        log_info("Gun%d ConnectorID:%d",gun_index,ShmDcCommonData->pGunInfo[gun_index].ConnectorID);
+        return;
+    }
+
+    FILE *pfile;
+    char cmd[500];
+    sprintf((char*)ShmDcCommonData->pGunInfo[gun_index].OcmfFileName,"/mnt/Gun_%d_%d_OCMF",
+        ShmDcCommonData->pGunInfo[gun_index].ConnectorID,trid);
+    log_info("OCMF File:%s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName);
+
+    pfile = fopen(ShmDcCommonData->pGunInfo[gun_index].OcmfFileName,"w+");
+    if (isRecord)
+        fprintf(pfile,"%s",pSysInfo->DcMeterReadTransactionRecord[gun_index].transactionOCMF);
+    else
+        fprintf(pfile,"%s",pSysInfo->DcMeterTransactionAction[gun_index].transactionOCMF);
+    fclose(pfile);
+    sprintf(cmd,"ftpput -u root -p y42j/4cj84 192.168.100.1 %s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName);
+    if (system(cmd) != 0 ) {
+        log_info("Put OCMF File to Cabinet Fail");
+        sprintf(cmd,"rm -f %s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName);
+        system(cmd);
+    } else {
+        log_info("Put OCMF File to Cabinet OK");
+        ShmDcCommonData->pGunInfo[gun_index].SendOcmfDataReq = TRUE;
+    }
+
+}
+void ChkOcmfRecord(uint8_t gun_index)
+{
+    if (pAlarmCode->AlarmEvents.bits.Meter1CommTimeout) {
+        return;
+    }
+
+	int trid = DB_Get_OcmfTrid(gun_index);
+
+	if (trid != 0 &&
+			trid != ShmDcCommonData->ocmfTridRecord[gun_index] &&
+			trid != ShmSelectGunInfo->PricesInfo[gun_index].TransactionId)
+	{
+		ShmDcCommonData->ocmfTridRecord[gun_index] = trid;
+		ConfigOcmfInfo_Record(ShmDcCommonData->ocmfTridRecord[gun_index], gun_index);
+		pSysInfo->DcMeterReadTransactionRecord[gun_index].ActionCmd = _DC_METER_TRANSACTION_ACTION_START;
+	}
+
+	if (pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady == _OCMF_INFO_READY_YES &&
+        ShmDcCommonData->pGunInfo[gun_index].SendOcmfDataReq == FALSE)
+	{
+		log_info("OCMF Record - Reture Pass \n");
+		pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady = _OCMF_INFO_READY_NO;
+		//ocpp_ocmf_information(gun_index);
+		DB_Update_ocmf_Record(gun_index, ShmDcCommonData->ocmfTridRecord[gun_index], true);
+        StoreOcmfFile(gun_index,trid,TRUE);
+		//ShmDcCommonData->ocmfTridRecord[gun_index] = 0;
+	}
+	else if (pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady == _OCMF_INFO_READY_FAIL)
+	{
+		log_info("OCMF Record - Reture Fail \n");
+		pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady = _OCMF_INFO_READY_NO;
+		DB_Update_ocmf_Record(gun_index, ShmDcCommonData->ocmfTridRecord[gun_index], false);
+		//ShmDcCommonData->ocmfTridRecord[gun_index] = 0;
+	}
+}
+void SetGunMeterCableLoss()
+{
+    if (pSysConfig->TotalConnectorCount >= 2) {
+        if (pSysConfig->ModelName[7] == 'V' || pSysConfig->ModelName[7] == 'F') {
+            pSysInfo->DcMeterTransactionAction[LEFT_GUN_NUM].head.cableId = 3;
+        }
+        if (pSysConfig->ModelName[9] == 'V' || pSysConfig->ModelName[9] == 'F') {
+            pSysInfo->DcMeterTransactionAction[RIGHT_GUN_NUM].head.cableId = 3;
+        }
+    } else if (pSysConfig->TotalConnectorCount == 1){
+        if (pSysConfig->ModelName[7] == 'V' || pSysConfig->ModelName[7] == 'F' ||
+            pSysConfig->ModelName[9] == 'V' || pSysConfig->ModelName[9] == 'F') {
+            pSysInfo->DcMeterTransactionAction[LEFT_GUN_NUM].head.cableId = 3;
+        }
+    }
+}
 int main(void)
 {
     bool isModelNameMatch = true;
@@ -4585,8 +4736,10 @@ int main(void)
     uint8_t evBoardStopState = 0;
     uint8_t _ocppProfileChkFlag;
     uint8_t gunIndex = 0;
+    uint8_t _isStop[2] = {0};
     float powerconsumption;
-
+    uint8_t ConnectID[2];
+    uint8_t SendOcmfDataReq[2];
     if (CreateAllCsuShareMemory() == FAIL) {
         log_error("create share memory error");
         return FAIL;
@@ -4660,6 +4813,7 @@ int main(void)
     CreateTimeoutFork();
     log_info("Start self test... ");
     PrimaryLedIndicatorCtrlFork();
+    ChangeLcmByIndex(_LCM_FIX);
     SelfTestRun();
     StopSystemTimeoutDet();
     log_info("Self test finished : SelfTestSeq = %d, Work_Step = %d ",
@@ -4750,7 +4904,9 @@ int main(void)
 
     time_t ShowEVStatusTimer[2] = { 0 };
 
-    //SetGunTypeOTPValue();
+    SetGunTypeOTPValue();
+
+    SetGunMeterCableLoss();
 
     for (;;) {
 
@@ -4804,6 +4960,9 @@ int main(void)
                     }
                 }
                 checkGunOTPState(gunIndex); //check gun OTP
+                
+                // OCMF
+                ChkOcmfRecord(gunIndex);
             }
             gettimeofday(&_cmdMainPriority_time, NULL);
         }
@@ -4824,6 +4983,8 @@ int main(void)
         }
         checkChillerAlarmState();
 
+        //log_info("MeterCommTimeout:%d",pAlarmCode->AlarmEvents.bits.MeterCommTimeout);
+
         for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
@@ -4853,6 +5014,13 @@ int main(void)
                 CheckSmartChargeProfile(gunIndex);
             }
 
+            checkGunTempFail(gunIndex);
+
+            if (pSysInfo->SelfTestSeq == _STEST_FAIL ) {
+                setChargerMode(gunIndex, MODE_MAINTAIN);
+                ChangeLcmByIndex(_LCM_FIX);
+            }
+
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
             case S_RESERVATION:
@@ -4874,11 +5042,18 @@ int main(void)
                     if (pDcChargingInfo->deratingByConnOtp.deratingIndex != 0) {
                         pDcChargingInfo->deratingByConnOtp.deratingIndex = 0;
                     }
+                    ShmDcCommonData->ocmfTridRecord[gunIndex] = 0 ;
+                    _isStop[gunIndex] = 0;
                     //Jerry add
                     memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo));
+
                     powerconsumption = ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption;
+                    ConnectID[gunIndex] = ShmDcCommonData->pGunInfo[gunIndex].ConnectorID;
+                    SendOcmfDataReq[gunIndex] = ShmDcCommonData->pGunInfo[gunIndex].SendOcmfDataReq;
                     memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo));
                     ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = powerconsumption;
+                    ShmDcCommonData->pGunInfo[gunIndex].ConnectorID = ConnectID[gunIndex];
+                    ShmDcCommonData->pGunInfo[gunIndex].SendOcmfDataReq = SendOcmfDataReq[gunIndex];
 
                     ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES;
                     destroySelGun(gunIndex);
@@ -4889,44 +5064,14 @@ int main(void)
                     //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, "");
                     ReleaseAlarmCode(gunIndex);
                 }
-
                 if (pDcChargingInfo->IsAvailable == NO) {
                     setChargerMode(gunIndex, MODE_MAINTAIN);
                 }
-
-            case S_MAINTAIN:
             case S_FAULT:
                 if (isModeChange(gunIndex)) {
-                    if(pDcChargingInfo->SystemStatus == S_MAINTAIN)
-                    {
-                        log_info("============================= S_MAINTAIN(%x) ============================= ", gunIndex);
-                        if (pSysInfo->FirmwareUpdate == YES)
-                            continue;
-                        if (pDcChargingInfo->IsAvailable == NO )
-                            continue;
-                        if (pSysWarning->Level != WARN_LV_ER) {
-                            if (!DisplaySelfTestFailReason()) { //DS60-120 add
-                                log_info("Soft reboot for retry self-tets. ");
-                                sleep(3);
-                                system("killall OcppBackend &");
-                                KillAllTask();
-                                system("/usr/bin/run_evse_restart.sh");
-                            }
-                        }
-
-                        sleep(3);
-                        if (pSysWarning->Level == WARN_LV_ER) { //DS60-120 add
-                            KillTaskExceptPrimary();
-                        } else {
-                            KillTask();
-                        }
-                        StopProcessingLoop();
-                    }
-                    if(pDcChargingInfo->SystemStatus == S_FAULT)
-                    {
-                        log_info("============================= S_FAULT(%x) ============================= ", gunIndex);
-                    }
+                    log_info("============================= S_FAULT(%x) ============================= ", gunIndex);
                 }
+
                 if (pSysWarning->Level == WARN_LV_ER) {
                     struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
                     if (gunIndex == pSysInfo->CurGunSelected) {
@@ -4950,7 +5095,9 @@ int main(void)
                     }
                     continue;
                 }
-
+                if (checkGunTempFail(gunIndex)) {
+                    continue;
+                }
                 if (pDcChargingInfo->SystemStatus == S_FAULT) {
                     systemPageRestoreInit();
                     setChargerMode(gunIndex, MODE_IDLE);
@@ -4996,6 +5143,7 @@ int main(void)
                             strcpy((char *)pDcChargingInfo->StartUserId, "");
                             ClearDetectPluginFlag(gunIndex);
                             StopGunInfoTimeoutDet(gunIndex);
+                            pDcChargingInfo->StartMethod = _CHARGING_START_REMOTESTART;
                             continue;
                         }
                     } else if (pSysInfo->OrderCharging == NO_DEFINE) {
@@ -5027,11 +5175,13 @@ int main(void)
                             ClearDetectPluginFlag(RIGHT_GUN_NUM);
                             StopGunInfoTimeoutDet(LEFT_GUN_NUM);
                             StopGunInfoTimeoutDet(RIGHT_GUN_NUM);
+                            if (pDcChargingInfo->StartMethod != _CHARGING_START_AUTOSTART)
+                                pDcChargingInfo->StartMethod = _CHARGING_START_RFID;
                             continue;
                         }
                     }
 
-                    if (!GetIsCardScan()) {
+                    if (isDetectPlugin(gunIndex) && pSysInfo->CurGunSelected == gunIndex) {
                         // LCM => Waiting for plugging
                         // AUDI_LCM_CHANGE
                         pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG;
@@ -5088,6 +5238,7 @@ int main(void)
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
 
                 if (pSysInfo->CurGunSelected == gunIndex) {
+                    systemPageRestoreInit();
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
                 }
                 break;
@@ -5103,16 +5254,37 @@ int main(void)
                 if (pDcChargingInfo->Type == _Type_Chademo) {
                     // 檢查車端的槍鎖是否為鎖上
                     if (isEvGunLocked_chademo(gunIndex) == YES) {
+                        if (pSysConfig->ModelName[3] == 'P')
+                        {
+                            ConfigOcmfInfo(gunIndex);
+                            DB_Insert_ocmf(gunIndex);
+                            //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3;
+                            pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START;
+                        }
                         setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE);
                     }
                 } else if (pDcChargingInfo->Type == _Type_GB) {
                     // 檢查車端的 charging enable 是否為 1
                     if (isEvGunLocked_gb(gunIndex) == YES) {
+                        if (pSysConfig->ModelName[3] == 'P')
+                        {
+                            ConfigOcmfInfo(gunIndex);
+                            DB_Insert_ocmf(gunIndex);
+                            //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3;
+                            pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START;
+                        }
                         setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE);
                     }
                 } else if (pDcChargingInfo->Type == _Type_CCS_2) {
                     // 檢查車端的 charging enable 是否為 1
                     if (isEvGunLocked_ccs(gunIndex) == YES) {
+                        if (pSysConfig->ModelName[3] == 'P')
+                        {
+                            ConfigOcmfInfo(gunIndex);
+                            DB_Insert_ocmf(gunIndex);
+                            //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3;
+                            pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START;
+                        }
                         setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE);
                     }
                 }
@@ -5130,6 +5302,10 @@ int main(void)
                     log_info("============================= S_PREPARING_FOR_EVSE(%x) ============================= ", gunIndex);
                     StopGunInfoTimeoutDet(gunIndex);
                     StartGunInfoTimeoutDet(gunIndex, Timeout_EvseChargingDet);
+                    if (pSysConfig->ModelName[3] == 'P') {
+                        ShmDcCommonData->pGunInfo[gunIndex].isMeterStart = TRUE;
+                        ShmDcCommonData->ocmfTridRecord[gunIndex] = ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId;
+                    }
                 }
 
                 checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
@@ -5230,10 +5406,16 @@ int main(void)
                     ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL);
                     if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
                         DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
+
                 }
 
                 //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
-
+                if (ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P' && ShmDcCommonData->pGunInfo[gunIndex].isMeterStart &&
+                    pDcChargingInfo->RelayK1K2Status == NO && !_isStop[gunIndex]) {
+                        pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_STOP;
+                        log_info("Gun%d Stop Dc Meter Transcation",gunIndex);
+                        _isStop[gunIndex] = TRUE;
+                }
                 if (pDcChargingInfo->SystemStatus == S_ALARM) {
                     if (pDcChargingInfo->ConnectorPlugIn == NO &&
                             GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
@@ -5266,6 +5448,17 @@ int main(void)
                     }
                 }
 
+                if (ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') {
+                    if (pDcChargingInfo->SystemStatus == S_ALARM && ShmDcCommonData->pGunInfo[gunIndex].isMeterStop &&
+                            pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady)
+                    {
+                        pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady = NO;
+                        DB_Update_ocmf(gunIndex);
+                        StoreOcmfFile(gunIndex,ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId,FALSE);
+                        DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
+                    }
+                }
+
                 if (pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->ConnectorPage = _LCM_COMPLETE;
                 }
@@ -5277,11 +5470,15 @@ int main(void)
                     if (strcmp((char *)pDcChargingInfo->StartDateTime, "") != EQUAL) {
                         OcppStopTransation(gunIndex);
                     }
-
                     TheEndCharging(gunIndex);
-
                 }
-
+                
+                if (pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady && ShmDcCommonData->pGunInfo[gunIndex].isMeterStop) {
+                    pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady = NO;
+                    DB_Update_ocmf(gunIndex);
+                    StoreOcmfFile(gunIndex,ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId,FALSE);
+                    DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
+                }
                 if (pDcChargingInfo->ConnectorPlugIn == NO &&
                         GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) {
                     if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) {
@@ -5374,6 +5571,57 @@ int main(void)
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
                 }
                 break;
+            case S_MAINTAIN:
+                if (isModeChange(gunIndex)) {
+                    log_info("============================= S_MAINTAIN(%x) ============================= ", gunIndex);
+                    //pSysInfo->SystemPage = _PAGE_MAINTAIN;
+                    if (pSysInfo->FirmwareUpdate == YES) {
+                        pSysInfo->SystemPage = _PAGE_MAINTAIN;
+                        continue;
+                    }
+                    if (pDcChargingInfo->IsAvailable == NO) {
+                        log_info("Gun%d is not availbale");
+                        break;
+                    }
+
+                    if (pSysWarning->Level != WARN_LV_ER) {
+                        if (!DisplaySelfTestFailReason()) { //DS60-120 add
+                            log_info("Soft reboot for retry self-tets. ");
+                            sleep(3);
+                            KillAllTask();
+                            system("/usr/bin/run_evse_restart.sh");
+                        }
+                    }
+
+                    if (pSysWarning->Level == WARN_LV_ER) { //DS60-120 add
+                        KillTaskExceptPrimary();
+                    } else {
+                        KillTask();
+                    }
+                    /*
+                    if (pSysInfo->SelfTestSeq == _STEST_FAIL)
+                        StopProcessingLoop();
+                        */
+                }
+
+                if (pSysInfo->SelfTestSeq == _STEST_FAIL && pSysInfo->SystemTimeoutFlag != Timeout_SelftestChk) {
+                    SelfTestRun();
+                    StopSystemTimeoutDet();
+                    sleep(3);
+                    break;
+                }
+                if (pDcChargingInfo->IsAvailable && pSysInfo->SelfTestSeq == _STEST_COMPLETE) {
+                    if (pSysWarning->Level == WARN_LV_ER)
+                        setChargerMode(gunIndex, MODE_FAULT);
+                    else
+                        setChargerMode(gunIndex, MODE_IDLE);
+                }
+#ifndef DD360Audi
+                if (pSysInfo->CurGunSelected == gunIndex) {
+                    pSysInfo->SystemPage = _PAGE_MAINTAIN;
+                }
+#endif
+                break;
             }//switch
             TryFeedWatchdog();
         }//for

+ 4 - 1
EVSE/Projects/DD360Audi/Apps/CSU/main.h

@@ -44,7 +44,10 @@
 #define GUN_PRECHARGING_TIMEOUT                 (60)
 #define EVCCID_LINK_TIMEOUT                     (120)
 #define PRECHARGING_TTIMEOUT                    (60)
-
+#define RETURN_VIEWPAGE_TIMEOUT                 (30)
+#define HELP_PAGE_TIMEOUT                       (30)
+#define LANGUAGE_PAGE_TIMEOUT                   (30)
+#define CONN_PLUG_TIMEOUT                       (40)
 #define WHILE_LOOP_TIME                         (10000)
 
 //#define log_info(format, args...) StoreLogMsg_1("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)

+ 152 - 10
EVSE/Projects/DD360Audi/Apps/Config.h

@@ -60,6 +60,8 @@
 #define BOOTTING                                (0)
 #define BOOT_COMPLETE                           (1)
 
+#define POWER_SAVE_MODE                         (1)
+
 //------------------------------------------------------------------------------
 //common define
 //------------------------------------------------------------------------------
@@ -96,6 +98,9 @@
 #define WARN_LV_ER                              (2) //emergency state
 
 //------------------------------------------------------------------------------
+
+#define DC_CONNECTOR_COUNT          2
+
 enum _SYSTEM_STATUS {
     S_BOOTING = 0,
     S_IDLE,
@@ -163,6 +168,23 @@ enum _LCM_INDEX {
     _LCM_NONE          = 0xFF,
 };
 
+enum _LCM_WISTRON_INDEX {
+    _PAGE_INIT = 0x00,
+    _PAGE_VIEW,
+    _PAGE_LANGUAGE,
+    _PAGE_SELECT_PAY,
+    _PAGE_AUTHORIZING,
+    _PAGE_AUTHORIZE_COMPLETE,
+    _PAGE_AUTHORIZE_FAIL,
+    _PAGE_PLUGIN_FAIL,
+    _PAGE_STOP_CHARGING,
+    _PAGE_SUMMARY,
+    _PAGE_HELP,
+    _PAGE_ALARM,
+    _PAGE_MAINTAIN,
+    _PAGE_EMG_BTN,
+
+};
 enum _SELF_TEST_SEQ {
     _STEST_VERSION      = 0x00,
     _STEST_AC_CONTACTOR = 0x01,
@@ -297,6 +319,47 @@ enum _DERATING_TEMP {
     STAGE1_GUN_DERATING_TEMP = 140,
     STAGE2_GUN_DERATING_TEMP = 145,
 };
+
+enum _TILT_SENSOR_STEP {
+    _TILT_SENSOR_STEP_NONE,
+    _TILT_SENSOR_STEP_PIN_ON,
+    _TILT_SENSOR_STEP_PIN_WAIT,
+    _TILT_SENSOR_STEP_PIN_OFF,
+    _TILT_SENSOR_STEP_PIN_FINISH,
+};
+// Meter OCMF
+struct StructMeter
+{
+	float curMeterValue;
+	float newMeterValue;
+	uint8_t isCalculation;
+	float _chargingValue;
+	float _curTotalCharging;
+};
+struct MeterInformation
+{
+	struct StructMeter _meter[DC_CONNECTOR_COUNT];
+	uint8_t isWorking;
+};
+enum _DC_METER_TRANSACTION_ACTION
+{
+	_DC_METER_TRANSACTION_ACTION_NONE	= 0,
+	_DC_METER_TRANSACTION_ACTION_START,
+	_DC_METER_TRANSACTION_ACTION_STOP,
+};
+enum _OCMF_INFO_READY_FLAG
+{
+	_OCMF_INFO_READY_NO					= 0,
+	_OCMF_INFO_READY_YES,
+	_OCMF_INFO_READY_FAIL
+};
+enum _CHARGING_START_METHOD
+{
+    _CHARGING_START_RFID = 0,
+    _CHARGING_START_AUTOSTART,
+    _CHARGING_START_REMOTESTART,
+};
+
 //------------------------------------------------------------------------------
 //struct StructMeter {
 //    float curMeterValue;
@@ -411,8 +474,7 @@ typedef struct StGunInfo {
     int ConnectorID;
     char ReceiptInfo[255];
     int finalcost_flag;
-    time_t EVLoseTimer;
-    uint8_t EVLoseFlag;
+
     char ReservationID[32];
     uint8_t ReservationStatus;
     char UserPriceString[255];
@@ -421,10 +483,27 @@ typedef struct StGunInfo {
     char ChargeStartTime[32];
     char ChargeStopTime[32];
     char ChargeDuration[32];
-    uint8_t withChiller;      //是否有水冷機
-    uint8_t WaitForPlugit;    // 等待插槍FLAG
+
+    uint8_t SendOcmfDataReq;
+    char OcmfFileName[300];
+    double curMeterValue;
+    double _curTotalCharging;
+    struct {
+        uint8_t withChiller:1;      //是否有水冷機
+        uint8_t WaitForPlugit:1;    // 等待插槍FLAG
+        uint8_t isMeterStart:1;
+        uint8_t isMeterStop:1;
+    };
 } GunInfo;
 
+
+typedef struct StGunStatus {
+    time_t EVLoseTimer;
+        struct {
+        uint8_t EVLoseFlag:1;
+    };
+} GunStatus;
+
 typedef struct Psu_VersionInfo{
 	uint8_t n_PSU;
 	uint8_t DCVersion[32];
@@ -488,21 +567,84 @@ typedef struct StDcCommonInfo {
     uint8_t chillerCtrl;
     uint8_t debugflag;
     uint8_t LcmFwVersion;
-    int TZOffset;
-    uint8_t AuthroizeType; // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
-    char QRCodeString[255];
-    char DefaultPriceString[255];
-    PowerConsumptionValue pConsumption;
+    uint8_t _upgrade_lcm_flag;
+    uint8_t _upgrade_lcm_result;
+    uint8_t _upgrade_lcm_apk_flag;
+    // Power Cabinet Version
+    uint8_t CabinetModelName[32];
+    uint8_t CabinetBoolLoaderVersion[32];
+    uint8_t CabinetKernelVersion[32];
+    uint8_t CabinetRFSystemVersion[32];
+    uint8_t CabinetPrimaryVersion[32];
+    uint8_t CabinetIPAddr[32];
+    uint8_t CabinetRelay0Version[32];
+    uint8_t CabinetRelay1Version[32];
+    uint8_t CabinetFanVersion[32];
+    // PSU Version
+    uint8_t PSU_Number;
+    PsuVerInfo PsuVer[12];
+    int ConnectorId[2];
     int WeatherID;
     float Temperature;
     int Location;
+    char PresentTime[128];
+    TransInfo pCreditCard[2];
+    int runningcost[2];
+    float finalcost[2];
+    unsigned int finalcost_flag[2];
+    float ChargingRate;
+    int PreAuth_Config;
+    int PreAuth_Result;
+    int LineStatus[2];
+    int donate_flag[2];
+    unsigned int AuthPass_flag[2];
+    unsigned int PayPass_flag[2];
+    unsigned int PayFinish[2];
+    unsigned int StopCharge[2];
+    unsigned int GetCardNo[2];
+    unsigned int TradeCancel;
+    int reupload_deduct_status;		// 0:Not ReUpload 1:ReUpload 2:ReUpload finish
+    RecordTransactionInfo TransactionInfo[2];
+    int TZOffset;
+ 	uint8_t AuthroizeType; // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MacAddress   7: NoAuthorization
+
+    time_t EVDisconnectTime[2];
+    int EVDisconnectFlag[2];
+    int isIntoCharge[2];
+    time_t RelayDisconnectTime;
+    time_t LedDisconnectTime;
+    time_t FanDisconnectTime;
+    int DemoCount;
+    char QRCodeString[255];
     GunInfo pGunInfo[2];
+    GunStatus pGunStatus[2];
+    char DefaultPriceString[255];
+    PowerConsumptionValue pConsumption;
+
     uint8_t showNetPackage;
     uint8_t showCanPackage;
+    char DebugVersion[32];
     time_t FanOnTime;
+    uint8_t language;
+    int lcmtest;
+    uint8_t previousPage;
+    int SDUPATENUM;
+    int BlackLight;
+    time_t SleepTimer; // control by sleep mode
+    time_t lcmwatchdog; // Detect LCM alive or not
+    int8_t lcmmacAddr[32];
+    int8_t lcmcmd;
     float TempVolt[4];
-    char DebugVersion[32];
+    int8_t demo_flag;
+    int8_t isDark;
     TestFlag pTest;
+    uint8_t _tiltSensorStep;
+    uint8_t LcmPage;
+    // Ocmf
+    uint8_t _hour_index;			//0 ~ 23
+    float energy_time_period[DC_CONNECTOR_COUNT][24];
+	// Ocmf Record resend
+	int ocmfTridRecord[DC_CONNECTOR_COUNT];
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 190 - 1
EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.c

@@ -8,6 +8,7 @@
 #include "../Log/log.h"
 #include "../Define/define.h"
 #include "../ShareMemory/shmMem.h"
+#include "../SelectGun/SelectGun.h"
 
 //------------------------------------------------------------------------------
 #define DB_FILE                                 "/Storage/ChargeLog/localCgargingRecord.db"
@@ -64,6 +65,15 @@ int DB_Open(void)
                          "connector TEXT, "
                          "val TEXT);";
 
+	char* createDcMeterSql="CREATE TABLE IF NOT EXISTS ocmf_record("
+							  "idx integer primary key AUTOINCREMENT, "
+							  "transactionId text, "
+			 	 	 	 	  "status INTEGER NOT NULL, "
+							  "connector INTEGER NOT NULL, "
+							  "publicKey text, "
+							  "ocmfInfo text"
+							  ");";
+
     if (sqlite3_open(DB_FILE, &localDb)) {
         result = FAIL;
         log_info( "Can't open database: %s", sqlite3_errmsg(localDb));
@@ -109,6 +119,15 @@ int DB_Open(void)
         }
         //-----
 
+		if (sqlite3_exec(localDb, createDcMeterSql, 0, 0, &errMsg) != SQLITE_OK)
+		{
+			result = FAIL;
+			log_info( "Create OCMF record table error message: %s\n", errMsg);
+		}
+		else
+		{
+			log_info( "Opened OCMF record table successfully\n");
+		}
         sqlite3_close(localDb);
     }
 
@@ -123,11 +142,12 @@ int DB_Insert_Record(int gunIndex)
     char insertSql[1024];
     struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
     struct OCPP16Data *ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
+    SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
 
     sprintf(insertSql, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason) "
             "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s');",
             pDcChargingInfo->ReservationId, //DS60-120 add
-            ShmOCPP16Data->StartTransaction[gunIndex].ResponseTransactionId,
+            ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId,
             pDcChargingInfo->StartMethod,
             pDcChargingInfo->StartUserId,
             pDcChargingInfo->StartDateTime,
@@ -436,3 +456,172 @@ int InsertEventRecord(uint8_t *statusCode)
 
     return result;
 }
+
+
+int DB_Insert_ocmf(uint8_t gun_index)
+{
+	int result = PASS;
+	char* errMsg = NULL;
+	char insertSql[2048];
+    SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+	memset(insertSql, 0, sizeof(insertSql));
+	sprintf(insertSql, "insert into ocmf_record (transactionId, status, connector) values('%d', 0, '%d');",
+					ShmSelectGunInfo->PricesInfo[gun_index].TransactionId,
+					gun_index);
+
+	if (sqlite3_open(DB_FILE, &localDb))
+	{
+		result = FAIL;
+		log_warn("Can't open database: %s\n", sqlite3_errmsg(localDb));
+		sqlite3_close(localDb);
+	}
+	else
+	{
+		if (sqlite3_exec(localDb, insertSql, 0, 0, & errMsg) != SQLITE_OK)
+		{
+			result = FAIL;
+			log_warn("Insert ocmf error message : %s\n", errMsg);
+		}
+		else
+		{
+			log_info("Insert ocmf successfully");
+		}
+
+		sqlite3_close(localDb);
+	}
+
+	return result;
+}
+
+void DB_Update_ocmf(uint8_t gun_index)
+{
+	char* errMsg = NULL;
+	char insertSql[4096];
+    struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
+    SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+	memset(insertSql, 0, sizeof(insertSql));
+	sprintf(insertSql, "update ocmf_record set status=0, publicKey='%s', ocmfInfo='%s' where status=0 and transactionId=%d and connector=%d;",
+		pSysInfo->DcMeterStatusInfo[gun_index].publicKeyOcmf,
+		pSysInfo->DcMeterTransactionAction[gun_index].transactionOCMF,
+		ShmSelectGunInfo->PricesInfo[gun_index].TransactionId,
+		gun_index);
+	if (sqlite3_open(DB_FILE, &localDb))
+	{
+		log_warn("Can't open database: %s\n", sqlite3_errmsg(localDb));
+		sqlite3_close(localDb);
+	}
+	else
+	{
+		if (sqlite3_exec(localDb, insertSql, 0, 0, & errMsg) != SQLITE_OK)
+		{
+			log_warn("Update ocmf error message : %s", errMsg);
+		}
+		else
+		{
+			log_info("Update ocmf successfully ");
+		}
+		sqlite3_close(localDb);
+	}
+}
+
+void DB_Update_ocmf_Record(uint8_t gun_index, int _trid, bool isGet)
+{
+	char* errMsg = NULL;
+	char insertSql[4096];
+    struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
+	memset(insertSql, 0, sizeof(insertSql));
+	if (isGet)
+	{
+		sprintf(insertSql, "update ocmf_record set status=0, publicKey='%s', ocmfInfo='%s' where status=0 and transactionId=%d and connector=%d;",
+                pSysInfo->DcMeterStatusInfo[gun_index].publicKeyOcmf,
+				pSysInfo->DcMeterReadTransactionRecord[gun_index].transactionOCMF,
+				_trid,
+				gun_index);
+	}
+	else
+	{
+		sprintf(insertSql, "update ocmf_record set status=2 where status=0 and transactionId=%d and connector=%d;",
+				_trid,
+				gun_index);
+	}
+	if (sqlite3_open(DB_FILE, &localDb))
+	{
+		log_warn("Can't open database: %s\n", sqlite3_errmsg(localDb));
+		sqlite3_close(localDb);
+	}
+	else
+	{
+		if (sqlite3_exec(localDb, insertSql, 0, 0, & errMsg) != SQLITE_OK)
+		{
+			log_warn("Update ocmf error message : %s", errMsg);
+		}
+		else
+		{
+			log_info("Update ocmf_Record successfully ");
+		}
+		sqlite3_close(localDb);
+	}
+}
+
+int DB_Get_OcmfTrid(uint8_t gun_index)
+{
+	int result = 0;
+	char* errMsg = NULL;
+	char sqlStr[2048];
+	char **rs;
+	int rows, cols;
+
+	memset(sqlStr, 0, sizeof(sqlStr));
+	sprintf(sqlStr, "select * from ocmf_record where status=0 and connector=%d and transactionId!=0;", gun_index);
+
+	if (sqlite3_open(DB_FILE, &localDb))
+	{
+		log_warn("Can't open database: %s\r\n", sqlite3_errmsg(localDb));
+		sqlite3_close(localDb);
+	}
+	else
+	{
+		//log_info("Local config query database open successfully.\r\n");
+		sqlite3_get_table(localDb, sqlStr, &rs, &rows, &cols, &errMsg);
+		if (rows > 0)
+		{
+			for (int idxRow = 1; idxRow <= rows; idxRow++)
+			{
+				result = atoi(rs[(idxRow * cols) + 1]);
+				break;
+			}
+		}
+
+		sqlite3_free_table(rs);
+		sqlite3_close(localDb);
+	}
+
+	return result;
+}
+
+void DB_Upload_ocmf(uint8_t gun_index, int txid)
+{
+	char* errMsg = NULL;
+	char insertSql[4096];
+    struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
+    SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+	memset(insertSql, 0, sizeof(insertSql));
+	sprintf(insertSql, "update ocmf_record set status=1 where transactionId=%d and connector=%d;",txid,gun_index);
+	if (sqlite3_open(DB_FILE, &localDb))
+	{
+		log_warn("Can't open database: %s\n", sqlite3_errmsg(localDb));
+		sqlite3_close(localDb);
+	}
+	else
+	{
+		if (sqlite3_exec(localDb, insertSql, 0, 0, & errMsg) != SQLITE_OK)
+		{
+			log_warn("Upload ocmf error message : %s", errMsg);
+		}
+		else
+		{
+			log_info("Upload ocmf successfully ");
+		}
+		sqlite3_close(localDb);
+	}
+}

+ 6 - 0
EVSE/Projects/DD360Audi/Apps/DataBase/DataBase.h

@@ -13,4 +13,10 @@ int InsertEventRecord(uint8_t *statusCode);
 int DB_Get_PowerConsumption(uint8_t gunIndex);
 int DB_Insert_PowerConsumption(uint8_t gunIndex, float energy);
 int DB_Update_PowerConsumption(uint8_t gunIndex, float energy);
+// OCMF
+int DB_Insert_ocmf(uint8_t gun_index);
+void DB_Update_ocmf(uint8_t gun_index);
+void DB_Update_ocmf_Record(uint8_t gun_index, int _trid, bool isGet);
+int DB_Get_OcmfTrid(uint8_t gun_index);
+void DB_Upload_ocmf(uint8_t gun_index, int txid);
 #endif /* _DATA_BASE_H_ */

+ 57 - 9
EVSE/Projects/DD360Audi/Apps/Define/define.h

@@ -612,6 +612,7 @@ struct SysConfigData
     unsigned int            PowerSharingCapacityPower;          // Local power sharing capacity power
     unsigned char           MaxChargingSoc;                     // 0: unlimit, 1 ~ 100 percent
     unsigned char			FanControlPolicy;					// 0: Auto mode		1: Quite mode
+	unsigned short			MaxChargingVoltage;					//0: rating value, 1 ~ RATING_VOLTAGE	volt
 };
 
 struct DERATING_BY_OTP
@@ -729,6 +730,7 @@ struct ChargingInfoData
     unsigned char       _TotalPsuCount;                 // Psu count for connector
     unsigned char       _TakePsuGpCount;                // Get the used psu group count
     struct DERATING_BY_OTP deratingByConnOtp;
+    unsigned char 		ParentIdTag[21];
 };
 
 typedef struct
@@ -1012,7 +1014,7 @@ struct DC_METER_TRANSACTION_HEAD
 struct DC_METER_TRANSACTION_ACTION
 {
 	struct DC_METER_TRANSACTION_HEAD head;
-	unsigned char transactionOCMF[512];
+	unsigned char transactionOCMF[2048];
 	unsigned char OcmfInfoReady;                // 0 = nothing, 1 = ocmp info ready
 	unsigned char ActionCmd;                   // 1 = transaction Start, 2 transaction Stop, sync time
 };
@@ -1548,11 +1550,11 @@ char AlarmStatusCode[160][6]=
     "012350",   // reserved
     "012351",   // reserved
     "012352",   // Payment system communication timeout
-    "012353",   // reserved
-    "012354",   // reserved
-    "012355",   // reserved
-    "012356",   // reserved
-    "012357",   // reserved
+    "012353",   // Meter Slave Los Link
+    "012354",   // Meter Sync Time Error
+    "012355",   // Meter Start Transaction Error
+    "012356",   // Meter Stop Transaction Error
+    "012357",   // Meter Get Transaction Ocmf Error
     "012358",   // reserved
     "012359",   // reserved
 };
@@ -1684,7 +1686,7 @@ struct AlarmCodeData
 			unsigned char CcsLiquidChillerWaterLevelWarning:1;      //bit 7
 			//AlarmVal[13]
             unsigned char DisconnectedFromDo:1;                     //bit 0
-            unsigned char MeterCommTimeout:1;                       //bit 1
+            unsigned char Meter1CommTimeout:1;                       //bit 1
             unsigned char PsuDipSwitchStestFail:1;                  //bit 2
             unsigned char PsuFuseBurnOut:1;                         //bit 3
             unsigned char PsuPfcAndDcdcCommFault:1;                 //bit 4
@@ -1726,7 +1728,9 @@ struct AlarmCodeData
             unsigned char PsuComminicationErrWithCSU:1;             //bit 2
             unsigned char LocalPowerSharingCommunicationError:1;    //bit 3
             unsigned char ChillerAlarmFail:1;                       //bit 4
-			unsigned char :3;                                       //reserved bit 4 ~ bit 7
+            unsigned char Meter2CommTimeout:1;                      //bit 5
+            unsigned char Meter3CommTimeout:1;                      //bit 6
+            unsigned char Meter4CommTimeout:1;                      //bit 7
             //AlarmVal[19]
             unsigned char PaymentCommTimeout:1;                     //Payment system communication timeout
            	unsigned char MeterSlaveLosLink:1;                     	//DCMB meter slave module los link
@@ -6022,12 +6026,52 @@ struct StructReaderStatus
     unsigned char ReportReaderStatusReq:1;
 };
 
+struct StructOccupancyFeeDisplay
+{
+	unsigned char occupancySN[64];
+	int   actionId;
+    unsigned char OccupancyFeeDisplayReq:1;
+};
+
+struct StructSetOccupancyPrice
+{
+	float   price;
+    unsigned char SetOccupancyPriceReq:1;
+};
+
+struct StructOccupancyFeeAct
+{
+	unsigned char occupancySN[64];
+	int action;
+
+	int   response_duration;
+	float response_occupancyFee;
+	unsigned char response_status[10];
+    unsigned char response_occupancySN[37];
+    unsigned char response_startTime[64];
+
+    unsigned char OccupancyFeeActReq:1;
+};
+
+struct StructOccupancyDeductResult
+{
+	unsigned char deductResult:1;
+	float amount;
+	unsigned char occupancySN[37];
+	unsigned char creditNo[64];
+	unsigned char approvalNo[20];
+};
+
 struct StructTcciCustomData
 {
     struct StructChargerInfo ChargerInfo;
     struct StructWeatherInfo WeatherInfo;
     struct StructCreditDeductResult DeductInfo;
     struct StructReaderStatus ReaderStatus[CONNECTOR_QUANTITY];
+    struct StructOccupancyFeeDisplay OccupancyFeeDisplay[CONNECTOR_QUANTITY];
+    struct StructSetOccupancyPrice SetOccupancyPrice;
+    struct StructOccupancyFeeAct OccupancyFeeAct[CONNECTOR_QUANTITY];
+    struct StructOccupancyDeductResult OccupancyDeductResult;
     unsigned char TriggerReaderReq[3];
     unsigned char SerialNo[CONNECTOR_QUANTITY][37];
     unsigned char VEMData[CONNECTOR_QUANTITY][65];
@@ -6037,7 +6081,8 @@ struct StructTcciCustomData
     unsigned char ChargerInfoConf:1;
     unsigned char WeatherInfoReq:1;
     unsigned char WeatherInfoConf:1;
-    unsigned char :3;                  // bit 5-7 , reserved
+    unsigned char ReportOccupancyDeductReq:1;
+    unsigned char :2;                  // bit 6-7 , reserved
 };
 
 struct OCMFData
@@ -6078,6 +6123,9 @@ struct OCPP16Data
     unsigned int                            Timeout_Secs;
     unsigned short                          Ping_Pong_Interval;
     long int                                procDogTime;            // Process watch dog refresh timer
+    unsigned int                            isBootNotificationDone;
+    unsigned char                           preOcppServerURL[512];
+
     union
     {
         //Operations Initiated by Charge Point

+ 11 - 4
EVSE/Projects/DD360Audi/Apps/Makefile

@@ -25,6 +25,9 @@ INC_FLAGS += -I $(TOP)/ModulePrimary
 INC_FLAGS += -I $(TOP)/ModuleLcmCtrl
 INC_FLAGS += -I $(TOP)/ModuleDoComm
 INC_FLAGS += -I $(TOP)/ModuleEventLog
+INC_FLAGS += -I ../../../Modularization/ocppfiles
+INC_FLAGS += -I ../../../GPL/mosquitto-2.0.13/release/usr/local/include
+
 
 DefineLib = $(TOP)/Define
 LogLib = $(TOP)/Log
@@ -41,7 +44,8 @@ DoCommLib = $(TOP)/ModuleDoComm
 EventLogLib = $(TOP)/ModuleEventLog
 SelectGunLib = $(TOP)/SelectGun
 ScriptLib = $(TOP)/Script
-
+Lib_MOSQUITTO = "-L../../../GPL/mosquitto-2.0.13/release/usr/local/lib" -lmosquitto
+Lib_JSONC = "-L../../../GPL/json-c-json-c-0.13.1-20180305/release/lib" -ljson-c
 
 #define library variable
 Internal485ProtocolLib = -L $(ModularizationPath)/Internal485Protocol -lInternal485Protocol
@@ -62,6 +66,7 @@ RatedCurrent_H = -include$(ModularizationPath)/Module_RatedCurrent.h
 
 InfypwrPsuComm_H = -include$(ModularizationPath)/Infypwr_PsuCommObj.h
 InfypwrPsuComm_A = $(ModularizationPath)/libInfypwr_PsuCommObj.a
+JSON_H = -include../../../GPL/json-c-json-c-0.13.1-20180305/release/include/json-c/json.h
 
 #common lib
 COMMON_OBJ_FILES = common.o \
@@ -81,7 +86,7 @@ MAIN_SRC_FILES = $(patsubst %.o, %.c, $(MAIN_OBJ_FILES))
 	$(CC) $(CFLAGS) -c $<
 
 #DoComm
-DOCOMM_OBJ_FILES = $(COMMON_OBJ_FILES) $(DoCommLib)/DoComm.o
+DOCOMM_OBJ_FILES = $(COMMON_OBJ_FILES) $(DoCommLib)/DoComm.o $(DataBaseLib)/DataBase.o
 DOCOMM_SRC_FILES = $(patsubst %.o, %.c, $(DOCOMM_OBJ_FILES))
 
 #internal comm lib
@@ -142,7 +147,7 @@ all: CopyFile apps
 apps: MainTask DoCommTask EvCommTask UpdateFWTask ChkSysTask \
 		EventLoggingTask InternalCommTask LcmControlTask \
 			PrimaryCommTask ReadCmdlineTask UnsafetyOutputTool \
-				FactoryConfigApp OtherTools CleanExec
+				FactoryConfigApp OtherTools CleanExec 
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
@@ -154,7 +159,7 @@ MainTask:
 	#$(CC) $(TFLAGS) -o main main.o timeout.o common.o ${Lib_Module_RFID} ${Lib_Module_Upgrade} ${Lib_SQLite3} $(Lib_Module_RatedCurrent)
 
 DoCommTask:
-	$(CC) $(DEFINE) $(DOCOMM_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) -o Module_DoComm
+	$(CC) $(DEFINE) $(DOCOMM_SRC_FILES) $(CFLAGS) $(TFLAGS) $(SQLite3_H) $(Lib_SQLite3) $(INC_FLAGS) -o Module_DoComm
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o define.o $(DefineLib)/define.c
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o DoComm.o $(DoCommLib)/DoComm.c
 	#$(CC) -o Module_DoComm DoComm.o define.o
@@ -226,6 +231,7 @@ OtherTools:
 	cp -f $(ScriptLib)/init.sh $(RootPath)
 	cp -f $(ScriptLib)/kill.sh $(RootPath)
 	cp -f $(ScriptLib)/web.sh $(RootPath)
+	cp -f $(ScriptLib)/Language.db $(RootPath)
 	cp -f main $(RootPath)
 	cp -f Module_DoComm $(RootPath)
 	cp -f Module_EvComm $(RootPath)
@@ -244,6 +250,7 @@ OtherTools:
 	cp -f $(ScriptLib)/init.sh $(OutputPath)
 	cp -f $(ScriptLib)/kill.sh $(OutputPath)
 	cp -f $(ScriptLib)/web.sh $(OutputPath)
+	cp -f $(ScriptLib)/Language.db $(OutputPath)
 	cp -f $(ScriptLib)/SearchIP.sh $(OutputPath)
 	cp -f main $(OutputPath)
 	cp -f Module_DoComm $(OutputPath)

+ 13 - 1
EVSE/Projects/DD360Audi/Apps/ModuleChkSysTask/Module_ChkSysTask.c

@@ -78,6 +78,7 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 	unsigned char count_doComm	    = GetProcessCount("Module_DoComm");
 	unsigned char count_produceComm	= GetProcessCount("Module_ProduceUtils");
 	unsigned char count_updateFW	= GetProcessCount("Module_UpdateFW");
+	unsigned char count_DcMeter  	= GetProcessCount("Module_DcMeter");
 
 	//if (systemPage != _LCM_FIX )
 	{
@@ -96,6 +97,8 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 			system("killall Module_DoComm");
 			system("killall Module_ProduceUtils");
 			system("killall Module_UpdateFW");
+			if (pSysConfig->ModelName[3] == 'P')
+				system("killall Module_DcMeter");
             sleep(3);
             system("/root/main &");
             sleep(20);
@@ -156,6 +159,12 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 				sleep(3);
 				system("/root/Module_UpdateFW &");
 			}
+			if (count_DcMeter < _SYSTEM_TASK_COUNT_DCMETER && pSysConfig->ModelName[3] == 'P' )
+			{
+				system("killall Module_DcMeter");
+				sleep(3);
+				system("/root/Module_DcMeter &");
+			}
 		}
 
 	}
@@ -180,7 +189,8 @@ unsigned char CheckSystemTask(unsigned char systemPage)
         result = _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS;
     else if (count_updateFW < _SYSTEM_TASK_COUNT_UPDATEFW)
         result = _SYSTEM_TASK_LOST_ITEM_UPDATEFW;
-
+    else if (count_DcMeter < _SYSTEM_TASK_COUNT_DCMETER && pSysConfig->ModelName[3] == 'P')
+        result = _SYSTEM_TASK_LOST_ITEM_DCMETER;
 
 	return result;
 }
@@ -214,6 +224,8 @@ void CheckSystemTaskAlive()
                log_error("System task lost (ProcductUtils Comm). ");
            else if (lostId == _SYSTEM_TASK_LOST_ITEM_UPDATEFW)
                log_error("System task lost (Update FW) ");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_DCMETER)
+               log_error("System task lost (DcMeter) ");
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = YES;
         }
     } else

+ 2 - 0
EVSE/Projects/DD360Audi/Apps/ModuleChkSysTask/Module_ChkSysTask.h

@@ -45,6 +45,7 @@
 #define _SYSTEM_TASK_LOST_ITEM_DOCOMM       7
 #define _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS 8
 #define _SYSTEM_TASK_LOST_ITEM_UPDATEFW     9
+#define _SYSTEM_TASK_LOST_ITEM_DCMETER      10
 
 ///*
 #define _SYSTEM_TASK_COUNT_MAIN             5 
@@ -56,6 +57,7 @@
 #define _SYSTEM_TASK_COUNT_DOCOMM           1
 #define _SYSTEM_TASK_COUNT_PRODUCEUTILS     1
 #define _SYSTEM_TASK_COUNT_UPDATEFW         1
+#define _SYSTEM_TASK_COUNT_DCMETER          1
 //*/
 /*
 #define _SYSTEM_TASK_COUNT_MAIN             3 

+ 144 - 8
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c

@@ -62,6 +62,7 @@ static int TimeZoneOffset = 0;
 int RxLen;
 char Rxdata[1024];
 uint8_t _isplugin = 0;
+int gunstatus[2];
 //------------------------------------------------------------------------------
 static void removeFaultCodeToBuf(uint8_t *Code);
 static void addFaultCodeToBuf(uint8_t *Code);
@@ -666,9 +667,8 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
         case MISC_CMD_DEFAULT_PRICES:
             prices = transPricesUnit((int)value);
             log_info("default prices = %.2f", prices);
-            //if (prices > 0)
-            //    ShmDcCommonData->ChargingRate = prices;
-            //pSysConfig->BillingData.isBilling = YES;
+            ShmDcCommonData->ChargingRate = prices;
+            pSysConfig->BillingData.isBilling = YES;
             for (j = 0; j < 24; j++) {
                 pSysConfig->BillingData.Fee[j] = prices;
             }
@@ -953,7 +953,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
         case MISC_CMD_RFIDCARD_ENDIAN:
             if (pSysConfig->RfidCardNumEndian != value) {
                 pSysConfig->RfidCardNumEndian = value;
-                log_info("Set RFID CARD %s endian", value ? "Little" : "Big");
+                log_info("Set RFID CARD %s endian", value ? "Big" : "Little");
             }
             break;
         default:
@@ -1958,7 +1958,6 @@ static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id)
         strncpy((char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode,
                 "",
                 sizeof(ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode));
-
         strncpy(&vendorErrorCodeTmp[plugNum][0], "", WARNING_CODE_SIZE);
     } else if ((pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EVSE) ||
                (pDcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0) ||
@@ -1968,9 +1967,28 @@ static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id)
         pConnState->State = CONN_ST_CHARGING;    //charging
     } else if (pDcChargingInfo->SystemStatus == S_TERMINATING ||
             pDcChargingInfo->SystemStatus == S_COMPLETE) {
+        if (pSysConfig->ModelName[3] == 'P') {
+            if (!ShmDcCommonData->pGunInfo[plugNum].isMeterStop) {
+                return FAIL;
+            }
+        } else {
+            if (pDcChargingInfo->RelayK1K2Status == YES) {
+                return FAIL;
+            }
+        }
         pConnState->State = CONN_ST_TERMINATING;    //terminating
+
     } else if ((pDcChargingInfo->SystemStatus == S_ALARM) ||
                (pDcChargingInfo->SystemStatus == S_FAULT)) {
+        if (pSysConfig->ModelName[3] == 'P') {
+            if (!ShmDcCommonData->pGunInfo[plugNum].isMeterStop && pDcChargingInfo->SystemStatus == S_ALARM) {
+                return FAIL;
+            }
+        } else {
+            if (pDcChargingInfo->RelayK1K2Status == YES && pDcChargingInfo->SystemStatus == S_ALARM) {
+                return FAIL;
+            }
+        }
         pConnState->State = CONN_ST_ALARM;
         strncpy((char *)pConnState->WarningCode,
                 (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode,
@@ -1985,7 +2003,7 @@ static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id)
             log_info("1 ID = %d, VendorErrorCode = %s",
                      plugNum,
                      (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode);
-                     */
+            */
         } else {
             if (strncmp(&vendorErrorCodeTmp[plugNum][0],
                         (char *)ShmOCPP16Data->StatusNotification[plugNum].VendorErrorCode,
@@ -2003,9 +2021,16 @@ static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id)
             }
         }
     }
+    if (gunstatus[plugNum] != pConnState->State) {
+        log_info("Gun%d Status[%d] to OCPP Backend",plugNum,pConnState->State);
+        gunstatus[plugNum] = pConnState->State;
+    }
+
 #ifdef DD360
-    memcpy((char*)&_consumption, (char*)&ShmDcCommonData->pGunInfo[plugNum].PowerConsumption, sizeof(float));
-    pConnState->consumption = ntohl(_consumption);
+
+        memcpy((char*)&_consumption, (char*)&ShmDcCommonData->pGunInfo[plugNum].PowerConsumption, sizeof(float));
+        pConnState->consumption = ntohl(_consumption);
+
 #endif
     ret = composeSocketData(fd,
                             id,
@@ -2016,6 +2041,92 @@ static int writeConnectorState(int fd, uint8_t plugNum, uint8_t id)
     return ret;
 }
 
+/**
+ *
+ * @param data
+ * @param length
+ * @return
+ */
+uint32_t crc32(uint8_t *data, uint32_t length)
+{
+	uint32_t crc=0xFFFFFFFF;
+
+	for(size_t i=0;i<length;i++)
+	{
+		char ch=data[i];
+		for(size_t j=0;j<8;j++)
+		{
+			uint32_t b=(ch^crc)&1;
+
+			crc>>=1;
+
+			if(b) crc=crc^0xEDB88320;
+
+			ch>>=1;
+		}
+	}
+
+	return ~crc;
+}
+
+/**
+ *
+ * @param filename
+ * @return
+ */
+uint32_t getFileCrc32(char *filename)
+{
+	uint32_t result = 0;
+
+	int fd = open(filename, O_RDONLY);
+    if(fd < 0)
+    {
+        log_error("Can not open file %s\n", filename);
+    }
+    else
+    {
+    	struct stat st;
+		stat(filename, &st);
+		uint8_t *data;
+		data = malloc(st.st_size);
+
+		if(read(fd,data,st.st_size) == st.st_size)
+		{
+			result = crc32(data, st.st_size);
+			close(fd);
+		} else {
+			log_error("Read file Error %d\n", st.st_size);
+		}
+
+		free(data);
+    }
+
+	return result;
+}
+static int wrtieOcmpInfo(int fd, uint8_t plugNum, uint8_t id)
+{
+    int ret = PASS;
+    uint8_t dataBuf[241];
+
+    OcmfInfoData* pOcmf = (OcmfInfoData*)dataBuf;
+    pOcmf->CRC = htonl(getFileCrc32(ShmDcCommonData->pGunInfo[plugNum].OcmfFileName));
+    if (pOcmf->CRC == 0) {
+        log_info("CRC is Zero! Not transmit to Cabinet");
+        return FAIL;
+    }
+    //memcpy((char*)pOcmf->TxId,pSysInfo->DcMeterReadTransactionRecord[plugNum].head.transactionId,sizeof(pSysInfo->DcMeterReadTransactionRecord[plugNum].head.transactionId));
+    sprintf((char*)pOcmf->TxId,"%d",ShmDcCommonData->ocmfTridRecord[plugNum]);
+
+    memcpy((char*)pOcmf->OcmfPublicKey, (char*)pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf,sizeof(pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf));
+    log_info("txid:[%s], crc:[%X], publicKey:[%s]",pOcmf->TxId,htonl(pOcmf->CRC),pSysInfo->DcMeterStatusInfo[plugNum].publicKeyOcmf);
+    ret = composeSocketData(fd,
+                        id,
+                        OP_WRITE_DATA,
+                        REG_OCMF_INFO,
+                        sizeof(dataBuf) - 1,
+                        &dataBuf[0]);
+    return ret;
+}
 static int writePlugInStatus(int fd, uint8_t plugNum, uint8_t id)
 {
     int ret = PASS;
@@ -2053,6 +2164,12 @@ static int writeChargingTarget(int fd, uint8_t plugNum, uint8_t id)
     uint8_t dataBuf[4] = {0};
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
 
+    if ((pDcChargingInfo->SystemStatus <= S_PREPARING_FOR_EV || pDcChargingInfo->SystemStatus >= S_TERMINATING) &&
+        pDcChargingInfo->SystemStatus != S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus != S_CCS_PRECHARGE_ST1) {
+        pDcChargingInfo->EvBatterytargetVoltage = 0;
+        pDcChargingInfo->EvBatterytargetCurrent = 0;
+    }
+
     ChargingVolt = pDcChargingInfo->EvBatterytargetVoltage;
     ChargingAmp = pDcChargingInfo->EvBatterytargetCurrent;
     ChargingVolt *= 10;
@@ -2462,6 +2579,25 @@ static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg
                 writeConnectorState(fd, plugNum, gunID);
                 ftime(&gRegTimeUp[plugNum][curReg]);
             }
+            curReg = REG_OCMF_INFO;
+            break;
+        case REG_OCMF_INFO:
+            if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME ||
+                    DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) {
+                if (ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq) {
+                    if (wrtieOcmpInfo(fd,plugNum,gunID) == PASS) {
+                        DB_Upload_ocmf(plugNum,ShmDcCommonData->ocmfTridRecord[plugNum]);
+                        ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq = FALSE;
+                        char cmd[500];
+                        sprintf(cmd,"rm -f %s",ShmDcCommonData->pGunInfo[plugNum].OcmfFileName);
+                        system(cmd);
+                        ShmDcCommonData->ocmfTridRecord[plugNum] = 0;
+                    } else {
+                        ShmDcCommonData->pGunInfo[plugNum].SendOcmfDataReq = FALSE;
+                    }
+                }
+                ftime(&gRegTimeUp[plugNum][curReg]);
+            }
             curReg = REG_DISPENSER_REQUEST;
             break;
         case REG_DISPENSER_REQUEST:

+ 7 - 0
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h

@@ -100,6 +100,7 @@
 #define REG_POWER_CONSUMPTION_INFO              0x24
 #define REG_READ_CHARGING_TIMESTAMP             0x25
 
+#define REG_OCMF_INFO                           0x29
 //------------------------------------------------------------------------------
 //--- dispenser result ---
 //------------------------------------------------------------------------------
@@ -245,6 +246,12 @@ typedef struct StDoCommGlobalVar {
     uint8_t Reserved[2];
 } DoCommGblData;
 
+typedef struct StOcmfInfoData {
+    uint8_t TxId[36];
+    unsigned int CRC;
+    uint8_t OcmfPublicKey[200];
+} OcmfInfoData;
+
 typedef struct StCommnadHead {
     uint8_t SeqNum;     //sequence number 0 ~ 255
     uint8_t ID;         //0: Reserved, 0x01 ~ 0xFE: connector ID, 0xFF: exists in register 1 and register 2

+ 2 - 1
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCCS.c

@@ -756,11 +756,12 @@ void ClearAbnormalStatus_CCS(uint8_t gun_index)
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
             if (index != gun_index || pSysConfig->TotalConnectorCount == 1) {
+                /*
                 log_info("CCS clean error : index = %d, EvConnAlarmCode = %s, code = %s \n",
                          index,
                          pDcChargingInfo->EvConnAlarmCode,
                          code);
-
+                */
                 if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, code, 6) != EQUAL) {
 
                     if (strncmp(code, "012219", 6) == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = NO; }

+ 2 - 1
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCHA.c

@@ -200,11 +200,12 @@ void ClearAbnormalStatus_Chademo(uint8_t gun_index)
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
 
             if (index != gun_index || pSysConfig->TotalConnectorCount == 1) {
+                /*
                 log_info("CHA clean error : index = %d, EvConnAlarmCode = %s, code = %s \n",
                          index,
                          pDcChargingInfo->EvConnAlarmCode,
                          code);
-
+                */
                 if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, code, 6) != EQUAL) {
                     if (strncmp(code, "023700", 6) == EQUAL) { pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO; }
                     if (strncmp(code, "023704", 6) == EQUAL) { pInfoCode->InfoEvents.bits.ChademoBatteryMalfun = NO; }

+ 2 - 1
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalGBT.c

@@ -340,11 +340,12 @@ void ClearAbnormalStatus_GB(uint8_t gun_index)
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
 
             if (index != gun_index || pSysConfig->TotalConnectorCount == 1) {
+                /*
                 log_info("GBT clean error : index = %d, EvConnAlarmCode = %s, code = %s \n",
                          index,
                          pDcChargingInfo->EvConnAlarmCode,
                          code);
-
+                */
                 if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, code, 6) != EQUAL) {
                     if (strncmp(code, "023702", 6) == EQUAL) { pInfoCode->InfoEvents.bits.GbEvCommFail = NO; }
                     if (strncmp(code, "023900", 6) == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = NO; }

+ 5 - 1
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c

@@ -37,7 +37,11 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
         return true;
     }
-
+    if (pDcChargingInfo->SystemStatus == S_TERMINATING || pDcChargingInfo->SystemStatus == S_COMPLETE ||
+        pDcChargingInfo->SystemStatus == S_ALARM) {
+            // 結束充電後不顯示小板錯誤Status Code
+            return true;
+    }
     memcpy(pDcChargingInfo->EvConnAlarmCode, string, 6);
     log_info("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s\n", pDcChargingInfo->EvConnAlarmCode);
 

+ 36 - 24
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -244,10 +244,10 @@ void CheckEvConnect(int gunIndex)
 
     if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) {
         isSameType = TRUE;
-        isDisconnect = ShmDcCommonData->pGunInfo[0].EVLoseFlag | ShmDcCommonData->pGunInfo[1].EVLoseFlag;
+        isDisconnect = ShmDcCommonData->pGunStatus[0].EVLoseFlag | ShmDcCommonData->pGunStatus[1].EVLoseFlag;
         gunType = pDcChargingInfo_0->Type;
     } else {
-        isDisconnect = ShmDcCommonData->pGunInfo[gunIndex].EVLoseFlag;
+        isDisconnect = ShmDcCommonData->pGunStatus[gunIndex].EVLoseFlag;
         gunType = pDcChargingInfo->Type;
     }
 
@@ -304,7 +304,7 @@ void CANReceiver(int fd)
         uint8_t printConnTemp = NO;
         uint8_t chillerTemp[2] = {0, 0};
         uint8_t maxChillerTemp = 0;
-        uint8_t lastChillerTemp = 0;
+        uint8_t lastChillerTemp[2] = {0};
         uint8_t maxConnTemp = 0;
         uint8_t lastConnTemp[2] = {0, 0};
         struct can_frame frame;
@@ -328,8 +328,8 @@ void CANReceiver(int fd)
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
 
-        ShmDcCommonData->pGunInfo[0].EVLoseTimer = time((time_t*)NULL);
-        ShmDcCommonData->pGunInfo[1].EVLoseTimer = time((time_t*)NULL);
+        ShmDcCommonData->pGunStatus[0].EVLoseTimer = time((time_t*)NULL);
+        ShmDcCommonData->pGunStatus[1].EVLoseTimer = time((time_t*)NULL);
 
         //log_info("Module_EvRXComm Child's PID is %d", getpid());
         CCS_PlugoutTimer[0] = time((time_t*)NULL);
@@ -341,23 +341,23 @@ void CANReceiver(int fd)
                 pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
                 // 檢查是否有收到EV小板訊號
                 if (pSysInfo->SelfTestSeq == _STEST_COMPLETE) {
-                    if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[_index].EVLoseTimer > 5) &&
-                        !ShmDcCommonData->pGunInfo[_index].EVLoseFlag &&
+                    if ((time((time_t*)NULL) - ShmDcCommonData->pGunStatus[_index].EVLoseTimer > 10) &&
+                        !ShmDcCommonData->pGunStatus[_index].EVLoseFlag && pSysInfo->SelfTestSeq == _STEST_COMPLETE &&
                         pDcChargingInfo->SystemStatus != S_UPDATE && !ShmDcCommonData->debugflag) {
 
-                        ShmDcCommonData->pGunInfo[_index].EVLoseTimer = time((time_t*)NULL);
-                        ShmDcCommonData->pGunInfo[_index].EVLoseFlag = TRUE;
+                        ShmDcCommonData->pGunStatus[_index].EVLoseTimer = time((time_t*)NULL);
+                        ShmDcCommonData->pGunStatus[_index].EVLoseFlag = TRUE;
 
                         system("/sbin/ip link set can0 down");
                         sleep(1);
                         system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
                         system("/sbin/ip link set can0 up");
                     }
-                    CheckEvConnect(_index);
                 } else {
-                    ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
-                    ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
+                    ShmDcCommonData->pGunStatus[targetGun].EVLoseTimer = time((time_t*)NULL);
+                    ShmDcCommonData->pGunStatus[targetGun].EVLoseFlag = FALSE;
                 }
+                CheckEvConnect(_index);
             }
 
             nbytes = read(fd, &frame, sizeof(struct can_frame));
@@ -422,8 +422,8 @@ void CANReceiver(int fd)
                 continue;
             }
             // Reset Connect Timer
-            ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
-            ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
+            ShmDcCommonData->pGunStatus[targetGun].EVLoseTimer = time((time_t*)NULL);
+            ShmDcCommonData->pGunStatus[targetGun].EVLoseFlag = FALSE;
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun);
             gunTypeIndex = pDcChargingInfo->type_index;
@@ -523,7 +523,8 @@ void CANReceiver(int fd)
                 //DS60-120 add
 
                 if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EV &&
-                        pDcChargingInfo->SystemStatus <= S_CHARGING) ||
+                        pDcChargingInfo->SystemStatus <= S_TERMINATING) ||
+                        pDcChargingInfo->SystemStatus == S_ALARM ||
                         (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                          pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)
                    ) {
@@ -540,9 +541,10 @@ void CANReceiver(int fd)
                         GunStatus[targetGun] = pDcChargingInfo->SystemStatus;
                     }
 
-                    if (frame.data[1] > pDcChargingInfo->EvBatterySoc) {
+                    if (frame.data[1] > pDcChargingInfo->EvBatterySoc || pDcChargingInfo->SystemStatus == S_CHARGING) {
                         pDcChargingInfo->EvBatterySoc = frame.data[1];
-                        log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc);
+                        if (frame.data[1] > pDcChargingInfo->EvBatterySoc)
+                            log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc);
                     }
                 }
                 //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove
@@ -663,26 +665,36 @@ void CANReceiver(int fd)
                     memcpy((char *)ShmDcCommonData->SystemTemp, (char *)chiilerTemp.Temp, sizeof(ChillerTemp));
                     chillerTemp[0] = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]);
                     chillerTemp[1] = getMaxConnectTemp(chiilerTemp.Temp[2], chiilerTemp.Temp[3]);
-
-                    maxChillerTemp = getMaxConnectTemp(chillerTemp[0], chillerTemp[1]);
-
+                    if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
+                        // 單Chiller
+                        maxChillerTemp = getMaxConnectTemp(chillerTemp[0], chillerTemp[1]);
+                    } else {
+                        // 雙Chiller
+                        if (gunTypeIndex == 0) {
+                            maxChillerTemp = chillerTemp[0];
+                        } else {
+                            maxChillerTemp = chillerTemp[1];
+                        }
+                    }
                     //if ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) {
                     //    printChillerTemp = YES;
                     //}
-                    if(maxChillerTemp > (lastChillerTemp + 2) || maxChillerTemp < (lastChillerTemp - 2))
+                    if(maxChillerTemp > (lastChillerTemp[gunTypeIndex] + 2) || maxChillerTemp < (lastChillerTemp[gunTypeIndex] - 2))
                     {
-                        lastChillerTemp = maxChillerTemp;
+                        lastChillerTemp[gunTypeIndex] = maxChillerTemp;
                         printChillerTemp = YES;
                     }
 
                     pDcChargingInfo->ChillerTemp = maxChillerTemp;
                 }
-                if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
+                if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 || ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
                     maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]);
                     //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
                     //    printConnTemp = YES;
                     //}
-                    maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
+                    if (maxConnTemp != UNDEFINED_TEMP)
+                        maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
+                    
                     if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
                     {
                         lastConnTemp[targetGun] = maxConnTemp;

+ 93 - 4
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -37,6 +37,7 @@ static struct GBTData *ShmGBTData = NULL;
 static struct CcsData *ShmCcsData = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
 static SelectGunInfo *ShmSelectGunInfo = NULL;
+struct MeterInformation *ShmCsuMeterData = NULL;
 
 // 限制最大充電電壓,因應不同 type 槍線來限制
 // Chademo : 500V, 125A,
@@ -50,7 +51,7 @@ static float maxChargingVol[2] = {0, 0};       // 限制最大充電電壓,如
 // 限制最大充電電流與能量透過 Web
 static float maxChargingCur[2] = {0, 0};         // 限制最大充電電流,如依照模塊則填上 0
 static float maxChargingPow = 0;                   // 限制最大充電能量,如依照模塊則填上 0
-
+int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 static float LogInfo[2][10]; //DS60-120 add
 static int CanFd = -1;
 
@@ -747,6 +748,83 @@ static int DiffTimeb(struct timeb ST, struct timeb ET)
     return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm;
 }
 
+void CalOutputPowerAndEnergy(int _index)
+{
+    struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
+    ShmCsuMeterData = (struct MeterInformation *)GetShmCsuMeterData();
+    
+    if (pSysConfig->ModelName[3] == 'P')
+	{
+		// DC Meter
+		if (ShmDcCommonData->pGunInfo[_index].curMeterValue == 0) {
+				ShmDcCommonData->pGunInfo[_index].curMeterValue = pSysInfo->DcMeterInfo[_index].totlizeImportEnergy;
+        } else
+		{
+			if (pSysInfo->DcMeterInfo[_index].totlizeImportEnergy >= ShmDcCommonData->pGunInfo[_index].curMeterValue)
+			{
+				ShmDcCommonData->pGunInfo[_index]._curTotalCharging += (pSysInfo->DcMeterInfo[_index].totlizeImportEnergy - ShmDcCommonData->pGunInfo[_index].curMeterValue);
+				float totalChargingValue = (float)ShmDcCommonData->pGunInfo[_index]._curTotalCharging;
+
+                ShmDcCommonData->pGunInfo[_index].curMeterValue = pSysInfo->DcMeterInfo[_index].totlizeImportEnergy;
+
+				if (totalChargingValue > pDcChargingInfo->PresentChargedEnergy)
+				{
+					ShmDcCommonData->energy_time_period[_index][ShmDcCommonData->_hour_index] += totalChargingValue - pDcChargingInfo->PresentChargedEnergy;
+					pDcChargingInfo->presentChargedEnergyPeriod[ShmDcCommonData->_hour_index] += totalChargingValue - pDcChargingInfo->PresentChargedEnergy;
+				}
+                
+                if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+				    pDcChargingInfo->PresentChargedEnergy = totalChargingValue;
+                    ShmDcCommonData->pGunInfo[_index].PowerConsumption += totalChargingValue;
+                } else {
+                    pDcChargingInfo->PresentChargedEnergy = (float ) pSysInfo->DcMeterTransactionResult[_index].energyImport;
+                    if (pSysInfo->DcMeterTransactionAction[_index].OcmfInfoReady) {
+                        ShmDcCommonData->pGunInfo[_index].PowerConsumption = (float ) pSysInfo->DcMeterTransactionResult[_index].energyImportTotalStop;
+                        ShmDcCommonData->pGunInfo[_index].isMeterStop = TRUE;
+                    }
+                }
+               //pDcChargingInfo->PresentChargedEnergy = totalChargingValue;
+				if (pSysConfig->BillingData.isBilling)
+				{
+					if(strcmp((char *)pSysConfig->OcppServerURL, "") == EQUAL ||
+						strcmp((char *)pSysConfig->ChargeBoxId, "") == EQUAL)
+						pDcChargingInfo->ChargingFee = totalChargingValue * pSysConfig->BillingData.Cur_fee;
+				}
+			}
+		}
+	}
+	else
+	{
+		if (chargingTime[_index] == 0 ||
+			chargingTime[_index] > pDcChargingInfo->PresentChargedDuration)
+		{
+			chargingTime[_index] = pDcChargingInfo->PresentChargedDuration;
+		}
+		else
+		{
+			int passTime = pDcChargingInfo->PresentChargedDuration - chargingTime[_index];
+
+			if (passTime > 0)
+			{
+				float changingPow = (pDcChargingInfo->PresentChargingPower) * passTime / 3600;
+				if (pSysConfig->BillingData.isBilling)
+				{
+					ShmDcCommonData->energy_time_period[_index][ShmDcCommonData->_hour_index] += changingPow;
+					pDcChargingInfo->presentChargedEnergyPeriod[ShmDcCommonData->_hour_index] += changingPow;
+					if(strcmp((char *)pSysConfig->OcppServerURL, "") == EQUAL ||
+						strcmp((char *)pSysConfig->ChargeBoxId, "") == EQUAL)
+					pDcChargingInfo->ChargingFee += changingPow * pSysConfig->BillingData.Cur_fee;
+				}
+
+				pDcChargingInfo->PowerConsumption += changingPow;
+                ShmDcCommonData->pGunInfo[_index].PowerConsumption += changingPow;
+				pDcChargingInfo->PresentChargedEnergy += changingPow;
+				chargingTime[_index] = pDcChargingInfo->PresentChargedDuration;
+			}
+		}
+	}
+}
+
 int main(int argc, char *argv[])
 {
     bool chkChademoPermission[2] = {false};
@@ -784,7 +862,7 @@ int main(int argc, char *argv[])
     ShmGBTData = (struct GBTData *)GetShmGBTData();
     ShmCcsData = (struct CcsData *)GetShmCcsData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
-
+    ShmCsuMeterData = (struct MeterInformation *)GetShmCsuMeterData();
     CanFd = InitCanBus();
 
     FormatVoltageAndCurrent();
@@ -933,7 +1011,11 @@ int main(int argc, char *argv[])
                     //maxChargingPow = (pSysConfig->MaxChargingPower * 10);
                     //DS60-120 add
                     SendErrorCount[gunIndex] = 0;
-
+                    if (pSysConfig->ModelName[3] == 'P') {
+                        ShmCsuMeterData->_meter[gunIndex].curMeterValue = 0;
+                        ShmCsuMeterData->_meter[gunIndex]._chargingValue = 0;
+                        ShmCsuMeterData->_meter[gunIndex]._curTotalCharging = 0;
+                    }
                     //maxChargingPow = pSysConfig->MaxChargingPower * 10;
                     // ShmPsuData->SystemAvailablePower 已是 * 10
                     //maxChargingPow = ShmPsuData->SystemAvailablePower;
@@ -996,7 +1078,7 @@ int main(int argc, char *argv[])
 
                     pDcChargingInfo->RealMaxVoltage = maxVol;
 
-                    SetChargingPermission(gunIndex,
+                    SetChargingPermission(gunIndex, 
                                           START,
                                           pDcChargingInfo->AvailableChargingPower,
                                           maxCur,
@@ -1105,6 +1187,8 @@ int main(int argc, char *argv[])
                     ((float)((pDcChargingInfo->PresentChargingVoltage) *
                              (pDcChargingInfo->PresentChargingCurrent)) / 1000);
 
+                CalOutputPowerAndEnergy(gunIndex);
+                /*
                 //DS60-120 remove
                 if (chargingTime[gunIndex] == 0 ||
                         chargingTime[gunIndex] > pDcChargingInfo->PresentChargedDuration) {
@@ -1126,6 +1210,7 @@ int main(int argc, char *argv[])
                     }
                     
                 }
+                */
 
                 // 開始確認車端是否同意開始充電
                 GetOutputReq(gunIndex, pDcChargingInfo->Evboard_id);
@@ -1168,6 +1253,8 @@ int main(int argc, char *argv[])
 
             case S_ALARM:
             case S_TERMINATING:
+                CalOutputPowerAndEnergy(gunIndex);
+
                 // 設定當前輸出
                 setCurrentOutput();
                 SetPresentChargingOutputPower();
@@ -1220,6 +1307,8 @@ int main(int argc, char *argv[])
                 // 設定當前輸出
                 SetPresentChargingOutputPower();
 
+                CalOutputPowerAndEnergy(gunIndex);
+
                 if (priorityLow == 1) {
                     // 樁端輸出能力
                     maxVol = pDcChargingInfo->MaximumChargingVoltage;

+ 27 - 9
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c

@@ -1155,6 +1155,14 @@ void GetFwAndHwVersion_Relay(void)
         // SystemInfo
         strcpy((char *)pSysInfo->RelayModuleFwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Relay s1 = %s ", ver.Version_FW);
+
+        if ((strlen((char *)pSysInfo->RelayModuleFwRev) != 0 ||
+                pSysInfo->RelayModuleFwRev[0] != '\0') &&
+                (ShmRelayModuleData->SelfTest_Comp != YES)
+            ) {
+            //log_info("Relay Board FW Rev = %s", pSysInfo->RelayModuleFwRev);
+            ShmRelayModuleData->SelfTest_Comp = YES;
+        }
     }
 
     if (Query_HW_Ver(Uart5Fd, ADDR_RELAY, &ver) == PASS) {
@@ -1397,6 +1405,13 @@ static void GetFwAndHwVersion_Fan(void)
         // SystemInfo
         strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
         //log_info("GetFwAndHwVersion_Fan s1 = %s ", ver.Version_FW);
+        if ((strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
+                pSysInfo->FanModuleFwRev[0] != '\0') &&
+                (ShmFanModuleData->SelfTest_Comp != YES)
+            ) {
+            //log_info("Fan Board FW Rev = %s", pSysInfo->FanModuleFwRev);
+            ShmFanModuleData->SelfTest_Comp = YES;
+        }
     }
 
     if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
@@ -1512,7 +1527,7 @@ static void SetLedColor(void)
     //printf("chargingData_1->SystemStatus=%d\n",chargingData_1->SystemStatus);
     //printf("chargingData_2->SystemStatus=%d\n",chargingData_2->SystemStatus);
     //printf("pSysWarning->Level=%d\n",pSysWarning->Level);
-    if (pSysWarning->Level == 2) {
+    if (pSysWarning->Level == 2 || pSysInfo->SelfTestSeq != _STEST_COMPLETE) {
         led_color.Connect_1_Green = COLOR_MIN_LV;
         led_color.Connect_1_Blue = COLOR_MIN_LV;
         led_color.Connect_1_Red = _colorBuf;
@@ -1556,7 +1571,9 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = _colorBuf;
                 led_color.Connect_2_Red = COLOR_MIN_LV;
-            } else if ( chargingData_1->SystemStatus == S_UPDATE ) {
+            } else if ( chargingData_1->SystemStatus == S_UPDATE ||
+                        chargingData_1->SystemStatus == S_FAULT ||
+                        chargingData_1->SystemStatus == S_MAINTAIN) {
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
@@ -1578,8 +1595,7 @@ static void SetLedColor(void)
         } else {
             //實際操作
             if (chargingData_1->SystemStatus == S_BOOTING ||
-                    chargingData_1->SystemStatus == S_IDLE ||
-                    chargingData_1->SystemStatus == S_MAINTAIN) {
+                    chargingData_1->SystemStatus == S_IDLE) {
 
                 if (chargingData_1->IsAvailable == NO) { //For Audi
                     led_color.Connect_1_Green = COLOR_MIN_LV;
@@ -1603,7 +1619,9 @@ static void SetLedColor(void)
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = _colorBuf;
                 led_color.Connect_1_Red = COLOR_MIN_LV;
-            }else if ( chargingData_1->SystemStatus == S_UPDATE ) {
+            }else if ( chargingData_1->SystemStatus == S_UPDATE ||
+                chargingData_1->SystemStatus == S_FAULT ||
+                    chargingData_1->SystemStatus == S_MAINTAIN) {
                 led_color.Connect_1_Green = COLOR_MIN_LV;
                 led_color.Connect_1_Blue = COLOR_MIN_LV;
                 led_color.Connect_1_Red = _colorBuf;
@@ -1617,11 +1635,9 @@ static void SetLedColor(void)
                 led_color.Connect_1_Red = COLOR_MIN_LV;
             }
 
-
             // --------------------------------------------------------------------------
             if (chargingData_2->SystemStatus == S_BOOTING ||
-                    chargingData_2->SystemStatus == S_IDLE ||
-                    chargingData_2->SystemStatus == S_MAINTAIN) {
+                    chargingData_2->SystemStatus == S_IDLE) {
                 if (chargingData_2->IsAvailable == NO) {
                     led_color.Connect_2_Green = COLOR_MIN_LV;
                     led_color.Connect_2_Blue = COLOR_MIN_LV;
@@ -1644,7 +1660,9 @@ static void SetLedColor(void)
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = _colorBuf;
                 led_color.Connect_2_Red = COLOR_MIN_LV;
-            }else if ( chargingData_2->SystemStatus == S_UPDATE ) {
+            }else if ( chargingData_2->SystemStatus == S_UPDATE ||
+                    chargingData_2->SystemStatus == S_FAULT ||
+                    chargingData_2->SystemStatus == S_MAINTAIN) {
                 led_color.Connect_2_Green = COLOR_MIN_LV;
                 led_color.Connect_2_Blue = COLOR_MIN_LV;
                 led_color.Connect_2_Red = _colorBuf;

+ 54 - 28
EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -1757,15 +1757,31 @@ void ProcessPageInfo()
     struct InfoCodeData *pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData();
     struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
 
+    bool isCharging = false;
+    for (uint8_t i = 0; i < _totalCount; i++) {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+
+        if (pDcChargingInfo->SystemStatus == S_IDLE) {
+            continue;
+        }
+
+        isCharging = true;
+        break;
+    }
+
     // 隨插即充 - 可省略該按鈕 //DS60-120 add
-    if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) {
+    //if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) {
         ChangeDisplay2Value(__ret_home_btn, _back_home_btn);
-        if (_totalCount >= 2 && pSysInfo->IsAlternatvieConf == NO) {
+#if defined DD360Audi
+        if (_totalCount >= 2) {
+#else
+        if (_totalCount >= 2 && isCharging /*&& pSysInfo->IsAlternatvieConf == NO*/) {
+#endif
             ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
         } else {
             ChangeDisplay2Value(__sel_gun_btn, _disappear);
         }
-    }
+    //}
     showPhihongLogo(false);
     // Show Time
     ShowDateTime();
@@ -1781,6 +1797,7 @@ void ProcessPageInfo()
             ChangeDisplay2Value(__right_gun_map, _right_gun_enable_map);
         }
         ChangeDisplay2Value(__add_chk_btn, _select_gun_btn);
+        ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
         break;
 #endif //defined DD360Audi
 
@@ -1815,7 +1832,7 @@ void ProcessPageInfo()
         if (pSysConfig->isQRCode) {
             needReloadQr = false;
             ChangeQrCode_Idle((char*)ShmDcCommonData->QRCodeString);
-            /*
+            
             if (pSysConfig->QRCodeMadeMode == NO) {
                 //uint8_t len = strlen((char *)pSysConfig->SystemId);
                 ChangeQrCode_Idle((char *)pSysConfig->SystemId);
@@ -1824,7 +1841,7 @@ void ProcessPageInfo()
                 ChangeQrCode_Idle((char *)pSysConfig->QRCodeContent);
             }
             //ChangeQrCode_Idle((char *)pSysConfig->SystemId);
-            */
+            
         }
         //}
 
@@ -1840,11 +1857,15 @@ void ProcessPageInfo()
             isCharging = true;
             break;
         }
-        if (isCharging && pSysInfo->IsAlternatvieConf == NO) {
-            ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
-        } else {
-            ChangeDisplay2Value(__sel_gun_btn, _disappear);
-        }
+        //if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) {
+            if (isCharging && _totalCount >= 2/*&& pSysInfo->IsAlternatvieConf == NO*/) {
+                ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
+            } else {
+                ChangeDisplay2Value(__sel_gun_btn, _disappear);
+            }
+        //} else {
+        //    ChangeDisplay2Value(__sel_gun_btn, _disappear);
+        //}
     }
     break;
     case _LCM_AUTHORIZING:
@@ -1870,23 +1891,21 @@ void ProcessPageInfo()
         if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) {
             // 新增隨插即充功能預設在等待插槍頁面在開啟
             ChangeDisplay2Value(__ret_home_btn, _disappear);
-            bool isCharging = false;
-            for (uint8_t i = 0; i < _totalCount; i++) {
-                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
-
-                if (pDcChargingInfo->SystemStatus == S_IDLE) {
-                    continue;
-                }
+        }
+        bool isCharging = false;
+        for (uint8_t i = 0; i < _totalCount; i++) {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-                isCharging = true;
-                break;
+            if (pDcChargingInfo->SystemStatus == S_IDLE) {
+                continue;
             }
 
-            if (isCharging && pSysInfo->IsAlternatvieConf == NO) {
-                ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
-            } else {
-                ChangeDisplay2Value(__sel_gun_btn, _disappear);
-            }
+            isCharging = true;
+            break;
+        }
+
+        if (isCharging && _totalCount >= 2/*&& pSysInfo->IsAlternatvieConf == NO*/) {
+            ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
         } else {
             ChangeDisplay2Value(__sel_gun_btn, _disappear);
         }
@@ -1993,7 +2012,7 @@ void ProcessPageInfo()
             }
         }
 
-        ChangeDisplay2Value(__money_by_rate, _disappear);
+        //ChangeDisplay2Value(__money_by_rate, _disappear);
 
         gunTargetIndex = 0; //DS60-120 add
         for (uint8_t i = 0; i < _totalCount; i++) {
@@ -2152,6 +2171,7 @@ void ProcessPageInfo()
                         }
                     }
                     /////////////////////// CTEP Add ///////////////////////
+#if defined DD360
                     if (strlen((char*)ShmDcCommonData->pGunInfo[i].ReceiptInfo) > 0) {
                         DisplayReceipt(ShmDcCommonData->pGunInfo[i].ReceiptInfo);
                         ChangeDisplay2Value(__receipt_backgroud, _receipt_bk);
@@ -2159,6 +2179,7 @@ void ProcessPageInfo()
                         DisplayReceipt("");
                         ChangeDisplay2Value(__receipt_backgroud, _disappear);
                     }
+#endif 
                     // EnergyCost
                     ChangeEnergyCostValue(ShmSelectGunInfo->PricesInfo[i].EnergyCost, _currentPage);
                     // Parking Fee
@@ -2242,7 +2263,7 @@ void ProcessPageInfo()
             break;
         }
         // For Network Disconnect
-        for (i = 0; i < pSysWarning->WarningCount; i++) {
+        for (int i = 0; i < pSysWarning->WarningCount; i++) {
             if (memcmp(&pSysWarning->WarningCode[i][0], "012304", 6) == 0 || 
                 memcmp(&pSysWarning->WarningCode[i][0], "042304", 6) == 0) {
                 ChangeToOtherPage(_LCM_DISCONNECT);
@@ -2279,10 +2300,15 @@ void ChangeDisplayMoneyInfo()
 #endif //defined DD360Audi
 
             pSysConfig->BillingData.Cur_fee = pSysConfig->BillingData.Fee[tmCSU->tm_hour];
+
+#if defined DD360Audi
+            if (tmCSU->tm_hour <= 23) {
+                DisplayMoneyRate(pSysConfig->BillingData.Cur_fee);
+            }
+#else
             ChangeDisplay2Value(__money_by_rate, _disappear);
             ShowAnimationPrice(ShmDcCommonData->DefaultPriceString);
-
-
+#endif
             if (pSysConfig->BillingData.Currency <= 53) {
                 DisplayMoneyCur((uint8_t *)GetCurrency(pSysConfig->BillingData.Currency));
             }

+ 169 - 29
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -53,12 +53,14 @@ uint8_t EmgBtn_count = 0;
 uint8_t Door_count = 0;
 uint8_t EmgBtn_flag = 0;
 uint8_t Door_flag = 0;
-
-
+bool _isNeedChkTilt = FALSE;
+struct timespec _tilt_time;
+uint8_t tilt = NO;
+bool _chargeSwitch;
 //================================================
 // Function
 //================================================
-void GetFwAndHwVersion(int fd)
+bool GetFwAndHwVersion(int fd)
 {
     Ver ver = {0};
 
@@ -66,8 +68,9 @@ void GetFwAndHwVersion(int fd)
         //log_info("Primary FW Rev = %s ", ver.Version_FW);
         strcpy((char *)ShmPrimaryMcuData->version, ver.Version_FW);
         strcpy((char *) pSysInfo->CsuPrimFwRev, ver.Version_FW);
+        return TRUE;
     }
-
+    return FALSE;
     //if (Query_HW_Ver(fd, OP_ADDR_IO_EXTEND, &ver) == PASS)
     //    ;//log_info("Primary HW Rev  = %s ", ver.Version_HW);
 }
@@ -85,8 +88,13 @@ void GetInputGpioStatus(int fd)
 
     ShmPrimaryMcuData->InputDet.bits.SpdDetec = gpio_in.SPD;
     //log_info("gpio_in.AC_Drop:%d", gpio_in.AC_Drop);
-    ShmPrimaryMcuData->InputDet.bits.Ac_Drop = gpio_in.AC_Drop; // Chiller Alarm ping
-
+    if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+        (strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+        (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0) ||
+        (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)
+    ) {
+        ShmPrimaryMcuData->InputDet.bits.Ac_Drop = gpio_in.AC_Drop; // Chiller Alarm ping
+    }
 #ifdef DD360ComBox
     EmgBtn_flag = 0;
 #else
@@ -134,8 +142,8 @@ void GetInputGpioStatus(int fd)
         pAlarmCode->AlarmEvents.bits.CcsLiquidChillerWaterLevelWarning = ~gpio_in.AC_Connector;
         pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault = ~gpio_in.AC_MainBreaker;
     } else {
-        pAlarmCode->AlarmEvents.bits.CcsLiquidChillerWaterLevelWarning = gpio_in.AC_Connector;
-        pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault = gpio_in.AC_MainBreaker;
+        //pAlarmCode->AlarmEvents.bits.CcsLiquidChillerWaterLevelWarning = gpio_in.AC_Connector;
+        //pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault = gpio_in.AC_MainBreaker;
     }
 
 #if defined DD360ComBox
@@ -297,12 +305,19 @@ void SetOutputGpio(int fd, uint8_t outputValue)
 
     gpio.Button_LED[0] = pLedConfig->LeftButtonLed;
     gpio.Button_LED[1] = pLedConfig->RightButtonLed;
-
+#if defined DD360ComBox
     gpio.System_LED[0] = pLedConfig->GreenLED;
     gpio.System_LED[1] = pLedConfig->YellowLED;
     gpio.System_LED[2] = pLedConfig->RedLED;
     gpio.System_LED[3] = 0x00;
-
+#else
+    if (_isNeedChkTilt) {
+        gpio.System_LED[0] = 0x00;
+        gpio.System_LED[1] = 0x00;
+        gpio.System_LED[2] = tilt;
+        gpio.System_LED[3] = tilt;
+    }
+#endif
     checkChillerStatus(&gpio);
 
     //gpio.AC_Breaker = 0x01;
@@ -388,25 +403,18 @@ int InitComPort()
     return fd;
 }
 
-unsigned long GetTimeoutValue(struct timeval _sour_time)
+int GetTimeoutValue(struct timespec *startTime)
 {
-    struct timeval _end_time;
-    gettimeofday(&_end_time, NULL);
+	struct timespec endTime;
 
-    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+	clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime);
+	return endTime.tv_sec - startTime->tv_sec;
 }
-unsigned long GetClockTimeoutValue(struct timespec _start_time)
-{
-    struct timespec ts_end;
-    unsigned long ret = 0;
 
-    clock_gettime(CLOCK_MONOTONIC, &ts_end);
-
-    ret = ((unsigned long)(ts_end.tv_sec - _start_time.tv_sec) * 1000000) + ((unsigned long)((ts_end.tv_nsec / 1000) - (_start_time.tv_nsec / 1000)));
-
-    return ret;
+void GetTimespecFunc(struct timespec *time)
+{
+	clock_gettime(CLOCK_MONOTONIC_COARSE, time);
 }
-
 static bool IsPrimaryProcessNeedPause(void)
 {
     bool _pause = false;
@@ -429,6 +437,128 @@ static bool IsPrimaryProcessNeedPause(void)
 
     return _pause;
 }
+bool CheckCustomer()
+{
+	bool result = false;
+	char _buf[3] = {0};
+
+	memcpy(_buf, &pSysConfig->ModelName[12], 2);
+	if (strcmp(_buf, "OL") == EQUAL)
+		result = true;
+	return result;
+}
+void TiltSensorSwitch(bool _switch)
+{
+	if (tilt != _switch)
+		tilt = _switch;
+
+}
+bool isChargingStatus(unsigned char status)
+{
+    if ((status >= S_REASSIGN_CHECK && status <= S_ALARM) ||
+        status == S_CCS_PRECHARGE_ST0 || status == S_CCS_PRECHARGE_ST1 ) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+void ChkTiltSensor(fd)
+{
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+    bool isCharing = NO;
+    Gpio_in gpio_in = {0};
+
+    if (Query_Gpio_Input(fd, OP_ADDR_IO_EXTEND, &gpio_in) != PASS) {
+        return;
+    }
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if (isChargingStatus(pDcChargingInfo->SystemStatus) || ShmPrimaryMcuData->SelfTest_Comp != PASS) {
+            isCharing = YES;
+        }
+    }
+
+	if (isCharing == YES)
+	{
+		if (_chargeSwitch == NO)
+		{
+			if (ShmDcCommonData->_tiltSensorStep == _TILT_SENSOR_STEP_NONE)
+			{
+				log_info("---- Tilt Sensor : _TILT_SENSOR_STEP_PIN_ON ---- ");
+				ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_PIN_ON;
+				_chargeSwitch = YES;
+			}
+		}
+		else
+		{
+			switch (ShmDcCommonData->_tiltSensorStep)
+			{
+				case _TILT_SENSOR_STEP_PIN_ON:
+				{
+					TiltSensorSwitch(YES);
+					GetTimespecFunc(&_tilt_time);
+					log_info("---- Tilt Sensor : _TILT_SENSOR_STEP_PIN_WAIT ---- ");
+					ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_PIN_WAIT;
+				}
+				break;
+				case _TILT_SENSOR_STEP_PIN_WAIT:
+				{
+					int _time = GetTimeoutValue(&_tilt_time);
+					if (_time < 0)
+						GetTimespecFunc(&_tilt_time);
+					else if (_time > 1)
+					{
+						if (gpio_in.Door_Open == NO)
+							pAlarmCode->AlarmEvents.bits.TiltSensorStestFail = YES;
+						else
+							pAlarmCode->AlarmEvents.bits.TiltSensorStestFail = NO;
+
+						if (_time > TILTSENSORDET)
+						{
+							GetTimespecFunc(&_tilt_time);
+							log_info("---- Tilt Sensor : _TILT_SENSOR_STEP_PIN_OFF ---- ");
+                            log_info("---- Tilt Sensor : _TILT_SENSOR_TEST %s ---- ",
+                                pAlarmCode->AlarmEvents.bits.TiltSensorStestFail ? "FAIL" : "PASS");
+							ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_PIN_OFF;
+						}
+					}
+				}
+                break;
+				case _TILT_SENSOR_STEP_PIN_OFF:
+				{
+					TiltSensorSwitch(NO);
+					GetTimespecFunc(&_tilt_time);
+					log_info("---- Tilt Sensor : _TILT_SENSOR_STEP_PIN_FINISH ---- ");
+					ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_PIN_FINISH;
+				}
+                break;
+				case _TILT_SENSOR_STEP_PIN_FINISH :
+				{
+					int _time = GetTimeoutValue(&_tilt_time);
+					if (_time < 0)
+						GetTimespecFunc(&_tilt_time);
+					else if (_time > TILTSENSORDET)
+					{
+						log_info("---- Tilt Sensor : _TILT_SENSOR_STEP_NONE ---- ");
+						ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_NONE;
+                        ShmPrimaryMcuData->SelfTest_Comp = PASS;
+					}
+				}
+                break;
+			}
+		}
+	}
+	else
+	{
+		TiltSensorSwitch(NO);
+		ShmDcCommonData->_tiltSensorStep = _TILT_SENSOR_STEP_NONE;
+		_chargeSwitch = NO;
+        //log_info("ShmPrimaryMcuData->SelfTest_Comp:%d",ShmPrimaryMcuData->SelfTest_Comp);
+	}
+    return;
+}
+
 
 int main(void)
 {
@@ -478,6 +608,9 @@ int main(void)
 
     //Initialization();
 
+    // 需要判斷這個的客戶碼 : OL
+	//_isNeedChkTilt = CheckCustomer();
+
     for (;;) {
         // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
         // 模組更新 FW 後,需重新做
@@ -488,16 +621,23 @@ int main(void)
         }
         if (ShmPrimaryMcuData->SelfTest_Comp != PASS) {
             //log_info("(407) Get Fw and Hw Ver. ");
-            GetFwAndHwVersion(Uart1Fd);
-            sleep(1);
-            ShmPrimaryMcuData->SelfTest_Comp = PASS;
+            if (GetFwAndHwVersion(Uart1Fd) != PASS ) {
+                sleep(1);
+                continue;
+            }
+            if (_isNeedChkTilt) {
+                ChkTiltSensor(Uart1Fd);
+            } else {
+                ShmPrimaryMcuData->SelfTest_Comp = PASS;
+            }
         } else {
+            if (_isNeedChkTilt) {
+                ChkTiltSensor(Uart1Fd);
+            }
             SetOutputGpio(Uart1Fd, ShmPrimaryMcuData->OutputDrv.OutputDrvValue[0]);
 
             GetInputGpioStatus(Uart1Fd);
         }
-
-
         usleep(50000);
     }
 

+ 1 - 1
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.h

@@ -31,5 +31,5 @@ typedef struct StLedConfig {
 //------------------------------------------------------------------------------
 //int StoreLogMsg(const char *fmt, ...);
 #define SensorTrigCount 3
-
+#define TILTSENSORDET		2
 #endif /* _MODULE_PRIMARY_COMM_H_ */

+ 7 - 3
EVSE/Projects/DD360Audi/Apps/ModuleUpdateFW/Module_UpdateFW.c

@@ -128,7 +128,8 @@ bool IsConnectorWholeIdle()
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(count);
 
         if (pDcChargingInfo->SystemStatus != S_IDLE &&
-                pDcChargingInfo->SystemStatus != S_RESERVATION) {
+                pDcChargingInfo->SystemStatus != S_RESERVATION &&
+                pDcChargingInfo->SystemStatus != S_MAINTAIN) {
             result = false;
             break;
         }
@@ -187,8 +188,11 @@ static int InitCanBus(void)
 
 unsigned long long getAvailableMemory()
 {
+    system("pkill ntpd");
+    sleep(1);
     long pages = sysconf(_SC_AVPHYS_PAGES);
     long page_size = sysconf(_SC_PAGE_SIZE);
+    log_info("Avaiable Memory size:%d MB",(pages*page_size/(1024*1024)));
     return pages * page_size;
 }
 
@@ -215,7 +219,7 @@ static int CheckUpdateProcess(void)
 
     if (getAvailableMemory() < (200 * 1024 * 1024))
     {
-        log_info("Available memory (%.2f Bytes) less than 200 MBytes, free cache first.\n", getAvailableMemory() / (1024 * 1024.0));
+        log_info("Available memory less than 200 MBytes, free cache first.\n");
         system("echo 3 > /proc/sys/vm/drop_caches");
     }
 
@@ -418,7 +422,7 @@ static int CheckUpdateProcess(void)
             free(new_str);
         }
     }
-    free(dir);
+    //free(dir);
     closedir(d);
 
     if (retFail != 0) {

BIN
EVSE/Projects/DD360Audi/Apps/Module_ChkSysTask


BIN
EVSE/Projects/DD360Audi/Apps/Module_DoComm


BIN
EVSE/Projects/DD360Audi/Apps/Module_EvComm


BIN
EVSE/Projects/DD360Audi/Apps/Module_EventLogging


BIN
EVSE/Projects/DD360Audi/Apps/Module_InternalComm


BIN
EVSE/Projects/DD360Audi/Apps/Module_UpdateFW


+ 80 - 24
EVSE/Projects/DD360Audi/Apps/ReadCmdline.c

@@ -43,6 +43,7 @@
 #include "./SelectGun/SelectGun.h"
 #include "Config.h"
 #include "./ModuleEvComm/Module_EvComm.h"
+#include "./CSU/main.h"
 
 //------------------------------------------------------------------------------
 #define CMD_KEY_WAIT                                (1)
@@ -840,7 +841,10 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
         curGun = pSysInfo->CurGunSelected;
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);
-
+        if (!pDcChargingInfo->IsAvailable) {
+            printf("Gun%d Not Available\n",curGun);
+            break;
+        }
         //fix gun 1
         switch (pDcChargingInfo->SystemStatus) {
         case S_IDLE:
@@ -928,7 +932,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;
 
                 printf ("[UnconditionalCharge - S_PREPARING_FOR_EVSE]\n");
-
+                strcpy((char *)pSysConfig->UserId, "");
             }
             //printf ("tar vol = %d \n", _Voltage);
             //printf ("tar cur = %d \n", _Current);
@@ -1099,13 +1103,14 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
                 if (PreviousSystemStatus[gunIndex] == 0xFF) {
                     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);
-                    pDcChargingInfo->SystemStatus = S_IDLE;
+                    pDcChargingInfo->IsAvailable ? (pDcChargingInfo->SystemStatus = S_IDLE) : (pDcChargingInfo->SystemStatus = S_MAINTAIN);
+                    
                 } else {
                     pSysInfo->CurGunSelected = gunIndex;
                 }
 
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
-                if (pDcChargingInfo->SystemStatus == S_IDLE) {
+                if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_MAINTAIN) {
                     stopChg++;
                 }
             }
@@ -1121,8 +1126,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
                 for (_GunIndex = 0; _GunIndex < pSysConfig->TotalConnectorCount; _GunIndex++) {
                     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);
-
-                    pDcChargingInfo->SystemStatus = S_IDLE;
+                    pDcChargingInfo->IsAvailable ? (pDcChargingInfo->SystemStatus = S_IDLE) : (pDcChargingInfo->SystemStatus = S_MAINTAIN);
                 }
                 return;
             }
@@ -1407,6 +1411,27 @@ void setSystemTime(char* date,char* time)
     system("hwclock -w -u");
     system("hwclock -s");
 }
+static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2)
+{
+    uint8_t maxTemp = 0;
+
+    if (headTemp1 > TEMP_BOUNDARY &&
+            headTemp2 > TEMP_BOUNDARY) {
+        return UNDEFINED_TEMP;
+    }
+
+    if (headTemp1 <= TEMP_BOUNDARY) {
+        maxTemp = headTemp1;
+    }
+
+    if (headTemp2 <= TEMP_BOUNDARY) {
+        if (headTemp2 > maxTemp) {
+            maxTemp = headTemp2;
+        }
+    }
+    return maxTemp;
+}
+
 static void writeGunAndChillerTemp(void)
 {
     uint8_t _GunIndex = 0;
@@ -1447,14 +1472,28 @@ static void writeGunAndChillerTemp(void)
             continue;
         }
 
-        if (atoi(newString[2]) > 255 ||
+        if (strcmp(newString[0], "chiller") == 0) {
+            if (atoi(newString[2]) > 255 ||
+                    atoi(newString[2]) == -1 ||
+                    atoi(newString[3]) > 255 ||
+                    atoi(newString[3]) == -1 ||
+                    atoi(newString[4]) > 255 ||
+                    atoi(newString[4]) == -1 ||
+                    atoi(newString[5]) > 255 ||
+                    atoi(newString[5]) == -1) {
+                printf("temperature value overflow\r\n");
+                continue;
+            }
+        } else {
+            if (atoi(newString[2]) > 255 ||
                 atoi(newString[2]) == -1) {
-            printf("temperature value overflow\r\n");
-            continue;
+                    printf("temperature value overflow\r\n");
+                    continue;
+                }
         }
 
         _GunIndex = atoi((char *)newString[1]);
-
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_GunIndex);
         if (_GunIndex >= pSysConfig->TotalConnectorCount) {
             printf("gun index over total connector\r\n");
             continue;
@@ -1462,18 +1501,30 @@ static void writeGunAndChillerTemp(void)
 
         if (strcmp(newString[0], "chiller") == 0) {//修改水冷機溫度值
             if (ShmDcCommonData->pGunInfo[_GunIndex].withChiller) {
-                pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_GunIndex);
-                memset((char*)ShmDcCommonData->SystemTemp, atoi(newString[2]), sizeof(ShmDcCommonData->SystemTemp));
-                pDcChargingInfo->ChillerTemp = atoi(newString[2]);
-                printf("set %d chiller temperature = %d\r\n",
-                    _GunIndex,
+                ShmDcCommonData->SystemTemp[0] = atoi(newString[2]);
+                ShmDcCommonData->SystemTemp[1] = atoi(newString[3]);
+                ShmDcCommonData->SystemTemp[2] = atoi(newString[4]);
+                ShmDcCommonData->SystemTemp[3] = atoi(newString[5]);
+                for(int i = 0 ; i < pSysConfig->TotalConnectorCount ; i++) {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+                    if (!ShmDcCommonData->pGunInfo[i].withChiller)
+                        continue;
+                    if (i == LEFT_GUN_NUM) {
+                        pDcChargingInfo->ChillerTemp = getMaxConnectTemp(ShmDcCommonData->SystemTemp[0],ShmDcCommonData->SystemTemp[1]);
+                    } else {
+                        pDcChargingInfo->ChillerTemp = getMaxConnectTemp(ShmDcCommonData->SystemTemp[2],ShmDcCommonData->SystemTemp[3]);
+                    }
+                    printf("set %d chiller temperature = %d\r\n",
+                    i,
                     pDcChargingInfo->ChillerTemp);
+                }
+                //memset((char*)ShmDcCommonData->SystemTemp, atoi(newString[2]), sizeof(ShmDcCommonData->SystemTemp));
+            
             } else {
-                printf("This Gun without Chiller");
+                printf("This Gun without Chiller\r\n");
             }
 
         } 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",
@@ -1573,10 +1624,6 @@ void ShowPowerConsumption(char* v1)
     printf("Dispenser Gun0 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[0].PowerConsumption);
     printf("Dispenser Gun1 PowerConsumption:%.4f\n", ShmDcCommonData->pGunInfo[1].PowerConsumption);
 
-    printf("Power Consumption Gun1:%.4f, Gun2:%.4f, Gun3:%.4f, Gun4:%.4f", ShmDcCommonData->pConsumption.Gun1_Consumption,
-        ShmDcCommonData->pConsumption.Gun2_Consumption,
-        ShmDcCommonData->pConsumption.Gun3_Consumption,
-        ShmDcCommonData->pConsumption.Gun4_Consumption);
 }
 int main(void)
 {
@@ -1602,7 +1649,6 @@ int main(void)
                      "       tempW                             : write connector header and Chiller temperature\r\n"
                      "       tempR                             : print connector header and chiller temperature\r\n"
                      "       OTP                               : Write OTP temperature\r\n"
-                     "       chiller                           : set chiller on/off\r\n"
                      "       netdump                           : show network package\r\n"
                      "       candump                           : show can package\r\n"
                      "       powerconsumption                  : Show Power Consumption\n"
@@ -1777,8 +1823,8 @@ int main(void)
             resdGunAndChillerTemp();
         } else if (strcmp(newString[0], "OTP") == 0) { //測試槍頭和水冷機溫度
             writeOTPTemp();
-        } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
-            writeChillerStatus(newString[1]);
+//        } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
+//            writeChillerStatus(newString[1]);
         } else if (strcmp(newString[0], "netdump") == 0) { //印出網路封包
             showNetworkPage(newString[1]);
         } else if (strcmp(newString[0], "candump") == 0) { //印出網路封包
@@ -1789,6 +1835,16 @@ int main(void)
             ShowPowerConsumption(newString[1]);
         } else if (strcmp(newString[0], "led") == 0) {              // LED
             setledcolor(newString[1]);
+        } else if (strcmp(newString[0], "btnl") == 0) {
+        	ShmPrimaryMcuData->InputDet.bits.Button1 = BTN_PRESS;
+        	sleep(1);
+        	ShmPrimaryMcuData->InputDet.bits.Button1 = BTN_RELEASE;
+        } else if (strcmp(newString[0], "btnr") == 0) {
+        	ShmPrimaryMcuData->InputDet.bits.Button2 = BTN_PRESS;
+        	sleep(1);
+        	ShmPrimaryMcuData->InputDet.bits.Button2 = BTN_RELEASE;
+        } else if (strcmp(newString[0], "DcMeter") == 0) {
+
         } else {
             printf("%s\n", usageMsg);
         }

+ 2 - 0
EVSE/Projects/DD360Audi/Apps/Script/init.sh

@@ -1,6 +1,7 @@
 chmod 777 Module_CSU
 chmod 777 Module_PrimaryComm
 chmod 777 Module_LcmControl
+chmod 777 Module_LcmWistronControl
 chmod 777 Module_InternalComm
 chmod 777 Module_EventLogging
 chmod 777 Module_EvComm
@@ -11,5 +12,6 @@ chmod 777 OcppBackend
 chmod 777 kill.sh
 chmod 777 ReadCmdline
 chmod 777 Module_DoComm
+chmod 777 Module_DcMeter
 chmod 777 SearchIP.sh
 chmod 777 FactoryConfig

+ 2 - 0
EVSE/Projects/DD360Audi/Apps/Script/kill.sh

@@ -1,6 +1,7 @@
 pkill Module_CSU;
 pkill Module_PrimaryComm;
 pkill Module_LcmControl;
+pkill Module_LcmWistronControl;
 pkill Module_InternalComm;
 pkill Module_EventLogging;
 pkill Module_EvComm;
@@ -12,6 +13,7 @@ pkill Module_Wifi;
 pkill OcppBackend;
 pkill Module_ProduceUtils;
 pkill Module_DoComm;
+pkill Module_DcMeter;
 pkill main;
 
 /usr/bin/fuser -k /dev/watchdog

+ 0 - 4
EVSE/Projects/DD360Audi/Apps/Script/replaceOtherDD360Project.sh

@@ -9,10 +9,6 @@ echo $SCRIPTPATH
 
 ProjectPath="/opt/ti-processor-sdk-linux-am335x-evm-04.02.00.09/EVSE/Projects"
 
-rm -rf $ProjectPath/DD360/Apps/;
-cp -r $ProjectPath/DD360Audi/Apps/ $ProjectPath/DD360/Apps;
-cp -r $ProjectPath/DD360Audi/ModelNameList.txt  $ProjectPath/DD360/ModelNameList.txt;
-
 rm -rf $ProjectPath/DD360ComBox/Apps/;
 cp -r $ProjectPath/DD360Audi/Apps/ $ProjectPath/DD360ComBox/Apps;
 cp -r $ProjectPath/DD360Audi/ModelNameList.txt $ProjectPath/DD360ComBox/ModelNameList.txt;

+ 36 - 5
EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c

@@ -42,6 +42,7 @@ static struct OCPP20Data* ShmOCPP20Data = NULL;
 
 static SelectGunInfo *ShmSelectGunInfo = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
+static struct MeterInformation *ShmCsuMeterData = NULL;
 
 static struct ChargingInfoData *DcChargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY] = {NULL};
 static struct ChargingInfoData *AcChargingData[AC_QUANTITY] = {NULL};
@@ -162,7 +163,6 @@ void *GetShmSysConfigData(void)
     if (ShmSysConfigAndInfo == NULL) {
         return NULL;
     }
-
     return &ShmSysConfigAndInfo->SysConfig;
 }
 
@@ -328,6 +328,15 @@ void *GetShmDcCommonData(void)
     return ShmDcCommonData;
 }
 
+void *GetShmCsuMeterData(void)
+{
+    if (ShmCsuMeterData == NULL) {
+        return NULL;
+    }
+
+    return ShmCsuMeterData;
+}
+
 //------------------------------------------------------------------------------
 static void initialGunIndexToUnUse(void)
 {
@@ -761,6 +770,24 @@ int InitSysConfigAndInfoShmMem(void)
     return PASS;
 }
 
+int InitShmCsuMeterShmMem(void)
+{
+    int MeterSMId = FAIL;
+
+    if ((MeterSMId = shmget(ShmCsuMeterKey, sizeof(struct MeterInformation), IPC_CREAT | 0777)) < 0)
+    {
+        printf("shmget ShmCsuMeterKey NG \n");
+        return 0;
+    }
+    else if ((ShmCsuMeterData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        printf("shmat ShmCsuMeterData NG \n");
+        return 0;
+    }
+
+    return PASS;
+}
+
 void ClearAllShmMemParameter(void)
 {
     uint8_t i = 0;
@@ -893,7 +920,7 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
             {
                 gGunIndexInfo.AcIndex++;
                 gGunIndexInfo.AcGunIndex++;
-                pAcChargingInfo->IsAvailable = YES;
+                //pAcChargingInfo->IsAvailable = YES;
             }
         } else {
             result = false;
@@ -921,7 +948,7 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
             setAcGunTiggerStatus();
             //if( strcmp(whichtask,"CSU task") == EQUAL ) 
             {
-                pDcChargingInfo->IsAvailable = YES;
+                //pDcChargingInfo->IsAvailable = YES;
                 gGunIndexInfo.ChademoIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
@@ -954,7 +981,7 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
             pCcsData->CommProtocol = _CCS_COMM_V2GMessage_DIN70121;
             //if( strcmp(whichtask,"CSU task") == EQUAL ) 
             {
-                pDcChargingInfo->IsAvailable = YES;
+                //pDcChargingInfo->IsAvailable = YES;
                 gGunIndexInfo.CcsIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
@@ -989,7 +1016,7 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichta
             setAcGunTiggerStatus();
             //if( strcmp(whichtask,"CSU task") == EQUAL ) 
             {
-                pDcChargingInfo->IsAvailable = YES;
+                //pDcChargingInfo->IsAvailable = YES;
                 gGunIndexInfo.GbIndex++;
                 gGunIndexInfo.DcGunIndex++;
             }
@@ -1162,6 +1189,10 @@ int CreateAllCsuShareMemory(void)
     if ((ret = InitCommonShmMem()) == FAIL) {
         return ret;
     }
+
+    if ((ret = InitShmCsuMeterShmMem()) == FAIL) {
+        return ret;
+    }
     //ClearAllShmMemParameter();
 
     //MappingChargingInfoData();

+ 1 - 1
EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.h

@@ -52,7 +52,7 @@ void *GetShmInfoCodeData(void);
 void *GetShmFaultCodeData(void);
 void *GetShmAlarmCodeData(void);
 void *GetShmStatusCodeData(void);
-
+void *GetShmCsuMeterData(void);
 void *GetShmPsuData(void);
 void *GetShmPrimaryMcuData(void);
 

BIN
EVSE/Projects/DD360Audi/Apps/UnsafetyOutputTask


BIN
EVSE/Projects/DD360Audi/Apps/main


+ 3 - 0
EVSE/Projects/DD360Audi/Apps/timeout.h

@@ -54,6 +54,9 @@ enum Timeout_flag {
     Timeout_SelectGun              = 13,
     Timeout_WaitBalance            = 14,
     Timeout_EVCCID_Link            = 15,
+    Timeout_ReturnViewPage         = 16,
+    Timeout_helpPage               = 17,
+    Timeout_LanguagePage           = 18,
 };
 
 //------------------------------------------------------------------------------

BIN
EVSE/Projects/DD360Audi/Images/ramdisk.gz


BIN
EVSE/Projects/DD360Audi/output/FactoryConfig


BIN
EVSE/Projects/DD360Audi/output/Module_ChkSysTask


BIN
EVSE/Projects/DD360Audi/output/Module_DoComm


BIN
EVSE/Projects/DD360Audi/output/Module_EvComm


BIN
EVSE/Projects/DD360Audi/output/Module_EventLogging


BIN
EVSE/Projects/DD360Audi/output/Module_InternalComm


BIN
EVSE/Projects/DD360Audi/output/Module_LcmControl


BIN
EVSE/Projects/DD360Audi/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360Audi/output/Module_UpdateFW


BIN
EVSE/Projects/DD360Audi/output/ReadCmdline


BIN
EVSE/Projects/DD360Audi/output/UnsafetyOutputTask


+ 2 - 0
EVSE/Projects/DD360Audi/output/init.sh

@@ -1,6 +1,7 @@
 chmod 777 Module_CSU
 chmod 777 Module_PrimaryComm
 chmod 777 Module_LcmControl
+chmod 777 Module_LcmWistronControl
 chmod 777 Module_InternalComm
 chmod 777 Module_EventLogging
 chmod 777 Module_EvComm
@@ -11,5 +12,6 @@ chmod 777 OcppBackend
 chmod 777 kill.sh
 chmod 777 ReadCmdline
 chmod 777 Module_DoComm
+chmod 777 Module_DcMeter
 chmod 777 SearchIP.sh
 chmod 777 FactoryConfig

+ 2 - 0
EVSE/Projects/DD360Audi/output/kill.sh

@@ -1,6 +1,7 @@
 pkill Module_CSU;
 pkill Module_PrimaryComm;
 pkill Module_LcmControl;
+pkill Module_LcmWistronControl;
 pkill Module_InternalComm;
 pkill Module_EventLogging;
 pkill Module_EvComm;
@@ -12,6 +13,7 @@ pkill Module_Wifi;
 pkill OcppBackend;
 pkill Module_ProduceUtils;
 pkill Module_DoComm;
+pkill Module_DcMeter;
 pkill main;
 
 /usr/bin/fuser -k /dev/watchdog

BIN
EVSE/Projects/DD360Audi/output/main