فهرست منبع

2021-08-10 / Wendell

Actions
1. modify status code logic
2. modify relay welding & driving fault logic
3. modify output ovp logic
4. modify gfd logic
5. clean EvConnAlarmCode at idle mode
6. fix upgrade issue
7. add two detection point of temperature
8. turn on chiller after authorization
9. modify internal commucation process

Files
1. As follow commit history

Image version : V1.12.XX.XXXX.XX
Wendell 3 سال پیش
والد
کامیت
567785b073
78فایلهای تغییر یافته به همراه3327 افزوده شده و 966 حذف شده
  1. 2 1
      EVSE/Projects/DD360/Apps/CSU/UpgradeFW.c
  2. 270 92
      EVSE/Projects/DD360/Apps/CSU/main.c
  3. 3 0
      EVSE/Projects/DD360/Apps/Config.h
  4. 19 0
      EVSE/Projects/DD360/Apps/Define/define.h
  5. 4 0
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalCCS.c
  6. 4 0
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalCHA.c
  7. 4 0
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalGBT.c
  8. 7 12
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalState.c
  9. 1 2
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvComm.h
  10. 21 14
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvRxComm.c
  11. 1 1
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c
  12. 5 5
      EVSE/Projects/DD360/Apps/ModuleInternalComm/Module_InternalComm.c
  13. 692 192
      EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c
  14. 68 1
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c
  15. 8 2
      EVSE/Projects/DD360/Apps/ReadCmdline.c
  16. BIN
      EVSE/Projects/DD360/Images/ramdisk.gz
  17. BIN
      EVSE/Projects/DD360/Images/u-boot.img
  18. BIN
      EVSE/Projects/DD360/output/FactoryConfig
  19. BIN
      EVSE/Projects/DD360/output/Module_DoComm
  20. BIN
      EVSE/Projects/DD360/output/Module_EvComm
  21. BIN
      EVSE/Projects/DD360/output/Module_EventLogging
  22. BIN
      EVSE/Projects/DD360/output/Module_InternalComm
  23. BIN
      EVSE/Projects/DD360/output/Module_LcmControl
  24. BIN
      EVSE/Projects/DD360/output/Module_PrimaryComm
  25. BIN
      EVSE/Projects/DD360/output/ReadCmdline
  26. BIN
      EVSE/Projects/DD360/output/main
  27. 2 1
      EVSE/Projects/DD360Audi/Apps/CSU/UpgradeFW.c
  28. 270 92
      EVSE/Projects/DD360Audi/Apps/CSU/main.c
  29. 3 0
      EVSE/Projects/DD360Audi/Apps/Config.h
  30. 19 0
      EVSE/Projects/DD360Audi/Apps/Define/define.h
  31. 4 0
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCCS.c
  32. 4 0
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCHA.c
  33. 4 0
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalGBT.c
  34. 7 12
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c
  35. 1 2
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvComm.h
  36. 21 14
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c
  37. 1 1
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c
  38. 5 5
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/Module_InternalComm.c
  39. 692 192
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c
  40. 68 1
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c
  41. 8 2
      EVSE/Projects/DD360Audi/Apps/ReadCmdline.c
  42. BIN
      EVSE/Projects/DD360Audi/Images/ramdisk.gz
  43. BIN
      EVSE/Projects/DD360Audi/Images/u-boot.img
  44. BIN
      EVSE/Projects/DD360Audi/output/FactoryConfig
  45. BIN
      EVSE/Projects/DD360Audi/output/Module_DoComm
  46. BIN
      EVSE/Projects/DD360Audi/output/Module_EvComm
  47. BIN
      EVSE/Projects/DD360Audi/output/Module_EventLogging
  48. BIN
      EVSE/Projects/DD360Audi/output/Module_InternalComm
  49. BIN
      EVSE/Projects/DD360Audi/output/Module_LcmControl
  50. BIN
      EVSE/Projects/DD360Audi/output/Module_PrimaryComm
  51. BIN
      EVSE/Projects/DD360Audi/output/ReadCmdline
  52. BIN
      EVSE/Projects/DD360Audi/output/main
  53. 2 1
      EVSE/Projects/DD360ComBox/Apps/CSU/UpgradeFW.c
  54. 270 92
      EVSE/Projects/DD360ComBox/Apps/CSU/main.c
  55. 3 0
      EVSE/Projects/DD360ComBox/Apps/Config.h
  56. 19 0
      EVSE/Projects/DD360ComBox/Apps/Define/define.h
  57. 4 0
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalCCS.c
  58. 4 0
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalCHA.c
  59. 4 0
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalGBT.c
  60. 7 12
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalState.c
  61. 1 2
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvComm.h
  62. 21 14
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvRxComm.c
  63. 1 1
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvTxComm.c
  64. 5 5
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/Module_InternalComm.c
  65. 692 192
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/RelayBoard.c
  66. 68 1
      EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.c
  67. 8 2
      EVSE/Projects/DD360ComBox/Apps/ReadCmdline.c
  68. BIN
      EVSE/Projects/DD360ComBox/Images/ramdisk.gz
  69. BIN
      EVSE/Projects/DD360ComBox/Images/u-boot.img
  70. BIN
      EVSE/Projects/DD360ComBox/output/FactoryConfig
  71. BIN
      EVSE/Projects/DD360ComBox/output/Module_DoComm
  72. BIN
      EVSE/Projects/DD360ComBox/output/Module_EvComm
  73. BIN
      EVSE/Projects/DD360ComBox/output/Module_EventLogging
  74. BIN
      EVSE/Projects/DD360ComBox/output/Module_InternalComm
  75. BIN
      EVSE/Projects/DD360ComBox/output/Module_LcmControl
  76. BIN
      EVSE/Projects/DD360ComBox/output/Module_PrimaryComm
  77. BIN
      EVSE/Projects/DD360ComBox/output/ReadCmdline
  78. BIN
      EVSE/Projects/DD360ComBox/output/main

+ 2 - 1
EVSE/Projects/DD360/Apps/CSU/UpgradeFW.c

@@ -328,7 +328,7 @@ void CheckFwUpdateFunction(void)
         for (uint8_t gun_index = 0; gun_index < pSysConfig->TotalConnectorCount; gun_index++) {
             setChargerMode(gun_index, MODE_UPDATE);
         }
-
+        sleep(1);
         uint8_t updateResult = CheckUpdateProcess();
 
         if (updateResult == PASS) {
@@ -366,6 +366,7 @@ void CheckFwUpdateFunction(void)
 
                 pAcChargingInfo->SystemStatus = MODE_UPDATE;
             }
+            sleep(1);
 
             uint8_t updateResult = CheckUpdateProcess();
 

+ 270 - 92
EVSE/Projects/DD360/Apps/CSU/main.c

@@ -77,7 +77,7 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.11.00.0000.00"; // "V0.16.00.0000.00";
+char *fwVersion = "V1.12.00.0000.00"; // "V0.16.00.0000.00";
 
 //sqlite3 *localDb;
 bool isDb_ready;
@@ -96,6 +96,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code);
 void ReleaseAlarmCode(uint8_t gunIndex);
 void ResetChargerAlarmCode(uint8_t gunIndex, char *code);
 void AdjustChargerCurrent(void);
+void UpdateErrorCodeToOcpp(uint8_t index);
 
 //------------------------------------------------------------------------------
 //Primary.c
@@ -390,15 +391,51 @@ static void checkGunOTPState(uint8_t gunIndex)
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
         if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) {
-                RecordAlarmCode(gunIndex, "012323");
+                if (((gunIndex == 0) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                         ||
+                    ((gunIndex == 1) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+                   ) {
+                    RecordAlarmCode(gunIndex, "012323");
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                }
+                else
+                {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                }
             } else if (pDcChargingInfo->ChillerTemp != 0 &&
                        pDcChargingInfo->ChillerTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012323");
+                //ResetChargerAlarmCode(gunIndex, "012323");
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
             }
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011038");
-            ResetChargerAlarmCode(gunIndex, "012323");
+            //RecordAlarmCode(gunIndex, "011038");
+            //ResetChargerAlarmCode(gunIndex, "012323");
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+            if (((gunIndex == 0) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                     ||
+                ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+               ) {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            }
+            else
+            {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+            }
+        }
+
+        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
+        {
+            RecordAlarmCode(gunIndex, "011037");
         }
     }
 
@@ -407,14 +444,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012229");
+                //ResetChargerAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
             //RecordAlarmCode(gunIndex, "011018");
-            ResetChargerAlarmCode(gunIndex, "012229");
+            //ResetChargerAlarmCode(gunIndex, "012229");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
         }
         break;
 
@@ -425,16 +467,20 @@ static void checkGunOTPState(uint8_t gunIndex)
 
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012230");
+                //ResetChargerAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
             }
-
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = NO;
             //ResetChargerAlarmCode(gunIndex, "011019");
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011019");
-            ResetChargerAlarmCode(gunIndex, "012230");
+            //RecordAlarmCode(gunIndex, "011019");
+            //ResetChargerAlarmCode(gunIndex, "012230");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = YES;
         }
         break;
 
@@ -442,14 +488,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012231");
+                //ResetChargerAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011020");
-            ResetChargerAlarmCode(gunIndex, "012231");
+            //RecordAlarmCode(gunIndex, "011020");
+            //ResetChargerAlarmCode(gunIndex, "012231");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = YES;
         }
         break;
     }
@@ -1690,30 +1741,46 @@ void ResetChargerAlarmCode(uint8_t gunIndex, char *code)
         ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
     }
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
-        if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
-           ) {
-            strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
-        }
+    //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
+    //    if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
+    //       ) {
+    //        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
+    //    }
+    //}
+    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012229", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012230", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012231", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011011", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011013", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011015", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011012", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011014", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011016", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011018", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011019", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011020", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL) {
+        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
 }
 
@@ -1721,10 +1788,20 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
-        memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+    if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+    {
+        if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+            memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+        }
+
+        if (pDcChargingInfo->StopChargeFlag == NO)
+        {
+            pDcChargingInfo->StopChargeFlag = YES;
+        }
     }
 
+#if 0
     if (strcmp(code, "012234") == EQUAL) {
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
     } else if (strcmp(code, "012235") == EQUAL) {
@@ -1792,6 +1869,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
             ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
         }
     }
+#endif
 }
 
 void ReleaseAlarmCode(uint8_t gunIndex)
@@ -1801,26 +1879,29 @@ void ReleaseAlarmCode(uint8_t gunIndex)
     //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
     //    return;
     //}
-
+#if 0
     // 回 idle 後主要清除  GFD Trip、UVP、OVP、GFD Warning
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL) {
         memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
-
+#endif
     switch (pDcChargingInfo->Type) {
     case _Type_Chademo:
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012234", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012289", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012217", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012296", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_CCS_2:
@@ -1828,13 +1909,16 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012235", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012288", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012219", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012297", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_GB:
@@ -1842,16 +1926,19 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012236", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012290", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012221", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012298", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
     }
-
+#if 0
     //system alarm
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL ||
@@ -1862,6 +1949,8 @@ void ReleaseAlarmCode(uint8_t gunIndex)
        ) {
         memset(pDcChargingInfo->ConnectorAlarmCode, 0, sizeof(pDcChargingInfo->ConnectorAlarmCode));
     }
+#endif
+    memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
 }
 
 //===============================================
@@ -1874,6 +1963,7 @@ void ChargingTerminalProcess(uint8_t gunIndex)
 
 void ChargingAlarmProcess(uint8_t gunIndex)
 {
+    UpdateErrorCodeToOcpp(gunIndex);
     setChargerMode(gunIndex, MODE_ALARM);
 }
 
@@ -1966,6 +2056,9 @@ void EmcOccureByString(char *code)
                     (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                      pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
                 //ChargingTerminalProcess(gun);
+                if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+                    memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+                }
                 ChargingAlarmProcess(gun);
             }
         }
@@ -2007,6 +2100,31 @@ void ReleaseEmsOccureByString(uint8_t index, char *code)
     }
 }
 
+static void checkOvpState(uint8_t gunIndex, uint8_t gunType)
+{
+    switch(gunType)
+    {
+        case _Type_Chademo:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012217");
+            }
+            break;
+        case _Type_CCS_2:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012219");
+            }
+            break;
+        case _Type_GB:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012221");
+            }
+            break;
+    }
+}
+
 //===============================================
 // 確認各小板偵測的錯誤狀況
 //===============================================
@@ -2083,6 +2201,8 @@ void CheckErrorOccurStatus(uint8_t index)
         }
     }
 
+    checkOvpState(index, pDcChargingInfo->Type);
+
     //--------------------------------------------------------------------------
     if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == 0) {
         //Primary
@@ -2096,11 +2216,11 @@ void CheckErrorOccurStatus(uint8_t index)
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "012304", 6);
         }
         //Chiller temperature
-        else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
-        } else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
-        }
+        //else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
+        //} else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
+        //}
     }
 }
 
@@ -3500,8 +3620,8 @@ void UpdateErrorCodeToOcpp(uint8_t index)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
 
-    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->ConnectorAlarmCode);
-    //log_info("%d = EvConnAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->EvConnAlarmCode);
+    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, pDcChargingInfo->ConnectorAlarmCode);
+    //log_info("%d = EvConnAlarmCode = %s\r\n", index, pDcChargingInfo->EvConnAlarmCode);
     if (strcmp((char *)pDcChargingInfo->ConnectorAlarmCode, "") != EQUAL) {
         //if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == EQUAL) {
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].ErrorCode, "InternalError");
@@ -3512,7 +3632,7 @@ void UpdateErrorCodeToOcpp(uint8_t index)
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode, (char *)pDcChargingInfo->EvConnAlarmCode);
     }
 
-    //log_info("2 %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
+    //log_info("Gun %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
 }
 
 void AdjustChargerCurrent()
@@ -3583,10 +3703,10 @@ static bool PrecheckIsPass(uint8_t gunIndex)
 
 static void ReviewCriticalAlarm(void)
 {
-    if (ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
+    if (//ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
             pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES ||
             pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES ||
             pAlarmCode->AlarmEvents.bits.DoorOpen == YES ||
@@ -3613,7 +3733,7 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
 
     // relay welding fault then stop the charging process.
     uint8_t faultCode = RELAY_STATUS_ERROR_NONE;
-    static uint8_t drivingCount = 0;
+    //static uint8_t drivingCount = 0;
 
     if (gunIndex == 0) {
         if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_WELDING ||
@@ -3649,45 +3769,58 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
         // welding
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = YES;
         }
 
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else if (faultCode == RELAY_STATUS_ERROR_DRIVING) {
-        if (drivingCount++ != 2) {
-            return;
-        }
+        //if (drivingCount++ != 2) {
+        //    return;
+        //}
 
         // driving
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011012");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011016");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011014");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = YES;
         }
 
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else {
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = NO;
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = NO;
-        drivingCount = 0;
-
+        //drivingCount = 0;
+#if 0
         if (pDcChargingInfo->Type == _Type_Chademo) {
-            ResetChargerAlarmCode(gunIndex, "011012");
-            ResetChargerAlarmCode(gunIndex, "011011");
+            //ResetChargerAlarmCode(gunIndex, "011012");
+            //ResetChargerAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-            ResetChargerAlarmCode(gunIndex, "011014");
-            ResetChargerAlarmCode(gunIndex, "011013");
+            //ResetChargerAlarmCode(gunIndex, "011014");
+            //ResetChargerAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_GB) {
-            ResetChargerAlarmCode(gunIndex, "011016");
-            ResetChargerAlarmCode(gunIndex, "011015");
+            //ResetChargerAlarmCode(gunIndex, "011016");
+            //ResetChargerAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
         }
+#endif
     }
 }
 
@@ -3810,9 +3943,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012234");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012296");
+            //RecordAlarmCode(gunIndex, "012296");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -3849,9 +3991,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012236");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012298");
+            //RecordAlarmCode(gunIndex, "012298");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           isPrechargeStatus_gb(gunIndex) == 10 &&
@@ -3890,9 +4041,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012235");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012297");
+            //RecordAlarmCode(gunIndex, "012297");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -4153,6 +4313,16 @@ int main(void)
 
         gEvBoardErr.GunErrMessage = 0; //清除系統執行中的錯誤訊息
         gChillerTempErr.TempErrMsg = 0;//清除系統執行中的錯誤訊息
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            // 重新收集各槍的錯誤狀態
+            collectError(gunIndex);
+        }
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+            // convert common status code to alarm event
+            checkEvBoardAlarmState(pDcChargingInfo->Type);
+        }
+        checkChillerAlarmState();
 
         for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -4166,9 +4336,6 @@ int main(void)
             // 確認 Relay Welding or Driving Fault
             CheckRelayWeldingOrDrivingFault(gunIndex);
 
-            // 重新收集各槍的錯誤狀態
-            collectError(gunIndex);
-
             ChkOcppStatus(gunIndex);
 
             if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
@@ -4183,7 +4350,6 @@ int main(void)
             //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-                ReleaseAlarmCode(gunIndex);
 
                 if (isModeChange(gunIndex)) {
                     log_info("S_IDLE================================== %x \n", gunIndex);
@@ -4205,6 +4371,7 @@ int main(void)
                         ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] = NO;
                     }
                     //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, "");
+                    ReleaseAlarmCode(gunIndex);
                 }
 
             case S_RESERVATION:
@@ -4219,16 +4386,26 @@ int main(void)
 
             case S_MAINTAIN:
             case S_FAULT:
+                if (isModeChange(gunIndex)) {
+                    if(pDcChargingInfo->SystemStatus == S_MAINTAIN)
+                    {
+                        log_info("S_MAINTAIN================================== %x \n", gunIndex);
+                    }
+                    if(pDcChargingInfo->SystemStatus == S_FAULT)
+                    {
+                        log_info("S_FAULT================================== %x \n", gunIndex);
+                    }
+                }
                 if (pSysWarning->Level == WARN_LV_ER) {
-                    pDcChargingInfo =  (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
+                    struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
 
                     if (gunIndex == pSysInfo->CurGunSelected) {
                         pSysInfo->SystemPage = _LCM_FIX;
-                    } else if (pDcChargingInfo->SystemStatus != S_IDLE &&
-                               pDcChargingInfo->SystemStatus != S_RESERVATION &&
-                               pDcChargingInfo->SystemStatus != S_MAINTAIN &&
-                               pDcChargingInfo->SystemStatus != S_FAULT) {
-                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                    } else if (pSelectedDcChargingInfo->SystemStatus != S_IDLE &&
+                            pSelectedDcChargingInfo->SystemStatus != S_RESERVATION &&
+                            pSelectedDcChargingInfo->SystemStatus != S_MAINTAIN &&
+                            pSelectedDcChargingInfo->SystemStatus != S_FAULT) {
+                        if (pSelectedDcChargingInfo->SystemStatus == S_CHARGING) {
                             pSysInfo->SystemPage = _LCM_COMPLETE;
                         } else {
                             systemPageRestoreInit();
@@ -4237,9 +4414,11 @@ int main(void)
 
                     ClearDetectPluginFlag();
 
-                    UpdateErrorCodeToOcpp(gunIndex);
-
-                    setChargerMode(gunIndex, MODE_FAULT);
+                    if (pDcChargingInfo->SystemStatus != S_FAULT)
+                    {
+                        UpdateErrorCodeToOcpp(gunIndex);
+                        setChargerMode(gunIndex, MODE_FAULT);
+                    }
                     continue;
                 }
 
@@ -4669,7 +4848,7 @@ int main(void)
                     StopGunInfoTimeoutDet(gunIndex);
                 }
 
-                checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
+                //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
 #if 0
                 if (pDcChargingInfo->Type == _Type_Chademo) {
                     // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
@@ -4808,6 +4987,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4854,6 +5034,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4870,9 +5051,6 @@ int main(void)
                 }
                 break;
             }//switch
-
-            checkEvBoardAlarmState(pDcChargingInfo->Type);
-            checkChillerAlarmState();
         }//for
 
 #if defined DD360Audi

+ 3 - 0
EVSE/Projects/DD360/Apps/Config.h

@@ -85,6 +85,7 @@
 #define GUN_OTP_VALUE                           (150)
 #define GUN_OTP_RECOVERY                        (140)
 #define UNDEFINED_TEMP                          (255)
+#define TEMP_BOUNDARY                           (200)
 
 #define WARN_LV_NL                              (0) //normal state
 #define WARN_LV_WARN                            (1)
@@ -362,6 +363,8 @@ typedef struct StDcCommonInfo {
     uint8_t CheckRelayStatus[6]; //check Relay welding or driving fault
     uint8_t GunRelayWeldingOccur[2];
     uint8_t GunRelayDrivingOccur[2];
+    uint8_t ConnectorTemp[2][2];
+    uint8_t SystemTemp[4];
     uint8_t SystemModeChange[2]; //for Module_EvRxComm
     PowerAlarmState PowerAlarmState;
     ChillerTempErr ChillerTempErr[2];

+ 19 - 0
EVSE/Projects/DD360/Apps/Define/define.h

@@ -378,6 +378,13 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_OVERRIDE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct Schedule
 {
 	unsigned char   isEnable;     						// 0: disable schedule function  1: enable schedule function
@@ -481,6 +488,7 @@ struct SysConfigData
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
+	struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
 
     /************PowerCabinet************/
     WiringInfoData          WiringInfo;
@@ -798,6 +806,16 @@ typedef struct
     unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
 }CabinetMiscCommand;
 
+typedef struct DC_METER_INFO
+{
+    double presetVoltage;                       // resolution: 1.000v
+    double presentCurrent;                      // resolution: 1.000a
+    double presentPower;                        // resolution: 1.000kw
+    double totlizeImportEnergy;                 // resolution: 1.000kwh
+    double totlizeExportEnergy;                 // resolution: 1.000kwh
+    unsigned char LinkStatus;                   // 0 = unknow ,1 = link , 2 miss link
+}DC_Meter_Info;
+
 struct SysInfoData
 {
 	/**************System***************/
@@ -889,6 +907,7 @@ struct SysInfoData
     CabinetSettingFlag      CabinetSetting;
     CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
+    DC_Meter_Info DcMeterInfo[4];
 };
 
 struct SysConfigAndInfo

+ 4 - 0
EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalCCS.c

@@ -910,4 +910,8 @@ void ClearAbnormalStatus_CCS(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalCHA.c

@@ -244,4 +244,8 @@ void ClearAbnormalStatus_Chademo(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalGBT.c

@@ -412,4 +412,8 @@ void ClearAbnormalStatus_GB(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 7 - 12
EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalState.c

@@ -27,7 +27,7 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     //iflog_info("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
     if (strncmp(string, "000000", 6) == EQUAL ||
-            strncmp(string, "023979", 6) == EQUAL
+            strncmp(string, "012219", 6) == EQUAL
        ) {
         return false;
     }
@@ -39,14 +39,6 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     memcpy(pDcChargingInfo->EvConnAlarmCode, string, 6);
     log_info("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s\n", pDcChargingInfo->EvConnAlarmCode);
 
-    //OVP error
-    if (strcmp(string, "012217") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES; }
-    if (strcmp(string, "012219") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES; }
-    if (strcmp(string, "012221") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES; }
-
-    //UVP error
-    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
-
     if (strcmp(string, "023700") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES; }
     if (strcmp(string, "023704") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoBatteryMalfun = YES; }
     if (strcmp(string, "023705") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoNoPermission = YES; }
@@ -81,7 +73,11 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023734") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReqCurrentMoreThanLimit = YES; }
     if (strcmp(string, "023735") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReCapBmsEqrCurrentExceed = YES; }
     if (strcmp(string, "023736") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoChargeRemainCountDown = YES; }
+    if (strcmp(string, "023980") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_BMS_CHARGE_ALLOW_ERROR = YES; }
+    if (strcmp(string, "023981") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_OUTPUT_VOLTAGE_MORE_THEN_10_PERCENT = YES; }
+    if (strcmp(string, "023982") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_ADC_LESS_THAN_10V = YES; }
 
+    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
     if (strcmp(string, "023701") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEvCommFail = YES; }
     if (strcmp(string, "023737") == EQUAL) { pInfoCode->InfoEvents.bits.CcsRESTemperatureInhibit = YES; }
     if (strcmp(string, "023738") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEVShiftPosition = YES; }
@@ -223,6 +219,8 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023891") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccNotReadyForCharging = YES; }
     if (strcmp(string, "023892") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = YES; }
     if (strcmp(string, "023893") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccFailForQCA7000SetKey = YES; }
+    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
+    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
 
     if (strcmp(string, "023702") == EQUAL) { pInfoCode->InfoEvents.bits.GbEvCommFail = YES; }
     if (strcmp(string, "023900") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = YES; }
@@ -287,8 +285,5 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023976") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_ISOLATE = YES; }
     if (strcmp(string, "023977") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_OUTPUT_CONNECTOR = YES; }
 
-    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
-    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
-
     return true;
 }

+ 1 - 2
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvComm.h

@@ -27,8 +27,7 @@ enum EV_LOG_INDEX {
 
 //------------------------------------------------------------------------------
 typedef struct StChiilerTemp {
-    uint8_t Temp[2];
-    uint8_t Reserved[2];
+    uint8_t Temp[4];
 } ChillerTemp;
 
 //------------------------------------------------------------------------------

+ 21 - 14
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -71,19 +71,17 @@ static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2)
 {
     uint8_t maxTemp = 0;
 
-    if (headTemp1 == UNDEFINED_TEMP &&
-            headTemp2 == UNDEFINED_TEMP) {
+    if (headTemp1 > TEMP_BOUNDARY &&
+            headTemp2 > TEMP_BOUNDARY) {
         return UNDEFINED_TEMP;
     }
 
-    if (headTemp1 != UNDEFINED_TEMP) {
+    if (headTemp1 <= TEMP_BOUNDARY) {
         maxTemp = headTemp1;
-    } else {
-        headTemp1 = 0;
     }
 
-    if (headTemp2 != UNDEFINED_TEMP) {
-        if (headTemp2 > headTemp1) {
+    if (headTemp2 <= TEMP_BOUNDARY) {
+        if (headTemp2 > maxTemp) {
             maxTemp = headTemp2;
         }
     }
@@ -121,7 +119,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
     float adcVoltage = 0.0;
     ChillerTemp *pChillerTemp = (ChillerTemp *)chillerTemp;
 
-    for (i = 0; i < 2; i++) {
+    for (i = 0; i < 4; i++) {
         adcVoltage = 0.0;
         adcVoltage =  ReadAdcVolt(i);
         if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40
@@ -131,7 +129,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
             pChillerTemp->Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60;
             //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500);
         } else {
-            pChillerTemp->Temp[i] = 195;
+            pChillerTemp->Temp[i] = UNDEFINED_TEMP;
         }
 
         /*CcsConnectorTemp1 = ReadAdcVolt(i);
@@ -207,6 +205,7 @@ void CANReceiver(int fd)
         uint8_t ver[16] = {0};
         uint8_t printChillerTemp = NO;
         uint8_t printConnTemp = NO;
+        uint8_t chillerTemp[2] = {0, 0};
         uint8_t maxChillerTemp = 0;
         uint8_t lastChillerTemp = 0;
         uint8_t maxConnTemp = 0;
@@ -470,6 +469,9 @@ void CANReceiver(int fd)
                 }
                 }*/
 
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] = frame.data[1];
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] = frame.data[2];
+
                 if (ShmDcCommonData->TestTemperature == YES) { //ReadCmdline test
                     break;
                 }
@@ -479,12 +481,16 @@ void CANReceiver(int fd)
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
                     getChillerTemperature(&chiilerTemp);
-                    maxChillerTemp = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]);
+                    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 ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) {
                     //    printChillerTemp = YES;
                     //}
-                    if(maxChillerTemp > (lastChillerTemp + 1) || maxChillerTemp < (lastChillerTemp - 1))
+                    if(maxChillerTemp > (lastChillerTemp + 2) || maxChillerTemp < (lastChillerTemp - 2))
                     {
                         lastChillerTemp = maxChillerTemp;
                         printChillerTemp = YES;
@@ -497,7 +503,7 @@ void CANReceiver(int fd)
                 //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
                 //    printConnTemp = YES;
                 //}
-                if(maxConnTemp > (lastConnTemp[targetGun] + 1) || maxConnTemp < (lastConnTemp[targetGun] - 1))
+                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
                 {
                     lastConnTemp[targetGun] = maxConnTemp;
                     printConnTemp = YES;
@@ -515,10 +521,11 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp %d, max chiller = %d\r\n",
+                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d\r\n",
                              targetGun,
                              maxConnTemp,
-                             maxChillerTemp);
+                             chillerTemp[0],
+                             chillerTemp[1]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {

+ 1 - 1
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -748,7 +748,7 @@ int main(int argc, char *argv[])
                                      (pDcChargingInfo->PresentChargingVoltage * 10),
                                      pDcChargingInfo->Evboard_id);
 
-                checkConnectorOVPState(gunIndex);
+                //checkConnectorOVPState(gunIndex);
             }
 
             switch (pDcChargingInfo->SystemStatus) {

+ 5 - 5
EVSE/Projects/DD360/Apps/ModuleInternalComm/Module_InternalComm.c

@@ -22,8 +22,8 @@
 
 //------------------------------------------------------------------------------
 extern void RelayBoardTask(int uartFD);
-extern void LEDBoardTask(int uartFD);
-extern void FanBoardTask(int uartFD);
+//extern void LEDBoardTask(int uartFD);
+//extern void FanBoardTask(int uartFD);
 extern void AcPlugTask(int uartFD);
 
 //------------------------------------------------------------------------------
@@ -95,9 +95,9 @@ int main(int argc, char *argv[])
 
     RelayBoardTask(fd);
     usleep(100000);
-    LEDBoardTask(fd);
-    usleep(100000);
-    FanBoardTask(fd);
+    //LEDBoardTask(fd);
+    //usleep(100000);
+    //FanBoardTask(fd);
 
     while (isContinue) {
         AcPlugTask(fd);

+ 692 - 192
EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c

@@ -22,10 +22,20 @@ static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
 static struct PrimaryMcuData *ShmPrimaryMcuData = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
+static struct WARNING_CODE_INFO *pSysWarning = NULL;
+static struct LedModuleData *ShmLedModuleData = NULL;
+static struct FanModuleData *ShmFanModuleData = NULL;
 
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
+static struct timeval gFanBoardRunTimer;
+static uint16_t _setFanSpeed = 0;
+static uint16_t fanSpeedSmoothValue = 500;
+
+static Led_Color cur_led_color = {COLOR_MIN_LV};
+static Led_Color led_color;
+static struct timeval _led_priority_time;
 
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -72,24 +82,21 @@ static void StopCheckRelayInfo(uint8_t _chkIndex)
 static void StartCheckRelayInfo(uint8_t _chkIndex, uint8_t toState)
 {
     // SMR1 *2 + SMR2 * 2 + Parallel * 2
-    static time_t lastCheckRelayStateTimer[6] = {0};
-    time_t nowTime = {0};
+    static struct timeval lastCheckRelayStateTimer[6] = {0};
     //uint8_t *pCheckRelayState = (uint8_t *)ShmDcCommonData->CheckRelayStatus[_chkIndex];
 
     if (ShmDcCommonData->CheckRelayStatus[_chkIndex] == STOP) {
-        time(&lastCheckRelayStateTimer[_chkIndex]);
+        gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         ShmDcCommonData->CheckRelayStatus[_chkIndex] = START;
     } else {
-        time(&nowTime);
-
-        if (nowTime - lastCheckRelayStateTimer[_chkIndex] >= 1) {
+        if ((GetTimeoutValue(lastCheckRelayStateTimer[_chkIndex]) / 1000000) >= 1) {
             //log_info("relay welding or driving fault = %d \n", _chkIndex);
             if (toState == 1) {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_DRIVING;
             } else {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_WELDING;
             }
-            lastCheckRelayStateTimer[_chkIndex] = nowTime;
+            gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         }
     }
 }
@@ -377,13 +384,16 @@ void CheckOutputPowerOverCarReq(uint8_t index)
                           (pDcChargingInfo->EvBatterytargetVoltage * 10));
                 if ((GetTimeoutValue(_checkOutputVolProtectTimer[index]) / 1000) >= OUTPUT_VOL_CHK_TIME) {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
-                        pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.ChaConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                        pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.CCSConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_GB) {
-                        pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.GBTConnectOVP = YES;
                     }
-                    pDcChargingInfo->StopChargeFlag = YES;
+                    //pDcChargingInfo->StopChargeFlag = YES;
                 }
             }
         } else {
@@ -550,11 +560,27 @@ void SetK1K2RelayStatus(uint8_t index)
         //if (pDcChargingInfo->RelayWeldingCheck != YES) {
         //    break;
         //}
-
         if (pRegGunPNState->GunN == NO) {
-            pOutputGunPNState->GunN = YES;
-        } else if (pRegGunPNState->GunP == NO) {
-            pOutputGunPNState->GunP = YES;
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunN = YES;
+            } else {
+                pOutputGunPNState->GunN = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunN = NO;
+            }
+        }
+        if (pRegGunPNState->GunP == NO) {
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunP = YES;
+            } else {
+                pOutputGunPNState->GunP = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunP = NO;
+            }
         }
         break;
 
@@ -562,11 +588,12 @@ void SetK1K2RelayStatus(uint8_t index)
     case S_COMPLETE:
     case S_ALARM:
         if ((pDcChargingInfo->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR) {
-            if (pRegGunPNState->GunP == YES) {
-                pOutputGunPNState->GunP = NO;
-            } else if (pRegGunPNState->GunN == YES) {
-                pOutputGunPNState->GunN = NO;
-            }
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
         }
         break;
 
@@ -582,6 +609,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pRegGunPNState->GunP = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
 
     case S_CCS_PRECHARGE_ST1:
@@ -596,6 +627,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pOutputPreChargingState->CcsPrecharge = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
     }
 }
@@ -721,7 +756,7 @@ void CableCheckDetected(uint8_t index)
              pSysConfig->AlwaysGfdFlag)
        ) {
         if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                pDcChargingInfo->SystemStatus <= S_TERMINATING) ||
+                pDcChargingInfo->SystemStatus < S_TERMINATING) ||
                 (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                  pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)
            ) {
@@ -735,7 +770,7 @@ void CableCheckDetected(uint8_t index)
                       ) {
                 SetGfdConfig(targetID, GFD_PRECHARGE);
             } else if ((pDcChargingInfo->SystemStatus >= S_CHARGING) &&
-                       (pDcChargingInfo->SystemStatus <= S_TERMINATING)
+                       (pDcChargingInfo->SystemStatus < S_TERMINATING)
                       ) {
                 if ((pDcChargingInfo->Type == _Type_GB) ||
                         (pDcChargingInfo->Type == _Type_Chademo)
@@ -745,9 +780,7 @@ void CableCheckDetected(uint8_t index)
                     SetGfdConfig(targetID, GFD_CHARGING);
                 }
             }
-        } else if (pDcChargingInfo->SystemStatus == S_COMPLETE ||
-                   pDcChargingInfo->SystemStatus == S_PREPARNING ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+        } else {
             SetGfdConfig(targetID, GFD_IDLE);
         }
     }
@@ -1124,6 +1157,495 @@ static void outputRelayInit(int fd)
     }
 }
 
+static bool IsRelayProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Relay Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
+static void SetFanModuleSpeed(void)
+{
+    {
+        FanSpeed _fanSpeed = {0};
+
+        _setFanSpeed += fanSpeedSmoothValue;
+
+        if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed) {
+            _setFanSpeed = ShmFanModuleData->SetFan1Speed;
+        }
+
+        //printf("_setFanSpeed = %d \n", _setFanSpeed);
+        _fanSpeed.speed[0] = _setFanSpeed;
+
+        _fanSpeed.speed[1] = _setFanSpeed;
+
+        _fanSpeed.speed[2] = _setFanSpeed;
+
+        _fanSpeed.speed[3] = _setFanSpeed;
+
+        if (Config_Fan_Speed(Uart5Fd, ADDR_FAN, &_fanSpeed) == PASS) {
+            //log_info("successfully Fan\n");
+        }
+    }
+}
+
+// 風扇速度
+static void GetFanSpeed(void)
+{
+    FanSpeed fanSpeed = {0};
+
+    //log_info("Get fan board speed \n");
+    if (Query_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed) == PASS) {
+        ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0];
+        ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1];
+        ShmFanModuleData->PresentFan3Speed = fanSpeed.speed[2];
+        ShmFanModuleData->PresentFan4Speed = fanSpeed.speed[3];
+//      log_info("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+//      log_info("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]);
+//      log_info("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]);
+//      log_info("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]);
+        // Config_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed[0]);
+        //SysInfoData (SystemFanRotaSpeed)
+    }
+}
+
+static void GetFanSpeedByFunction(void)
+{
+    if (pSysConfig->SwitchDebugFlag == YES) {
+        return;
+    }
+
+    // 風控修改 :
+    // ******************************************************* //
+    //
+    //       當前PSU輸出總 KW       PSU Temp
+    // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
+    //       當前樁最大功率 KW         45
+    //
+    // ******************************************************* //
+
+    // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower
+    uint32_t _maxPower = ShmPsuData->SystemAvailablePower;
+    // 當前PSU輸出總 KW & PSU Temp :
+    uint8_t temp = 0;
+    uint8_t index = 0;
+    uint8_t count = 0;
+    uint8_t gunIndex = 0;
+    uint8_t _temp_diff = 0;
+    float power = 0;
+    double _pw_rate = 0;
+    double _temp_rate = 0;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (index = 0; index < ShmPsuData->GroupCount; index++) {
+        for (count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) {
+            if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp) {
+                temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp;
+            }
+        }
+    }
+
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+
+        power += (pDcChargingInfo->PresentChargingPower * 10);
+    }
+
+    if (_maxPower > 0) {
+        _pw_rate = power / (double)_maxPower;
+    }
+
+    if (temp > 0) {
+        _temp_rate = (double)temp / 50;
+    }
+
+    if (temp > 45) {
+        _temp_diff = temp - 70;
+    }
+
+    ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED) {
+        ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
+    }
+
+    if (ShmFanModuleData->TestFanSpeed < 0) {
+        ShmFanModuleData->TestFanSpeed = 0;
+    }
+//
+//  printf("power = %f \n", power);
+//  printf("_maxPower = %d \n", _maxPower);
+//  printf("temp = %d \n", temp);
+//
+//  printf("_pw_rate = %f \n", _pw_rate);
+//  printf("_temp_rate = %f \n", _temp_rate);
+//  printf("_temp_diff = %d \n", _temp_diff);
+//  printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff));
+//  printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed);
+}
+
+static void SetRtcData_Fan(void)
+{
+    struct timeb csuTime;
+    struct tm *tmCSU;
+    Rtc rtc = {0};
+
+    ftime(&csuTime);
+    tmCSU = localtime(&csuTime.time);
+    //  log_info("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+    //          tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+    //          tmCSU->tm_sec);
+
+    rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+    rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+    rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+    rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+    rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+    rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+    rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+    rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+    rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+    rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+    rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+    rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+    rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+    rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+    if (Config_Rtc_Data(Uart5Fd, ADDR_FAN, &rtc) == PASS) {
+        //log_info("SetRtc (FB) sucessfully. \n");
+    }
+}
+
+static void SetModelName_Fan(void)
+{
+    if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
+        log_info("Set Model name PASS = %s \n", pSysConfig->ModelName);
+    }
+}
+
+static void GetFwAndHwVersion_Fan(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // FanModuleData
+        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW);
+    }
+
+    if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW);
+    }
+}
+
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
+static void fanBoardPorcess(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (ShmFanModuleData->SelfTest_Comp == YES ||
+            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
+            pSysInfo->FanModuleFwRev[0] != '\0') {
+        ShmFanModuleData->SelfTest_Comp = YES;
+
+        if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
+            //GetPsuTempForFanSpeed();
+            GetFanSpeedByFunction();
+            GetFanSpeed();
+            pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
+            gettimeofday(&gFanBoardRunTimer, NULL);
+
+            ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+
+            //log_info("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
+            SetFanModuleSpeed();
+        }
+    }
+}
+
+static void GetFwAndHwVersion_Led(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS) {
+        // LedModuleData
+        strcpy((char *) ShmLedModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *) pSysInfo->LedModuleFwRev, ver.Version_FW);
+        log_info("GetFwAndHwVersion_Led s1 = %s \n", ver.Version_FW);
+        ShmLedModuleData->SelfTest_Comp = YES;
+    } else {
+        //log_info("GetFwAndHwVersion_Led fail \n");
+    }
+
+//  if (Query_HW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS)
+//  {
+//      // SystemInfo
+//      strcpy((char *) pSysInfo->RelayModuleHwRev, ver.Version_FW);
+//      //log_info("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW);
+//  }
+}
+
+static bool IsNoneMatchLedColor(void)
+{
+    bool result = false;
+
+    if (cur_led_color.Connect_1_Red != led_color.Connect_1_Red ||
+            cur_led_color.Connect_1_Green != led_color.Connect_1_Green ||
+            cur_led_color.Connect_1_Blue != led_color.Connect_1_Blue ||
+            cur_led_color.Connect_2_Red != led_color.Connect_2_Red ||
+            cur_led_color.Connect_2_Green != led_color.Connect_2_Green ||
+            cur_led_color.Connect_2_Blue != led_color.Connect_2_Blue) {
+        result = true;
+    }
+
+    return result;
+}
+
+//static void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
+static void SetLedColor(void)
+{
+    static uint8_t _checkLedChanged = 3;
+    struct ChargingInfoData *chargingData_1 = NULL;
+    struct ChargingInfoData *chargingData_2 = NULL;
+    uint8_t _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST;
+
+    if (pSysConfig->TotalConnectorCount == 1) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+    } else if (pSysConfig->TotalConnectorCount == 2) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(1);
+    }
+
+    if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_DARKEST) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST;
+    } else if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_MEDIUM) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM;
+    }
+
+    //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) {
+        led_color.Connect_1_Green = COLOR_MIN_LV;
+        led_color.Connect_1_Blue = COLOR_MIN_LV;
+        led_color.Connect_1_Red = _colorBuf;
+        led_color.Connect_2_Green = COLOR_MIN_LV;
+        led_color.Connect_2_Blue = COLOR_MIN_LV;
+        led_color.Connect_2_Red = _colorBuf;
+    } else {
+        if (pSysInfo->IsAlternatvieConf) {
+            if ((chargingData_1->SystemStatus == S_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    (chargingData_2->SystemStatus == S_BOOTING ||
+                     chargingData_2->SystemStatus == S_IDLE ||
+                     chargingData_2->SystemStatus == S_RESERVATION)) {
+#if defined DD360Audi
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = _colorBuf;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = _colorBuf;
+#else
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                       (chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+                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_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION ||
+                    chargingData_1->SystemStatus == S_MAINTAIN) {
+
+                if (chargingData_1->IsAvailable == NO) { //For Audi
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = _colorBuf;
+                    led_color.Connect_1_Red = _colorBuf;
+#else
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+            }
+
+            // --------------------------------------------------------------------------
+            if (chargingData_2->SystemStatus == S_BOOTING ||
+                    chargingData_2->SystemStatus == S_IDLE ||
+                    chargingData_2->SystemStatus == S_RESERVATION ||
+                    chargingData_2->SystemStatus == S_MAINTAIN) {
+                if (chargingData_2->IsAvailable == NO) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = _colorBuf;
+                    led_color.Connect_2_Red = _colorBuf;
+#else
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_2_Green = COLOR_MIN_LV;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
+        }
+    }
+
+    if (_checkLedChanged > 0) {
+        if (Config_Led_Color(Uart5Fd, ADDR_LED, &led_color) == PASS) {
+            _checkLedChanged--;
+
+            cur_led_color.Connect_1_Red     = led_color.Connect_1_Red;
+            cur_led_color.Connect_1_Green   = led_color.Connect_1_Green;
+            cur_led_color.Connect_1_Blue    = led_color.Connect_1_Blue;
+            cur_led_color.Connect_2_Red     = led_color.Connect_2_Red;
+            cur_led_color.Connect_2_Green   = led_color.Connect_2_Green;
+            cur_led_color.Connect_2_Blue    = led_color.Connect_2_Blue;
+        }
+    } else if (IsNoneMatchLedColor()) {
+        _checkLedChanged = 3;
+    }
+}
+
+static void LEDBoardSelfTest(void)
+{
+    // 自檢階段處理,自檢階段如果讀不到版號則代表該系統沒有掛燈板
+    if (ShmLedModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+#if defined DD360 ||defined DD360Audi
+    GetFwAndHwVersion_Led();
+    sleep(1);
+    gettimeofday(&_led_priority_time, NULL);
+
+    return;
+#endif //defined DD360 || defined DD360Audi
+
+    // 自檢階段
+    if (pSysInfo->SelfTestSeq <= _STEST_PSU_CAP) {
+        GetFwAndHwVersion_Led();
+        sleep(1);
+        gettimeofday(&_led_priority_time, NULL);
+    } else {
+        // 自檢階段沒有問到版號
+        if (pAlarmCode->AlarmEvents.bits.LedboardStestFail == NO) {
+            pAlarmCode->AlarmEvents.bits.LedboardStestFail = YES;
+        }
+    }
+}
+
+static void LEDBoardProcess(void)
+{
+    //struct ChargingInfoData *pDcChargingInfo0 = NULL;
+    //struct ChargingInfoData *pDcChargingInfo1 = NULL;
+
+    if (ShmLedModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (GetTimeoutValue(_led_priority_time) / 1000 >= 1000) {
+
+        //if (pSysConfig->TotalConnectorCount == 1) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo0);
+        //} else if (pSysConfig->TotalConnectorCount == 2) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
+        //}
+        SetLedColor();
+        gettimeofday(&_led_priority_time, NULL);
+    }
+}
+
 void RelayBoardTask(int uartFD)
 {
     pid_t pid = fork();
@@ -1143,6 +1665,9 @@ void RelayBoardTask(int uartFD)
         ShmPsuData = (struct PsuData *)GetShmPsuData();
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
+        pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
+        ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
+        ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
 
         Uart5Fd = uartFD;
 
@@ -1150,214 +1675,189 @@ void RelayBoardTask(int uartFD)
         outputRelayInit(uartFD);
 
         while (isContinue) {
+
+            if(IsRelayProcessNeedPause() == true)
+            {
+                sleep(1);
+                continue;
+            }
+
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
             if (ShmRelayModuleData->SelfTest_Comp == NO) {
                 GetFwAndHwVersion_Relay();
                 SetModelName_Relay(); //DS60-120 add
                 SetRtcData_Relay();
                 sleep(1);
-
-                continue;
             }
 
-            // ==============優先權最高 10 ms ==============
-            // 輸出電壓
-            GetPersentOutputVol();
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardSelfTest();
+#endif //NO_FAN_BOARD
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-            // 三相輸入電壓
-            GetPresentInputVol();
-#endif //!defined DD360 && !defined DD360Audi
+#if !defined DD360ComBox
+            LEDBoardSelfTest();
+#endif //defined DD360ComBox
 
-            // 讀取當前 AC relay 狀態
-            regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+            if (ShmRelayModuleData->SelfTest_Comp == YES)
+            {
+                // ==============優先權最高 10 ms ==============
+                // 輸出電壓
+                GetPersentOutputVol();
 
-            GetRelayOutputStatus();
+    #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                // 三相輸入電壓
+                GetPresentInputVol();
+    #endif //!defined DD360 && !defined DD360Audi
 
-            for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
-                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+                // 讀取當前 AC relay 狀態
+                regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
 
-                // Cable check (Set)
-                CableCheckDetected(i);
+                GetRelayOutputStatus();
 
-                // check k1 k2 relay 狀態
-                CheckK1K2RelayOutput(i);
+                // Cable check (Get)
+                GetGfdAdc();
 
-                // 依據當前各槍的狀態選擇 搭上/放開 Relay
-                SetK1K2RelayStatus(i);
+                for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-                if (pSysConfig->PhaseLossPolicy == YES) {
-                    CheckPhaseLossStatus(i);
-                }
+                    // Cable check (Set)
+                    CableCheckDetected(i);
 
-                CheckAcInputOvpStatus(i);
-#endif //!defined DD360 && !defined DD360Audi
+                    // check k1 k2 relay 狀態
+                    CheckK1K2RelayOutput(i);
 
-                if (pDcChargingInfo->SystemStatus == S_IDLE ||
-                        pDcChargingInfo->SystemStatus == S_RESERVATION ||
-                        pDcChargingInfo->SystemStatus == S_MAINTAIN) {
-                    //pDcChargingInfo->RelayWeldingCheck = NO;
-                    //_isRelayWelding[i] = NO;
-                    _isOvpChkTimeFlag[i] = NO;
-                    //ResetDetAlarmStatus(i); //DS60-120 add
-                }
+                    // 依據當前各槍的狀態選擇 搭上/放開 Relay
+                    SetK1K2RelayStatus(i);
 
-                if (pDcChargingInfo->SystemStatus == S_BOOTING ||
-                        (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                         pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
-                        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
-                         pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
-                        pSysInfo->WaitForPlugit == YES ||
-                        (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
-                         pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
-                   ) {
-                    pDcChargingInfo->IsReadyToCharging = YES;
-                    isCharging = true;
-
-                    // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-                    //if (pDcChargingInfo->Type == _Type_GB) {
-                    //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                    //            pDcChargingInfo->RelayWeldingCheck == NO) {
-                    //        CheckRelayWeldingStatus(i);
-                    //    }
-                    //} else {
-                    //pDcChargingInfo->RelayWeldingCheck = YES;
-                    //}
-
-                    if (pDcChargingInfo->SystemStatus == S_CHARGING) {
-                        CheckOutputPowerOverCarReq(i);
-                        //CheckOutputVolNoneMatchFire(i);
+#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                    if (pSysConfig->PhaseLossPolicy == YES) {
+                        CheckPhaseLossStatus(i);
                     }
-                    /*else {
-                        _isOutputNoneMatch[i] = NO;
-                    }*/
-                } else {
-                    pDcChargingInfo->IsReadyToCharging = NO;
-                }
-            }
 
-            // Cable check (Get)
-            GetGfdAdc();
-
-            // 橋接 relay
-            SetParalleRelayStatus();
+                    CheckAcInputOvpStatus(i);
+#endif //!defined DD360 && !defined DD360Audi
 
-            // 搭上 AC Contactor
-            //if (isCharging) {
-            //    outputRelay.relay_event.bits.AC_Contactor = YES;
-            //} else {
-            //    outputRelay.relay_event.bits.AC_Contactor = NO;
-            //}
+                    if (pDcChargingInfo->SystemStatus == S_IDLE ||
+                            pDcChargingInfo->SystemStatus == S_RESERVATION ||
+                            pDcChargingInfo->SystemStatus == S_MAINTAIN) {
+                        //pDcChargingInfo->RelayWeldingCheck = NO;
+                        //_isRelayWelding[i] = NO;
+                        _isOvpChkTimeFlag[i] = NO;
+                        //ResetDetAlarmStatus(i); //DS60-120 add
+                    }
 
-            if (isCharging ||
-                    (ShmPsuData->Work_Step >= _TEST_MODE &&
-                     ShmPsuData->Work_Step <= _TEST_MODE)) {
-                isStopChargingCount = false;
-                outputRelay.relay_event.bits.AC_Contactor = YES;
-            } else {
-                if (!isStopChargingCount) {
-                    gettimeofday(&_close_ac_contactor, NULL);
-                    isStopChargingCount = true;
-                } else {
-                    if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
-                            GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
-                        outputRelay.relay_event.bits.AC_Contactor = NO;
+                    if (pDcChargingInfo->SystemStatus == S_BOOTING ||
+                            (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
+                             pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
+                            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                             pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                            pSysInfo->WaitForPlugit == YES ||
+                            (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
+                             pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
+                       ) {
+                        pDcChargingInfo->IsReadyToCharging = YES;
+                        isCharging = true;
+
+                        // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
+                        //if (pDcChargingInfo->Type == _Type_GB) {
+                        //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                        //            pDcChargingInfo->RelayWeldingCheck == NO) {
+                        //        CheckRelayWeldingStatus(i);
+                        //    }
+                        //} else {
+                        //pDcChargingInfo->RelayWeldingCheck = YES;
+                        //}
+
+                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                            CheckOutputPowerOverCarReq(i);
+                            //CheckOutputVolNoneMatchFire(i);
+                        }
+                        /*else {
+                            _isOutputNoneMatch[i] = NO;
+                        }*/
+                    } else {
+                        pDcChargingInfo->IsReadyToCharging = NO;
                     }
                 }
-            }
 
-            if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
-                RunForceStopProcess();
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
-                outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
-            }
+                    // 橋接 relay
+                    SetParalleRelayStatus();
 
-            // 搭上/鬆開 Relay
-            if (IsNoneMatchRelayStatus()) {
-                if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
-                    //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
-
-                    //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
-                    //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
-                    //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
-                    //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
-                    //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
-                    //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
-                    //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
-
-                    //MatchRelayStatus();
-
-                    //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
-                    //         regRelay.relay_event.bits.AC_Contactor,
-                    //         regRelay.relay_event.bits.Gun1_P,
-                    //         regRelay.relay_event.bits.Gun1_N,
-                    //         regRelay.relay_event.bits.Gun2_P,
-                    //         regRelay.relay_event.bits.Gun2_N,
-                    //         regRelay.relay_event.bits.CCS_Precharge,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_P,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_N);
+                    // 搭上 AC Contactor
+                    //if (isCharging) {
+                    //    outputRelay.relay_event.bits.AC_Contactor = YES;
+                    //} else {
+                    //    outputRelay.relay_event.bits.AC_Contactor = NO;
+                    //}
 
-                }
-            } /*else {
-                    log_info("======== Relay Status Start========\n");
-                    if (regRelay.relay_event.bits.AC_Contactor == YES) {
-                        log_info("AC Power : ON \n");
+                    if (isCharging ||
+                            (ShmPsuData->Work_Step >= _TEST_MODE &&
+                             ShmPsuData->Work_Step <= _TEST_MODE)) {
+                        isStopChargingCount = false;
+                        outputRelay.relay_event.bits.AC_Contactor = YES;
                     } else {
-                        log_info("AC Power : OFF \n");
+                        if (!isStopChargingCount) {
+                            gettimeofday(&_close_ac_contactor, NULL);
+                            isStopChargingCount = true;
+                        } else {
+                            if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
+                                    GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
+                                outputRelay.relay_event.bits.AC_Contactor = NO;
+                            }
+                        }
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_P == YES) {
-                        log_info("Conn1(+) : ON \n");
-                    } else {
-                        log_info("Conn1(+) : OFF \n");
+                    if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_N == YES) {
-                        log_info("Conn1(-) : ON \n");
-                    } else {
-                        log_info("Conn1(-) : OFF \n");
+                    if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
+                        RunForceStopProcess();
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_P == YES) {
-                        log_info("Conn2(+) : ON \n");
-                    } else {
-                        log_info("Conn2(+) : OFF \n");
+                    if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
+                        outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_N == YES) {
-                        log_info("Conn2(-) : ON \n");
-                    } else {
-                        log_info("Conn2(-) : OFF \n");
-                    }
+                    // 搭上/鬆開 Relay
+                    if (IsNoneMatchRelayStatus()) {
+                        if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
+                            //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+
+                            //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
+                            //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
+                            //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
+                            //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
+                            //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
+                            //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
+                            //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
+
+                            //MatchRelayStatus();
+
+                            //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+                            //         regRelay.relay_event.bits.AC_Contactor,
+                            //         regRelay.relay_event.bits.Gun1_P,
+                        //         regRelay.relay_event.bits.Gun1_N,
+                        //         regRelay.relay_event.bits.Gun2_P,
+                        //         regRelay.relay_event.bits.Gun2_N,
+                        //         regRelay.relay_event.bits.CCS_Precharge,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_P,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_N);
 
-                    if (regRelay.relay_event.bits.CCS_Precharge == YES) {
-                        log_info("Precharge : ON \n");
-                    } else {
-                        log_info("Precharge : OFF \n");
                     }
+                }
+            }
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) {
-                        log_info("Parallel(+) : ON \n");
-                    } else {
-                        log_info("Parallel(+) : OFF \n");
-                    }
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardPorcess();
+#endif //NO_FAN_BOARD
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) {
-                        log_info("Parallel(-) : ON \n");
-                    } else {
-                        log_info("Parallel(-) : OFF \n");
-                    }
-                    log_info("======== Relay Status End========\n");
-                }*/
+#if !defined DD360ComBox
+            LEDBoardProcess();
+#endif //defined DD360ComBox
+
+            usleep(10000);
         }
-        usleep(100000);
     }
 }

+ 68 - 1
EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -288,6 +288,7 @@ static void checkChillerStatus(Gpio_out *gpio)
     uint8_t chillerCount = 0;
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
+    static ChillerInfo _chiller;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
@@ -309,6 +310,28 @@ static void checkChillerStatus(Gpio_out *gpio)
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
+        if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+        {
+            pChillerInfo->ChillerSwitch = YES;
+            pChillerInfo->ChillerOnTime = time((time_t *)NULL);
+        }
+        else
+        {
+            if(pChillerInfo->ChillerSwitch == YES)
+            {
+                //10分鐘後停止
+                if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
+                {
+                    pChillerInfo->ChillerSwitch = NO;
+                }
+            }
+            else
+            {
+                pChillerInfo->ChillerSwitch = NO;
+            }
+        }
+#if 0
         if ((pDcChargingInfo->PresentChargingCurrent) >= 150) { //當前電壓於150A,打開水冷機
             pChillerInfo->ChillerSwitch = YES;
             pChillerInfo->ChillerOnTime = time((time_t *)NULL);
@@ -328,9 +351,25 @@ static void checkChillerStatus(Gpio_out *gpio)
                 pChillerInfo->ChillerSwitch = NO;
             }
         }
+#endif
+    }
+
+    uint8_t _chillerNeedOn = NO;
+    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    {
+        pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
+        if(pChillerInfo->ChillerSwitch == YES)
+        {
+            _chillerNeedOn = YES;
+        }
     }
 
-    pGpio->AC_Connector = pChillerInfo->ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
+    if(_chiller.ChillerSwitch != _chillerNeedOn)
+    {
+        log_info("Chiller Need Turn %s\n", _chillerNeedOn == YES ? "ON" : "OFF");
+    }
+    _chiller.ChillerSwitch = _chillerNeedOn;
+    pGpio->AC_Connector = _chiller.ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
 }
 
 void SetOutputGpio(int fd, uint8_t outputValue)
@@ -497,6 +536,29 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
 //    }
 //}
 
+static bool IsPrimaryProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Primary Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
 int main(void)
 {
     int Uart1Fd = -1;
@@ -545,6 +607,11 @@ int main(void)
     //Initialization();
 
     for (;;) {
+        if(IsPrimaryProcessNeedPause() == true)
+        {
+            sleep(1);
+            continue;
+        }
         // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
         // 模組更新 FW 後,需重新做
         if (ShmPrimaryMcuData->SelfTest_Comp != PASS) {

+ 8 - 2
EVSE/Projects/DD360/Apps/ReadCmdline.c

@@ -1097,10 +1097,16 @@ static void resdGunAndChillerTemp(void)
 
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-                printTimeMsg("get %d gun temp = %d, chiller temp = %d\r\n",
+                printTimeMsg("get gun %d temp = %3d, chiller = %3d, ConnTemp = %3d, %3d,SysTemp = %3d, %3d, %3d, %3d\r\n",
                              i,
                              pDcChargingInfo->ConnectorTemp,
-                             pDcChargingInfo->ChillerTemp);
+                             pDcChargingInfo->ChillerTemp,
+                             ShmDcCommonData->ConnectorTemp[i][0],
+                             ShmDcCommonData->ConnectorTemp[i][1],
+                             ShmDcCommonData->SystemTemp[0],
+                             ShmDcCommonData->SystemTemp[1],
+                             ShmDcCommonData->SystemTemp[2],
+                             ShmDcCommonData->SystemTemp[3]);
             }//for
             ftime(&showTime);
         }

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


BIN
EVSE/Projects/DD360/Images/u-boot.img


BIN
EVSE/Projects/DD360/output/FactoryConfig


BIN
EVSE/Projects/DD360/output/Module_DoComm


BIN
EVSE/Projects/DD360/output/Module_EvComm


BIN
EVSE/Projects/DD360/output/Module_EventLogging


BIN
EVSE/Projects/DD360/output/Module_InternalComm


BIN
EVSE/Projects/DD360/output/Module_LcmControl


BIN
EVSE/Projects/DD360/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360/output/ReadCmdline


BIN
EVSE/Projects/DD360/output/main


+ 2 - 1
EVSE/Projects/DD360Audi/Apps/CSU/UpgradeFW.c

@@ -328,7 +328,7 @@ void CheckFwUpdateFunction(void)
         for (uint8_t gun_index = 0; gun_index < pSysConfig->TotalConnectorCount; gun_index++) {
             setChargerMode(gun_index, MODE_UPDATE);
         }
-
+        sleep(1);
         uint8_t updateResult = CheckUpdateProcess();
 
         if (updateResult == PASS) {
@@ -366,6 +366,7 @@ void CheckFwUpdateFunction(void)
 
                 pAcChargingInfo->SystemStatus = MODE_UPDATE;
             }
+            sleep(1);
 
             uint8_t updateResult = CheckUpdateProcess();
 

+ 270 - 92
EVSE/Projects/DD360Audi/Apps/CSU/main.c

@@ -77,7 +77,7 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.11.00.0000.00"; // "V0.16.00.0000.00";
+char *fwVersion = "V1.12.00.0000.00"; // "V0.16.00.0000.00";
 
 //sqlite3 *localDb;
 bool isDb_ready;
@@ -96,6 +96,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code);
 void ReleaseAlarmCode(uint8_t gunIndex);
 void ResetChargerAlarmCode(uint8_t gunIndex, char *code);
 void AdjustChargerCurrent(void);
+void UpdateErrorCodeToOcpp(uint8_t index);
 
 //------------------------------------------------------------------------------
 //Primary.c
@@ -390,15 +391,51 @@ static void checkGunOTPState(uint8_t gunIndex)
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
         if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) {
-                RecordAlarmCode(gunIndex, "012323");
+                if (((gunIndex == 0) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                         ||
+                    ((gunIndex == 1) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+                   ) {
+                    RecordAlarmCode(gunIndex, "012323");
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                }
+                else
+                {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                }
             } else if (pDcChargingInfo->ChillerTemp != 0 &&
                        pDcChargingInfo->ChillerTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012323");
+                //ResetChargerAlarmCode(gunIndex, "012323");
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
             }
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011038");
-            ResetChargerAlarmCode(gunIndex, "012323");
+            //RecordAlarmCode(gunIndex, "011038");
+            //ResetChargerAlarmCode(gunIndex, "012323");
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+            if (((gunIndex == 0) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                     ||
+                ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+               ) {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            }
+            else
+            {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+            }
+        }
+
+        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
+        {
+            RecordAlarmCode(gunIndex, "011037");
         }
     }
 
@@ -407,14 +444,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012229");
+                //ResetChargerAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
             //RecordAlarmCode(gunIndex, "011018");
-            ResetChargerAlarmCode(gunIndex, "012229");
+            //ResetChargerAlarmCode(gunIndex, "012229");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
         }
         break;
 
@@ -425,16 +467,20 @@ static void checkGunOTPState(uint8_t gunIndex)
 
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012230");
+                //ResetChargerAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
             }
-
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = NO;
             //ResetChargerAlarmCode(gunIndex, "011019");
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011019");
-            ResetChargerAlarmCode(gunIndex, "012230");
+            //RecordAlarmCode(gunIndex, "011019");
+            //ResetChargerAlarmCode(gunIndex, "012230");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = YES;
         }
         break;
 
@@ -442,14 +488,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012231");
+                //ResetChargerAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011020");
-            ResetChargerAlarmCode(gunIndex, "012231");
+            //RecordAlarmCode(gunIndex, "011020");
+            //ResetChargerAlarmCode(gunIndex, "012231");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = YES;
         }
         break;
     }
@@ -1690,30 +1741,46 @@ void ResetChargerAlarmCode(uint8_t gunIndex, char *code)
         ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
     }
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
-        if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
-           ) {
-            strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
-        }
+    //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
+    //    if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
+    //       ) {
+    //        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
+    //    }
+    //}
+    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012229", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012230", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012231", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011011", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011013", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011015", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011012", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011014", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011016", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011018", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011019", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011020", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL) {
+        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
 }
 
@@ -1721,10 +1788,20 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
-        memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+    if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+    {
+        if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+            memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+        }
+
+        if (pDcChargingInfo->StopChargeFlag == NO)
+        {
+            pDcChargingInfo->StopChargeFlag = YES;
+        }
     }
 
+#if 0
     if (strcmp(code, "012234") == EQUAL) {
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
     } else if (strcmp(code, "012235") == EQUAL) {
@@ -1792,6 +1869,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
             ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
         }
     }
+#endif
 }
 
 void ReleaseAlarmCode(uint8_t gunIndex)
@@ -1801,26 +1879,29 @@ void ReleaseAlarmCode(uint8_t gunIndex)
     //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
     //    return;
     //}
-
+#if 0
     // 回 idle 後主要清除  GFD Trip、UVP、OVP、GFD Warning
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL) {
         memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
-
+#endif
     switch (pDcChargingInfo->Type) {
     case _Type_Chademo:
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012234", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012289", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012217", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012296", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_CCS_2:
@@ -1828,13 +1909,16 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012235", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012288", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012219", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012297", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_GB:
@@ -1842,16 +1926,19 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012236", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012290", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012221", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012298", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
     }
-
+#if 0
     //system alarm
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL ||
@@ -1862,6 +1949,8 @@ void ReleaseAlarmCode(uint8_t gunIndex)
        ) {
         memset(pDcChargingInfo->ConnectorAlarmCode, 0, sizeof(pDcChargingInfo->ConnectorAlarmCode));
     }
+#endif
+    memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
 }
 
 //===============================================
@@ -1874,6 +1963,7 @@ void ChargingTerminalProcess(uint8_t gunIndex)
 
 void ChargingAlarmProcess(uint8_t gunIndex)
 {
+    UpdateErrorCodeToOcpp(gunIndex);
     setChargerMode(gunIndex, MODE_ALARM);
 }
 
@@ -1966,6 +2056,9 @@ void EmcOccureByString(char *code)
                     (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                      pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
                 //ChargingTerminalProcess(gun);
+                if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+                    memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+                }
                 ChargingAlarmProcess(gun);
             }
         }
@@ -2007,6 +2100,31 @@ void ReleaseEmsOccureByString(uint8_t index, char *code)
     }
 }
 
+static void checkOvpState(uint8_t gunIndex, uint8_t gunType)
+{
+    switch(gunType)
+    {
+        case _Type_Chademo:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012217");
+            }
+            break;
+        case _Type_CCS_2:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012219");
+            }
+            break;
+        case _Type_GB:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012221");
+            }
+            break;
+    }
+}
+
 //===============================================
 // 確認各小板偵測的錯誤狀況
 //===============================================
@@ -2083,6 +2201,8 @@ void CheckErrorOccurStatus(uint8_t index)
         }
     }
 
+    checkOvpState(index, pDcChargingInfo->Type);
+
     //--------------------------------------------------------------------------
     if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == 0) {
         //Primary
@@ -2096,11 +2216,11 @@ void CheckErrorOccurStatus(uint8_t index)
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "012304", 6);
         }
         //Chiller temperature
-        else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
-        } else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
-        }
+        //else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
+        //} else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
+        //}
     }
 }
 
@@ -3500,8 +3620,8 @@ void UpdateErrorCodeToOcpp(uint8_t index)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
 
-    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->ConnectorAlarmCode);
-    //log_info("%d = EvConnAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->EvConnAlarmCode);
+    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, pDcChargingInfo->ConnectorAlarmCode);
+    //log_info("%d = EvConnAlarmCode = %s\r\n", index, pDcChargingInfo->EvConnAlarmCode);
     if (strcmp((char *)pDcChargingInfo->ConnectorAlarmCode, "") != EQUAL) {
         //if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == EQUAL) {
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].ErrorCode, "InternalError");
@@ -3512,7 +3632,7 @@ void UpdateErrorCodeToOcpp(uint8_t index)
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode, (char *)pDcChargingInfo->EvConnAlarmCode);
     }
 
-    //log_info("2 %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
+    //log_info("Gun %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
 }
 
 void AdjustChargerCurrent()
@@ -3583,10 +3703,10 @@ static bool PrecheckIsPass(uint8_t gunIndex)
 
 static void ReviewCriticalAlarm(void)
 {
-    if (ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
+    if (//ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
             pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES ||
             pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES ||
             pAlarmCode->AlarmEvents.bits.DoorOpen == YES ||
@@ -3613,7 +3733,7 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
 
     // relay welding fault then stop the charging process.
     uint8_t faultCode = RELAY_STATUS_ERROR_NONE;
-    static uint8_t drivingCount = 0;
+    //static uint8_t drivingCount = 0;
 
     if (gunIndex == 0) {
         if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_WELDING ||
@@ -3649,45 +3769,58 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
         // welding
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = YES;
         }
 
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else if (faultCode == RELAY_STATUS_ERROR_DRIVING) {
-        if (drivingCount++ != 2) {
-            return;
-        }
+        //if (drivingCount++ != 2) {
+        //    return;
+        //}
 
         // driving
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011012");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011016");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011014");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = YES;
         }
 
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else {
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = NO;
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = NO;
-        drivingCount = 0;
-
+        //drivingCount = 0;
+#if 0
         if (pDcChargingInfo->Type == _Type_Chademo) {
-            ResetChargerAlarmCode(gunIndex, "011012");
-            ResetChargerAlarmCode(gunIndex, "011011");
+            //ResetChargerAlarmCode(gunIndex, "011012");
+            //ResetChargerAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-            ResetChargerAlarmCode(gunIndex, "011014");
-            ResetChargerAlarmCode(gunIndex, "011013");
+            //ResetChargerAlarmCode(gunIndex, "011014");
+            //ResetChargerAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_GB) {
-            ResetChargerAlarmCode(gunIndex, "011016");
-            ResetChargerAlarmCode(gunIndex, "011015");
+            //ResetChargerAlarmCode(gunIndex, "011016");
+            //ResetChargerAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
         }
+#endif
     }
 }
 
@@ -3810,9 +3943,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012234");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012296");
+            //RecordAlarmCode(gunIndex, "012296");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -3849,9 +3991,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012236");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012298");
+            //RecordAlarmCode(gunIndex, "012298");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           isPrechargeStatus_gb(gunIndex) == 10 &&
@@ -3890,9 +4041,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012235");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012297");
+            //RecordAlarmCode(gunIndex, "012297");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -4153,6 +4313,16 @@ int main(void)
 
         gEvBoardErr.GunErrMessage = 0; //清除系統執行中的錯誤訊息
         gChillerTempErr.TempErrMsg = 0;//清除系統執行中的錯誤訊息
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            // 重新收集各槍的錯誤狀態
+            collectError(gunIndex);
+        }
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+            // convert common status code to alarm event
+            checkEvBoardAlarmState(pDcChargingInfo->Type);
+        }
+        checkChillerAlarmState();
 
         for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -4166,9 +4336,6 @@ int main(void)
             // 確認 Relay Welding or Driving Fault
             CheckRelayWeldingOrDrivingFault(gunIndex);
 
-            // 重新收集各槍的錯誤狀態
-            collectError(gunIndex);
-
             ChkOcppStatus(gunIndex);
 
             if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
@@ -4183,7 +4350,6 @@ int main(void)
             //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-                ReleaseAlarmCode(gunIndex);
 
                 if (isModeChange(gunIndex)) {
                     log_info("S_IDLE================================== %x \n", gunIndex);
@@ -4205,6 +4371,7 @@ int main(void)
                         ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] = NO;
                     }
                     //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, "");
+                    ReleaseAlarmCode(gunIndex);
                 }
 
             case S_RESERVATION:
@@ -4219,16 +4386,26 @@ int main(void)
 
             case S_MAINTAIN:
             case S_FAULT:
+                if (isModeChange(gunIndex)) {
+                    if(pDcChargingInfo->SystemStatus == S_MAINTAIN)
+                    {
+                        log_info("S_MAINTAIN================================== %x \n", gunIndex);
+                    }
+                    if(pDcChargingInfo->SystemStatus == S_FAULT)
+                    {
+                        log_info("S_FAULT================================== %x \n", gunIndex);
+                    }
+                }
                 if (pSysWarning->Level == WARN_LV_ER) {
-                    pDcChargingInfo =  (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
+                    struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
 
                     if (gunIndex == pSysInfo->CurGunSelected) {
                         pSysInfo->SystemPage = _LCM_FIX;
-                    } else if (pDcChargingInfo->SystemStatus != S_IDLE &&
-                               pDcChargingInfo->SystemStatus != S_RESERVATION &&
-                               pDcChargingInfo->SystemStatus != S_MAINTAIN &&
-                               pDcChargingInfo->SystemStatus != S_FAULT) {
-                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                    } else if (pSelectedDcChargingInfo->SystemStatus != S_IDLE &&
+                            pSelectedDcChargingInfo->SystemStatus != S_RESERVATION &&
+                            pSelectedDcChargingInfo->SystemStatus != S_MAINTAIN &&
+                            pSelectedDcChargingInfo->SystemStatus != S_FAULT) {
+                        if (pSelectedDcChargingInfo->SystemStatus == S_CHARGING) {
                             pSysInfo->SystemPage = _LCM_COMPLETE;
                         } else {
                             systemPageRestoreInit();
@@ -4237,9 +4414,11 @@ int main(void)
 
                     ClearDetectPluginFlag();
 
-                    UpdateErrorCodeToOcpp(gunIndex);
-
-                    setChargerMode(gunIndex, MODE_FAULT);
+                    if (pDcChargingInfo->SystemStatus != S_FAULT)
+                    {
+                        UpdateErrorCodeToOcpp(gunIndex);
+                        setChargerMode(gunIndex, MODE_FAULT);
+                    }
                     continue;
                 }
 
@@ -4669,7 +4848,7 @@ int main(void)
                     StopGunInfoTimeoutDet(gunIndex);
                 }
 
-                checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
+                //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
 #if 0
                 if (pDcChargingInfo->Type == _Type_Chademo) {
                     // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
@@ -4808,6 +4987,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4854,6 +5034,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4870,9 +5051,6 @@ int main(void)
                 }
                 break;
             }//switch
-
-            checkEvBoardAlarmState(pDcChargingInfo->Type);
-            checkChillerAlarmState();
         }//for
 
 #if defined DD360Audi

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

@@ -85,6 +85,7 @@
 #define GUN_OTP_VALUE                           (150)
 #define GUN_OTP_RECOVERY                        (140)
 #define UNDEFINED_TEMP                          (255)
+#define TEMP_BOUNDARY                           (200)
 
 #define WARN_LV_NL                              (0) //normal state
 #define WARN_LV_WARN                            (1)
@@ -362,6 +363,8 @@ typedef struct StDcCommonInfo {
     uint8_t CheckRelayStatus[6]; //check Relay welding or driving fault
     uint8_t GunRelayWeldingOccur[2];
     uint8_t GunRelayDrivingOccur[2];
+    uint8_t ConnectorTemp[2][2];
+    uint8_t SystemTemp[4];
     uint8_t SystemModeChange[2]; //for Module_EvRxComm
     PowerAlarmState PowerAlarmState;
     ChillerTempErr ChillerTempErr[2];

+ 19 - 0
EVSE/Projects/DD360Audi/Apps/Define/define.h

@@ -378,6 +378,13 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_OVERRIDE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct Schedule
 {
 	unsigned char   isEnable;     						// 0: disable schedule function  1: enable schedule function
@@ -481,6 +488,7 @@ struct SysConfigData
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
+	struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
 
     /************PowerCabinet************/
     WiringInfoData          WiringInfo;
@@ -798,6 +806,16 @@ typedef struct
     unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
 }CabinetMiscCommand;
 
+typedef struct DC_METER_INFO
+{
+    double presetVoltage;                       // resolution: 1.000v
+    double presentCurrent;                      // resolution: 1.000a
+    double presentPower;                        // resolution: 1.000kw
+    double totlizeImportEnergy;                 // resolution: 1.000kwh
+    double totlizeExportEnergy;                 // resolution: 1.000kwh
+    unsigned char LinkStatus;                   // 0 = unknow ,1 = link , 2 miss link
+}DC_Meter_Info;
+
 struct SysInfoData
 {
 	/**************System***************/
@@ -889,6 +907,7 @@ struct SysInfoData
     CabinetSettingFlag      CabinetSetting;
     CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
+    DC_Meter_Info DcMeterInfo[4];
 };
 
 struct SysConfigAndInfo

+ 4 - 0
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCCS.c

@@ -910,4 +910,8 @@ void ClearAbnormalStatus_CCS(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalCHA.c

@@ -244,4 +244,8 @@ void ClearAbnormalStatus_Chademo(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalGBT.c

@@ -412,4 +412,8 @@ void ClearAbnormalStatus_GB(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 7 - 12
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c

@@ -27,7 +27,7 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     //iflog_info("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
     if (strncmp(string, "000000", 6) == EQUAL ||
-            strncmp(string, "023979", 6) == EQUAL
+            strncmp(string, "012219", 6) == EQUAL
        ) {
         return false;
     }
@@ -39,14 +39,6 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     memcpy(pDcChargingInfo->EvConnAlarmCode, string, 6);
     log_info("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s\n", pDcChargingInfo->EvConnAlarmCode);
 
-    //OVP error
-    if (strcmp(string, "012217") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES; }
-    if (strcmp(string, "012219") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES; }
-    if (strcmp(string, "012221") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES; }
-
-    //UVP error
-    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
-
     if (strcmp(string, "023700") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES; }
     if (strcmp(string, "023704") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoBatteryMalfun = YES; }
     if (strcmp(string, "023705") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoNoPermission = YES; }
@@ -81,7 +73,11 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023734") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReqCurrentMoreThanLimit = YES; }
     if (strcmp(string, "023735") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReCapBmsEqrCurrentExceed = YES; }
     if (strcmp(string, "023736") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoChargeRemainCountDown = YES; }
+    if (strcmp(string, "023980") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_BMS_CHARGE_ALLOW_ERROR = YES; }
+    if (strcmp(string, "023981") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_OUTPUT_VOLTAGE_MORE_THEN_10_PERCENT = YES; }
+    if (strcmp(string, "023982") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_ADC_LESS_THAN_10V = YES; }
 
+    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
     if (strcmp(string, "023701") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEvCommFail = YES; }
     if (strcmp(string, "023737") == EQUAL) { pInfoCode->InfoEvents.bits.CcsRESTemperatureInhibit = YES; }
     if (strcmp(string, "023738") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEVShiftPosition = YES; }
@@ -223,6 +219,8 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023891") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccNotReadyForCharging = YES; }
     if (strcmp(string, "023892") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = YES; }
     if (strcmp(string, "023893") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccFailForQCA7000SetKey = YES; }
+    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
+    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
 
     if (strcmp(string, "023702") == EQUAL) { pInfoCode->InfoEvents.bits.GbEvCommFail = YES; }
     if (strcmp(string, "023900") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = YES; }
@@ -287,8 +285,5 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023976") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_ISOLATE = YES; }
     if (strcmp(string, "023977") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_OUTPUT_CONNECTOR = YES; }
 
-    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
-    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
-
     return true;
 }

+ 1 - 2
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvComm.h

@@ -27,8 +27,7 @@ enum EV_LOG_INDEX {
 
 //------------------------------------------------------------------------------
 typedef struct StChiilerTemp {
-    uint8_t Temp[2];
-    uint8_t Reserved[2];
+    uint8_t Temp[4];
 } ChillerTemp;
 
 //------------------------------------------------------------------------------

+ 21 - 14
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -71,19 +71,17 @@ static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2)
 {
     uint8_t maxTemp = 0;
 
-    if (headTemp1 == UNDEFINED_TEMP &&
-            headTemp2 == UNDEFINED_TEMP) {
+    if (headTemp1 > TEMP_BOUNDARY &&
+            headTemp2 > TEMP_BOUNDARY) {
         return UNDEFINED_TEMP;
     }
 
-    if (headTemp1 != UNDEFINED_TEMP) {
+    if (headTemp1 <= TEMP_BOUNDARY) {
         maxTemp = headTemp1;
-    } else {
-        headTemp1 = 0;
     }
 
-    if (headTemp2 != UNDEFINED_TEMP) {
-        if (headTemp2 > headTemp1) {
+    if (headTemp2 <= TEMP_BOUNDARY) {
+        if (headTemp2 > maxTemp) {
             maxTemp = headTemp2;
         }
     }
@@ -121,7 +119,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
     float adcVoltage = 0.0;
     ChillerTemp *pChillerTemp = (ChillerTemp *)chillerTemp;
 
-    for (i = 0; i < 2; i++) {
+    for (i = 0; i < 4; i++) {
         adcVoltage = 0.0;
         adcVoltage =  ReadAdcVolt(i);
         if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40
@@ -131,7 +129,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
             pChillerTemp->Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60;
             //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500);
         } else {
-            pChillerTemp->Temp[i] = 195;
+            pChillerTemp->Temp[i] = UNDEFINED_TEMP;
         }
 
         /*CcsConnectorTemp1 = ReadAdcVolt(i);
@@ -207,6 +205,7 @@ void CANReceiver(int fd)
         uint8_t ver[16] = {0};
         uint8_t printChillerTemp = NO;
         uint8_t printConnTemp = NO;
+        uint8_t chillerTemp[2] = {0, 0};
         uint8_t maxChillerTemp = 0;
         uint8_t lastChillerTemp = 0;
         uint8_t maxConnTemp = 0;
@@ -470,6 +469,9 @@ void CANReceiver(int fd)
                 }
                 }*/
 
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] = frame.data[1];
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] = frame.data[2];
+
                 if (ShmDcCommonData->TestTemperature == YES) { //ReadCmdline test
                     break;
                 }
@@ -479,12 +481,16 @@ void CANReceiver(int fd)
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
                     getChillerTemperature(&chiilerTemp);
-                    maxChillerTemp = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]);
+                    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 ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) {
                     //    printChillerTemp = YES;
                     //}
-                    if(maxChillerTemp > (lastChillerTemp + 1) || maxChillerTemp < (lastChillerTemp - 1))
+                    if(maxChillerTemp > (lastChillerTemp + 2) || maxChillerTemp < (lastChillerTemp - 2))
                     {
                         lastChillerTemp = maxChillerTemp;
                         printChillerTemp = YES;
@@ -497,7 +503,7 @@ void CANReceiver(int fd)
                 //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
                 //    printConnTemp = YES;
                 //}
-                if(maxConnTemp > (lastConnTemp[targetGun] + 1) || maxConnTemp < (lastConnTemp[targetGun] - 1))
+                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
                 {
                     lastConnTemp[targetGun] = maxConnTemp;
                     printConnTemp = YES;
@@ -515,10 +521,11 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp %d, max chiller = %d\r\n",
+                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d\r\n",
                              targetGun,
                              maxConnTemp,
-                             maxChillerTemp);
+                             chillerTemp[0],
+                             chillerTemp[1]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {

+ 1 - 1
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -748,7 +748,7 @@ int main(int argc, char *argv[])
                                      (pDcChargingInfo->PresentChargingVoltage * 10),
                                      pDcChargingInfo->Evboard_id);
 
-                checkConnectorOVPState(gunIndex);
+                //checkConnectorOVPState(gunIndex);
             }
 
             switch (pDcChargingInfo->SystemStatus) {

+ 5 - 5
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/Module_InternalComm.c

@@ -22,8 +22,8 @@
 
 //------------------------------------------------------------------------------
 extern void RelayBoardTask(int uartFD);
-extern void LEDBoardTask(int uartFD);
-extern void FanBoardTask(int uartFD);
+//extern void LEDBoardTask(int uartFD);
+//extern void FanBoardTask(int uartFD);
 extern void AcPlugTask(int uartFD);
 
 //------------------------------------------------------------------------------
@@ -95,9 +95,9 @@ int main(int argc, char *argv[])
 
     RelayBoardTask(fd);
     usleep(100000);
-    LEDBoardTask(fd);
-    usleep(100000);
-    FanBoardTask(fd);
+    //LEDBoardTask(fd);
+    //usleep(100000);
+    //FanBoardTask(fd);
 
     while (isContinue) {
         AcPlugTask(fd);

+ 692 - 192
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c

@@ -22,10 +22,20 @@ static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
 static struct PrimaryMcuData *ShmPrimaryMcuData = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
+static struct WARNING_CODE_INFO *pSysWarning = NULL;
+static struct LedModuleData *ShmLedModuleData = NULL;
+static struct FanModuleData *ShmFanModuleData = NULL;
 
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
+static struct timeval gFanBoardRunTimer;
+static uint16_t _setFanSpeed = 0;
+static uint16_t fanSpeedSmoothValue = 500;
+
+static Led_Color cur_led_color = {COLOR_MIN_LV};
+static Led_Color led_color;
+static struct timeval _led_priority_time;
 
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -72,24 +82,21 @@ static void StopCheckRelayInfo(uint8_t _chkIndex)
 static void StartCheckRelayInfo(uint8_t _chkIndex, uint8_t toState)
 {
     // SMR1 *2 + SMR2 * 2 + Parallel * 2
-    static time_t lastCheckRelayStateTimer[6] = {0};
-    time_t nowTime = {0};
+    static struct timeval lastCheckRelayStateTimer[6] = {0};
     //uint8_t *pCheckRelayState = (uint8_t *)ShmDcCommonData->CheckRelayStatus[_chkIndex];
 
     if (ShmDcCommonData->CheckRelayStatus[_chkIndex] == STOP) {
-        time(&lastCheckRelayStateTimer[_chkIndex]);
+        gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         ShmDcCommonData->CheckRelayStatus[_chkIndex] = START;
     } else {
-        time(&nowTime);
-
-        if (nowTime - lastCheckRelayStateTimer[_chkIndex] >= 1) {
+        if ((GetTimeoutValue(lastCheckRelayStateTimer[_chkIndex]) / 1000000) >= 1) {
             //log_info("relay welding or driving fault = %d \n", _chkIndex);
             if (toState == 1) {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_DRIVING;
             } else {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_WELDING;
             }
-            lastCheckRelayStateTimer[_chkIndex] = nowTime;
+            gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         }
     }
 }
@@ -377,13 +384,16 @@ void CheckOutputPowerOverCarReq(uint8_t index)
                           (pDcChargingInfo->EvBatterytargetVoltage * 10));
                 if ((GetTimeoutValue(_checkOutputVolProtectTimer[index]) / 1000) >= OUTPUT_VOL_CHK_TIME) {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
-                        pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.ChaConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                        pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.CCSConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_GB) {
-                        pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.GBTConnectOVP = YES;
                     }
-                    pDcChargingInfo->StopChargeFlag = YES;
+                    //pDcChargingInfo->StopChargeFlag = YES;
                 }
             }
         } else {
@@ -550,11 +560,27 @@ void SetK1K2RelayStatus(uint8_t index)
         //if (pDcChargingInfo->RelayWeldingCheck != YES) {
         //    break;
         //}
-
         if (pRegGunPNState->GunN == NO) {
-            pOutputGunPNState->GunN = YES;
-        } else if (pRegGunPNState->GunP == NO) {
-            pOutputGunPNState->GunP = YES;
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunN = YES;
+            } else {
+                pOutputGunPNState->GunN = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunN = NO;
+            }
+        }
+        if (pRegGunPNState->GunP == NO) {
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunP = YES;
+            } else {
+                pOutputGunPNState->GunP = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunP = NO;
+            }
         }
         break;
 
@@ -562,11 +588,12 @@ void SetK1K2RelayStatus(uint8_t index)
     case S_COMPLETE:
     case S_ALARM:
         if ((pDcChargingInfo->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR) {
-            if (pRegGunPNState->GunP == YES) {
-                pOutputGunPNState->GunP = NO;
-            } else if (pRegGunPNState->GunN == YES) {
-                pOutputGunPNState->GunN = NO;
-            }
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
         }
         break;
 
@@ -582,6 +609,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pRegGunPNState->GunP = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
 
     case S_CCS_PRECHARGE_ST1:
@@ -596,6 +627,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pOutputPreChargingState->CcsPrecharge = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
     }
 }
@@ -721,7 +756,7 @@ void CableCheckDetected(uint8_t index)
              pSysConfig->AlwaysGfdFlag)
        ) {
         if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                pDcChargingInfo->SystemStatus <= S_TERMINATING) ||
+                pDcChargingInfo->SystemStatus < S_TERMINATING) ||
                 (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                  pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)
            ) {
@@ -735,7 +770,7 @@ void CableCheckDetected(uint8_t index)
                       ) {
                 SetGfdConfig(targetID, GFD_PRECHARGE);
             } else if ((pDcChargingInfo->SystemStatus >= S_CHARGING) &&
-                       (pDcChargingInfo->SystemStatus <= S_TERMINATING)
+                       (pDcChargingInfo->SystemStatus < S_TERMINATING)
                       ) {
                 if ((pDcChargingInfo->Type == _Type_GB) ||
                         (pDcChargingInfo->Type == _Type_Chademo)
@@ -745,9 +780,7 @@ void CableCheckDetected(uint8_t index)
                     SetGfdConfig(targetID, GFD_CHARGING);
                 }
             }
-        } else if (pDcChargingInfo->SystemStatus == S_COMPLETE ||
-                   pDcChargingInfo->SystemStatus == S_PREPARNING ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+        } else {
             SetGfdConfig(targetID, GFD_IDLE);
         }
     }
@@ -1124,6 +1157,495 @@ static void outputRelayInit(int fd)
     }
 }
 
+static bool IsRelayProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Relay Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
+static void SetFanModuleSpeed(void)
+{
+    {
+        FanSpeed _fanSpeed = {0};
+
+        _setFanSpeed += fanSpeedSmoothValue;
+
+        if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed) {
+            _setFanSpeed = ShmFanModuleData->SetFan1Speed;
+        }
+
+        //printf("_setFanSpeed = %d \n", _setFanSpeed);
+        _fanSpeed.speed[0] = _setFanSpeed;
+
+        _fanSpeed.speed[1] = _setFanSpeed;
+
+        _fanSpeed.speed[2] = _setFanSpeed;
+
+        _fanSpeed.speed[3] = _setFanSpeed;
+
+        if (Config_Fan_Speed(Uart5Fd, ADDR_FAN, &_fanSpeed) == PASS) {
+            //log_info("successfully Fan\n");
+        }
+    }
+}
+
+// 風扇速度
+static void GetFanSpeed(void)
+{
+    FanSpeed fanSpeed = {0};
+
+    //log_info("Get fan board speed \n");
+    if (Query_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed) == PASS) {
+        ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0];
+        ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1];
+        ShmFanModuleData->PresentFan3Speed = fanSpeed.speed[2];
+        ShmFanModuleData->PresentFan4Speed = fanSpeed.speed[3];
+//      log_info("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+//      log_info("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]);
+//      log_info("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]);
+//      log_info("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]);
+        // Config_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed[0]);
+        //SysInfoData (SystemFanRotaSpeed)
+    }
+}
+
+static void GetFanSpeedByFunction(void)
+{
+    if (pSysConfig->SwitchDebugFlag == YES) {
+        return;
+    }
+
+    // 風控修改 :
+    // ******************************************************* //
+    //
+    //       當前PSU輸出總 KW       PSU Temp
+    // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
+    //       當前樁最大功率 KW         45
+    //
+    // ******************************************************* //
+
+    // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower
+    uint32_t _maxPower = ShmPsuData->SystemAvailablePower;
+    // 當前PSU輸出總 KW & PSU Temp :
+    uint8_t temp = 0;
+    uint8_t index = 0;
+    uint8_t count = 0;
+    uint8_t gunIndex = 0;
+    uint8_t _temp_diff = 0;
+    float power = 0;
+    double _pw_rate = 0;
+    double _temp_rate = 0;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (index = 0; index < ShmPsuData->GroupCount; index++) {
+        for (count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) {
+            if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp) {
+                temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp;
+            }
+        }
+    }
+
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+
+        power += (pDcChargingInfo->PresentChargingPower * 10);
+    }
+
+    if (_maxPower > 0) {
+        _pw_rate = power / (double)_maxPower;
+    }
+
+    if (temp > 0) {
+        _temp_rate = (double)temp / 50;
+    }
+
+    if (temp > 45) {
+        _temp_diff = temp - 70;
+    }
+
+    ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED) {
+        ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
+    }
+
+    if (ShmFanModuleData->TestFanSpeed < 0) {
+        ShmFanModuleData->TestFanSpeed = 0;
+    }
+//
+//  printf("power = %f \n", power);
+//  printf("_maxPower = %d \n", _maxPower);
+//  printf("temp = %d \n", temp);
+//
+//  printf("_pw_rate = %f \n", _pw_rate);
+//  printf("_temp_rate = %f \n", _temp_rate);
+//  printf("_temp_diff = %d \n", _temp_diff);
+//  printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff));
+//  printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed);
+}
+
+static void SetRtcData_Fan(void)
+{
+    struct timeb csuTime;
+    struct tm *tmCSU;
+    Rtc rtc = {0};
+
+    ftime(&csuTime);
+    tmCSU = localtime(&csuTime.time);
+    //  log_info("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+    //          tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+    //          tmCSU->tm_sec);
+
+    rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+    rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+    rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+    rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+    rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+    rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+    rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+    rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+    rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+    rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+    rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+    rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+    rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+    rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+    if (Config_Rtc_Data(Uart5Fd, ADDR_FAN, &rtc) == PASS) {
+        //log_info("SetRtc (FB) sucessfully. \n");
+    }
+}
+
+static void SetModelName_Fan(void)
+{
+    if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
+        log_info("Set Model name PASS = %s \n", pSysConfig->ModelName);
+    }
+}
+
+static void GetFwAndHwVersion_Fan(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // FanModuleData
+        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW);
+    }
+
+    if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW);
+    }
+}
+
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
+static void fanBoardPorcess(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (ShmFanModuleData->SelfTest_Comp == YES ||
+            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
+            pSysInfo->FanModuleFwRev[0] != '\0') {
+        ShmFanModuleData->SelfTest_Comp = YES;
+
+        if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
+            //GetPsuTempForFanSpeed();
+            GetFanSpeedByFunction();
+            GetFanSpeed();
+            pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
+            gettimeofday(&gFanBoardRunTimer, NULL);
+
+            ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+
+            //log_info("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
+            SetFanModuleSpeed();
+        }
+    }
+}
+
+static void GetFwAndHwVersion_Led(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS) {
+        // LedModuleData
+        strcpy((char *) ShmLedModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *) pSysInfo->LedModuleFwRev, ver.Version_FW);
+        log_info("GetFwAndHwVersion_Led s1 = %s \n", ver.Version_FW);
+        ShmLedModuleData->SelfTest_Comp = YES;
+    } else {
+        //log_info("GetFwAndHwVersion_Led fail \n");
+    }
+
+//  if (Query_HW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS)
+//  {
+//      // SystemInfo
+//      strcpy((char *) pSysInfo->RelayModuleHwRev, ver.Version_FW);
+//      //log_info("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW);
+//  }
+}
+
+static bool IsNoneMatchLedColor(void)
+{
+    bool result = false;
+
+    if (cur_led_color.Connect_1_Red != led_color.Connect_1_Red ||
+            cur_led_color.Connect_1_Green != led_color.Connect_1_Green ||
+            cur_led_color.Connect_1_Blue != led_color.Connect_1_Blue ||
+            cur_led_color.Connect_2_Red != led_color.Connect_2_Red ||
+            cur_led_color.Connect_2_Green != led_color.Connect_2_Green ||
+            cur_led_color.Connect_2_Blue != led_color.Connect_2_Blue) {
+        result = true;
+    }
+
+    return result;
+}
+
+//static void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
+static void SetLedColor(void)
+{
+    static uint8_t _checkLedChanged = 3;
+    struct ChargingInfoData *chargingData_1 = NULL;
+    struct ChargingInfoData *chargingData_2 = NULL;
+    uint8_t _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST;
+
+    if (pSysConfig->TotalConnectorCount == 1) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+    } else if (pSysConfig->TotalConnectorCount == 2) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(1);
+    }
+
+    if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_DARKEST) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST;
+    } else if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_MEDIUM) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM;
+    }
+
+    //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) {
+        led_color.Connect_1_Green = COLOR_MIN_LV;
+        led_color.Connect_1_Blue = COLOR_MIN_LV;
+        led_color.Connect_1_Red = _colorBuf;
+        led_color.Connect_2_Green = COLOR_MIN_LV;
+        led_color.Connect_2_Blue = COLOR_MIN_LV;
+        led_color.Connect_2_Red = _colorBuf;
+    } else {
+        if (pSysInfo->IsAlternatvieConf) {
+            if ((chargingData_1->SystemStatus == S_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    (chargingData_2->SystemStatus == S_BOOTING ||
+                     chargingData_2->SystemStatus == S_IDLE ||
+                     chargingData_2->SystemStatus == S_RESERVATION)) {
+#if defined DD360Audi
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = _colorBuf;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = _colorBuf;
+#else
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                       (chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+                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_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION ||
+                    chargingData_1->SystemStatus == S_MAINTAIN) {
+
+                if (chargingData_1->IsAvailable == NO) { //For Audi
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = _colorBuf;
+                    led_color.Connect_1_Red = _colorBuf;
+#else
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+            }
+
+            // --------------------------------------------------------------------------
+            if (chargingData_2->SystemStatus == S_BOOTING ||
+                    chargingData_2->SystemStatus == S_IDLE ||
+                    chargingData_2->SystemStatus == S_RESERVATION ||
+                    chargingData_2->SystemStatus == S_MAINTAIN) {
+                if (chargingData_2->IsAvailable == NO) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = _colorBuf;
+                    led_color.Connect_2_Red = _colorBuf;
+#else
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_2_Green = COLOR_MIN_LV;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
+        }
+    }
+
+    if (_checkLedChanged > 0) {
+        if (Config_Led_Color(Uart5Fd, ADDR_LED, &led_color) == PASS) {
+            _checkLedChanged--;
+
+            cur_led_color.Connect_1_Red     = led_color.Connect_1_Red;
+            cur_led_color.Connect_1_Green   = led_color.Connect_1_Green;
+            cur_led_color.Connect_1_Blue    = led_color.Connect_1_Blue;
+            cur_led_color.Connect_2_Red     = led_color.Connect_2_Red;
+            cur_led_color.Connect_2_Green   = led_color.Connect_2_Green;
+            cur_led_color.Connect_2_Blue    = led_color.Connect_2_Blue;
+        }
+    } else if (IsNoneMatchLedColor()) {
+        _checkLedChanged = 3;
+    }
+}
+
+static void LEDBoardSelfTest(void)
+{
+    // 自檢階段處理,自檢階段如果讀不到版號則代表該系統沒有掛燈板
+    if (ShmLedModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+#if defined DD360 ||defined DD360Audi
+    GetFwAndHwVersion_Led();
+    sleep(1);
+    gettimeofday(&_led_priority_time, NULL);
+
+    return;
+#endif //defined DD360 || defined DD360Audi
+
+    // 自檢階段
+    if (pSysInfo->SelfTestSeq <= _STEST_PSU_CAP) {
+        GetFwAndHwVersion_Led();
+        sleep(1);
+        gettimeofday(&_led_priority_time, NULL);
+    } else {
+        // 自檢階段沒有問到版號
+        if (pAlarmCode->AlarmEvents.bits.LedboardStestFail == NO) {
+            pAlarmCode->AlarmEvents.bits.LedboardStestFail = YES;
+        }
+    }
+}
+
+static void LEDBoardProcess(void)
+{
+    //struct ChargingInfoData *pDcChargingInfo0 = NULL;
+    //struct ChargingInfoData *pDcChargingInfo1 = NULL;
+
+    if (ShmLedModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (GetTimeoutValue(_led_priority_time) / 1000 >= 1000) {
+
+        //if (pSysConfig->TotalConnectorCount == 1) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo0);
+        //} else if (pSysConfig->TotalConnectorCount == 2) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
+        //}
+        SetLedColor();
+        gettimeofday(&_led_priority_time, NULL);
+    }
+}
+
 void RelayBoardTask(int uartFD)
 {
     pid_t pid = fork();
@@ -1143,6 +1665,9 @@ void RelayBoardTask(int uartFD)
         ShmPsuData = (struct PsuData *)GetShmPsuData();
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
+        pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
+        ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
+        ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
 
         Uart5Fd = uartFD;
 
@@ -1150,214 +1675,189 @@ void RelayBoardTask(int uartFD)
         outputRelayInit(uartFD);
 
         while (isContinue) {
+
+            if(IsRelayProcessNeedPause() == true)
+            {
+                sleep(1);
+                continue;
+            }
+
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
             if (ShmRelayModuleData->SelfTest_Comp == NO) {
                 GetFwAndHwVersion_Relay();
                 SetModelName_Relay(); //DS60-120 add
                 SetRtcData_Relay();
                 sleep(1);
-
-                continue;
             }
 
-            // ==============優先權最高 10 ms ==============
-            // 輸出電壓
-            GetPersentOutputVol();
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardSelfTest();
+#endif //NO_FAN_BOARD
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-            // 三相輸入電壓
-            GetPresentInputVol();
-#endif //!defined DD360 && !defined DD360Audi
+#if !defined DD360ComBox
+            LEDBoardSelfTest();
+#endif //defined DD360ComBox
 
-            // 讀取當前 AC relay 狀態
-            regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+            if (ShmRelayModuleData->SelfTest_Comp == YES)
+            {
+                // ==============優先權最高 10 ms ==============
+                // 輸出電壓
+                GetPersentOutputVol();
 
-            GetRelayOutputStatus();
+    #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                // 三相輸入電壓
+                GetPresentInputVol();
+    #endif //!defined DD360 && !defined DD360Audi
 
-            for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
-                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+                // 讀取當前 AC relay 狀態
+                regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
 
-                // Cable check (Set)
-                CableCheckDetected(i);
+                GetRelayOutputStatus();
 
-                // check k1 k2 relay 狀態
-                CheckK1K2RelayOutput(i);
+                // Cable check (Get)
+                GetGfdAdc();
 
-                // 依據當前各槍的狀態選擇 搭上/放開 Relay
-                SetK1K2RelayStatus(i);
+                for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-                if (pSysConfig->PhaseLossPolicy == YES) {
-                    CheckPhaseLossStatus(i);
-                }
+                    // Cable check (Set)
+                    CableCheckDetected(i);
 
-                CheckAcInputOvpStatus(i);
-#endif //!defined DD360 && !defined DD360Audi
+                    // check k1 k2 relay 狀態
+                    CheckK1K2RelayOutput(i);
 
-                if (pDcChargingInfo->SystemStatus == S_IDLE ||
-                        pDcChargingInfo->SystemStatus == S_RESERVATION ||
-                        pDcChargingInfo->SystemStatus == S_MAINTAIN) {
-                    //pDcChargingInfo->RelayWeldingCheck = NO;
-                    //_isRelayWelding[i] = NO;
-                    _isOvpChkTimeFlag[i] = NO;
-                    //ResetDetAlarmStatus(i); //DS60-120 add
-                }
+                    // 依據當前各槍的狀態選擇 搭上/放開 Relay
+                    SetK1K2RelayStatus(i);
 
-                if (pDcChargingInfo->SystemStatus == S_BOOTING ||
-                        (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                         pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
-                        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
-                         pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
-                        pSysInfo->WaitForPlugit == YES ||
-                        (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
-                         pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
-                   ) {
-                    pDcChargingInfo->IsReadyToCharging = YES;
-                    isCharging = true;
-
-                    // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-                    //if (pDcChargingInfo->Type == _Type_GB) {
-                    //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                    //            pDcChargingInfo->RelayWeldingCheck == NO) {
-                    //        CheckRelayWeldingStatus(i);
-                    //    }
-                    //} else {
-                    //pDcChargingInfo->RelayWeldingCheck = YES;
-                    //}
-
-                    if (pDcChargingInfo->SystemStatus == S_CHARGING) {
-                        CheckOutputPowerOverCarReq(i);
-                        //CheckOutputVolNoneMatchFire(i);
+#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                    if (pSysConfig->PhaseLossPolicy == YES) {
+                        CheckPhaseLossStatus(i);
                     }
-                    /*else {
-                        _isOutputNoneMatch[i] = NO;
-                    }*/
-                } else {
-                    pDcChargingInfo->IsReadyToCharging = NO;
-                }
-            }
 
-            // Cable check (Get)
-            GetGfdAdc();
-
-            // 橋接 relay
-            SetParalleRelayStatus();
+                    CheckAcInputOvpStatus(i);
+#endif //!defined DD360 && !defined DD360Audi
 
-            // 搭上 AC Contactor
-            //if (isCharging) {
-            //    outputRelay.relay_event.bits.AC_Contactor = YES;
-            //} else {
-            //    outputRelay.relay_event.bits.AC_Contactor = NO;
-            //}
+                    if (pDcChargingInfo->SystemStatus == S_IDLE ||
+                            pDcChargingInfo->SystemStatus == S_RESERVATION ||
+                            pDcChargingInfo->SystemStatus == S_MAINTAIN) {
+                        //pDcChargingInfo->RelayWeldingCheck = NO;
+                        //_isRelayWelding[i] = NO;
+                        _isOvpChkTimeFlag[i] = NO;
+                        //ResetDetAlarmStatus(i); //DS60-120 add
+                    }
 
-            if (isCharging ||
-                    (ShmPsuData->Work_Step >= _TEST_MODE &&
-                     ShmPsuData->Work_Step <= _TEST_MODE)) {
-                isStopChargingCount = false;
-                outputRelay.relay_event.bits.AC_Contactor = YES;
-            } else {
-                if (!isStopChargingCount) {
-                    gettimeofday(&_close_ac_contactor, NULL);
-                    isStopChargingCount = true;
-                } else {
-                    if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
-                            GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
-                        outputRelay.relay_event.bits.AC_Contactor = NO;
+                    if (pDcChargingInfo->SystemStatus == S_BOOTING ||
+                            (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
+                             pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
+                            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                             pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                            pSysInfo->WaitForPlugit == YES ||
+                            (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
+                             pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
+                       ) {
+                        pDcChargingInfo->IsReadyToCharging = YES;
+                        isCharging = true;
+
+                        // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
+                        //if (pDcChargingInfo->Type == _Type_GB) {
+                        //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                        //            pDcChargingInfo->RelayWeldingCheck == NO) {
+                        //        CheckRelayWeldingStatus(i);
+                        //    }
+                        //} else {
+                        //pDcChargingInfo->RelayWeldingCheck = YES;
+                        //}
+
+                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                            CheckOutputPowerOverCarReq(i);
+                            //CheckOutputVolNoneMatchFire(i);
+                        }
+                        /*else {
+                            _isOutputNoneMatch[i] = NO;
+                        }*/
+                    } else {
+                        pDcChargingInfo->IsReadyToCharging = NO;
                     }
                 }
-            }
 
-            if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
-                RunForceStopProcess();
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
-                outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
-            }
+                    // 橋接 relay
+                    SetParalleRelayStatus();
 
-            // 搭上/鬆開 Relay
-            if (IsNoneMatchRelayStatus()) {
-                if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
-                    //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
-
-                    //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
-                    //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
-                    //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
-                    //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
-                    //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
-                    //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
-                    //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
-
-                    //MatchRelayStatus();
-
-                    //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
-                    //         regRelay.relay_event.bits.AC_Contactor,
-                    //         regRelay.relay_event.bits.Gun1_P,
-                    //         regRelay.relay_event.bits.Gun1_N,
-                    //         regRelay.relay_event.bits.Gun2_P,
-                    //         regRelay.relay_event.bits.Gun2_N,
-                    //         regRelay.relay_event.bits.CCS_Precharge,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_P,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_N);
+                    // 搭上 AC Contactor
+                    //if (isCharging) {
+                    //    outputRelay.relay_event.bits.AC_Contactor = YES;
+                    //} else {
+                    //    outputRelay.relay_event.bits.AC_Contactor = NO;
+                    //}
 
-                }
-            } /*else {
-                    log_info("======== Relay Status Start========\n");
-                    if (regRelay.relay_event.bits.AC_Contactor == YES) {
-                        log_info("AC Power : ON \n");
+                    if (isCharging ||
+                            (ShmPsuData->Work_Step >= _TEST_MODE &&
+                             ShmPsuData->Work_Step <= _TEST_MODE)) {
+                        isStopChargingCount = false;
+                        outputRelay.relay_event.bits.AC_Contactor = YES;
                     } else {
-                        log_info("AC Power : OFF \n");
+                        if (!isStopChargingCount) {
+                            gettimeofday(&_close_ac_contactor, NULL);
+                            isStopChargingCount = true;
+                        } else {
+                            if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
+                                    GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
+                                outputRelay.relay_event.bits.AC_Contactor = NO;
+                            }
+                        }
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_P == YES) {
-                        log_info("Conn1(+) : ON \n");
-                    } else {
-                        log_info("Conn1(+) : OFF \n");
+                    if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_N == YES) {
-                        log_info("Conn1(-) : ON \n");
-                    } else {
-                        log_info("Conn1(-) : OFF \n");
+                    if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
+                        RunForceStopProcess();
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_P == YES) {
-                        log_info("Conn2(+) : ON \n");
-                    } else {
-                        log_info("Conn2(+) : OFF \n");
+                    if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
+                        outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_N == YES) {
-                        log_info("Conn2(-) : ON \n");
-                    } else {
-                        log_info("Conn2(-) : OFF \n");
-                    }
+                    // 搭上/鬆開 Relay
+                    if (IsNoneMatchRelayStatus()) {
+                        if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
+                            //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+
+                            //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
+                            //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
+                            //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
+                            //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
+                            //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
+                            //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
+                            //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
+
+                            //MatchRelayStatus();
+
+                            //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+                            //         regRelay.relay_event.bits.AC_Contactor,
+                            //         regRelay.relay_event.bits.Gun1_P,
+                        //         regRelay.relay_event.bits.Gun1_N,
+                        //         regRelay.relay_event.bits.Gun2_P,
+                        //         regRelay.relay_event.bits.Gun2_N,
+                        //         regRelay.relay_event.bits.CCS_Precharge,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_P,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_N);
 
-                    if (regRelay.relay_event.bits.CCS_Precharge == YES) {
-                        log_info("Precharge : ON \n");
-                    } else {
-                        log_info("Precharge : OFF \n");
                     }
+                }
+            }
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) {
-                        log_info("Parallel(+) : ON \n");
-                    } else {
-                        log_info("Parallel(+) : OFF \n");
-                    }
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardPorcess();
+#endif //NO_FAN_BOARD
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) {
-                        log_info("Parallel(-) : ON \n");
-                    } else {
-                        log_info("Parallel(-) : OFF \n");
-                    }
-                    log_info("======== Relay Status End========\n");
-                }*/
+#if !defined DD360ComBox
+            LEDBoardProcess();
+#endif //defined DD360ComBox
+
+            usleep(10000);
         }
-        usleep(100000);
     }
 }

+ 68 - 1
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -288,6 +288,7 @@ static void checkChillerStatus(Gpio_out *gpio)
     uint8_t chillerCount = 0;
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
+    static ChillerInfo _chiller;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
@@ -309,6 +310,28 @@ static void checkChillerStatus(Gpio_out *gpio)
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
+        if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+        {
+            pChillerInfo->ChillerSwitch = YES;
+            pChillerInfo->ChillerOnTime = time((time_t *)NULL);
+        }
+        else
+        {
+            if(pChillerInfo->ChillerSwitch == YES)
+            {
+                //10分鐘後停止
+                if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
+                {
+                    pChillerInfo->ChillerSwitch = NO;
+                }
+            }
+            else
+            {
+                pChillerInfo->ChillerSwitch = NO;
+            }
+        }
+#if 0
         if ((pDcChargingInfo->PresentChargingCurrent) >= 150) { //當前電壓於150A,打開水冷機
             pChillerInfo->ChillerSwitch = YES;
             pChillerInfo->ChillerOnTime = time((time_t *)NULL);
@@ -328,9 +351,25 @@ static void checkChillerStatus(Gpio_out *gpio)
                 pChillerInfo->ChillerSwitch = NO;
             }
         }
+#endif
+    }
+
+    uint8_t _chillerNeedOn = NO;
+    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    {
+        pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
+        if(pChillerInfo->ChillerSwitch == YES)
+        {
+            _chillerNeedOn = YES;
+        }
     }
 
-    pGpio->AC_Connector = pChillerInfo->ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
+    if(_chiller.ChillerSwitch != _chillerNeedOn)
+    {
+        log_info("Chiller Need Turn %s\n", _chillerNeedOn == YES ? "ON" : "OFF");
+    }
+    _chiller.ChillerSwitch = _chillerNeedOn;
+    pGpio->AC_Connector = _chiller.ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
 }
 
 void SetOutputGpio(int fd, uint8_t outputValue)
@@ -497,6 +536,29 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
 //    }
 //}
 
+static bool IsPrimaryProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Primary Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
 int main(void)
 {
     int Uart1Fd = -1;
@@ -545,6 +607,11 @@ int main(void)
     //Initialization();
 
     for (;;) {
+        if(IsPrimaryProcessNeedPause() == true)
+        {
+            sleep(1);
+            continue;
+        }
         // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
         // 模組更新 FW 後,需重新做
         if (ShmPrimaryMcuData->SelfTest_Comp != PASS) {

+ 8 - 2
EVSE/Projects/DD360Audi/Apps/ReadCmdline.c

@@ -1097,10 +1097,16 @@ static void resdGunAndChillerTemp(void)
 
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-                printTimeMsg("get %d gun temp = %d, chiller temp = %d\r\n",
+                printTimeMsg("get gun %d temp = %3d, chiller = %3d, ConnTemp = %3d, %3d,SysTemp = %3d, %3d, %3d, %3d\r\n",
                              i,
                              pDcChargingInfo->ConnectorTemp,
-                             pDcChargingInfo->ChillerTemp);
+                             pDcChargingInfo->ChillerTemp,
+                             ShmDcCommonData->ConnectorTemp[i][0],
+                             ShmDcCommonData->ConnectorTemp[i][1],
+                             ShmDcCommonData->SystemTemp[0],
+                             ShmDcCommonData->SystemTemp[1],
+                             ShmDcCommonData->SystemTemp[2],
+                             ShmDcCommonData->SystemTemp[3]);
             }//for
             ftime(&showTime);
         }

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


BIN
EVSE/Projects/DD360Audi/Images/u-boot.img


BIN
EVSE/Projects/DD360Audi/output/FactoryConfig


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/ReadCmdline


BIN
EVSE/Projects/DD360Audi/output/main


+ 2 - 1
EVSE/Projects/DD360ComBox/Apps/CSU/UpgradeFW.c

@@ -328,7 +328,7 @@ void CheckFwUpdateFunction(void)
         for (uint8_t gun_index = 0; gun_index < pSysConfig->TotalConnectorCount; gun_index++) {
             setChargerMode(gun_index, MODE_UPDATE);
         }
-
+        sleep(1);
         uint8_t updateResult = CheckUpdateProcess();
 
         if (updateResult == PASS) {
@@ -366,6 +366,7 @@ void CheckFwUpdateFunction(void)
 
                 pAcChargingInfo->SystemStatus = MODE_UPDATE;
             }
+            sleep(1);
 
             uint8_t updateResult = CheckUpdateProcess();
 

+ 270 - 92
EVSE/Projects/DD360ComBox/Apps/CSU/main.c

@@ -77,7 +77,7 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.11.00.0000.00"; // "V0.16.00.0000.00";
+char *fwVersion = "V1.12.00.0000.00"; // "V0.16.00.0000.00";
 
 //sqlite3 *localDb;
 bool isDb_ready;
@@ -96,6 +96,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code);
 void ReleaseAlarmCode(uint8_t gunIndex);
 void ResetChargerAlarmCode(uint8_t gunIndex, char *code);
 void AdjustChargerCurrent(void);
+void UpdateErrorCodeToOcpp(uint8_t index);
 
 //------------------------------------------------------------------------------
 //Primary.c
@@ -390,15 +391,51 @@ static void checkGunOTPState(uint8_t gunIndex)
     if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
         if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) {
-                RecordAlarmCode(gunIndex, "012323");
+                if (((gunIndex == 0) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                         ||
+                    ((gunIndex == 1) &&
+                        ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                         (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+                   ) {
+                    RecordAlarmCode(gunIndex, "012323");
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES;
+                }
+                else
+                {
+                    ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+                }
             } else if (pDcChargingInfo->ChillerTemp != 0 &&
                        pDcChargingInfo->ChillerTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012323");
+                //ResetChargerAlarmCode(gunIndex, "012323");
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
             }
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011038");
-            ResetChargerAlarmCode(gunIndex, "012323");
+            //RecordAlarmCode(gunIndex, "011038");
+            //ResetChargerAlarmCode(gunIndex, "012323");
+            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO;
+            if (((gunIndex == 0) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)))
+                     ||
+                ((gunIndex == 1) &&
+                    ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) ||
+                     (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)))
+               ) {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
+            }
+            else
+            {
+                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
+            }
+        }
+
+        if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES)
+        {
+            RecordAlarmCode(gunIndex, "011037");
         }
     }
 
@@ -407,14 +444,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012229");
+                //ResetChargerAlarmCode(gunIndex, "012229");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
             //RecordAlarmCode(gunIndex, "011018");
-            ResetChargerAlarmCode(gunIndex, "012229");
+            //ResetChargerAlarmCode(gunIndex, "012229");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES;
         }
         break;
 
@@ -425,16 +467,20 @@ static void checkGunOTPState(uint8_t gunIndex)
 
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012230");
+                //ResetChargerAlarmCode(gunIndex, "012230");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
             }
-
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = NO;
             //ResetChargerAlarmCode(gunIndex, "011019");
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011019");
-            ResetChargerAlarmCode(gunIndex, "012230");
+            //RecordAlarmCode(gunIndex, "011019");
+            //ResetChargerAlarmCode(gunIndex, "012230");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = YES;
         }
         break;
 
@@ -442,14 +488,19 @@ static void checkGunOTPState(uint8_t gunIndex)
         if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
             if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) {
                 RecordAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES;
             } else if (pDcChargingInfo->ConnectorTemp != 0 &&
                        pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) {
-                ResetChargerAlarmCode(gunIndex, "012231");
+                //ResetChargerAlarmCode(gunIndex, "012231");
+                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
             }
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = NO;
         } else {
             // 沒接上 Sensor or 異常
-            RecordAlarmCode(gunIndex, "011020");
-            ResetChargerAlarmCode(gunIndex, "012231");
+            //RecordAlarmCode(gunIndex, "011020");
+            //ResetChargerAlarmCode(gunIndex, "012231");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = YES;
         }
         break;
     }
@@ -1690,30 +1741,46 @@ void ResetChargerAlarmCode(uint8_t gunIndex, char *code)
         ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO;
     }
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
-        if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
-                ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
-                ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
-           ) {
-            strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
-        }
+    //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) != EQUAL) {
+    //    if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO &&
+    //            ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO
+    //       ) {
+    //        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
+    //    }
+    //}
+    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012229", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012230", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012231", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011011", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011013", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011015", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011012", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011014", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011016", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011018", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011019", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011020", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL ||
+            strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL) {
+        strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
 }
 
@@ -1721,10 +1788,20 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
 
-    if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
-        memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+    if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+    {
+        if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+            memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+        }
+
+        if (pDcChargingInfo->StopChargeFlag == NO)
+        {
+            pDcChargingInfo->StopChargeFlag = YES;
+        }
     }
 
+#if 0
     if (strcmp(code, "012234") == EQUAL) {
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
     } else if (strcmp(code, "012235") == EQUAL) {
@@ -1792,6 +1869,7 @@ void RecordAlarmCode(uint8_t gunIndex, char *code)
             ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES;
         }
     }
+#endif
 }
 
 void ReleaseAlarmCode(uint8_t gunIndex)
@@ -1801,26 +1879,29 @@ void ReleaseAlarmCode(uint8_t gunIndex)
     //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
     //    return;
     //}
-
+#if 0
     // 回 idle 後主要清除  GFD Trip、UVP、OVP、GFD Warning
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL) {
         memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
     }
-
+#endif
     switch (pDcChargingInfo->Type) {
     case _Type_Chademo:
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012234", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012289", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012217", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012296", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_CCS_2:
@@ -1828,13 +1909,16 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012235", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012288", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012219", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012297", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
 
     case _Type_GB:
@@ -1842,16 +1926,19 @@ void ReleaseAlarmCode(uint8_t gunIndex)
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP = NO;
         ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
-
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+        ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
+#if 0
         if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012236", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012290", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012221", 6) == EQUAL ||
                 strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012298", 6) == EQUAL) {
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
         }
+#endif
         break;
     }
-
+#if 0
     //system alarm
     if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL ||
             strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL ||
@@ -1862,6 +1949,8 @@ void ReleaseAlarmCode(uint8_t gunIndex)
        ) {
         memset(pDcChargingInfo->ConnectorAlarmCode, 0, sizeof(pDcChargingInfo->ConnectorAlarmCode));
     }
+#endif
+    memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6);
 }
 
 //===============================================
@@ -1874,6 +1963,7 @@ void ChargingTerminalProcess(uint8_t gunIndex)
 
 void ChargingAlarmProcess(uint8_t gunIndex)
 {
+    UpdateErrorCodeToOcpp(gunIndex);
     setChargerMode(gunIndex, MODE_ALARM);
 }
 
@@ -1966,6 +2056,9 @@ void EmcOccureByString(char *code)
                     (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                      pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
                 //ChargingTerminalProcess(gun);
+                if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) {
+                    memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6);
+                }
                 ChargingAlarmProcess(gun);
             }
         }
@@ -2007,6 +2100,31 @@ void ReleaseEmsOccureByString(uint8_t index, char *code)
     }
 }
 
+static void checkOvpState(uint8_t gunIndex, uint8_t gunType)
+{
+    switch(gunType)
+    {
+        case _Type_Chademo:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012217");
+            }
+            break;
+        case _Type_CCS_2:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012219");
+            }
+            break;
+        case _Type_GB:
+            if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP == YES)
+            {
+                RecordAlarmCode(gunIndex, "012221");
+            }
+            break;
+    }
+}
+
 //===============================================
 // 確認各小板偵測的錯誤狀況
 //===============================================
@@ -2083,6 +2201,8 @@ void CheckErrorOccurStatus(uint8_t index)
         }
     }
 
+    checkOvpState(index, pDcChargingInfo->Type);
+
     //--------------------------------------------------------------------------
     if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == 0) {
         //Primary
@@ -2096,11 +2216,11 @@ void CheckErrorOccurStatus(uint8_t index)
             memcpy(pDcChargingInfo->ConnectorAlarmCode, "012304", 6);
         }
         //Chiller temperature
-        else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
-        } else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
-            memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
-        }
+        //else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6);
+        //} else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) {
+        //    memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6);
+        //}
     }
 }
 
@@ -3500,8 +3620,8 @@ void UpdateErrorCodeToOcpp(uint8_t index)
 {
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index);
 
-    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->ConnectorAlarmCode);
-    //log_info("%d = EvConnAlarmCode = %s\r\n", index, (char *)chargingInfo[index]->EvConnAlarmCode);
+    //log_info("%d = ConnectorAlarmCode = %s\r\n", index, pDcChargingInfo->ConnectorAlarmCode);
+    //log_info("%d = EvConnAlarmCode = %s\r\n", index, pDcChargingInfo->EvConnAlarmCode);
     if (strcmp((char *)pDcChargingInfo->ConnectorAlarmCode, "") != EQUAL) {
         //if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == EQUAL) {
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].ErrorCode, "InternalError");
@@ -3512,7 +3632,7 @@ void UpdateErrorCodeToOcpp(uint8_t index)
         strcpy((char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode, (char *)pDcChargingInfo->EvConnAlarmCode);
     }
 
-    //log_info("2 %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
+    //log_info("Gun %d = VendorErrorCode = %s\r\n", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode);
 }
 
 void AdjustChargerCurrent()
@@ -3583,10 +3703,10 @@ static bool PrecheckIsPass(uint8_t gunIndex)
 
 static void ReviewCriticalAlarm(void)
 {
-    if (ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
-            ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
+    if (//ShmDcCommonData->GunRelayDrivingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayDrivingOccur[1] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[0] == YES ||
+            //ShmDcCommonData->GunRelayWeldingOccur[1] == YES ||
             pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES ||
             pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES ||
             pAlarmCode->AlarmEvents.bits.DoorOpen == YES ||
@@ -3613,7 +3733,7 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
 
     // relay welding fault then stop the charging process.
     uint8_t faultCode = RELAY_STATUS_ERROR_NONE;
-    static uint8_t drivingCount = 0;
+    //static uint8_t drivingCount = 0;
 
     if (gunIndex == 0) {
         if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_WELDING ||
@@ -3649,45 +3769,58 @@ static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex)
         // welding
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = YES;
         }
 
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else if (faultCode == RELAY_STATUS_ERROR_DRIVING) {
-        if (drivingCount++ != 2) {
-            return;
-        }
+        //if (drivingCount++ != 2) {
+        //    return;
+        //}
 
         // driving
         if (pDcChargingInfo->Type == _Type_Chademo) {
             RecordAlarmCode(gunIndex, "011012");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_GB) {
             RecordAlarmCode(gunIndex, "011016");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = YES;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
             RecordAlarmCode(gunIndex, "011014");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = YES;
         }
 
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = YES;
-        EmcOccureByString("");
+        //EmcOccureByString("");
     } else {
         ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = NO;
         ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = NO;
-        drivingCount = 0;
-
+        //drivingCount = 0;
+#if 0
         if (pDcChargingInfo->Type == _Type_Chademo) {
-            ResetChargerAlarmCode(gunIndex, "011012");
-            ResetChargerAlarmCode(gunIndex, "011011");
+            //ResetChargerAlarmCode(gunIndex, "011012");
+            //ResetChargerAlarmCode(gunIndex, "011011");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-            ResetChargerAlarmCode(gunIndex, "011014");
-            ResetChargerAlarmCode(gunIndex, "011013");
+            //ResetChargerAlarmCode(gunIndex, "011014");
+            //ResetChargerAlarmCode(gunIndex, "011013");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO;
         } else if (pDcChargingInfo->Type == _Type_GB) {
-            ResetChargerAlarmCode(gunIndex, "011016");
-            ResetChargerAlarmCode(gunIndex, "011015");
+            //ResetChargerAlarmCode(gunIndex, "011016");
+            //ResetChargerAlarmCode(gunIndex, "011015");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO;
         }
+#endif
     }
 }
 
@@ -3810,9 +3943,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012234");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012296");
+            //RecordAlarmCode(gunIndex, "012296");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -3849,9 +3991,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012236");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012298");
+            //RecordAlarmCode(gunIndex, "012298");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           isPrechargeStatus_gb(gunIndex) == 10 &&
@@ -3890,9 +4041,18 @@ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sys
         if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
             // GFD 錯誤停止
             RecordAlarmCode(gunIndex, "012235");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) {
             // GFD 警告
-            RecordAlarmCode(gunIndex, "012297");
+            //RecordAlarmCode(gunIndex, "012297");
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = YES;
+        }
+        else
+        {
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO;
+            ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO;
         }
         //else if (sysStatus == S_CHARGING &&
         //           ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 &&
@@ -4153,6 +4313,16 @@ int main(void)
 
         gEvBoardErr.GunErrMessage = 0; //清除系統執行中的錯誤訊息
         gChillerTempErr.TempErrMsg = 0;//清除系統執行中的錯誤訊息
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            // 重新收集各槍的錯誤狀態
+            collectError(gunIndex);
+        }
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+            // convert common status code to alarm event
+            checkEvBoardAlarmState(pDcChargingInfo->Type);
+        }
+        checkChillerAlarmState();
 
         for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -4166,9 +4336,6 @@ int main(void)
             // 確認 Relay Welding or Driving Fault
             CheckRelayWeldingOrDrivingFault(gunIndex);
 
-            // 重新收集各槍的錯誤狀態
-            collectError(gunIndex);
-
             ChkOcppStatus(gunIndex);
 
             if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
@@ -4183,7 +4350,6 @@ int main(void)
             //         ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode);
             switch (pDcChargingInfo->SystemStatus) {
             case S_IDLE:
-                ReleaseAlarmCode(gunIndex);
 
                 if (isModeChange(gunIndex)) {
                     log_info("S_IDLE================================== %x \n", gunIndex);
@@ -4205,6 +4371,7 @@ int main(void)
                         ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] = NO;
                     }
                     //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, "");
+                    ReleaseAlarmCode(gunIndex);
                 }
 
             case S_RESERVATION:
@@ -4219,16 +4386,26 @@ int main(void)
 
             case S_MAINTAIN:
             case S_FAULT:
+                if (isModeChange(gunIndex)) {
+                    if(pDcChargingInfo->SystemStatus == S_MAINTAIN)
+                    {
+                        log_info("S_MAINTAIN================================== %x \n", gunIndex);
+                    }
+                    if(pDcChargingInfo->SystemStatus == S_FAULT)
+                    {
+                        log_info("S_FAULT================================== %x \n", gunIndex);
+                    }
+                }
                 if (pSysWarning->Level == WARN_LV_ER) {
-                    pDcChargingInfo =  (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
+                    struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
 
                     if (gunIndex == pSysInfo->CurGunSelected) {
                         pSysInfo->SystemPage = _LCM_FIX;
-                    } else if (pDcChargingInfo->SystemStatus != S_IDLE &&
-                               pDcChargingInfo->SystemStatus != S_RESERVATION &&
-                               pDcChargingInfo->SystemStatus != S_MAINTAIN &&
-                               pDcChargingInfo->SystemStatus != S_FAULT) {
-                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                    } else if (pSelectedDcChargingInfo->SystemStatus != S_IDLE &&
+                            pSelectedDcChargingInfo->SystemStatus != S_RESERVATION &&
+                            pSelectedDcChargingInfo->SystemStatus != S_MAINTAIN &&
+                            pSelectedDcChargingInfo->SystemStatus != S_FAULT) {
+                        if (pSelectedDcChargingInfo->SystemStatus == S_CHARGING) {
                             pSysInfo->SystemPage = _LCM_COMPLETE;
                         } else {
                             systemPageRestoreInit();
@@ -4237,9 +4414,11 @@ int main(void)
 
                     ClearDetectPluginFlag();
 
-                    UpdateErrorCodeToOcpp(gunIndex);
-
-                    setChargerMode(gunIndex, MODE_FAULT);
+                    if (pDcChargingInfo->SystemStatus != S_FAULT)
+                    {
+                        UpdateErrorCodeToOcpp(gunIndex);
+                        setChargerMode(gunIndex, MODE_FAULT);
+                    }
                     continue;
                 }
 
@@ -4669,7 +4848,7 @@ int main(void)
                     StopGunInfoTimeoutDet(gunIndex);
                 }
 
-                checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
+                //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus);
 #if 0
                 if (pDcChargingInfo->Type == _Type_Chademo) {
                     // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍
@@ -4808,6 +4987,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4854,6 +5034,7 @@ int main(void)
                 if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
                     // GFD 錯誤停止
                     RecordAlarmCode(gunIndex, "012235");
+                    ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES;
                 }
 
                 checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex);
@@ -4870,9 +5051,6 @@ int main(void)
                 }
                 break;
             }//switch
-
-            checkEvBoardAlarmState(pDcChargingInfo->Type);
-            checkChillerAlarmState();
         }//for
 
 #if defined DD360Audi

+ 3 - 0
EVSE/Projects/DD360ComBox/Apps/Config.h

@@ -85,6 +85,7 @@
 #define GUN_OTP_VALUE                           (150)
 #define GUN_OTP_RECOVERY                        (140)
 #define UNDEFINED_TEMP                          (255)
+#define TEMP_BOUNDARY                           (200)
 
 #define WARN_LV_NL                              (0) //normal state
 #define WARN_LV_WARN                            (1)
@@ -362,6 +363,8 @@ typedef struct StDcCommonInfo {
     uint8_t CheckRelayStatus[6]; //check Relay welding or driving fault
     uint8_t GunRelayWeldingOccur[2];
     uint8_t GunRelayDrivingOccur[2];
+    uint8_t ConnectorTemp[2][2];
+    uint8_t SystemTemp[4];
     uint8_t SystemModeChange[2]; //for Module_EvRxComm
     PowerAlarmState PowerAlarmState;
     ChillerTempErr ChillerTempErr[2];

+ 19 - 0
EVSE/Projects/DD360ComBox/Apps/Define/define.h

@@ -378,6 +378,13 @@ struct LED
 	unsigned char			Blue[3];					// Blue color	0~100, element 0: IDLE		1: CHARGING		2: FAULT
 };
 
+struct LCD_OVERRIDE
+{
+    unsigned char           page_index;                 // LCD override page index
+    unsigned char           duration;                   // LCD override duration
+    unsigned char           isOverideReq:1;             // LCD override request
+};
+
 struct Schedule
 {
 	unsigned char   isEnable;     						// 0: disable schedule function  1: enable schedule function
@@ -481,6 +488,7 @@ struct SysConfigData
 	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 	unsigned char           isEnableLocalPowerSharging; //0: Disable power sharing  1: Enable power sharing
 	unsigned char           StopChargingByButton;       //0: Disable  1: Enable
+	struct LCD_OVERRIDE     LcdOveride;                 // LCD override info
 
     /************PowerCabinet************/
     WiringInfoData          WiringInfo;
@@ -798,6 +806,16 @@ typedef struct
     unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
 }CabinetMiscCommand;
 
+typedef struct DC_METER_INFO
+{
+    double presetVoltage;                       // resolution: 1.000v
+    double presentCurrent;                      // resolution: 1.000a
+    double presentPower;                        // resolution: 1.000kw
+    double totlizeImportEnergy;                 // resolution: 1.000kwh
+    double totlizeExportEnergy;                 // resolution: 1.000kwh
+    unsigned char LinkStatus;                   // 0 = unknow ,1 = link , 2 miss link
+}DC_Meter_Info;
+
 struct SysInfoData
 {
 	/**************System***************/
@@ -889,6 +907,7 @@ struct SysInfoData
     CabinetSettingFlag      CabinetSetting;
     CabinetMiscCommand      CabinetMicsStatus;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
+    DC_Meter_Info DcMeterInfo[4];
 };
 
 struct SysConfigAndInfo

+ 4 - 0
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalCCS.c

@@ -910,4 +910,8 @@ void ClearAbnormalStatus_CCS(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalCHA.c

@@ -244,4 +244,8 @@ void ClearAbnormalStatus_Chademo(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 4 - 0
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalGBT.c

@@ -412,4 +412,8 @@ void ClearAbnormalStatus_GB(uint8_t gun_index)
             }
         }
     }
+
+    if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) != EQUAL) {
+        memcpy(pDcChargingInfo->EvConnAlarmCode, "", 6);
+    }
 }

+ 7 - 12
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalState.c

@@ -27,7 +27,7 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     //iflog_info("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
     if (strncmp(string, "000000", 6) == EQUAL ||
-            strncmp(string, "023979", 6) == EQUAL
+            strncmp(string, "012219", 6) == EQUAL
        ) {
         return false;
     }
@@ -39,14 +39,6 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     memcpy(pDcChargingInfo->EvConnAlarmCode, string, 6);
     log_info("NOTIFICATION_EV_STOP : EvConnAlarmCode = %s\n", pDcChargingInfo->EvConnAlarmCode);
 
-    //OVP error
-    if (strcmp(string, "012217") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES; }
-    if (strcmp(string, "012219") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES; }
-    if (strcmp(string, "012221") == EQUAL) { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES; }
-
-    //UVP error
-    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
-
     if (strcmp(string, "023700") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES; }
     if (strcmp(string, "023704") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoBatteryMalfun = YES; }
     if (strcmp(string, "023705") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoNoPermission = YES; }
@@ -81,7 +73,11 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023734") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReqCurrentMoreThanLimit = YES; }
     if (strcmp(string, "023735") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoReCapBmsEqrCurrentExceed = YES; }
     if (strcmp(string, "023736") == EQUAL) { pInfoCode->InfoEvents.bits.ChademoChargeRemainCountDown = YES; }
+    if (strcmp(string, "023980") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_BMS_CHARGE_ALLOW_ERROR = YES; }
+    if (strcmp(string, "023981") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_OUTPUT_VOLTAGE_MORE_THEN_10_PERCENT = YES; }
+    if (strcmp(string, "023982") == EQUAL) { pInfoCode->InfoEvents.bits.CHADEMO_ADC_LESS_THAN_10V = YES; }
 
+    if (strcmp(string, "012288") == EQUAL) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; }
     if (strcmp(string, "023701") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEvCommFail = YES; }
     if (strcmp(string, "023737") == EQUAL) { pInfoCode->InfoEvents.bits.CcsRESTemperatureInhibit = YES; }
     if (strcmp(string, "023738") == EQUAL) { pInfoCode->InfoEvents.bits.CcsEVShiftPosition = YES; }
@@ -223,6 +219,8 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023891") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccNotReadyForCharging = YES; }
     if (strcmp(string, "023892") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm = YES; }
     if (strcmp(string, "023893") == EQUAL) { pInfoCode->InfoEvents.bits.CcsSeccFailForQCA7000SetKey = YES; }
+    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
+    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
 
     if (strcmp(string, "023702") == EQUAL) { pInfoCode->InfoEvents.bits.GbEvCommFail = YES; }
     if (strcmp(string, "023900") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = YES; }
@@ -287,8 +285,5 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     if (strcmp(string, "023976") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_ISOLATE = YES; }
     if (strcmp(string, "023977") == EQUAL) { pInfoCode->InfoEvents.bits.ERROR_CODE_BSM_OUTPUT_CONNECTOR = YES; }
 
-    if (strcmp(string, "023979") == EQUAL) { pInfoCode->InfoEvents.bits.EV_Full_Charging = YES; }
-    if (strcmp(string, "023983") == EQUAL) { pInfoCode->InfoEvents.bits.Stop_by_EV_with_unknow_reason = YES; }
-
     return true;
 }

+ 1 - 2
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvComm.h

@@ -27,8 +27,7 @@ enum EV_LOG_INDEX {
 
 //------------------------------------------------------------------------------
 typedef struct StChiilerTemp {
-    uint8_t Temp[2];
-    uint8_t Reserved[2];
+    uint8_t Temp[4];
 } ChillerTemp;
 
 //------------------------------------------------------------------------------

+ 21 - 14
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -71,19 +71,17 @@ static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2)
 {
     uint8_t maxTemp = 0;
 
-    if (headTemp1 == UNDEFINED_TEMP &&
-            headTemp2 == UNDEFINED_TEMP) {
+    if (headTemp1 > TEMP_BOUNDARY &&
+            headTemp2 > TEMP_BOUNDARY) {
         return UNDEFINED_TEMP;
     }
 
-    if (headTemp1 != UNDEFINED_TEMP) {
+    if (headTemp1 <= TEMP_BOUNDARY) {
         maxTemp = headTemp1;
-    } else {
-        headTemp1 = 0;
     }
 
-    if (headTemp2 != UNDEFINED_TEMP) {
-        if (headTemp2 > headTemp1) {
+    if (headTemp2 <= TEMP_BOUNDARY) {
+        if (headTemp2 > maxTemp) {
             maxTemp = headTemp2;
         }
     }
@@ -121,7 +119,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
     float adcVoltage = 0.0;
     ChillerTemp *pChillerTemp = (ChillerTemp *)chillerTemp;
 
-    for (i = 0; i < 2; i++) {
+    for (i = 0; i < 4; i++) {
         adcVoltage = 0.0;
         adcVoltage =  ReadAdcVolt(i);
         if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40
@@ -131,7 +129,7 @@ static void getChillerTemperature(ChillerTemp *chillerTemp)
             pChillerTemp->Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60;
             //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500);
         } else {
-            pChillerTemp->Temp[i] = 195;
+            pChillerTemp->Temp[i] = UNDEFINED_TEMP;
         }
 
         /*CcsConnectorTemp1 = ReadAdcVolt(i);
@@ -207,6 +205,7 @@ void CANReceiver(int fd)
         uint8_t ver[16] = {0};
         uint8_t printChillerTemp = NO;
         uint8_t printConnTemp = NO;
+        uint8_t chillerTemp[2] = {0, 0};
         uint8_t maxChillerTemp = 0;
         uint8_t lastChillerTemp = 0;
         uint8_t maxConnTemp = 0;
@@ -470,6 +469,9 @@ void CANReceiver(int fd)
                 }
                 }*/
 
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] = frame.data[1];
+                ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] = frame.data[2];
+
                 if (ShmDcCommonData->TestTemperature == YES) { //ReadCmdline test
                     break;
                 }
@@ -479,12 +481,16 @@ void CANReceiver(int fd)
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
                     getChillerTemperature(&chiilerTemp);
-                    maxChillerTemp = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]);
+                    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 ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) {
                     //    printChillerTemp = YES;
                     //}
-                    if(maxChillerTemp > (lastChillerTemp + 1) || maxChillerTemp < (lastChillerTemp - 1))
+                    if(maxChillerTemp > (lastChillerTemp + 2) || maxChillerTemp < (lastChillerTemp - 2))
                     {
                         lastChillerTemp = maxChillerTemp;
                         printChillerTemp = YES;
@@ -497,7 +503,7 @@ void CANReceiver(int fd)
                 //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
                 //    printConnTemp = YES;
                 //}
-                if(maxConnTemp > (lastConnTemp[targetGun] + 1) || maxConnTemp < (lastConnTemp[targetGun] - 1))
+                if(maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
                 {
                     lastConnTemp[targetGun] = maxConnTemp;
                     printConnTemp = YES;
@@ -515,10 +521,11 @@ void CANReceiver(int fd)
                         //  (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
                    ) {
                     ShmDcCommonData->SystemModeChange[targetGun] = NO;
-                    log_info("Conn %d max head temp %d, max chiller = %d\r\n",
+                    log_info("Conn %d max head temp = %d, max chiller = %d, max chiller2 = %d\r\n",
                              targetGun,
                              maxConnTemp,
-                             maxChillerTemp);
+                             chillerTemp[0],
+                             chillerTemp[1]);
                 }
 
                 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {

+ 1 - 1
EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -748,7 +748,7 @@ int main(int argc, char *argv[])
                                      (pDcChargingInfo->PresentChargingVoltage * 10),
                                      pDcChargingInfo->Evboard_id);
 
-                checkConnectorOVPState(gunIndex);
+                //checkConnectorOVPState(gunIndex);
             }
 
             switch (pDcChargingInfo->SystemStatus) {

+ 5 - 5
EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/Module_InternalComm.c

@@ -22,8 +22,8 @@
 
 //------------------------------------------------------------------------------
 extern void RelayBoardTask(int uartFD);
-extern void LEDBoardTask(int uartFD);
-extern void FanBoardTask(int uartFD);
+//extern void LEDBoardTask(int uartFD);
+//extern void FanBoardTask(int uartFD);
 extern void AcPlugTask(int uartFD);
 
 //------------------------------------------------------------------------------
@@ -95,9 +95,9 @@ int main(int argc, char *argv[])
 
     RelayBoardTask(fd);
     usleep(100000);
-    LEDBoardTask(fd);
-    usleep(100000);
-    FanBoardTask(fd);
+    //LEDBoardTask(fd);
+    //usleep(100000);
+    //FanBoardTask(fd);
 
     while (isContinue) {
         AcPlugTask(fd);

+ 692 - 192
EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/RelayBoard.c

@@ -22,10 +22,20 @@ static struct RelayModuleData *ShmRelayModuleData = NULL;
 static struct PsuData *ShmPsuData = NULL;
 static struct PrimaryMcuData *ShmPrimaryMcuData = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
+static struct WARNING_CODE_INFO *pSysWarning = NULL;
+static struct LedModuleData *ShmLedModuleData = NULL;
+static struct FanModuleData *ShmFanModuleData = NULL;
 
 static Relay outputRelay = {0};
 static Relay regRelay = {0};
 static int Uart5Fd = 0;
+static struct timeval gFanBoardRunTimer;
+static uint16_t _setFanSpeed = 0;
+static uint16_t fanSpeedSmoothValue = 500;
+
+static Led_Color cur_led_color = {COLOR_MIN_LV};
+static Led_Color led_color;
+static struct timeval _led_priority_time;
 
 //static bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 //static struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -72,24 +82,21 @@ static void StopCheckRelayInfo(uint8_t _chkIndex)
 static void StartCheckRelayInfo(uint8_t _chkIndex, uint8_t toState)
 {
     // SMR1 *2 + SMR2 * 2 + Parallel * 2
-    static time_t lastCheckRelayStateTimer[6] = {0};
-    time_t nowTime = {0};
+    static struct timeval lastCheckRelayStateTimer[6] = {0};
     //uint8_t *pCheckRelayState = (uint8_t *)ShmDcCommonData->CheckRelayStatus[_chkIndex];
 
     if (ShmDcCommonData->CheckRelayStatus[_chkIndex] == STOP) {
-        time(&lastCheckRelayStateTimer[_chkIndex]);
+        gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         ShmDcCommonData->CheckRelayStatus[_chkIndex] = START;
     } else {
-        time(&nowTime);
-
-        if (nowTime - lastCheckRelayStateTimer[_chkIndex] >= 1) {
+        if ((GetTimeoutValue(lastCheckRelayStateTimer[_chkIndex]) / 1000000) >= 1) {
             //log_info("relay welding or driving fault = %d \n", _chkIndex);
             if (toState == 1) {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_DRIVING;
             } else {
                 ShmDcCommonData->CheckRelayStatus[_chkIndex] = RELAY_STATUS_ERROR_WELDING;
             }
-            lastCheckRelayStateTimer[_chkIndex] = nowTime;
+            gettimeofday(&lastCheckRelayStateTimer[_chkIndex], NULL);
         }
     }
 }
@@ -377,13 +384,16 @@ void CheckOutputPowerOverCarReq(uint8_t index)
                           (pDcChargingInfo->EvBatterytargetVoltage * 10));
                 if ((GetTimeoutValue(_checkOutputVolProtectTimer[index]) / 1000) >= OUTPUT_VOL_CHK_TIME) {
                     if (pDcChargingInfo->Type == _Type_Chademo) {
-                        pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.ChaConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                        pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.CCSConnectOVP = YES;
                     } else if (pDcChargingInfo->Type == _Type_GB) {
-                        pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        //pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES;
+                        ShmDcCommonData->ConnectErrList[index].GunBits.GBTConnectOVP = YES;
                     }
-                    pDcChargingInfo->StopChargeFlag = YES;
+                    //pDcChargingInfo->StopChargeFlag = YES;
                 }
             }
         } else {
@@ -550,11 +560,27 @@ void SetK1K2RelayStatus(uint8_t index)
         //if (pDcChargingInfo->RelayWeldingCheck != YES) {
         //    break;
         //}
-
         if (pRegGunPNState->GunN == NO) {
-            pOutputGunPNState->GunN = YES;
-        } else if (pRegGunPNState->GunP == NO) {
-            pOutputGunPNState->GunP = YES;
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunN = YES;
+            } else {
+                pOutputGunPNState->GunN = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunN = NO;
+            }
+        }
+        if (pRegGunPNState->GunP == NO) {
+            if (pDcChargingInfo->GroundFaultStatus != GFD_FAIL) {
+                pOutputGunPNState->GunP = YES;
+            } else {
+                pOutputGunPNState->GunP = NO;
+            }
+        } else {
+            if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+                pOutputGunPNState->GunP = NO;
+            }
         }
         break;
 
@@ -562,11 +588,12 @@ void SetK1K2RelayStatus(uint8_t index)
     case S_COMPLETE:
     case S_ALARM:
         if ((pDcChargingInfo->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR) {
-            if (pRegGunPNState->GunP == YES) {
-                pOutputGunPNState->GunP = NO;
-            } else if (pRegGunPNState->GunN == YES) {
-                pOutputGunPNState->GunN = NO;
-            }
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
         }
         break;
 
@@ -582,6 +609,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pRegGunPNState->GunP = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
 
     case S_CCS_PRECHARGE_ST1:
@@ -596,6 +627,10 @@ void SetK1K2RelayStatus(uint8_t index)
         //        pOutputPreChargingState->CcsPrecharge = NO;
         //    }
         //}
+        if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) {
+            pOutputGunPNState->GunP = NO;
+            pOutputGunPNState->GunN = NO;
+        }
         break;
     }
 }
@@ -721,7 +756,7 @@ void CableCheckDetected(uint8_t index)
              pSysConfig->AlwaysGfdFlag)
        ) {
         if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                pDcChargingInfo->SystemStatus <= S_TERMINATING) ||
+                pDcChargingInfo->SystemStatus < S_TERMINATING) ||
                 (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
                  pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)
            ) {
@@ -735,7 +770,7 @@ void CableCheckDetected(uint8_t index)
                       ) {
                 SetGfdConfig(targetID, GFD_PRECHARGE);
             } else if ((pDcChargingInfo->SystemStatus >= S_CHARGING) &&
-                       (pDcChargingInfo->SystemStatus <= S_TERMINATING)
+                       (pDcChargingInfo->SystemStatus < S_TERMINATING)
                       ) {
                 if ((pDcChargingInfo->Type == _Type_GB) ||
                         (pDcChargingInfo->Type == _Type_Chademo)
@@ -745,9 +780,7 @@ void CableCheckDetected(uint8_t index)
                     SetGfdConfig(targetID, GFD_CHARGING);
                 }
             }
-        } else if (pDcChargingInfo->SystemStatus == S_COMPLETE ||
-                   pDcChargingInfo->SystemStatus == S_PREPARNING ||
-                   pDcChargingInfo->SystemStatus == S_IDLE) {
+        } else {
             SetGfdConfig(targetID, GFD_IDLE);
         }
     }
@@ -1124,6 +1157,495 @@ static void outputRelayInit(int fd)
     }
 }
 
+static bool IsRelayProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Relay Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
+static void SetFanModuleSpeed(void)
+{
+    {
+        FanSpeed _fanSpeed = {0};
+
+        _setFanSpeed += fanSpeedSmoothValue;
+
+        if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed) {
+            _setFanSpeed = ShmFanModuleData->SetFan1Speed;
+        }
+
+        //printf("_setFanSpeed = %d \n", _setFanSpeed);
+        _fanSpeed.speed[0] = _setFanSpeed;
+
+        _fanSpeed.speed[1] = _setFanSpeed;
+
+        _fanSpeed.speed[2] = _setFanSpeed;
+
+        _fanSpeed.speed[3] = _setFanSpeed;
+
+        if (Config_Fan_Speed(Uart5Fd, ADDR_FAN, &_fanSpeed) == PASS) {
+            //log_info("successfully Fan\n");
+        }
+    }
+}
+
+// 風扇速度
+static void GetFanSpeed(void)
+{
+    FanSpeed fanSpeed = {0};
+
+    //log_info("Get fan board speed \n");
+    if (Query_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed) == PASS) {
+        ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0];
+        ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1];
+        ShmFanModuleData->PresentFan3Speed = fanSpeed.speed[2];
+        ShmFanModuleData->PresentFan4Speed = fanSpeed.speed[3];
+//      log_info("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+//      log_info("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]);
+//      log_info("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]);
+//      log_info("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]);
+        // Config_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed[0]);
+        //SysInfoData (SystemFanRotaSpeed)
+    }
+}
+
+static void GetFanSpeedByFunction(void)
+{
+    if (pSysConfig->SwitchDebugFlag == YES) {
+        return;
+    }
+
+    // 風控修改 :
+    // ******************************************************* //
+    //
+    //       當前PSU輸出總 KW       PSU Temp
+    // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45)
+    //       當前樁最大功率 KW         45
+    //
+    // ******************************************************* //
+
+    // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower
+    uint32_t _maxPower = ShmPsuData->SystemAvailablePower;
+    // 當前PSU輸出總 KW & PSU Temp :
+    uint8_t temp = 0;
+    uint8_t index = 0;
+    uint8_t count = 0;
+    uint8_t gunIndex = 0;
+    uint8_t _temp_diff = 0;
+    float power = 0;
+    double _pw_rate = 0;
+    double _temp_rate = 0;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (index = 0; index < ShmPsuData->GroupCount; index++) {
+        for (count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) {
+            if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp) {
+                temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp;
+            }
+        }
+    }
+
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
+
+        power += (pDcChargingInfo->PresentChargingPower * 10);
+    }
+
+    if (_maxPower > 0) {
+        _pw_rate = power / (double)_maxPower;
+    }
+
+    if (temp > 0) {
+        _temp_rate = (double)temp / 50;
+    }
+
+    if (temp > 45) {
+        _temp_diff = temp - 70;
+    }
+
+    ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED;
+
+    if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED) {
+        ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
+    }
+
+    if (ShmFanModuleData->TestFanSpeed < 0) {
+        ShmFanModuleData->TestFanSpeed = 0;
+    }
+//
+//  printf("power = %f \n", power);
+//  printf("_maxPower = %d \n", _maxPower);
+//  printf("temp = %d \n", temp);
+//
+//  printf("_pw_rate = %f \n", _pw_rate);
+//  printf("_temp_rate = %f \n", _temp_rate);
+//  printf("_temp_diff = %d \n", _temp_diff);
+//  printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff));
+//  printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed);
+}
+
+static void SetRtcData_Fan(void)
+{
+    struct timeb csuTime;
+    struct tm *tmCSU;
+    Rtc rtc = {0};
+
+    ftime(&csuTime);
+    tmCSU = localtime(&csuTime.time);
+    //  log_info("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+    //          tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+    //          tmCSU->tm_sec);
+
+    rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+    rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+    rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+    rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+    rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+    rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+    rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+    rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+    rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+    rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+    rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+    rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+    rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+    rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+    if (Config_Rtc_Data(Uart5Fd, ADDR_FAN, &rtc) == PASS) {
+        //log_info("SetRtc (FB) sucessfully. \n");
+    }
+}
+
+static void SetModelName_Fan(void)
+{
+    if (Config_Model_Name(Uart5Fd, ADDR_FAN, pSysConfig->ModelName) == PASS) {
+        log_info("Set Model name PASS = %s \n", pSysConfig->ModelName);
+    }
+}
+
+static void GetFwAndHwVersion_Fan(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // FanModuleData
+        strcpy((char *)ShmFanModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleFwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW);
+    }
+
+    if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) {
+        // SystemInfo
+        strcpy((char *)pSysInfo->FanModuleHwRev, ver.Version_FW);
+        //log_info("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW);
+    }
+}
+
+static void fanBoardSelfTest(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+    GetFwAndHwVersion_Fan();
+    SetModelName_Fan();
+    SetRtcData_Fan();
+    sleep(1);
+    gettimeofday(&gFanBoardRunTimer, NULL);
+}
+
+static void fanBoardPorcess(void)
+{
+    if (ShmFanModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (ShmFanModuleData->SelfTest_Comp == YES ||
+            strlen((char *)pSysInfo->FanModuleFwRev) != 0 ||
+            pSysInfo->FanModuleFwRev[0] != '\0') {
+        ShmFanModuleData->SelfTest_Comp = YES;
+
+        if (GetTimeoutValue(gFanBoardRunTimer) / 1000 >= 1000) {
+            //GetPsuTempForFanSpeed();
+            GetFanSpeedByFunction();
+            GetFanSpeed();
+            pSysInfo->SystemFanRotaSpeed = _setFanSpeed;
+            gettimeofday(&gFanBoardRunTimer, NULL);
+
+            ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+            ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+
+            //log_info("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
+            SetFanModuleSpeed();
+        }
+    }
+}
+
+static void GetFwAndHwVersion_Led(void)
+{
+    Ver ver = {0};
+
+    if (Query_FW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS) {
+        // LedModuleData
+        strcpy((char *) ShmLedModuleData->version, ver.Version_FW);
+        // SystemInfo
+        strcpy((char *) pSysInfo->LedModuleFwRev, ver.Version_FW);
+        log_info("GetFwAndHwVersion_Led s1 = %s \n", ver.Version_FW);
+        ShmLedModuleData->SelfTest_Comp = YES;
+    } else {
+        //log_info("GetFwAndHwVersion_Led fail \n");
+    }
+
+//  if (Query_HW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS)
+//  {
+//      // SystemInfo
+//      strcpy((char *) pSysInfo->RelayModuleHwRev, ver.Version_FW);
+//      //log_info("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW);
+//  }
+}
+
+static bool IsNoneMatchLedColor(void)
+{
+    bool result = false;
+
+    if (cur_led_color.Connect_1_Red != led_color.Connect_1_Red ||
+            cur_led_color.Connect_1_Green != led_color.Connect_1_Green ||
+            cur_led_color.Connect_1_Blue != led_color.Connect_1_Blue ||
+            cur_led_color.Connect_2_Red != led_color.Connect_2_Red ||
+            cur_led_color.Connect_2_Green != led_color.Connect_2_Green ||
+            cur_led_color.Connect_2_Blue != led_color.Connect_2_Blue) {
+        result = true;
+    }
+
+    return result;
+}
+
+//static void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2)
+static void SetLedColor(void)
+{
+    static uint8_t _checkLedChanged = 3;
+    struct ChargingInfoData *chargingData_1 = NULL;
+    struct ChargingInfoData *chargingData_2 = NULL;
+    uint8_t _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST;
+
+    if (pSysConfig->TotalConnectorCount == 1) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+    } else if (pSysConfig->TotalConnectorCount == 2) {
+        chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
+        chargingData_2 = (struct ChargingInfoData *)GetDcChargingInfoData(1);
+    }
+
+    if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_DARKEST) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST;
+    } else if (pSysConfig->LedInfo.Intensity == _LED_INTENSITY_MEDIUM) {
+        _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM;
+    }
+
+    //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) {
+        led_color.Connect_1_Green = COLOR_MIN_LV;
+        led_color.Connect_1_Blue = COLOR_MIN_LV;
+        led_color.Connect_1_Red = _colorBuf;
+        led_color.Connect_2_Green = COLOR_MIN_LV;
+        led_color.Connect_2_Blue = COLOR_MIN_LV;
+        led_color.Connect_2_Red = _colorBuf;
+    } else {
+        if (pSysInfo->IsAlternatvieConf) {
+            if ((chargingData_1->SystemStatus == S_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION) &&
+                    (chargingData_2->SystemStatus == S_BOOTING ||
+                     chargingData_2->SystemStatus == S_IDLE ||
+                     chargingData_2->SystemStatus == S_RESERVATION)) {
+#if defined DD360Audi
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = _colorBuf;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = _colorBuf;
+#else
+                led_color.Connect_1_Green = _colorBuf;
+                led_color.Connect_1_Blue = COLOR_MIN_LV;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+
+                led_color.Connect_2_Green = _colorBuf;
+                led_color.Connect_2_Blue = COLOR_MIN_LV;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                       (chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+                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_BOOTING ||
+                    chargingData_1->SystemStatus == S_IDLE ||
+                    chargingData_1->SystemStatus == S_RESERVATION ||
+                    chargingData_1->SystemStatus == S_MAINTAIN) {
+
+                if (chargingData_1->IsAvailable == NO) { //For Audi
+                    led_color.Connect_1_Green = COLOR_MIN_LV;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = _colorBuf;
+                    led_color.Connect_1_Red = _colorBuf;
+#else
+                    led_color.Connect_1_Green = _colorBuf;
+                    led_color.Connect_1_Blue = COLOR_MIN_LV;
+                    led_color.Connect_1_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_1->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_1_Green = COLOR_MIN_LV;
+                led_color.Connect_1_Blue = _colorBuf;
+                led_color.Connect_1_Red = COLOR_MIN_LV;
+            }
+
+            // --------------------------------------------------------------------------
+            if (chargingData_2->SystemStatus == S_BOOTING ||
+                    chargingData_2->SystemStatus == S_IDLE ||
+                    chargingData_2->SystemStatus == S_RESERVATION ||
+                    chargingData_2->SystemStatus == S_MAINTAIN) {
+                if (chargingData_2->IsAvailable == NO) {
+                    led_color.Connect_2_Green = COLOR_MIN_LV;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = _colorBuf;
+                } else {
+#if defined DD360Audi
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = _colorBuf;
+                    led_color.Connect_2_Red = _colorBuf;
+#else
+                    led_color.Connect_2_Green = _colorBuf;
+                    led_color.Connect_2_Blue = COLOR_MIN_LV;
+                    led_color.Connect_2_Red = COLOR_MIN_LV;
+#endif
+                }
+            } else if ((chargingData_2->SystemStatus >= S_AUTHORIZING &&
+                        chargingData_2->SystemStatus <= S_COMPLETE) ||
+                       (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                        chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
+                led_color.Connect_2_Green = COLOR_MIN_LV;
+                led_color.Connect_2_Blue = _colorBuf;
+                led_color.Connect_2_Red = COLOR_MIN_LV;
+            }
+        }
+    }
+
+    if (_checkLedChanged > 0) {
+        if (Config_Led_Color(Uart5Fd, ADDR_LED, &led_color) == PASS) {
+            _checkLedChanged--;
+
+            cur_led_color.Connect_1_Red     = led_color.Connect_1_Red;
+            cur_led_color.Connect_1_Green   = led_color.Connect_1_Green;
+            cur_led_color.Connect_1_Blue    = led_color.Connect_1_Blue;
+            cur_led_color.Connect_2_Red     = led_color.Connect_2_Red;
+            cur_led_color.Connect_2_Green   = led_color.Connect_2_Green;
+            cur_led_color.Connect_2_Blue    = led_color.Connect_2_Blue;
+        }
+    } else if (IsNoneMatchLedColor()) {
+        _checkLedChanged = 3;
+    }
+}
+
+static void LEDBoardSelfTest(void)
+{
+    // 自檢階段處理,自檢階段如果讀不到版號則代表該系統沒有掛燈板
+    if (ShmLedModuleData->SelfTest_Comp == YES) {
+        return;
+    }
+
+#if defined DD360 ||defined DD360Audi
+    GetFwAndHwVersion_Led();
+    sleep(1);
+    gettimeofday(&_led_priority_time, NULL);
+
+    return;
+#endif //defined DD360 || defined DD360Audi
+
+    // 自檢階段
+    if (pSysInfo->SelfTestSeq <= _STEST_PSU_CAP) {
+        GetFwAndHwVersion_Led();
+        sleep(1);
+        gettimeofday(&_led_priority_time, NULL);
+    } else {
+        // 自檢階段沒有問到版號
+        if (pAlarmCode->AlarmEvents.bits.LedboardStestFail == NO) {
+            pAlarmCode->AlarmEvents.bits.LedboardStestFail = YES;
+        }
+    }
+}
+
+static void LEDBoardProcess(void)
+{
+    //struct ChargingInfoData *pDcChargingInfo0 = NULL;
+    //struct ChargingInfoData *pDcChargingInfo1 = NULL;
+
+    if (ShmLedModuleData->SelfTest_Comp == NO) {
+        return;
+    }
+
+    if (GetTimeoutValue(_led_priority_time) / 1000 >= 1000) {
+
+        //if (pSysConfig->TotalConnectorCount == 1) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo0);
+        //} else if (pSysConfig->TotalConnectorCount == 2) {
+        //    pDcChargingInfo0 = (struct ChargeingInfoData *)GetDcChargingInfoData(0);
+        //    pDcChargingInfo1 = (struct ChargeingInfoData *)GetDcChargingInfoData(1);
+        //    SetLedColor(pDcChargingInfo0, pDcChargingInfo1);
+        //}
+        SetLedColor();
+        gettimeofday(&_led_priority_time, NULL);
+    }
+}
+
 void RelayBoardTask(int uartFD)
 {
     pid_t pid = fork();
@@ -1143,6 +1665,9 @@ void RelayBoardTask(int uartFD)
         ShmPsuData = (struct PsuData *)GetShmPsuData();
         ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
         ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
+        pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
+        ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
+        ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData();
 
         Uart5Fd = uartFD;
 
@@ -1150,214 +1675,189 @@ void RelayBoardTask(int uartFD)
         outputRelayInit(uartFD);
 
         while (isContinue) {
+
+            if(IsRelayProcessNeedPause() == true)
+            {
+                sleep(1);
+                continue;
+            }
+
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
             if (ShmRelayModuleData->SelfTest_Comp == NO) {
                 GetFwAndHwVersion_Relay();
                 SetModelName_Relay(); //DS60-120 add
                 SetRtcData_Relay();
                 sleep(1);
-
-                continue;
             }
 
-            // ==============優先權最高 10 ms ==============
-            // 輸出電壓
-            GetPersentOutputVol();
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardSelfTest();
+#endif //NO_FAN_BOARD
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-            // 三相輸入電壓
-            GetPresentInputVol();
-#endif //!defined DD360 && !defined DD360Audi
+#if !defined DD360ComBox
+            LEDBoardSelfTest();
+#endif //defined DD360ComBox
 
-            // 讀取當前 AC relay 狀態
-            regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+            if (ShmRelayModuleData->SelfTest_Comp == YES)
+            {
+                // ==============優先權最高 10 ms ==============
+                // 輸出電壓
+                GetPersentOutputVol();
 
-            GetRelayOutputStatus();
+    #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                // 三相輸入電壓
+                GetPresentInputVol();
+    #endif //!defined DD360 && !defined DD360Audi
 
-            for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
-                pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+                // 讀取當前 AC relay 狀態
+                regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
 
-                // Cable check (Set)
-                CableCheckDetected(i);
+                GetRelayOutputStatus();
 
-                // check k1 k2 relay 狀態
-                CheckK1K2RelayOutput(i);
+                // Cable check (Get)
+                GetGfdAdc();
 
-                // 依據當前各槍的狀態選擇 搭上/放開 Relay
-                SetK1K2RelayStatus(i);
+                for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
-                if (pSysConfig->PhaseLossPolicy == YES) {
-                    CheckPhaseLossStatus(i);
-                }
+                    // Cable check (Set)
+                    CableCheckDetected(i);
 
-                CheckAcInputOvpStatus(i);
-#endif //!defined DD360 && !defined DD360Audi
+                    // check k1 k2 relay 狀態
+                    CheckK1K2RelayOutput(i);
 
-                if (pDcChargingInfo->SystemStatus == S_IDLE ||
-                        pDcChargingInfo->SystemStatus == S_RESERVATION ||
-                        pDcChargingInfo->SystemStatus == S_MAINTAIN) {
-                    //pDcChargingInfo->RelayWeldingCheck = NO;
-                    //_isRelayWelding[i] = NO;
-                    _isOvpChkTimeFlag[i] = NO;
-                    //ResetDetAlarmStatus(i); //DS60-120 add
-                }
+                    // 依據當前各槍的狀態選擇 搭上/放開 Relay
+                    SetK1K2RelayStatus(i);
 
-                if (pDcChargingInfo->SystemStatus == S_BOOTING ||
-                        (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
-                         pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
-                        (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
-                         pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
-                        pSysInfo->WaitForPlugit == YES ||
-                        (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
-                         pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
-                   ) {
-                    pDcChargingInfo->IsReadyToCharging = YES;
-                    isCharging = true;
-
-                    // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-                    //if (pDcChargingInfo->Type == _Type_GB) {
-                    //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                    //            pDcChargingInfo->RelayWeldingCheck == NO) {
-                    //        CheckRelayWeldingStatus(i);
-                    //    }
-                    //} else {
-                    //pDcChargingInfo->RelayWeldingCheck = YES;
-                    //}
-
-                    if (pDcChargingInfo->SystemStatus == S_CHARGING) {
-                        CheckOutputPowerOverCarReq(i);
-                        //CheckOutputVolNoneMatchFire(i);
+#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
+                    if (pSysConfig->PhaseLossPolicy == YES) {
+                        CheckPhaseLossStatus(i);
                     }
-                    /*else {
-                        _isOutputNoneMatch[i] = NO;
-                    }*/
-                } else {
-                    pDcChargingInfo->IsReadyToCharging = NO;
-                }
-            }
 
-            // Cable check (Get)
-            GetGfdAdc();
-
-            // 橋接 relay
-            SetParalleRelayStatus();
+                    CheckAcInputOvpStatus(i);
+#endif //!defined DD360 && !defined DD360Audi
 
-            // 搭上 AC Contactor
-            //if (isCharging) {
-            //    outputRelay.relay_event.bits.AC_Contactor = YES;
-            //} else {
-            //    outputRelay.relay_event.bits.AC_Contactor = NO;
-            //}
+                    if (pDcChargingInfo->SystemStatus == S_IDLE ||
+                            pDcChargingInfo->SystemStatus == S_RESERVATION ||
+                            pDcChargingInfo->SystemStatus == S_MAINTAIN) {
+                        //pDcChargingInfo->RelayWeldingCheck = NO;
+                        //_isRelayWelding[i] = NO;
+                        _isOvpChkTimeFlag[i] = NO;
+                        //ResetDetAlarmStatus(i); //DS60-120 add
+                    }
 
-            if (isCharging ||
-                    (ShmPsuData->Work_Step >= _TEST_MODE &&
-                     ShmPsuData->Work_Step <= _TEST_MODE)) {
-                isStopChargingCount = false;
-                outputRelay.relay_event.bits.AC_Contactor = YES;
-            } else {
-                if (!isStopChargingCount) {
-                    gettimeofday(&_close_ac_contactor, NULL);
-                    isStopChargingCount = true;
-                } else {
-                    if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
-                            GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
-                        outputRelay.relay_event.bits.AC_Contactor = NO;
+                    if (pDcChargingInfo->SystemStatus == S_BOOTING ||
+                            (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK &&
+                             pDcChargingInfo->SystemStatus <= S_COMPLETE) ||
+                            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                             pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                            pSysInfo->WaitForPlugit == YES ||
+                            (pSysInfo->PageIndex >= _LCM_AUTHORIZING &&
+                             pSysInfo->PageIndex <= _LCM_WAIT_FOR_PLUG)
+                       ) {
+                        pDcChargingInfo->IsReadyToCharging = YES;
+                        isCharging = true;
+
+                        // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
+                        //if (pDcChargingInfo->Type == _Type_GB) {
+                        //    if (pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                        //            pDcChargingInfo->RelayWeldingCheck == NO) {
+                        //        CheckRelayWeldingStatus(i);
+                        //    }
+                        //} else {
+                        //pDcChargingInfo->RelayWeldingCheck = YES;
+                        //}
+
+                        if (pDcChargingInfo->SystemStatus == S_CHARGING) {
+                            CheckOutputPowerOverCarReq(i);
+                            //CheckOutputVolNoneMatchFire(i);
+                        }
+                        /*else {
+                            _isOutputNoneMatch[i] = NO;
+                        }*/
+                    } else {
+                        pDcChargingInfo->IsReadyToCharging = NO;
                     }
                 }
-            }
 
-            if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
-                RunForceStopProcess();
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-            }
-
-            if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
-                outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
-            }
+                    // 橋接 relay
+                    SetParalleRelayStatus();
 
-            // 搭上/鬆開 Relay
-            if (IsNoneMatchRelayStatus()) {
-                if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
-                    //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
-
-                    //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
-                    //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
-                    //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
-                    //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
-                    //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
-                    //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
-                    //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
-
-                    //MatchRelayStatus();
-
-                    //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
-                    //         regRelay.relay_event.bits.AC_Contactor,
-                    //         regRelay.relay_event.bits.Gun1_P,
-                    //         regRelay.relay_event.bits.Gun1_N,
-                    //         regRelay.relay_event.bits.Gun2_P,
-                    //         regRelay.relay_event.bits.Gun2_N,
-                    //         regRelay.relay_event.bits.CCS_Precharge,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_P,
-                    //         regRelay.relay_event.bits.Gun1_Parallel_N);
+                    // 搭上 AC Contactor
+                    //if (isCharging) {
+                    //    outputRelay.relay_event.bits.AC_Contactor = YES;
+                    //} else {
+                    //    outputRelay.relay_event.bits.AC_Contactor = NO;
+                    //}
 
-                }
-            } /*else {
-                    log_info("======== Relay Status Start========\n");
-                    if (regRelay.relay_event.bits.AC_Contactor == YES) {
-                        log_info("AC Power : ON \n");
+                    if (isCharging ||
+                            (ShmPsuData->Work_Step >= _TEST_MODE &&
+                             ShmPsuData->Work_Step <= _TEST_MODE)) {
+                        isStopChargingCount = false;
+                        outputRelay.relay_event.bits.AC_Contactor = YES;
                     } else {
-                        log_info("AC Power : OFF \n");
+                        if (!isStopChargingCount) {
+                            gettimeofday(&_close_ac_contactor, NULL);
+                            isStopChargingCount = true;
+                        } else {
+                            if ((outputRelay.relay_event.bits.AC_Contactor == YES &&
+                                    GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) {
+                                outputRelay.relay_event.bits.AC_Contactor = NO;
+                            }
+                        }
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_P == YES) {
-                        log_info("Conn1(+) : ON \n");
-                    } else {
-                        log_info("Conn1(+) : OFF \n");
+                    if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) {
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun1_N == YES) {
-                        log_info("Conn1(-) : ON \n");
-                    } else {
-                        log_info("Conn1(-) : OFF \n");
+                    if (pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == ABNORMAL) {
+                        RunForceStopProcess();
+                        outputRelay.relay_event.bits.AC_Contactor = NO;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_P == YES) {
-                        log_info("Conn2(+) : ON \n");
-                    } else {
-                        log_info("Conn2(+) : OFF \n");
+                    if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) {
+                        outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES;
                     }
 
-                    if (regRelay.relay_event.bits.Gun2_N == YES) {
-                        log_info("Conn2(-) : ON \n");
-                    } else {
-                        log_info("Conn2(-) : OFF \n");
-                    }
+                    // 搭上/鬆開 Relay
+                    if (IsNoneMatchRelayStatus()) {
+                        if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay)) {
+                            //regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
+
+                            //regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
+                            //regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
+                            //regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
+                            //regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
+                            //regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
+                            //regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P;
+                            //regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N;
+
+                            //MatchRelayStatus();
+
+                            //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+                            //         regRelay.relay_event.bits.AC_Contactor,
+                            //         regRelay.relay_event.bits.Gun1_P,
+                        //         regRelay.relay_event.bits.Gun1_N,
+                        //         regRelay.relay_event.bits.Gun2_P,
+                        //         regRelay.relay_event.bits.Gun2_N,
+                        //         regRelay.relay_event.bits.CCS_Precharge,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_P,
+                        //         regRelay.relay_event.bits.Gun1_Parallel_N);
 
-                    if (regRelay.relay_event.bits.CCS_Precharge == YES) {
-                        log_info("Precharge : ON \n");
-                    } else {
-                        log_info("Precharge : OFF \n");
                     }
+                }
+            }
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) {
-                        log_info("Parallel(+) : ON \n");
-                    } else {
-                        log_info("Parallel(+) : OFF \n");
-                    }
+#if !defined NO_FAN_BOARD && !defined DD360ComBox
+            fanBoardPorcess();
+#endif //NO_FAN_BOARD
 
-                    if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) {
-                        log_info("Parallel(-) : ON \n");
-                    } else {
-                        log_info("Parallel(-) : OFF \n");
-                    }
-                    log_info("======== Relay Status End========\n");
-                }*/
+#if !defined DD360ComBox
+            LEDBoardProcess();
+#endif //defined DD360ComBox
+
+            usleep(10000);
         }
-        usleep(100000);
     }
 }

+ 68 - 1
EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -288,6 +288,7 @@ static void checkChillerStatus(Gpio_out *gpio)
     uint8_t chillerCount = 0;
     struct ChargingInfoData *pDcChargingInfo = NULL;
     static ChillerInfo fChillerInfo[2] = {0}, *pChillerInfo = NULL;
+    static ChillerInfo _chiller;
     Gpio_out *pGpio = (Gpio_out *)gpio;
 
     if ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) ||
@@ -309,6 +310,28 @@ static void checkChillerStatus(Gpio_out *gpio)
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
+        if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
+        {
+            pChillerInfo->ChillerSwitch = YES;
+            pChillerInfo->ChillerOnTime = time((time_t *)NULL);
+        }
+        else
+        {
+            if(pChillerInfo->ChillerSwitch == YES)
+            {
+                //10分鐘後停止
+                if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
+                {
+                    pChillerInfo->ChillerSwitch = NO;
+                }
+            }
+            else
+            {
+                pChillerInfo->ChillerSwitch = NO;
+            }
+        }
+#if 0
         if ((pDcChargingInfo->PresentChargingCurrent) >= 150) { //當前電壓於150A,打開水冷機
             pChillerInfo->ChillerSwitch = YES;
             pChillerInfo->ChillerOnTime = time((time_t *)NULL);
@@ -328,9 +351,25 @@ static void checkChillerStatus(Gpio_out *gpio)
                 pChillerInfo->ChillerSwitch = NO;
             }
         }
+#endif
+    }
+
+    uint8_t _chillerNeedOn = NO;
+    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    {
+        pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
+        if(pChillerInfo->ChillerSwitch == YES)
+        {
+            _chillerNeedOn = YES;
+        }
     }
 
-    pGpio->AC_Connector = pChillerInfo->ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
+    if(_chiller.ChillerSwitch != _chillerNeedOn)
+    {
+        log_info("Chiller Need Turn %s\n", _chillerNeedOn == YES ? "ON" : "OFF");
+    }
+    _chiller.ChillerSwitch = _chillerNeedOn;
+    pGpio->AC_Connector = _chiller.ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
 }
 
 void SetOutputGpio(int fd, uint8_t outputValue)
@@ -497,6 +536,29 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
 //    }
 //}
 
+static bool IsPrimaryProcessNeedPause(void)
+{
+    bool _pause = false;
+    static bool isPause = false;
+    struct ChargingInfoData *pDcChargingInfo = NULL;
+
+    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->SystemStatus == S_UPDATE)
+        {
+            _pause = true;
+        }
+    }
+    if(isPause != _pause)
+    {
+        log_info("Primary Process Now Is %s \n", _pause == true ? "Paused" : "Continued");
+    }
+    isPause = _pause;
+
+    return _pause;
+}
+
 int main(void)
 {
     int Uart1Fd = -1;
@@ -545,6 +607,11 @@ int main(void)
     //Initialization();
 
     for (;;) {
+        if(IsPrimaryProcessNeedPause() == true)
+        {
+            sleep(1);
+            continue;
+        }
         // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
         // 模組更新 FW 後,需重新做
         if (ShmPrimaryMcuData->SelfTest_Comp != PASS) {

+ 8 - 2
EVSE/Projects/DD360ComBox/Apps/ReadCmdline.c

@@ -1097,10 +1097,16 @@ static void resdGunAndChillerTemp(void)
 
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
 
-                printTimeMsg("get %d gun temp = %d, chiller temp = %d\r\n",
+                printTimeMsg("get gun %d temp = %3d, chiller = %3d, ConnTemp = %3d, %3d,SysTemp = %3d, %3d, %3d, %3d\r\n",
                              i,
                              pDcChargingInfo->ConnectorTemp,
-                             pDcChargingInfo->ChillerTemp);
+                             pDcChargingInfo->ChillerTemp,
+                             ShmDcCommonData->ConnectorTemp[i][0],
+                             ShmDcCommonData->ConnectorTemp[i][1],
+                             ShmDcCommonData->SystemTemp[0],
+                             ShmDcCommonData->SystemTemp[1],
+                             ShmDcCommonData->SystemTemp[2],
+                             ShmDcCommonData->SystemTemp[3]);
             }//for
             ftime(&showTime);
         }

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


BIN
EVSE/Projects/DD360ComBox/Images/u-boot.img


BIN
EVSE/Projects/DD360ComBox/output/FactoryConfig


BIN
EVSE/Projects/DD360ComBox/output/Module_DoComm


BIN
EVSE/Projects/DD360ComBox/output/Module_EvComm


BIN
EVSE/Projects/DD360ComBox/output/Module_EventLogging


BIN
EVSE/Projects/DD360ComBox/output/Module_InternalComm


BIN
EVSE/Projects/DD360ComBox/output/Module_LcmControl


BIN
EVSE/Projects/DD360ComBox/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360ComBox/output/ReadCmdline


BIN
EVSE/Projects/DD360ComBox/output/main