ソースを参照

Merge branch 'AW-CCS' of https://git.phihong.com.tw:30000/System_Integration/CSU3_AM335x into AW-CCS

8009 2 年 前
コミット
acc2a663d9
71 ファイル変更4158 行追加1338 行削除
  1. BIN
      EVSE/GPL/open-plc-utils-0.3/release/usr/local/bin/plcinit
  2. 5 1
      EVSE/Projects/AW-CCS/Apps/CCS/SeccComm.c
  3. 5 1
      EVSE/Projects/AX80/Apps/CCS/SeccComm.c
  4. 5 1
      EVSE/Projects/CCS/Apps/SeccComm.c
  5. 1 1
      EVSE/Projects/DD360UCar/Apps/CSU/Ethernet.c
  6. 4 4
      EVSE/Projects/DD360UCar/Apps/CSU/RFID.c
  7. 55 69
      EVSE/Projects/DD360UCar/Apps/CSU/main.c
  8. 2 0
      EVSE/Projects/DD360UCar/Apps/CSU/main.h
  9. 1 0
      EVSE/Projects/DD360UCar/Apps/Config.h
  10. 3 4
      EVSE/Projects/DD360UCar/Apps/ModuleDoComm/DoComm.c
  11. 31 4
      EVSE/Projects/DD360UCar/Apps/ModuleEvComm/Module_EvRxComm.c
  12. 35 28
      EVSE/Projects/DD360UCar/Apps/ModuleEvComm/Module_EvTxComm.c
  13. 27 22
      EVSE/Projects/DD360UCar/Apps/ModuleLcmCtrl/Module_LcmControl.c
  14. 1 1
      EVSE/Projects/DD360UCar/Apps/ModuleLcmCtrl/Module_LcmControl.h
  15. 17 2
      EVSE/Projects/DD360UCar/Apps/ModuleUpdateFW/Module_UpdateFW.c
  16. 1 0
      EVSE/Projects/DD360UCar/Apps/ReadCmdline.c
  17. 1 0
      EVSE/Projects/DD360UCar/Apps/timeout.h
  18. BIN
      EVSE/Projects/DD360UCar/Images/ramdisk.gz
  19. BIN
      EVSE/Projects/DD360UCar/output/FactoryConfig
  20. BIN
      EVSE/Projects/DD360UCar/output/Module_ChkSysTask
  21. BIN
      EVSE/Projects/DD360UCar/output/Module_DoComm
  22. BIN
      EVSE/Projects/DD360UCar/output/Module_EvComm
  23. BIN
      EVSE/Projects/DD360UCar/output/Module_EventLogging
  24. BIN
      EVSE/Projects/DD360UCar/output/Module_InternalComm
  25. BIN
      EVSE/Projects/DD360UCar/output/Module_LcmControl
  26. BIN
      EVSE/Projects/DD360UCar/output/Module_PrimaryComm
  27. BIN
      EVSE/Projects/DD360UCar/output/Module_UpdateFW
  28. BIN
      EVSE/Projects/DD360UCar/output/ReadCmdline
  29. BIN
      EVSE/Projects/DD360UCar/output/main
  30. 1 1
      EVSE/Projects/DO360/Apps/main.c
  31. BIN
      EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin
  32. BIN
      EVSE/Projects/DO360/Images/ramdisk.gz
  33. 10 5
      EVSE/Projects/DS60-120/Apps/CheckSystemTask.c
  34. 158 28
      EVSE/Projects/DS60-120/Apps/Config.h
  35. BIN
      EVSE/Projects/DS60-120/Apps/FactoryConfig
  36. 7 2
      EVSE/Projects/DS60-120/Apps/Makefile
  37. BIN
      EVSE/Projects/DS60-120/Apps/Module_EvComm
  38. 393 247
      EVSE/Projects/DS60-120/Apps/Module_EvComm.c
  39. 0 1
      EVSE/Projects/DS60-120/Apps/Module_EvComm.h
  40. BIN
      EVSE/Projects/DS60-120/Apps/Module_EventLogging
  41. 70 23
      EVSE/Projects/DS60-120/Apps/Module_EventLogging.c
  42. BIN
      EVSE/Projects/DS60-120/Apps/Module_InternalComm
  43. 456 105
      EVSE/Projects/DS60-120/Apps/Module_InternalComm.c
  44. 62 0
      EVSE/Projects/DS60-120/Apps/Module_LcmContro.h
  45. BIN
      EVSE/Projects/DS60-120/Apps/Module_LcmControl
  46. 86 13
      EVSE/Projects/DS60-120/Apps/Module_LcmControl.c
  47. BIN
      EVSE/Projects/DS60-120/Apps/Module_PrimaryComm
  48. 3 5
      EVSE/Projects/DS60-120/Apps/Module_PrimaryComm.c
  49. BIN
      EVSE/Projects/DS60-120/Apps/Module_PsuComm
  50. 415 574
      EVSE/Projects/DS60-120/Apps/Module_PsuComm.c
  51. 12 11
      EVSE/Projects/DS60-120/Apps/Module_PsuComm.h
  52. BIN
      EVSE/Projects/DS60-120/Apps/Module_SmartBox
  53. 1475 0
      EVSE/Projects/DS60-120/Apps/Module_SmartBox.c
  54. 75 0
      EVSE/Projects/DS60-120/Apps/Module_SmartBox.h
  55. 1 1
      EVSE/Projects/DS60-120/Apps/OutputTask.c
  56. BIN
      EVSE/Projects/DS60-120/Apps/ReadCmdline
  57. 344 39
      EVSE/Projects/DS60-120/Apps/ReadCmdline.c
  58. BIN
      EVSE/Projects/DS60-120/Apps/UnsafetyOutputTask
  59. 3 3
      EVSE/Projects/DS60-120/Apps/internalComm.c
  60. 4 4
      EVSE/Projects/DS60-120/Apps/internalComm.h
  61. BIN
      EVSE/Projects/DS60-120/Apps/main
  62. 387 137
      EVSE/Projects/DS60-120/Apps/main.c
  63. 2 1
      EVSE/Projects/DS60-120/Apps/timeout.h
  64. BIN
      EVSE/Projects/DS60-120/Images/FactoryDefaultConfig.bin
  65. BIN
      EVSE/Projects/DS60-120/Images/ramdisk.gz
  66. BIN
      EVSE/rootfs/bin/plcboot
  67. BIN
      EVSE/rootfs/bin/plcinit
  68. BIN
      EVSE/rootfs/bin/plctool
  69. BIN
      EVSE/rootfs/root/Module_Payment_Bazel8
  70. BIN
      EVSE/rootfs/root/Module_Payment_Enegate
  71. BIN
      EVSE/rootfs/root/Module_PowerSharing

BIN
EVSE/GPL/open-plc-utils-0.3/release/usr/local/bin/plcinit


+ 5 - 1
EVSE/Projects/AW-CCS/Apps/CCS/SeccComm.c

@@ -17612,7 +17612,11 @@ int End_Process()
 	free(V2gtpMsgTxBuf);
 	//DetachShareMemory();
 	Qca7kPowerReset();  //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/
-    system("cd /root;./reset_soft.sh");
+#ifdef AWCCS
+	system("killall SeccComm");
+#else	
+    	system("cd /root;./reset_soft.sh");
+#endif
     while(1)
     {
         //wait for CSU configrm

+ 5 - 1
EVSE/Projects/AX80/Apps/CCS/SeccComm.c

@@ -17612,7 +17612,11 @@ int End_Process()
 	free(V2gtpMsgTxBuf);
 	//DetachShareMemory();
 	Qca7kPowerReset();  //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/
-    system("cd /root;./reset_soft.sh");
+#ifdef	AX80
+	system("killall SeccComm");
+#else
+	system("cd /root;./reset_soft.sh");
+#endif
     while(1)
     {
         //wait for CSU configrm

+ 5 - 1
EVSE/Projects/CCS/Apps/SeccComm.c

@@ -17612,7 +17612,11 @@ int End_Process()
 	free(V2gtpMsgTxBuf);
 	//DetachShareMemory();
 	Qca7kPowerReset();  //reset QCA7000 /* +++ 20200808, vern, should disconnected PLC connection after session stop ---*/
-    system("cd /root;./reset_soft.sh");
+#ifdef AWCCS
+	system("killall SeccComm");
+#else	
+    	system("cd /root;./reset_soft.sh");
+#endif
     while(1)
     {
         //wait for CSU configrm

+ 1 - 1
EVSE/Projects/DD360UCar/Apps/CSU/Ethernet.c

@@ -98,7 +98,7 @@ static int isReachableInternet(void)
         while (fgets(buf, sizeof(buf), fp) != NULL) {
             if (strstr(buf, "inet addr:") > 0) {
                 sscanf(buf, "%*s%s", tmp);
-                substr(tmp, tmp, strspn(tmp, "addr:"), strlen(buf) - strspn(tmp, "addr:"));
+                substr(tmp, tmp, strspn(tmp, "addr:"), strlen(tmp) - strspn(tmp, "addr:"));
 
                 if (strcmp(tmp, (char *)pSysConfig->Eth0Interface.EthIpAddress) != EQUAL) {
                     strcpy((char *) pSysConfig->Eth0Interface.EthIpAddress, tmp);

+ 4 - 4
EVSE/Projects/DD360UCar/Apps/CSU/RFID.c

@@ -262,10 +262,10 @@ void AuthorizeToCharge()
     SelectGunInfo *ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
     struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(pSysInfo->CurGunSelected);
     ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
-    if(!isAuthorizedComplete())
-        StartSystemTimeoutDet(Timeout_Authorizing);
-    else {
-        //StopSystemTimeoutDet();
+    if (!isAuthorizedComplete()) {
+        //StartSystemTimeoutDet(Timeout_Authorizing);
+    } else {
+        StopGunInfoTimeoutDet(pSysInfo->CurGunSelected);
         StartSystemTimeoutDet(Timeout_WaitBalance);
         if (ShmSelectGunInfo->PricesInfo[pSysInfo->CurGunSelected].Balance != FAIL_BALANCE_PRICES) {
             StopSystemTimeoutDet();

+ 55 - 69
EVSE/Projects/DD360UCar/Apps/CSU/main.c

@@ -82,8 +82,8 @@ uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V2.07.00.0000.00"; // Phihong version
-char* DebugVersion = "V2.07.04";      // Software debug version
+char *fwVersion = "V2.09.00.0000.00"; // Phihong version
+char* DebugVersion = "V2.09.00";      // Software debug version
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -277,6 +277,7 @@ static void GetFirmwareVersion(void)
 {
     // Get CSU root file system version
     sprintf((char *)pSysInfo->CsuRootFsFwRev, fwVersion);
+    sprintf((char*)ShmDcCommonData->DebugVersion, DebugVersion);
 
     uint8_t count = 0, chademo = 0, ccs = 0, gb = 0;
     for (uint8_t idx = 0; idx < 3; idx++) {
@@ -2607,19 +2608,6 @@ void CreateTimeoutFork(void)
                     StopSystemTimeoutDet();
                 }
                 break;
-            case Timeout_Terminating:
-                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TERMINATING_TIMEOUT) {
-                    
-                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
-                    log_info("Terminating timeout not get final cost");
-                    /*
-                    if (!ShmDcCommonData->finalcost_flag[pSysInfo->CurGunSelected] && pDcChargingInfo->ChargingFee < 0) {
-                        pDcChargingInfo->ChargingFee = pDcChargingInfo->PresentChargedEnergy * ShmDcCommonData->ChargingRate;
-                    }
-                    */
-                    setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE);
-                }
-                break;
             case Timeout_LinkError:
                 if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= LINKERROR_TIMEOUT) {
                     StopSystemTimeoutDet();
@@ -2695,7 +2683,24 @@ void CreateTimeoutFork(void)
                     if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= PLUGOUT_TIMEOUT) {
                         StopGunInfoTimeoutDet(gunIndex);
                         destroySelGun(gunIndex); //jerry add
-                        pSysInfo->SystemPage = _LCM_VIEW;
+                        setChargerMode(gunIndex, S_IDLE);
+                    }
+                    break;
+                case Timeout_GunAuthorizePage:
+                    if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_AUTHORIZE_PAGE) {
+                        StopGunInfoTimeoutDet(gunIndex);
+                        destroySelGun(gunIndex); //jerry add
+                        pDcChargingInfo->SystemStatus = S_IDLE;
+                    }
+                    break;
+                case Timeout_Terminating:
+                    if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= TERMINATING_TIMEOUT) {
+                        StopGunInfoTimeoutDet(gunIndex);
+                        pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+
+                        ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag = TRUE;
+
+                        setChargerMode(gunIndex, S_COMPLETE);
                     }
                     break;
                 }
@@ -4009,14 +4014,12 @@ int main(void)
              pSysInfo->SelfTestSeq,
              ShmPsuData->Work_Step);
 
-    if (pSysInfo->SelfTestSeq == _STEST_FAIL ||
-            ShmPsuData->Work_Step == _NO_WORKING ||
-            pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES //DS60-120 add
-       ) {
-            for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+    if (pSysInfo->SelfTestSeq == _STEST_FAIL ||ShmPsuData->Work_Step == _NO_WORKING ||
+        pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES ) {
+        ChangeLcmByIndex(_LCM_MAINTAIN);
+        for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             setChargerMode(gunIndex, MODE_MAINTAIN);
         }
-        ChangeLcmByIndex(_LCM_MAINTAIN);
     } else {
         for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
             setChargerMode(gunIndex, MODE_IDLE);
@@ -4233,6 +4236,7 @@ CheckStatus:
                 if (isModeChange(gunIndex)) {
                     log_info("============================= S_AUTHORIZING(%x) ============================= ", gunIndex);
                     pSysInfo->SystemPage = _LCM_START_SCAN;
+                    StartGunInfoTimeoutDet(gunIndex, Timeout_GunAuthorizePage);
                 }
                 // 讀卡邏輯
                 ScannerCardProcess();
@@ -4250,6 +4254,7 @@ CheckStatus:
                             ChangeGunSelectByIndex(gunIndex);
                             //AddPlugInTimes(gunIndex);
                             setChargerMode(gunIndex, MODE_REASSIGN_CHECK);
+                            StopGunInfoTimeoutDet(gunIndex);
                             strcpy((char *)pDcChargingInfo->StartUserId, "");
                             ClearDetectPluginFlag();
                             continue;
@@ -4273,6 +4278,7 @@ CheckStatus:
                             strcpy((char *)pSysConfig->UserId, "");
                             // 當前操作的槍號,進入 Preparing
                             setChargerMode(gunIndex, MODE_REASSIGN_CHECK);
+                            StopGunInfoTimeoutDet(gunIndex);
                             ClearDetectPluginFlag();
                             continue;
                         }
@@ -4508,21 +4514,22 @@ CheckStatus:
                     if (ShmDcCommonData->isIntoCharge[gunIndex]) {
                         if (pSysInfo->CurGunSelected == gunIndex)
                             pSysInfo->SystemPage = _LCM_SUMMARY;
-                        if (pSysInfo->SystemPage != _LCM_SUMMARY) {
-                            setChargerMode(gunIndex, MODE_IDLE);
-                        }
                         StartGunInfoTimeoutDet(gunIndex, Timeout_PlugOut);
                     } else {
                         setChargerMode(gunIndex, MODE_IDLE);
                     }
                 } else {
-                    if (ShmDcCommonData->isIntoCharge[gunIndex]) {
-                        if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _LCM_SUMMARY) {
-                            pSysInfo->SystemPage = _LCM_VIEW;
-                        }
-                    } else {
-                        if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _LCM_LINK_ERROR) {
-                            pSysInfo->SystemPage = _LCM_VIEW;
+                    if (pSysInfo->CurGunSelected == gunIndex) {
+                        if (ShmDcCommonData->isIntoCharge[gunIndex]) {
+                            if (!ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
+                                pSysInfo->SystemPage = _LCM_STOPPING;
+                            } else if (pSysInfo->SystemPage != _LCM_SUMMARY) {
+                                pSysInfo->SystemPage = _LCM_VIEW;
+                            }
+                        } else {
+                            if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _LCM_LINK_ERROR) {
+                                pSysInfo->SystemPage = _LCM_VIEW;
+                            }
                         }
                     }
                 }
@@ -4538,42 +4545,23 @@ CheckStatus:
                     }
                     StopGunInfoTimeoutDet(gunIndex);
                     
-                    pSysInfo->CurGunSelected = gunIndex;
-                    StartSystemTimeoutDet(Timeout_Terminating);
+                    //pSysInfo->CurGunSelected = gunIndex;
+                    StartGunInfoTimeoutDet(gunIndex, Timeout_Terminating);
+
                     if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0)
                         DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption);
                 }
-                // Show EV Board Status
-                if ((time((time_t*)NULL) - ShowEVStatusTimer[gunIndex]) > 3) {
-                    ShowEVStatusTimer[gunIndex] = time((time_t*)NULL);
-                    if (pDcChargingInfo->Type == _Type_Chademo) {
-                        EVStatus[gunIndex] = isPrechargeStatus_chademo(gunIndex);
-                    } else if (pDcChargingInfo->Type == _Type_GB) {
-                        EVStatus[gunIndex] = isPrechargeStatus_gb(gunIndex);
-                    } else if (pDcChargingInfo->Type == _Type_CCS_2) {
-                        EVStatus[gunIndex] = isPrechargeStatus_ccs(gunIndex);
-                    }
-                    log_info("EV Board Status:%d, Final Cost Flag:%d", EVStatus[gunIndex], ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag);
-                }
+
                 // For Precharging timeout
                 if (pDcChargingInfo->Type == _Type_Chademo) {
                     if (isEvStopCharging_chademo(gunIndex) == YES ||
                             isPrechargeStatus_chademo(gunIndex) <= 0 ) {
-                        if (!ShmDcCommonData->isIntoCharge[gunIndex]) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        } else if (ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        }
+                        setChargerMode(gunIndex, MODE_COMPLETE);
                     }
                 } else if (pDcChargingInfo->Type == _Type_GB) {
                     if (isEvStopCharging_gb(gunIndex) == YES ||
                             isPrechargeStatus_gb(gunIndex) <= 0){
-
-                        if (!ShmDcCommonData->isIntoCharge[gunIndex]) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        } else if (ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        }
+                        setChargerMode(gunIndex, MODE_COMPLETE);
                     }
                 } else if (pDcChargingInfo->Type == _Type_CCS_2) {
                     if (isEvStopCharging_ccs(gunIndex) == YES &&
@@ -4581,16 +4569,11 @@ CheckStatus:
                              isPrechargeStatus_ccs(gunIndex) == 0  ||
                              isPrechargeStatus_ccs(gunIndex) == 13 ||
                              isPrechargeStatus_ccs(gunIndex) == 14) ) {
-
-                        if (!ShmDcCommonData->isIntoCharge[gunIndex]) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        } else if (ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
-                            setChargerMode(gunIndex, MODE_COMPLETE);
-                        }
+                        setChargerMode(gunIndex, MODE_COMPLETE);
                     }
                 }
 
-                if (pSysInfo->CurGunSelected == gunIndex) {
+                if (pSysInfo->CurGunSelected == gunIndex && !ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
                     pSysInfo->SystemPage = _LCM_STOPPING;
                 }
                 break;
@@ -4613,16 +4596,19 @@ CheckStatus:
                 }
 
                 if (!pDcChargingInfo->ConnectorPlugIn) {
-                    if (pSysInfo->CurGunSelected == gunIndex)
+                    if (pSysInfo->CurGunSelected == gunIndex) {
                         pSysInfo->SystemPage = _LCM_SUMMARY;
-                    if (pSysInfo->SystemPage != _LCM_SUMMARY) {
-                        setChargerMode(gunIndex, MODE_IDLE);
                     }
                     StartGunInfoTimeoutDet(gunIndex, Timeout_PlugOut);
                 } else {
-                    if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _LCM_SUMMARY) {
-                        pSysInfo->SystemPage = _LCM_VIEW;
+                    if (pSysInfo->CurGunSelected == gunIndex) {
+                        if (!ShmDcCommonData->pGunInfo[gunIndex].finalcost_flag) {
+                            pSysInfo->SystemPage = _LCM_STOPPING;
+                        } else if(pSysInfo->SystemPage != _LCM_SUMMARY) {
+                            pSysInfo->SystemPage = _LCM_VIEW;
+                        }
                     }
+
                 }
                 break;
 

+ 2 - 0
EVSE/Projects/DD360UCar/Apps/CSU/main.h

@@ -43,8 +43,10 @@
 #define CONN_PLUG_TIMEOUT                       (40)
 #define PLUGOUT_TIMEOUT                         (120)
 #define TERMINATING_TIMEOUT                     (30)
+#define GUN_AUTHORIZE_PAGE                      (120)
 #define WHILE_LOOP_TIME                         (10000)
 
+
 //#define log_info(format, args...) StoreLogMsg_1("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg_1("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_error(format, args...) StoreLogMsg_1("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)

+ 1 - 0
EVSE/Projects/DD360UCar/Apps/Config.h

@@ -532,6 +532,7 @@ typedef struct StDcCommonInfo {
     uint8_t showNetPackage;
     uint8_t showCanPackage;
     int LcmFwVersion;
+    char DebugVersion[32];
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 3 - 4
EVSE/Projects/DD360UCar/Apps/ModuleDoComm/DoComm.c

@@ -526,7 +526,7 @@ static int qrCodeUrlInfoHandle(uint8_t *data)
     string2Date((char*)data, (uint8_t*)_setTime);
     //printf("SystemId =  %s", pSysConfig->SystemId);
     if (!timecmp(localTime, _setTime)) {
-        log_info("Set Timer:%s Time Zone:%d", _setTime,ShmDcCommonData->TZOffset);
+        //log_info("Set Timer:%s Time Zone:%d", _setTime,ShmDcCommonData->TZOffset);
         sprintf((char*)cmdBuf, "date -u -s \"%s\" >> /dev/null &", _setTime);
         system((char*)cmdBuf);
         system("hwclock -w -u");
@@ -1042,7 +1042,7 @@ static int chargingcapabilityHandle(uint8_t *data, uint8_t plugNum)
         pricesInfo[plugNum].ParkingFee = ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee;
         pricesInfo[plugNum].EnergyCost = ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost;
         pricesInfo[plugNum].RemainAmount = ShmSelectGunInfo->PricesInfo[plugNum].RemainAmount;
-
+        log_info(" ======== Gun%d Cost Information ========", plugNum);
         log_info("Total Cost:%.2f", pDcChargingInfo->ChargingFee);
         log_info("Parking Fee:%.2f", ShmSelectGunInfo->PricesInfo[plugNum].ParkingFee);
         log_info("Energy Cost:%.2f", ShmSelectGunInfo->PricesInfo[plugNum].EnergyCost);
@@ -2321,7 +2321,6 @@ static int CheckNetworkStatus(void)
 {
     char *ipAddr = (char *)&pSysConfig->Eth0Interface.EthIpAddress;
 
-    //printf("Check network IP Header = %s\n", ipAddr);
     if (strstr(ipAddr, CMP_ETH_IP_HEAD) != NULL) {
         return 1;
     }
@@ -2480,7 +2479,7 @@ static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg
 					pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
 					//ShmDcCommonData->TransactionInfo[plugNum].Amount = pDcChargingInfo->ChargingFee;
 					ShmDcCommonData->pGunInfo[plugNum].finalcost_flag = TRUE;
-                    log_info("Set Final Cost Flag");
+                    //log_info("Set Final Cost Flag");
                 }
             }
             curReg = REG_PLUG_IN_STATE;

+ 31 - 4
EVSE/Projects/DD360UCar/Apps/ModuleEvComm/Module_EvRxComm.c

@@ -34,6 +34,8 @@ uint8_t TempArray_2[TempArraySize]={0};
 uint8_t ptemp_1 = 0;
 uint8_t ptemp_2 = 0;
 bool firstcircule = true;
+float EvTargetVolt[2] = { 0 };
+float EvTargetCur[2] = { 0 };
 
 //------------------------------------------------------------------------------
 extern bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode);
@@ -319,6 +321,7 @@ void CANReceiver(int fd)
         ShmDcCommonData->EVDisconnectTime[0] = time((time_t*)NULL);
         ShmDcCommonData->EVDisconnectTime[1] = time((time_t*)NULL);
         //log_info("Module_EvRXComm Child's PID is %d", getpid());
+        int is_busy;
         CCS_PlugoutTimer[0] = time((time_t*)NULL);
         CCS_PlugoutTimer[1] = time((time_t*)NULL);
 
@@ -327,6 +330,7 @@ void CANReceiver(int fd)
 
             for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
                 pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
+
                 // 檢查是否有收到EV小板訊號
                 if ((time((time_t*)NULL) - ShmDcCommonData->EVDisconnectTime[_index]) > 3 &&
                     !ShmDcCommonData->EVDisconnectFlag[_index] && 
@@ -340,6 +344,7 @@ void CANReceiver(int fd)
                     system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
                     system("/sbin/ip link set can0 up");
                 }
+
                 CheckEvConnect(_index);
             }
             
@@ -418,23 +423,37 @@ void CANReceiver(int fd)
                     } else {
                         log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]);
                     }
+                    /*
                     if(pDcChargingInfo->RemoteStartFlag == YES) {
                         pSysInfo->CurGunSelected = targetGun;
-                    }
+                    }*/
                 }
                 pDcChargingInfo->PilotVoltage = frame.data[1];
                 // CCS 小板確認Pilot Voltage != 0
+                is_busy = FALSE;
+                for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
+                    struct ChargingInfoData*  DcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
+                    if ((DcChargingInfo->SystemStatus >= S_AUTHORIZING && DcChargingInfo->SystemStatus <= S_PREPARING_FOR_EVSE) ||
+                        DcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0 || DcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1) {
+                        is_busy = TRUE;
+                        break;
+                    }
+                }
+
                 if (pDcChargingInfo->Type == _Type_CCS_2 && pDcChargingInfo->PilotVoltage != 0) {
                     if (frame.data[0] == UNPLUG && pDcChargingInfo->ConnectorPlugIn != frame.data[0]) {
                         log_info("Conn %d, Unplug. ", targetGun);
-                        if (pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) {
+
+                        if ((pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) &&
+                        !is_busy){
                             pSysInfo->CurGunSelected = targetGun;
                         }
                     }
                     pDcChargingInfo->ConnectorPlugIn = frame.data[0];
                 } else {
                     if (frame.data[0] == UNPLUG && pDcChargingInfo->ConnectorPlugIn != frame.data[0]) {
-                        if (pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) {
+                        if ((pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) &&
+                        !is_busy) {
                             pSysInfo->CurGunSelected = targetGun;
                         }
                     }
@@ -565,7 +584,15 @@ void CANReceiver(int fd)
                         }
                     }
                 }
-
+                if (pDcChargingInfo->EvBatterytargetVoltage > (EvTargetVolt[targetGun] + 3) ||
+                    pDcChargingInfo->EvBatterytargetVoltage < (EvTargetVolt[targetGun] - 3) ||
+                    pDcChargingInfo->EvBatterytargetCurrent >(EvTargetCur[targetGun] + 1) ||
+                    pDcChargingInfo->EvBatterytargetCurrent < (EvTargetCur[targetGun] - 1)) {
+                    log_info("Gun%d Battery TargetVoltage = %.1f , TargetCurrent = %.1f",
+                        targetGun, pDcChargingInfo->EvBatterytargetVoltage, pDcChargingInfo->EvBatterytargetCurrent);
+                    EvTargetVolt[targetGun] = pDcChargingInfo->EvBatterytargetVoltage;
+                    EvTargetCur[targetGun] = pDcChargingInfo->EvBatterytargetCurrent;
+                }
                 //log_info("EvBatterytargetVoltage = %f ", pDcChargingInfo->EvBatterytargetVoltage);
                 //log_info("EvBatterytargetCurrent = %f ", pDcChargingInfo->EvBatterytargetCurrent);
                 //log_info("BatteryVoltage = %d ",

+ 35 - 28
EVSE/Projects/DD360UCar/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -396,25 +396,27 @@ static void SetPresentChargingOutputCap(void)
 
     //DS60-120 add
     if ((LogInfo[0][EV_LOG_OUTPUT_CAP_POW] <= pow1 - 5 ||
-            LogInfo[0][EV_LOG_OUTPUT_CAP_POW] >= pow1 + 5) ||
-            (LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] <= cur1 - 5 ||
-             LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] >= cur1 + 5) ||
-            (LogInfo[1][EV_LOG_OUTPUT_CAP_POW] <= pow2 - 5 ||
-             LogInfo[1][EV_LOG_OUTPUT_CAP_POW] >= pow2 + 5) ||
-            (LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] <= cur2 - 5 ||
-             LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] >= cur2 + 5)
-       ) {
-        //log_info("----------------------------------------------------- ");
-        log_info("To EV (Real) Power_1 = %.1f, Cur_1 = %.1f, Power_2 = %.1f, Cur_2 = %.1f",
-                 pow1 / 10, cur1 / 10, pow2 / 10, cur2 / 10);
-        //log_info("----------------------------------------------------- ");
-
+        LogInfo[0][EV_LOG_OUTPUT_CAP_POW] >= pow1 + 5) ||
+        (LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] <= cur1 - 5 ||
+            LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] >= cur1 + 5)
+        ) {
+        log_info("Gun0 To EV Power_1 = %3.1fkW, Cur_1 = %3.1fA", pow1 / 10, cur1 / 10);
         LogInfo[0][EV_LOG_OUTPUT_CAP_POW] = pow1;
         LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] = cur1;
-        LogInfo[1][EV_LOG_OUTPUT_CAP_POW] = pow2;
-        LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] = cur2;
         chargingData_1->RealMaxCurrent = cur1;
         chargingData_1->RealMaxPower = pow1;
+    }
+
+    if ((LogInfo[1][EV_LOG_OUTPUT_CAP_POW] <= pow2 - 5 ||
+        LogInfo[1][EV_LOG_OUTPUT_CAP_POW] >= pow2 + 5) ||
+        (LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] <= cur2 - 5 ||
+        LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] >= cur2 + 5)
+       ) {
+        log_info("Gun1 To EV Power_2 = %3.1fkW, Cur_2 = %3.1fA", pow2 / 10, cur2 / 10);
+
+        LogInfo[1][EV_LOG_OUTPUT_CAP_POW] = pow2;
+        LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] = cur2;
+
 
         if (pSysConfig->TotalConnectorCount == 2) {
             chargingData_2->RealMaxCurrent = cur2;
@@ -538,22 +540,27 @@ static void SetPresentChargingOutputPower(void)
 
     //DS60-120 add
     if ((LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] >= vol1 + CHK_VOL_RANGE) ||
-            (LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] <= vol1 - CHK_VOL_RANGE) ||
-            (LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] >= cur1 + CHK_CUR_RANGE) ||
-            (LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] <= cur1 - CHK_CUR_RANGE) ||
-            (LogInfo[1][EV_LOG_NOW_OUTPUT_VOL] >= vol2 + CHK_VOL_RANGE) ||
-            (LogInfo[1][EV_LOG_NOW_OUTPUT_VOL] <= vol2 - CHK_VOL_RANGE) ||
-            (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] >= cur2 + CHK_CUR_RANGE) ||
-            (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] <= cur2 - CHK_CUR_RANGE)
-       ) {
-        log_info("G1-> Vol=%.1f, Cur=%.1f - G2-> Vol = %.1f, Cur = %.1f",
-            vol1 / 10,
-            cur1 / 10,
-            vol2 / 10,
-            cur2 / 10);
+        (LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] <= vol1 - CHK_VOL_RANGE) ||
+        (LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] >= cur1 + CHK_CUR_RANGE) ||
+        (LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] <= cur1 - CHK_CUR_RANGE)) {
+
+        log_info("Gun0 Set Output Voltage=%3.1fV, Cur=%3.1fA",
+                vol1 / 10,
+                cur1 / 10);
 
         LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] = vol1;
         LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] = cur1;
+    }
+
+    if ((LogInfo[1][EV_LOG_NOW_OUTPUT_VOL] >= vol2 + CHK_VOL_RANGE) ||
+        (LogInfo[1][EV_LOG_NOW_OUTPUT_VOL] <= vol2 - CHK_VOL_RANGE) ||
+        (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] >= cur2 + CHK_CUR_RANGE) ||
+        (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] <= cur2 - CHK_CUR_RANGE)) {
+
+        log_info("Gun1 Set Output Voltage=%3.1fV, Cur=%3.1fA",
+                vol2 / 10,
+                cur2 / 10);
+
         LogInfo[1][EV_LOG_NOW_OUTPUT_VOL] = vol2;
         LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] = cur2;
     }

+ 27 - 22
EVSE/Projects/DD360UCar/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -383,7 +383,6 @@ void ChangeCurPage()
                 pSysInfo->PageIndex = __VIEW_RIGHT_CHARGE_;
             } else if(pDcChargingInfo_0->SystemStatus == S_CHARGING && pDcChargingInfo_1->SystemStatus == S_CHARGING) {
                 pSysInfo->PageIndex = __VIEW_ALL_CHARGE_;
-
             } else if ((pDcChargingInfo_0->SystemStatus == S_ALARM || pDcChargingInfo_0->SystemStatus == S_FAULT )&&
                 pDcChargingInfo_1->SystemStatus == S_CHARGING) {
                 if (pDcChargingInfo_0->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[LEFT_GUN_NUM])
@@ -412,7 +411,7 @@ void ChangeCurPage()
                 (pDcChargingInfo_1->SystemStatus == S_ALARM || pDcChargingInfo_1->SystemStatus == S_FAULT)) {
                 if (pDcChargingInfo_0->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[LEFT_GUN_NUM] &&
                     pDcChargingInfo_1->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[RIGHT_GUN_NUM]) {
-                    pSysInfo->PageIndex = __VIEW_L_OUT_R_OUT;
+                    pSysInfo->PageIndex = __VIEW_L_FAIL_R_FAIL;
                 } else if (pDcChargingInfo_0->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[LEFT_GUN_NUM]) {
                     pSysInfo->PageIndex = __VIEW_L_LINK_R_FAIL;
                 } else if (pDcChargingInfo_1->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[RIGHT_GUN_NUM]) {
@@ -429,35 +428,34 @@ void ChangeCurPage()
                 pSysInfo->PageIndex = __VIEW_L_MAINTAIN_R_CHARGE;
             } else if (pDcChargingInfo_0->SystemStatus == S_MAINTAIN && pDcChargingInfo_1->SystemStatus == S_MAINTAIN) {
                 pSysInfo->PageIndex = __MAINTAIN_PAGE_;
-
-            } else if (pDcChargingInfo_0->SystemStatus == S_IDLE && pDcChargingInfo_1->SystemStatus == S_COMPLETE &&
-                pDcChargingInfo_1->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_IDLE && pDcChargingInfo_1->SystemStatus == S_COMPLETE /* &&
+                pDcChargingInfo_1->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_IDLE_R_OUT;
-            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_IDLE &&
-                pDcChargingInfo_0->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_IDLE /* &&
+                pDcChargingInfo_0->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_OUT_R_IDLE;
-            } else if (pDcChargingInfo_0->SystemStatus == S_CHARGING && pDcChargingInfo_1->SystemStatus == S_COMPLETE &&
-                pDcChargingInfo_1->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_CHARGING && pDcChargingInfo_1->SystemStatus == S_COMPLETE /* &&
+                pDcChargingInfo_1->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_CHARGE_R_OUT;
-            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_CHARGING &&
-                pDcChargingInfo_0->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_CHARGING /* &&
+                pDcChargingInfo_0->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_OUT_R_CHARGE;
-            } else if (pDcChargingInfo_0->SystemStatus == S_MAINTAIN && pDcChargingInfo_1->SystemStatus == S_COMPLETE &&
-                pDcChargingInfo_1->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_MAINTAIN && pDcChargingInfo_1->SystemStatus == S_COMPLETE /* &&
+                pDcChargingInfo_1->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_MAINTAIN_R_OUT;
-            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_MAINTAIN &&
-                pDcChargingInfo_0->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_MAINTAIN /* &&
+                pDcChargingInfo_0->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_OUT_R_MAINTAIN;
-            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_COMPLETE &&
-                pDcChargingInfo_0->ConnectorPlugIn && pDcChargingInfo_1->ConnectorPlugIn) {
+            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_1->SystemStatus == S_COMPLETE /* &&
+                pDcChargingInfo_0->ConnectorPlugIn && pDcChargingInfo_1->ConnectorPlugIn*/) {
                 pSysInfo->PageIndex = __VIEW_L_OUT_R_OUT;
             } else if ((pDcChargingInfo_0->SystemStatus == S_ALARM || pDcChargingInfo_0->SystemStatus == S_FAULT) &&
-                pDcChargingInfo_1->SystemStatus == S_COMPLETE && pDcChargingInfo_1->ConnectorPlugIn) {
+                pDcChargingInfo_1->SystemStatus == S_COMPLETE /* && pDcChargingInfo_1->ConnectorPlugIn*/) {
                 if (pDcChargingInfo_0->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[LEFT_GUN_NUM])
                     pSysInfo->PageIndex = __VIEW_L_LINK_R_OUT;
                 else
                     pSysInfo->PageIndex = __VIEW_L_FAIL_R_OUT;
-            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE && pDcChargingInfo_0->ConnectorPlugIn &&
+            } else if (pDcChargingInfo_0->SystemStatus == S_COMPLETE /* && pDcChargingInfo_0->ConnectorPlugIn*/ &&
                 (pDcChargingInfo_1->SystemStatus == S_ALARM || pDcChargingInfo_1->SystemStatus == S_FAULT)) {
                 if (pDcChargingInfo_1->SystemStatus == S_ALARM && !ShmDcCommonData->isIntoCharge[RIGHT_GUN_NUM])
                     pSysInfo->PageIndex = __VIEW_L_OUT_R_LINK;
@@ -476,7 +474,14 @@ void ChangeCurPage()
                 else
                     pSysInfo->PageIndex = __VIEW_L_FAIL_R_MAINTAIN;
             } else {
-                pSysInfo->PageIndex = __VIEW_ALL_IDLE_;
+                if (pDcChargingInfo_0->SystemStatus == S_CHARGING) {
+                    pSysInfo->PageIndex = __VIEW_LEFT_CHARGE_;
+                } else if (pDcChargingInfo_1->SystemStatus == S_CHARGING) {
+                    pSysInfo->PageIndex = __VIEW_RIGHT_CHARGE_;
+                } else {
+                    pSysInfo->PageIndex = __VIEW_ALL_IDLE_;
+                }
+                
             }
             break;
         case _LCM_START_SCAN:
@@ -907,7 +912,7 @@ void ShowGunCountDownTimer()
     int min,sec;
     uint8_t value[10] = {0};
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
-    int tm = 30 - (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL);
+    int tm = 120 - (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL);
     // GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL
     min = tm/60;
     sec = tm%60;
@@ -1118,7 +1123,7 @@ void ProcessPageInfo()
     case _LCM_START_SCAN:
         ChangeQrCode();
         ShowSelectGunIcon();
-        ShowCountDownTimer();
+        ShowGunCountDownTimer();
         break;
     case _LCM_START_AUTHORIZING:
     case _LCM_PRECHARGE:

+ 1 - 1
EVSE/Projects/DD360UCar/Apps/ModuleLcmCtrl/Module_LcmControl.h

@@ -95,7 +95,7 @@
 #define __VIEW_L_MAINTAIN_R_LINK   0x003E
 #define __VIEW_L_MAINTAIN_R_FAIL   0x003F
 #define __VIEW_L_FAIL_R_MAINTAIN   0x0040
-#define __VIEW_L_OUT_R_OUT         0x0041
+#define __VIEW_L_FAIL_R_FAIL       0x0041
 
 // ICON Map Address
 #define _LeftGun_type_pic_U         0x0001

+ 17 - 2
EVSE/Projects/DD360UCar/Apps/ModuleUpdateFW/Module_UpdateFW.c

@@ -168,6 +168,13 @@ static int InitCanBus(void)
     return fd;
 }
 
+unsigned long long getAvailableMemory()
+{
+    long pages = sysconf(_SC_AVPHYS_PAGES);
+    long page_size = sysconf(_SC_PAGE_SIZE);
+    return pages * page_size;
+}
+
 static int CheckUpdateProcess(void)
 {
     //bool isPass = true;
@@ -188,6 +195,12 @@ static int CheckUpdateProcess(void)
     DcCommonInfo *ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     struct ChargingInfoData *pDcChargingInfo = NULL;
 
+    if (getAvailableMemory() < (200 * 1024 * 1024))
+    {
+        log_info("Available memory (%.2f Bytes) less than 200 MBytes, free cache first.\n", getAvailableMemory() / (1024 * 1024.0));
+        system("echo 3 > /proc/sys/vm/drop_caches");
+    }
+
     pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     d = opendir("/mnt/");
     if (d) {
@@ -225,7 +238,7 @@ static int CheckUpdateProcess(void)
                         ((unsigned int)ptr[18]) << 8  |
                         ((unsigned int)ptr[19]));
                 log_info("Typed...%x ", Type);
-
+                free(ptr);
                 switch (Type) {
                 case 0x10000001:
                 case 0x10000002:
@@ -379,9 +392,11 @@ static int CheckUpdateProcess(void)
                     //return isPass;
                     break;
                 }
+            } else {
+                free(ptr);
             }
             free(new_str);
-            free(ptr);
+ 
         }
     }
     free(dir);

+ 1 - 0
EVSE/Projects/DD360UCar/Apps/ReadCmdline.c

@@ -325,6 +325,7 @@ void GetFwVerProc(void)
 {
     printf("ModelName = %s\r\n", pSysConfig->ModelName);
     printf("DC Main Version = %s \n", pSysInfo->CsuRootFsFwRev);
+    printf("DC Debug Version = %s \n", ShmDcCommonData->DebugVersion);
     printf("407 FW Version = %s\n", ShmPrimaryMcuData->version);
     printf("Gun 0 FW Version = %s \n", pSysInfo->Connector1FwRev);
     printf("Gun 1 FW Version = %s \n", pSysInfo->Connector2FwRev);

+ 1 - 0
EVSE/Projects/DD360UCar/Apps/timeout.h

@@ -53,6 +53,7 @@ enum Timeout_flag {
 	Timeout_LinkError              = 16,
 	Timeout_PlugOut                = 17,
 	Timeout_Terminating            = 18,
+    Timeout_GunAuthorizePage       = 19,
 };
 
 //------------------------------------------------------------------------------

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


BIN
EVSE/Projects/DD360UCar/output/FactoryConfig


BIN
EVSE/Projects/DD360UCar/output/Module_ChkSysTask


BIN
EVSE/Projects/DD360UCar/output/Module_DoComm


BIN
EVSE/Projects/DD360UCar/output/Module_EvComm


BIN
EVSE/Projects/DD360UCar/output/Module_EventLogging


BIN
EVSE/Projects/DD360UCar/output/Module_InternalComm


BIN
EVSE/Projects/DD360UCar/output/Module_LcmControl


BIN
EVSE/Projects/DD360UCar/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360UCar/output/Module_UpdateFW


BIN
EVSE/Projects/DD360UCar/output/ReadCmdline


BIN
EVSE/Projects/DD360UCar/output/main


+ 1 - 1
EVSE/Projects/DO360/Apps/main.c

@@ -425,7 +425,7 @@ bool isModelNameMatch = true;
 //char* rfidPortName = "/dev/ttyS2";
 #if ENABLE_PCBA_TEST == 0
 char* fwVersion = "V2.03.00.0000.00";
-char* subVersion = "00";
+char* subVersion = "01";
 #else
 char* fwVersion = "PCBA.00.04";
 char* subVersion = "00";

BIN
EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin


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


+ 10 - 5
EVSE/Projects/DS60-120/Apps/CheckSystemTask.c

@@ -11,6 +11,7 @@
 #define	TASK_CNT_MAIN		5
 #define TASK_CNT_EV_COMM	2
 #define TASK_CNT_PSU_COMM	2
+#define TASK_CNT_SBOX_COMM	3
 
 bool Taskconutstring(char *src, char *taskname)
 {
@@ -58,6 +59,7 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 	unsigned char count_main 		= GetProcessCount("Module_CSU");
 	unsigned char count_evComm 		= GetProcessCount("Module_EvComm");
 	unsigned char count_psuComm 	= GetProcessCount("Module_PsuComm");
+	unsigned char count_sboxComm	= GetProcessCount("Module_SmartBox");
 
 	if (count_main == 0)
 		count_main = GetProcessCount("main");
@@ -74,7 +76,7 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 
 	if (systemPage == _LCM_FIX || systemPage == _LCM_EMC)
 	{
-		if (count_main < TASK_CNT_MAIN || count_psuComm < TASK_CNT_PSU_COMM)
+		if (count_main < TASK_CNT_MAIN || count_psuComm < TASK_CNT_PSU_COMM || count_sboxComm < TASK_CNT_SBOX_COMM)
 		{
 			system("killall Module_EventLogging");
 			system("killall Module_PrimaryComm");
@@ -82,10 +84,11 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 			system("killall Module_LcmControl");
 			system("killall Module_InternalComm");
 			system("killall Module_PsuComm");
-			system("killall OcppBackend &");
-			system("killall Module_4g &");
-			system("killall Module_Wifi &");
-			system("killall Module_DcMeter &");
+			system("killall OcppBackend");
+			system("killall Module_4g");
+			system("killall Module_Wifi");
+			system("killall Module_DcMeter");
+			system("killall Module_SmartBox");
 			sleep(3);
 			system("/usr/bin/run_evse_restart.sh");
 		}
@@ -120,6 +123,8 @@ unsigned char CheckSystemTask(unsigned char systemPage)
 		result = _SYSTEM_TASK_LOST_ITEM_EVCOMM;
 	else if (count_psuComm < TASK_CNT_PSU_COMM)
 		result = _SYSTEM_TASK_LOST_ITEM_PSUCOMM;
+	else if (count_sboxComm < TASK_CNT_SBOX_COMM)
+		result = _SYSTEM_TASK_LOST_ITEM_SMARTBOX;
 	else if (system("pidof -s Module_EventLogging > /dev/null") != 0)
 		result = _SYSTEM_TASK_LOST_ITEM_EVENTLOG;
 	else if (system("pidof -s Module_PrimaryComm > /dev/null") != 0)

+ 158 - 28
EVSE/Projects/DS60-120/Apps/Config.h

@@ -15,8 +15,10 @@
 typedef unsigned char			byte;
 
 #define TOTAL_QUANTITY_GUN			4				//Max Count
+#define PSU_GROUP_COUNT				4
 #define DC_CONNECTOR_COUNT			2
 #define AC_CONNECTOR_COUNT			1
+#define VOLTAGE_SAMPLE_COUNT		30
 
 #define GFD_WAIT			0
 #define GFD_PASS			1
@@ -34,6 +36,21 @@ typedef unsigned char			byte;
 #define	AC_MINIMUM_DUTY			6
 #define	AC_STOP_DUTY			100
 
+#define GUN_LEFT			0
+#define GUN_RIGHT			1
+#define GUN_CHECK			255
+
+//=======================================
+// Price type
+//=======================================
+#define DEFAULT_VALUE						0
+#define CONNECTION_FEE						1
+#define CURRENT_RATE						2
+#define OCCUPANCY_FEE						3
+#define SESSION_FEE							4
+#define TOTAL_COST							5
+#define ACCOUNT_BALANCE						6
+
 enum _AC_SYSTEM_STATUS
 {
 	AC_SYS_NONE = 	0,
@@ -47,10 +64,11 @@ enum _AC_SYSTEM_STATUS
 
 enum _GUN_TYPE
 {
-	_Type_Chademo = 		0,
-	_Type_CCS,
-	_Type_GB,
-	_Type_AC,
+	_Type_Chademo 	= 0,
+	_Type_CCS		= 1,
+	_Type_GB		= 2,
+	_Type_AC		= 3,
+	_Type_Test		= 9
 };
 
 enum _CCS_TYPE
@@ -108,25 +126,10 @@ enum _OFFLINE_POLICY
 	_OFFLINE_POLICY_NO_CHARGING = 0x03,
 };
 
-enum _REASSIGNED_RESOURCE_STEP
-{
-	_REASSIGNED_NONE = 				0,	//
-	_REASSIGNED_PREPARE_M_TO_A =	1,	// 系統收到需要降載需求 (輸出總電流降低),PSU Task 收到將狀態切換至下個狀態
-	_REASSIGNED_GET_NEW_CAP = 		2,	// 充電中的重新取得屬於自己火線上的總能量並透過小板通知車端 - 超過10秒直接跳下一步
-	_REASSIGNED_ADJUST_M_TO_A = 	3,	// 模塊重新分配完成
-	_REASSIGNED_RELAY_M_TO_A =		4,	// 切斷橋接的 Relay
-
-	_REASSIGNED_PREPARE_A_TO_M = 	11,
-	_REASSIGNED_ADJUST_A_TO_M = 	12, // 模塊升壓
-	_REASSIGNED_RELAY_A_TO_M = 		13,	// 搭接橋接的 Relay
-	_REASSIGNED_WAITING = 			14,
-	_REASSIGNED_COMP = 				15
-};
-
 enum _MAIN_CHARGING_MODE
 {
-	_MAIN_CHARGING_MODE_MAX = 0,
-	_MAIN_CHARGING_MODE_AVER = 1,
+	_MAIN_CHARGING_MODE_NORMAL	 	= 0,
+	_MAIN_CHARGING_MODE_BOTH 		= 1,
 };
 
 enum _EXTRA_ERR_PROCESS
@@ -140,6 +143,7 @@ enum _CHARGER_TYPE
 {
 	_CHARGER_TYPE_IEC = 0,
 	_CHARGER_TYPE_UL = 1,
+	_CHARGER_TYPE_JARI = 2 //LWADD
 };
 
 enum _SYS_WIFI_MODE
@@ -221,7 +225,67 @@ enum _SYSTEM_TASK_LOST_ITEM
 	_SYSTEM_TASK_LOST_ITEM_EVENTLOG		= 4,
 	_SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM	= 5,
 	_SYSTEM_TASK_LOST_ITEM_LCMCONTROL	= 6,
-	_SYSTEM_TASK_LOST_ITEM_INTERCOMM	= 7
+	_SYSTEM_TASK_LOST_ITEM_INTERCOMM	= 7,
+	_SYSTEM_TASK_LOST_ITEM_SMARTBOX		= 8
+};
+
+enum _PSU_PROTOCOL_TYPE
+{
+	_PSU_PROTOCOL_INFY 					= 0,
+	_PSU_PROTOCOL_UU					= 1
+};
+
+
+enum _PSU_USING_TARGET
+{
+	_PSU_USING_TARGET_CON1		= 0x00,
+	_PSU_USING_TARGET_CON2		= 0x01,
+	_PSU_USING_TARGET_READY		= 0xFF,
+};
+
+enum _PSU_POWER_STATUS
+{
+	_PSU_POWER_STATUS_OFF		= 0x00,
+	_PSU_POWER_STATUS_ON		= 0x01,
+};
+
+enum _PSU_DYNAMIC_FETCH_STEP
+{
+	_PSU_DYNAMIC_FETCH_STEP_NONE			= 0x00,
+	_PSU_DYNAMIC_FETCH_STEP_WAIT			= 0x01,
+	_PSU_DYNAMIC_FETCH_STEP_TG_VOL			= 0x02,
+	_PSU_DYNAMIC_FETCH_STEP_RELAY			= 0x03,
+	_PSU_DYNAMIC_FETCH_STEP_CUR_SHARE		= 0x04,
+	_PSU_DYNAMIC_FETCH_STEP_WATI_FINISH		= 0x05,
+	_PSU_DYNAMIC_FETCH_STEP_FINISH			= 0x06,
+	_PSU_DYNAMIC_FETCH_STEP_ABORT			= 0x10,
+};
+
+enum _PSU_DYNAMIC_RELEASE_STEP
+{
+	_PSU_DYNAMIC_RELEASE_STEP_NONE			= 0x00,
+	_PSU_DYNAMIC_RELEASE_STEP_WAIT			= 0x01,
+	_PSU_DYNAMIC_RELEASE_STEP_LIMIT			= 0x02,
+	_PSU_DYNAMIC_RELEASE_STEP_PWROFF		= 0x03,
+	_PSU_DYNAMIC_RELEASE_STEP_RELAYOFF		= 0x04,
+	_PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH 	= 0x05,
+	_PSU_DYNAMIC_RELEASE_STEP_FINISH		= 0x06,
+	_PSU_DYNAMIC_RELEASE_STEP_ABORT			= 0x10,
+};
+
+enum _PSU_GROUP_INDEX
+{
+	_PSU_GROUP_INDEX_0	= 0x00,
+	_PSU_GROUP_INDEX_1	= 0x01,
+	_PSU_GROUP_INDEX_2	= 0x02,
+	_PSU_GROUP_INDEX_3	= 0x03,
+};
+
+enum _RELAY_SWITCH_NAME
+{
+	_RELAY_SWITCH_NAME_R3			= 0x00,
+	_RELAY_SWITCH_NAME_R4			= 0x01,
+	_RELAY_SWITCH_NAME_R5			= 0x02,
 };
 
 struct StructMeter
@@ -239,6 +303,19 @@ struct MeterInformation
 	byte isWorking;
 };
 
+//struct ConnectorBalanceInfo
+//{
+//	unsigned int UserPrice; // connector user's user price, unit: 0.01 (dollar / kWh)
+//	unsigned int TotalCost; // connector user's total cost, unit: 0.01 dollar
+//	int AccountBalance; // connector user's account balance, unit: 0.01 dollar
+//};
+//
+//struct BalanceInfo
+//{
+//	unsigned int defaultPrice;
+//	struct ConnectorBalanceInfo connectorBalanceInfo[3]; // Max count : DC * 2 + AC * 1
+//};
+
 struct ConnectorBalanceInfo
 {
 	unsigned int UserPrice; // connector user's user price, unit: 0.01 (dollar / kWh)
@@ -273,6 +350,7 @@ enum RELAY_STATUS_ERROR_INDEX
 	RELAY_SMR2_N_STATUS = 	3,
 	RELAY_PARA_P_STATUS = 	4,
 	RELAY_PARA_N_STATUS = 	5,
+	RELAY_PRE_STATUS =		6
 };
 
 enum RELAY_STATUS_ERROR_TYPE
@@ -315,6 +393,26 @@ enum _CCID_INDEX
 	_CCID_NONE 		= 0xFF,
 };
 
+enum _CONNECTOR_STATUS
+{
+	_CONNECTOR_STATUS_NONE 		= 0x00,
+	_CONNECTOR_STATUS_WAIT		= 0x01,
+	_CONNECTOR_STATUS_USING		= 0x02,
+};
+
+enum _SYSTEM_TYPE
+{
+	_SYSTEM_TYPE_SIMPLE 		= 0x00,
+	_SYSTEM_TYPE_STANDARD		= 0x01,
+	_SYSTEM_TYPE_SMART			= 0x10
+};
+
+enum _TPC_PLUG_DETECT_STATUS
+{
+	_TPC_PLUG_DETECT_STATUS_NONE 		= 0x00,
+	_TPC_PLUG_DETECT_STATUS_WAIT		= 0x01,
+};
+
 typedef union
 {
     unsigned int GunErrMessage;
@@ -352,12 +450,16 @@ typedef union
 		unsigned char GBTConnectUCP :1;
 		unsigned char ParallelRelayWeldingFault :1;
 		unsigned char ParallelRelayDrivingFault :1;
-		unsigned char :3;
+		unsigned char StopByEvseCondition:1;
+		unsigned char :2;
     }GunBits;
 }GunErr;
 
 struct DcCommonInformation
 {
+	// 0 : Standard (only one psu module), 1 : Standard (two psu module), 2 : Smart
+	byte systemType;
+	byte halfGroupCount;
 	byte rebootCount;
 	// charger type (standard、simple)
 	byte chargerType;
@@ -379,6 +481,7 @@ struct DcCommonInformation
 	byte acContactSwitch;
 	byte psuKeepCommunication;
 	byte startTransactionFlag[DC_CONNECTOR_COUNT];
+	int startTransactionID[DC_CONNECTOR_COUNT];
 
 	GunErr ConnectErrList[DC_CONNECTOR_COUNT];
 	byte CcsTypeSaved[DC_CONNECTOR_COUNT];
@@ -411,28 +514,55 @@ struct DcCommonInformation
 	// for reset ev board (GBT or Chademo)
 	byte evBoardResetFlag;
 
-	// Psu module split by connector
-	int connector[DC_CONNECTOR_COUNT][12];
-	byte conn_1_count;
-	byte conn_2_count;
-
 	// Use ccid to obtain authorization
 	byte enObtainAuthorizbyCCID;
 	byte _CcidAuthProcessStep;
 	byte _authWithCcidFlag[DC_CONNECTOR_COUNT];
 
 	// balance information - for tariff
+	//struct BalanceInfo balanceInfo;
+	// balance information - for standard
 	struct BalanceInfo balanceInfo;
 
 	// the hold time before return idle
 	byte _returnIdleHoldFlag[DC_CONNECTOR_COUNT];
 
+	// Date - YYYY/MM/DD
+	byte _sys_date[11];
+	// Date - hh/mm
+	byte _sys_time[8];
+	// Date - a / p .m
+	byte _sys_period[6];
+
 	// isPsuError
 	byte _isPsuErrorOccur;
 
+	// PSU Protocol
+	byte _psuProtocol;
+
+	//CHAdeMo transfer TPC plug in detect
+	//LW_tpc plug detect
+	byte _tpcPlugDetectState;
+	byte TpcDetectFunction;
+
+	// Check if the output voltage is stable
+	float _outputVoltageSapmle[PSU_GROUP_COUNT][VOLTAGE_SAMPLE_COUNT];
+
+	// offline power - LW_OfflinePower
+	int _offlinePower;
+
+	// CTEP : California Type Evaluation Program
+	double _ctepEnergyCost [DC_CONNECTOR_COUNT];
+	double _ctepParkingFee [DC_CONNECTOR_COUNT];
+	double _ctepTotalCost [DC_CONNECTOR_COUNT];
+
 	byte for_alston_test_1;
 	byte for_alston_test_2;
 	byte for_alston_test_3;
+
+	// for test smartbox - fetch / release
+	byte smartFetchRun[DC_CONNECTOR_COUNT];
+	byte smartReleaseRun[DC_CONNECTOR_COUNT];
 };
 
 #endif /* CONFIG_H_ */

BIN
EVSE/Projects/DS60-120/Apps/FactoryConfig


+ 7 - 2
EVSE/Projects/DS60-120/Apps/Makefile

@@ -13,7 +13,7 @@ Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 all: CopyFile apps
 #apps: Module_CSU Module_EvComm Module_EventLogging Module_InternalComm Module_LcmControl Module_PrimaryComm Module_PsuComm 
 # ReadCmdline kill.sh
-apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask ReadCmdlineTask UnsafetyOutputTool FactoryConfigApp OtherTools
+apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask PrimaryCommTask PsuCommTask SmartBoxTask ReadCmdlineTask UnsafetyOutputTool FactoryConfigApp OtherTools
 
 MainTask:
 	rm -f *.o
@@ -62,7 +62,12 @@ PsuCommTask:
 	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PsuComm.o Module_PsuComm.c
 	$(CC) -lrt -o Module_PsuComm Module_PsuComm.o ../../../Modularization/libInfypwr_PsuCommObj.a
 	cp -f Module_PsuComm ../Images/root	
-	
+SmartBoxTask:
+	rm -f Module_SmartBox; 
+	$(CC) -D $(Project) -include../../../Modularization/Infypwr_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_SmartBox.o Module_SmartBox.c
+	$(CC) -lrt -o Module_SmartBox Module_SmartBox.o ../../../Modularization/libInfypwr_PsuCommObj.a
+	cp -f Module_SmartBox ../Images/root	
+
 ReadCmdlineTask:
 	rm -f ReadCmdline; 
 	$(CC) -D $(Project) -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o ReadCmdline.o ReadCmdline.c

BIN
EVSE/Projects/DS60-120/Apps/Module_EvComm


ファイルの差分が大きいため隠しています
+ 393 - 247
EVSE/Projects/DS60-120/Apps/Module_EvComm.c


+ 0 - 1
EVSE/Projects/DS60-120/Apps/Module_EvComm.h

@@ -7,7 +7,6 @@ int CanFd;
 
 typedef unsigned char 		byte;
 
-
 typedef enum
 {
     EV_Slave_Address_Broadcast  	= 0xFF,

BIN
EVSE/Projects/DS60-120/Apps/Module_EventLogging


+ 70 - 23
EVSE/Projects/DS60-120/Apps/Module_EventLogging.c

@@ -87,7 +87,7 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
 			tm->tm_year+1900,tm->tm_mon+1,
@@ -437,21 +437,43 @@ int main(void)
 					{
 						memset(EventCodeTmp,0,sizeof(EventCodeTmp));
 						memcpy(EventCodeTmp,FaultStatusCode[ByteCount*8+BitCount],sizeof(EventCodeTmp)-1);
-						if(((tmp>>BitCount)&0x01)==0)//Recovered
+
+						if((strstr((char*)EventCodeTmp, "11021") == NULL) &&
+								(strstr((char*)EventCodeTmp, "11022") == NULL))
 						{
-							//EventCodeTmp[0]=1;
-							DEBUG_INFO("Recovery Fault Code = %s\n", EventCodeTmp);
-							ShmStatusCodeData->FaultCode.PreviousFaultVal[ByteCount] &= ~(1<<BitCount);
-							RemoveFaultCodeToBuf(EventCodeTmp);
-							EventCodeTmp[0] = '1';
-							isChanged = CHANGED;
+							if(((tmp>>BitCount)&0x01)==0)//Recovered
+							{
+								//EventCodeTmp[0]=1;
+								DEBUG_INFO("Recovery Fault Code = %s\n", EventCodeTmp);
+								ShmStatusCodeData->FaultCode.PreviousFaultVal[ByteCount] &= ~(1<<BitCount);
+								RemoveFaultCodeToBuf(EventCodeTmp);
+								EventCodeTmp[0] = '1';
+								isChanged = CHANGED;
+							}
+							else
+							{
+								DEBUG_INFO("Fault Code = %s\n", EventCodeTmp);
+								ShmStatusCodeData->FaultCode.PreviousFaultVal[ByteCount] |= (1<<BitCount);
+								AddFaultCodeToBuf(EventCodeTmp);
+								isChanged = CHANGED;
+							}
 						}
 						else
 						{
-							DEBUG_INFO("Fault Code = %s\n", EventCodeTmp);
-							ShmStatusCodeData->FaultCode.PreviousFaultVal[ByteCount] |= (1<<BitCount);
-							AddFaultCodeToBuf(EventCodeTmp);
-							isChanged = CHANGED;
+							if (((tmp >> BitCount) & 0x01) == 0) //Recovered
+							{
+								//EventCodeTmp[0]=1;
+								DEBUG_INFO( "Recovery Fault Code - no show = %s\n", EventCodeTmp );
+								ShmStatusCodeData->FaultCode.PreviousFaultVal [ByteCount] &= ~ (1 << BitCount);
+								EventCodeTmp [0] = '1';
+								isChanged = CHANGED;
+							}
+							else
+							{
+								DEBUG_INFO( "Fault Code - no show = %s\n", EventCodeTmp );
+								ShmStatusCodeData->FaultCode.PreviousFaultVal [ByteCount] |= (1 << BitCount);
+								isChanged = CHANGED;
+							}
 						}
 
 						EVENT_INFO("%s\n", EventCodeTmp);
@@ -521,21 +543,46 @@ int main(void)
 					{
 						memset(EventCodeTmp,0,sizeof(EventCodeTmp));
 						memcpy(EventCodeTmp,InfoStatusCode[ByteCount*8+BitCount],sizeof(EventCodeTmp)-1);
-						if(((tmp>>BitCount)&0x01)==0)//Recovered
+
+						if ((strstr ( (char*) EventCodeTmp, "13622" ) == NULL) &&
+								(strstr ( (char*) EventCodeTmp, "13623" ) == NULL) &&
+								(strstr ( (char*) EventCodeTmp, "13624" ) == NULL) &&
+								(strstr ( (char*) EventCodeTmp, "13625" ) == NULL) &&
+								(strstr ( (char*) EventCodeTmp, "13626" ) == NULL))
 						{
-							//EventCodeTmp[0]=1;
-							DEBUG_INFO("Recovery Info Code = %s\n", EventCodeTmp);
-							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] &= ~(1<<BitCount);
-							RemoveFaultCodeToBuf(EventCodeTmp);
-							EventCodeTmp[0] = '1';
-							isChanged = CHANGED;
+							if(((tmp>>BitCount)&0x01)==0)//Recovered
+							{
+								//EventCodeTmp[0]=1;
+								DEBUG_INFO("Recovery Info Code = %s\n", EventCodeTmp);
+								ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] &= ~(1<<BitCount);
+								RemoveFaultCodeToBuf(EventCodeTmp);
+								EventCodeTmp[0] = '1';
+								isChanged = CHANGED;
+							}
+							else
+							{
+								DEBUG_INFO("Info Code = %s\n", EventCodeTmp);
+								ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] |= (1<<BitCount);
+								AddFaultCodeToBuf(EventCodeTmp);
+								isChanged = CHANGED;
+							}
 						}
 						else
 						{
-							DEBUG_INFO("Info Code = %s\n", EventCodeTmp);
-							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] |= (1<<BitCount);
-							AddFaultCodeToBuf(EventCodeTmp);
-							isChanged = CHANGED;
+							if (((tmp >> BitCount) & 0x01) == 0) //Recovered
+							{
+								//EventCodeTmp[0]=1;
+								DEBUG_INFO( "Recovery Info Code - no show = %s\n", EventCodeTmp );
+								ShmStatusCodeData->InfoCode.PreviousInfoVal [ByteCount] &= ~ (1 << BitCount);
+								EventCodeTmp [0] = '1';
+								isChanged = CHANGED;
+							}
+							else
+							{
+								DEBUG_INFO( "Info Code - no show = %s \n", EventCodeTmp );
+								ShmStatusCodeData->InfoCode.PreviousInfoVal [ByteCount] |= (1 << BitCount);
+								isChanged = CHANGED;
+							}
 						}
 
 						EVENT_INFO("%s\n", EventCodeTmp);

BIN
EVSE/Projects/DS60-120/Apps/Module_InternalComm


+ 456 - 105
EVSE/Projects/DS60-120/Apps/Module_InternalComm.c

@@ -69,6 +69,7 @@ struct OCPP16Data				*ShmOCPP16Data;
 struct OCPP20Data				*ShmOCPP20Data;
 struct PrimaryMcuData			*ShmPrimaryMcuData;
 struct DcCommonInformation		*ShmDcCommonData;
+struct SmartBoxData				*ShmSmartBoxData;
 
 #define VIN_MAX_VOLTAGE_IEC			285	// 大於該值 : OVP
 #define VIN_MAX_REV_VOLTAGE_IEC		275	// 小於賦歸 OVP
@@ -80,6 +81,18 @@ struct DcCommonInformation		*ShmDcCommonData;
 #define VIN_MIN_VOLTAGE_UL			210	// 小於該值 : UVP
 #define VIN_MIN_REV_VOLTAGE_UL 		220	// 大於賦歸 UVP
 
+//LWADD
+#define VIN_MAX_VOLTAGE_JARI			285	// 大於該值 : OVP // 日規 (W)
+#define VIN_MAX_REV_VOLTAGE_JARI		275	// 小於賦歸 OVP
+#define VIN_MIN_VOLTAGE_JARI			187	// 小於該值 : UVP
+#define VIN_MIN_REV_VOLTAGE_JARI 		197	// 大於賦歸 UVP
+
+// 50KW 系統
+#define VIN_MAX_VOLTAGE_JARI_50KW		250	// 大於該值 : OVP // 日規 (W)
+#define VIN_MAX_REV_VOLTAGE_JARI_50KW	240	// 小於賦歸 OVP
+#define VIN_MIN_VOLTAGE_JARI_50KW		170	// 小於該值 : UVP
+#define VIN_MIN_REV_VOLTAGE_JARI_50KW	180	// 大於賦歸 UVP
+
 #define VIN_DROP_VOLTAGE	150	// 小於該值 : ac drop
 
 #define VOUT_MAX_VOLTAGE	995
@@ -168,11 +181,14 @@ byte 			_ac_duty;
 
 bool isCriticalStop;
 struct timespec	_psuCriticalStop;
+bool isSelftestComp = false;
 
 unsigned short _setFanSpeed = 0;
 float _beforeChargingTotalEnergy = 0.0;
 byte _checkLedChanged = 3;
 byte relayMatchFlag = 0;
+// 50KW系統
+bool is50kwSystem;
 
 Ver ver;
 PresentInputVoltage inputVoltage;
@@ -304,7 +320,7 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
 			tm->tm_year+1900,tm->tm_mon+1,
@@ -520,10 +536,17 @@ void GetPresentInputVol()
 	if (Query_Present_InputVoltage(Uart5Fd, Addr.Relay, &inputVoltage) == PASS)
 	{
 		// resolution : 0.1
+		if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI &&
+				is50kwSystem)
+		{
+			inputVoltage.L1N_L12 *= 1.732;
+			inputVoltage.L2N_L23 *= 1.732;
+			inputVoltage.L3N_L31 *= 1.732;
+		}
+
 		ShmSysConfigAndInfo->SysInfo.InputVoltageR = ShmRelayModuleData->InputL1Volt = inputVoltage.L1N_L12;
 		ShmSysConfigAndInfo->SysInfo.InputVoltageS = ShmRelayModuleData->InputL2Volt = inputVoltage.L2N_L23;
 		ShmSysConfigAndInfo->SysInfo.InputVoltageT = ShmRelayModuleData->InputL3Volt = inputVoltage.L3N_L31;
-
 		//********************************************************************************************************//
 		// Vin (UVP)
 		if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC)
@@ -650,6 +673,134 @@ void GetPresentInputVol()
 				}
 			}
 		}
+		else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI)
+		{
+			if (!is50kwSystem)
+			{
+				//LWADD
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == NO)
+				{
+					if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
+						if (_threePhaseUvp[0] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
+						else
+							_threePhaseUvp[0] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L1N_L12 > VIN_MIN_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO;
+						_threePhaseUvp[0] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == NO)
+				{
+					if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
+						if (_threePhaseUvp[1] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
+						else
+							_threePhaseUvp[1] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L2N_L23 > VIN_MIN_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO;
+						_threePhaseUvp[1] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == NO)
+				{
+					if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
+						if (_threePhaseUvp[2] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
+						else
+							_threePhaseUvp[2] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L3N_L31 > VIN_MIN_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO;
+						_threePhaseUvp[2] = 0;
+					}
+				}
+			}
+			else
+			{
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == NO)
+				{
+					if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12);
+						if (_threePhaseUvp[0] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
+						else
+							_threePhaseUvp[0] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L1N_L12 > VIN_MIN_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO;
+						_threePhaseUvp[0] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == NO)
+				{
+					if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23);
+						if (_threePhaseUvp[1] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
+						else
+							_threePhaseUvp[1] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L2N_L23 > VIN_MIN_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO;
+						_threePhaseUvp[1] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == NO)
+				{
+					if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31);
+						if (_threePhaseUvp[2] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
+						else
+							_threePhaseUvp[2] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L3N_L31 > VIN_MIN_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO;
+						_threePhaseUvp[2] = 0;
+					}
+				}
+			}
+		}
 		//********************************************************************************************************//
 		// Vin (OVP)
 		if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC)
@@ -776,6 +927,134 @@ void GetPresentInputVol()
 				}
 			}
 		}
+		else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI)
+		{
+			if (!is50kwSystem)
+			{
+				//LWADD
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == NO)
+				{
+					if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
+						if (_threePhaseOvp[0] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
+						else
+							_threePhaseOvp[0] += 0;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L1N_L12 < VIN_MAX_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO;
+						_threePhaseOvp[0] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == NO)
+				{
+					if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
+						if (_threePhaseOvp[1] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
+						else
+							_threePhaseOvp[1] += 0;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L2N_L23 < VIN_MAX_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO;
+						_threePhaseOvp[1] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == NO)
+				{
+					if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_JARI)
+					{
+						PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
+						if (_threePhaseOvp[2] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
+						else
+							_threePhaseOvp[2] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L3N_L31 < VIN_MAX_REV_VOLTAGE_JARI)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO;
+						_threePhaseOvp[2] = 0;
+					}
+				}
+			}
+			else
+			{
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == NO)
+				{
+					if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12);
+						if (_threePhaseOvp[0] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
+						else
+							_threePhaseOvp[0] += 0;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L1N_L12 < VIN_MAX_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO;
+						_threePhaseOvp[0] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == NO)
+				{
+					if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23);
+						if (_threePhaseOvp[1] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
+						else
+							_threePhaseOvp[1] += 0;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L2N_L23 < VIN_MAX_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO;
+						_threePhaseOvp[1] = 0;
+					}
+				}
+
+				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == NO)
+				{
+					if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_JARI_50KW)
+					{
+						PRINTF_FUNC("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31);
+						if (_threePhaseOvp[2] >= OVP_UVP_CHK_COUNT)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
+						else
+							_threePhaseOvp[2] += 1;
+					}
+				}
+				else
+				{
+					if (inputVoltage.L3N_L31 < VIN_MAX_REV_VOLTAGE_JARI_50KW)
+					{
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO;
+						_threePhaseOvp[2] = 0;
+					}
+				}
+			}
+		}
 	}
 }
 
@@ -935,17 +1214,37 @@ void CheckK1K2RelayOutput(byte index)
 		}
 	}
 
-	if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES)
+	if (ShmSmartBoxData->RcbParallelStatus[0] == YES)
 	{
-		if (regRelay.relay_event.bits.Gun1_Parallel_N == NO &&
-				regRelay.relay_event.bits.Gun1_Parallel_P == NO)
-			ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = NO;
+		if (regRelay.relay_event.bits.R3_BOTH_K1_K4 == NO)
+			ShmSmartBoxData->RcbParallelStatus[0] = NO;
 	}
-	else if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO)
+	else if (ShmSmartBoxData->RcbParallelStatus[0] == NO)
 	{
-		if (regRelay.relay_event.bits.Gun1_Parallel_N == YES &&
-				regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-				ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = YES;
+		if (regRelay.relay_event.bits.R3_BOTH_K1_K4 == YES)
+			ShmSmartBoxData->RcbParallelStatus[0] = YES;
+	}
+
+	if (ShmSmartBoxData->RcbParallelStatus[1] == YES)
+	{
+		if (regRelay.relay_event.bits.R4_BOTH_K2_K5 == NO)
+			ShmSmartBoxData->RcbParallelStatus [1] = NO;
+	}
+	else if (ShmSmartBoxData->RcbParallelStatus [1] == NO)
+	{
+		if (regRelay.relay_event.bits.R4_BOTH_K2_K5 == YES)
+			ShmSmartBoxData->RcbParallelStatus [1] = YES;
+	}
+
+	if (ShmSmartBoxData->RcbParallelStatus[2] == YES)
+	{
+		if (regRelay.relay_event.bits.R5_BOTH_K3_K6 == NO)
+			ShmSmartBoxData->RcbParallelStatus [2] = NO;
+	}
+	else if (ShmSmartBoxData->RcbParallelStatus [2] == NO)
+	{
+		if (regRelay.relay_event.bits.R5_BOTH_K3_K6 == YES)
+			ShmSmartBoxData->RcbParallelStatus [2] = YES;
 	}
 
 //	PRINTF_FUNC("Check Relay Output. index = %d, RelayKPK2Status = %d, BridgeRelayStatus = %d \n",
@@ -1155,23 +1454,11 @@ void SetK1K2RelayStatus(byte index)
 		{
 			outputRelay.relay_event.bits.Gun1_P = NO;
 			outputRelay.relay_event.bits.Gun1_N = NO;
-
-			if (gunCount == 1 && _chargingData[index]->Type == _Type_CCS)
-			{
-				if(regRelay.relay_event.bits.CCS_Precharge == YES)
-					outputRelay.relay_event.bits.CCS_Precharge = NO;
-			}
 		}
 		else if (_chargingData[index]->Evboard_id == 0x02)
 		{
 			outputRelay.relay_event.bits.Gun2_P = NO;
 			outputRelay.relay_event.bits.Gun2_N = NO;
-
-			if (_chargingData[index]->Type == _Type_CCS)
-			{
-				if(regRelay.relay_event.bits.CCS_Precharge == YES)
-					outputRelay.relay_event.bits.CCS_Precharge = NO;
-			}
 		}
 	}
 	else if ((_chargingData[index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE &&
@@ -1276,60 +1563,46 @@ void SetParalleRelayStatus()
 	if (gunCount >= 2 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO)
 	{
 		if (_chargingData[0]->SystemStatus == SYS_MODE_BOOTING || _chargingData[1]->SystemStatus == SYS_MODE_BOOTING ||
-				ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_CRITICAL ||
+				ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_CRITICAL || !isSelftestComp ||
 				((_chargingData[0]->SystemStatus == SYS_MODE_IDLE || _chargingData[0]->SystemStatus == SYS_MODE_MAINTAIN) &&
 				(_chargingData[1]->SystemStatus == SYS_MODE_IDLE || _chargingData[1]->SystemStatus == SYS_MODE_MAINTAIN)))
 		{
 			// 初始化~ 不搭橋接
-			if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-				outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
-			else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
-				outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
+
 		}
 		else
 		{
-			if (_chargingData[0]->IsReadyToCharging == YES ||
-					_chargingData[1]->IsReadyToCharging == YES)
+			if (ShmSmartBoxData->ParallelRelayStatus[_RELAY_SWITCH_NAME_R3])
 			{
-				// ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************
-				if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
-				{
-					if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_M_TO_A)
-					{
-						// 最大充 - 搭上橋接
-						if (regRelay.relay_event.bits.Gun1_Parallel_N == NO)
-							outputRelay.relay_event.bits.Gun1_Parallel_N = YES;
-						else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO)
-							outputRelay.relay_event.bits.Gun1_Parallel_P = YES;
-					}
-					else
-					{
-						// 平均充 - 不搭
-						if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-							outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
-						else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
-							outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
-					}
-				}
-				else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
-				{
-					if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_A_TO_M)
-					{
-						// 平均充 - 不搭
-						if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-							outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
-						else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
-							outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
-					}
-					else
-					{
-						// 最大充 - 搭上橋接
-						if (regRelay.relay_event.bits.Gun1_Parallel_N == NO)
-							outputRelay.relay_event.bits.Gun1_Parallel_N = YES;
-						else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO)
-							outputRelay.relay_event.bits.Gun1_Parallel_P = YES;
-					}
-				}
+				if (regRelay.relay_event.bits.R3_BOTH_K1_K4 == NO)
+					outputRelay.relay_event.bits.R3_BOTH_K1_K4 = YES;
+			}
+			else
+			{
+				if (regRelay.relay_event.bits.R3_BOTH_K1_K4 == YES)
+					outputRelay.relay_event.bits.R3_BOTH_K1_K4 = NO;
+			}
+
+			if (ShmSmartBoxData->ParallelRelayStatus [_RELAY_SWITCH_NAME_R4])
+			{
+				if (regRelay.relay_event.bits.R4_BOTH_K2_K5 == NO)
+					outputRelay.relay_event.bits.R4_BOTH_K2_K5 = YES;
+			}
+			else
+			{
+				if (regRelay.relay_event.bits.R4_BOTH_K2_K5 == YES)
+					outputRelay.relay_event.bits.R4_BOTH_K2_K5 = NO;
+			}
+
+			if (ShmSmartBoxData->ParallelRelayStatus [_RELAY_SWITCH_NAME_R5])
+			{
+				if (regRelay.relay_event.bits.R5_BOTH_K3_K6 == NO)
+					outputRelay.relay_event.bits.R5_BOTH_K3_K6 = YES;
+			}
+			else
+			{
+				if (regRelay.relay_event.bits.R5_BOTH_K3_K6 == YES)
+					outputRelay.relay_event.bits.R5_BOTH_K3_K6 = NO;
 			}
 		}
 	}
@@ -1614,7 +1887,7 @@ void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoDat
 		}
 	}
 	else if (IsNoneMatchLedColor())
-		_checkLedChanged = 3;
+		_checkLedChanged = 5;
 }
 //==========================================
 // Init all share memory
@@ -1792,6 +2065,21 @@ int InitShareMemory()
    		return 0;
    	}
 
+	if ((MeterSMId = shmget ( ShmSmartBoxKey, sizeof(struct SmartBoxData), IPC_CREAT | 0777 )) < 0)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmat ShmSmartBoxKey NG \n");
+		#endif
+		return 0;
+	}
+	else if ((ShmSmartBoxData = shmat ( MeterSMId, NULL, 0 )) == (void *) - 1)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmat ShmSmartBoxData NG \n");
+		#endif
+		return 0;
+	}
+
 	return result;
 }
 
@@ -1961,13 +2249,13 @@ bool IsNoneMatchRelayStatus()
 	bool result = false;
 
 	if ((regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor) ||
-		(regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge) ||
+		(regRelay.relay_event.bits.R3_BOTH_K1_K4 != outputRelay.relay_event.bits.R3_BOTH_K1_K4) ||
 		(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))
+		(regRelay.relay_event.bits.R4_BOTH_K2_K5 != outputRelay.relay_event.bits.R4_BOTH_K2_K5) ||
+		(regRelay.relay_event.bits.R5_BOTH_K3_K6 != outputRelay.relay_event.bits.R5_BOTH_K3_K6))
 	{
 		result = true;
 	}
@@ -1977,11 +2265,6 @@ bool IsNoneMatchRelayStatus()
 		//PRINTF_FUNC("AC Contact Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.AC_Contactor);
 	}
 
-	if (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge)
-	{
-		//PRINTF_FUNC("CCS Precharge Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.CCS_Precharge);
-	}
-
 	if (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P)
 	{
 		StartCheckRelayInfo(RELAY_SMR1_P_STATUS, outputRelay.relay_event.bits.Gun1_P);
@@ -2023,9 +2306,9 @@ bool IsNoneMatchRelayStatus()
 		StopCheckRelayInfo(RELAY_SMR2_N_STATUS);
 	}
 
-	if (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P)
+	if (regRelay.relay_event.bits.R4_BOTH_K2_K5 != outputRelay.relay_event.bits.R4_BOTH_K2_K5)
 	{
-		StartCheckRelayInfo(RELAY_PARA_P_STATUS, outputRelay.relay_event.bits.Gun1_Parallel_P);
+		StartCheckRelayInfo(RELAY_PARA_P_STATUS, outputRelay.relay_event.bits.R4_BOTH_K2_K5);
 		//PRINTF_FUNC("Parallel:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_P);
 	}
 	else
@@ -2033,9 +2316,9 @@ bool IsNoneMatchRelayStatus()
 		StopCheckRelayInfo(RELAY_PARA_P_STATUS);
 	}
 
-	if (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N)
+	if (regRelay.relay_event.bits.R5_BOTH_K3_K6 != outputRelay.relay_event.bits.R5_BOTH_K3_K6)
 	{
-		StartCheckRelayInfo(RELAY_PARA_N_STATUS, outputRelay.relay_event.bits.Gun1_Parallel_N);
+		StartCheckRelayInfo(RELAY_PARA_N_STATUS, outputRelay.relay_event.bits.R5_BOTH_K3_K6);
 		//PRINTF_FUNC("Parallel:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_N);
 	}
 	else
@@ -2043,6 +2326,16 @@ bool IsNoneMatchRelayStatus()
 		StopCheckRelayInfo(RELAY_PARA_N_STATUS);
 	}
 
+	if (regRelay.relay_event.bits.R3_BOTH_K1_K4 != outputRelay.relay_event.bits.R3_BOTH_K1_K4)
+	{
+		StartCheckRelayInfo(RELAY_PRE_STATUS, outputRelay.relay_event.bits.R3_BOTH_K1_K4);
+		//PRINTF_FUNC("Parallel:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_N);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_PRE_STATUS);
+	}
+
 	return result;
 }
 
@@ -2051,13 +2344,13 @@ void MatchRelayStatus()
 	// 因為 AC Contactor 沒有 Feedback,所以暫時先這樣處理
 	//regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor;
 	ShmSysConfigAndInfo->SysInfo.AcContactorStatus  = regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor;
-	regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
+	regRelay.relay_event.bits.R5_BOTH_K3_K6 = outputRelay.relay_event.bits.R5_BOTH_K3_K6;
 	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;
+	regRelay.relay_event.bits.R4_BOTH_K2_K5 = outputRelay.relay_event.bits.R4_BOTH_K2_K5;
+	regRelay.relay_event.bits.R3_BOTH_K1_K4 = outputRelay.relay_event.bits.R3_BOTH_K1_K4;
 }
 
 void CheckRelayStatusByADC()
@@ -2140,7 +2433,8 @@ void CableCheckDetected(byte index)
 			else if (_chargingData[index]->SystemStatus >= SYS_MODE_CHARGING &&
 					_chargingData[index]->SystemStatus < SYS_MODE_TERMINATING)
 			{
-				if (_chargingData[index]->Type == _Type_GB || _chargingData[index]->Type == _Type_Chademo)
+				//if (_chargingData[index]->Type == _Type_GB || _chargingData[index]->Type == _Type_Chademo)
+				if (_chargingData[index]->Type == _Type_GB)
 					SetGfdConfig(index, GFD_IDLE);
 				else
 					SetGfdConfig(index, GFD_CHARGING);
@@ -2241,13 +2535,13 @@ void CheckOutputVolNoneMatchFire(byte index)
 					PRINTF_FUNC("Abnormal voltage on the Output at the stage of GFD. (%d) : pre = %.1f, fire = %.1f \n",
 							index, (_chargingData[index]->PresentChargingVoltage * 10), _chargingData[index]->FireChargingVoltage);
 
-					if (index == 0)
+					if (index == GUN_LEFT)
 					{
 						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AbnormalVoltageOnOutputLine_1 = YES;
 						if (strncmp((char *)_chargingData[index]->ConnectorAlarmCode, "", 6) == EQUAL)
 								memcpy(_chargingData[index]->ConnectorAlarmCode, "012324", 6);
 					}
-					else if (index == 1)
+					else if (index == GUN_RIGHT)
 					{
 						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AbnormalVoltageOnOutputLine_2 = YES;
 						if (strncmp((char *)_chargingData[index]->ConnectorAlarmCode, "", 6) == EQUAL)
@@ -2345,6 +2639,24 @@ void GetFanSpeedByFunction()
 	}
 
 	ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED;
+	// 日規 50KW 系統~ 只能限制 3000 轉輸出
+	if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI)
+	{
+		if (is50kwSystem)
+		{
+			// 50KW 系統,使用 14000 轉風扇
+			// 如果輸出大於 2.5KW
+			if (ShmFanModuleData->TestFanSpeed > 5000 ||
+					power >= 25)
+				ShmFanModuleData->TestFanSpeed = 5000;
+		}
+		else
+		{
+			// 日規其他系統,使用 4400 轉風扇
+			if (ShmFanModuleData->TestFanSpeed > 9545)
+				ShmFanModuleData->TestFanSpeed = 9545;
+		}
+	}
 
 	if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED)
 		ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED;
@@ -3198,6 +3510,24 @@ void AcChargeTypeProcess()
 	}
 }
 
+bool Is50kwSystemChk()
+{
+	bool result = false;
+	char EvsePower[2];
+
+	EvsePower[2] = '\0';
+	if (strlen ( (char *) ShmSysConfigAndInfo->SysConfig.ModelName ) >= 6)
+	{
+		strncpy ( EvsePower, (char *) (ShmSysConfigAndInfo->SysConfig.ModelName + 4), 2);
+		if (strcmp ( EvsePower, "50" ) == EQUAL)
+		{
+			result = true;
+		}
+	}
+
+	return result;
+}
+
 void RunForceStopProcess()
 {
 	if (isCriticalStop == NO)
@@ -3244,6 +3574,8 @@ int main(void)
 	// Open Uart5 for RB
 	Uart5Fd = InitComPort();
 	Initialization();
+	is50kwSystem = Is50kwSystemChk();
+
 	sleep(1);
 
 	if(Uart5Fd < 0)
@@ -3261,16 +3593,27 @@ int main(void)
 	}
 
 	outputRelay.relay_event.bits.AC_Contactor = 0x00;
-	outputRelay.relay_event.bits.CCS_Precharge = 0x00;
-	outputRelay.relay_event.bits.Gun1_Parallel_P = 0x00;
-	outputRelay.relay_event.bits.Gun1_Parallel_N = 0x00;
-	outputRelay.relay_event.bits.Gun1_P = 0x00;
-	outputRelay.relay_event.bits.Gun1_N = 0x00;
-	outputRelay.relay_event.bits.Gun2_N = 0x00;
-	outputRelay.relay_event.bits.Gun2_P = 0x00;
+	outputRelay.relay_event.bits.R5_BOTH_K3_K6 = 0x00;		// K3 - K6 (R4)
+	outputRelay.relay_event.bits.R4_BOTH_K2_K5 = 0x00;		// K2 - K5 (R4)
+	outputRelay.relay_event.bits.R3_BOTH_K1_K4 = 0x00;		// K1 - K4 (R3)
+	outputRelay.relay_event.bits.Gun1_P = 0x00;				// 左槍 D+ (R1 +)
+	outputRelay.relay_event.bits.Gun1_N = 0x00;				// 左槍 D- (R1 -)
+	outputRelay.relay_event.bits.Gun2_N = 0x00;				// 右槍 D- (R2 -)
+	outputRelay.relay_event.bits.Gun2_P = 0x00;				// 右槍 D+ (R2 +)
 	if(Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay) != PASS)
 		PRINTF_FUNC("Config_Relay_Output fail \n");
 
+//	sleep(1);
+//	GetRelayOutputStatus();
+//	PRINTF_FUNC("Gun1_P = %d \n", outputRelay.relay_event.bits.Gun1_P);
+//	PRINTF_FUNC("Gun1_N = %d \n", outputRelay.relay_event.bits.Gun1_N);
+//	PRINTF_FUNC("Gun2_P = %d", outputRelay.relay_event.bits.Gun2_P);
+//	PRINTF_FUNC("Gun2_N = %d", outputRelay.relay_event.bits.Gun2_N);
+//	PRINTF_FUNC("R3 = %d \n", regRelay.relay_event.bits.R3_BOTH_K1_K4);
+//	PRINTF_FUNC("R4 = %d \n", regRelay.relay_event.bits.R4_BOTH_K2_K5);
+//	PRINTF_FUNC("R5 = %d \n", regRelay.relay_event.bits.R5_BOTH_K3_K6);
+//	return -1;
+
 	cur_led_color.Connect_1_Red = COLOR_MIN_LV;
 	cur_led_color.Connect_1_Green = COLOR_MIN_LV;
 	cur_led_color.Connect_1_Blue = COLOR_MIN_LV;
@@ -3280,6 +3623,7 @@ int main(void)
 
 	relayMatchFlag = NO;
 	isCriticalStop = NO;
+	isSelftestComp = NO;
 	GetTimespecFunc(&_led_blink_time);
 
 	for(;;)
@@ -3325,6 +3669,8 @@ int main(void)
 
 		if (ShmRelayModuleData->SelfTest_Comp == YES)
 		{
+			if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_IDLE && !isSelftestComp)
+				isSelftestComp = true;
 			// ==============優先權最高 10 ms ==============
 			// 輸出電壓
 			GetPersentOutputVol();
@@ -3354,7 +3700,7 @@ int main(void)
 					_isOvpChkTimeFlag[i] = NO;
 				}
 
-				if (_chargingData[i]->SystemStatus == SYS_MODE_BOOTING	||
+				if (_chargingData[i]->SystemStatus == SYS_MODE_BOOTING || _chargingData[i]->ConnectorPlugIn ||
 					(_chargingData[i]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && _chargingData[i]->SystemStatus <= SYS_MODE_ALARM) ||
 					(_chargingData[i]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && _chargingData[i]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) ||
 					ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
@@ -3435,7 +3781,11 @@ int main(void)
 
 				if (Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay))
 				{
-					//regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+//					regRelay.relay_event.bits.R5_BOTH_K3_K6 = outputRelay.relay_event.bits.R5_BOTH_K3_K6;
+//					regRelay.relay_event.bits.R4_BOTH_K2_K5 = outputRelay.relay_event.bits.R4_BOTH_K2_K5;
+//					regRelay.relay_event.bits.R3_BOTH_K1_K4 = outputRelay.relay_event.bits.R3_BOTH_K1_K4;
+
+//					regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.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;
@@ -3474,20 +3824,21 @@ int main(void)
 				else
 					PRINTF_FUNC("Conn2(-) : OFF \n");
 
-				if (regRelay.relay_event.bits.CCS_Precharge == YES)
-					PRINTF_FUNC("Precharge : ON \n");
+				if (regRelay.relay_event.bits.R3_BOTH_K1_K4 == YES)
+					PRINTF_FUNC("R3_BOTH_K1_K4 : ON \n");
 				else
-					PRINTF_FUNC("Precharge : OFF \n");
+					PRINTF_FUNC("R3_BOTH_K1_K4 : OFF \n");
 
-				if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-					PRINTF_FUNC("Parallel(+) : ON \n");
+				if (regRelay.relay_event.bits.R4_BOTH_K2_K5 == YES)
+					PRINTF_FUNC("R4_BOTH_K2_K5 : ON \n");
 				else
-					PRINTF_FUNC("Parallel(+) : OFF \n");
+					PRINTF_FUNC("R4_BOTH_K2_K5 : OFF \n");
 
-				if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
-					PRINTF_FUNC("Parallel(-) : ON \n");
+				if (regRelay.relay_event.bits.R5_BOTH_K3_K6 == YES)
+					PRINTF_FUNC("R5_BOTH_K3_K6 : ON \n");
 				else
-					PRINTF_FUNC("Parallel(-) : OFF \n");
+					PRINTF_FUNC("R5_BOTH_K3_K6 : OFF \n");
+
 				PRINTF_FUNC("======== Relay Status End========\n");
 			}
 		}

+ 62 - 0
EVSE/Projects/DS60-120/Apps/Module_LcmContro.h

@@ -123,11 +123,16 @@ short __plug_in_arrow = 0x0060;
 short __conn_line = 0x0066;
 
 short __gun_type_index = 0x0070;
+short __gun_type_index_jp = 0x0076;
 short __cmp_gun_type_index = 0x0080;
+short __cmp_gun_type_index_jp = 0x0086;
 short __qr_code_pre = 0x0280;
 
 short __batt_map_empty = 0x0090;
 
+//LW_tpc plug detect
+short __tpc_detect_map = 0x0092;
+
 short __conn_line_chag = 0x0096;
 short __batt_map = 0x0100;
 short __soc_value_charging = 0x0102;
@@ -165,6 +170,40 @@ short __eth0_ip_value = 0x0370;
 short __sn_string = 0x0410;
 short __sn_value = 0x0420;
 
+short __sys_date_value = 0x0470;
+short __sys_time_value = 0x0480;
+short __sys_period_value = 0x0489;
+
+short __Energy_Cost_complete = 0x0500;
+short __Parking_Fee_complete = 0x0510;
+short __Total_Cost_complete = 0x0520;
+short __ctep_time_string = 0x0530;
+short __ctep_energy_string = 0x0540;
+short __ctep_energy_mon_string = 0x0550;
+short __ctep_packing_mon_string = 0x0560;
+short __ctep_total_mon_string = 0x0570;
+
+short __Energy_Cost_charging = 0x610;
+short __Parking_Fee_charging = 0x620;
+short __Total_Cost_charging = 0x630;
+
+short __Energy_Cost_comp = 0x640;
+short __Parking_Fee_comp = 0x650;
+short __Total_Cost_comp = 0x660;
+short __receipt_qrcode = 0x0670;
+short __receipt_qrcode_bg = 0x0700;
+short _ctep_energy_mon_comm = 0x0702;
+short _ctep_packing_mon_comm = 0x0704;
+short _ctep_total_mon_comm = 0x0706;
+short _ctep_energy_mon_chg = 0x0708;
+short _ctep_packing_mon_chg = 0x070A;
+short _ctep_total_mon_chg = 0x070C;
+short _ctep_energy_mon_comp = 0x070E;
+short _ctep_packing_mon_comp = 0x0710;
+short _ctep_total_mon_comp = 0x0712;
+
+short __scroll_display_value = 0x6010;
+
 // ICON ID
 byte _disappear = 0;
 byte _disconnect = 1;
@@ -233,3 +272,26 @@ byte _battery_eng_trp_map = 63;
 byte _money_trp_map = 64;
 byte _elapse_time_trp_map = 65;
 byte _phihong_string_map = 66;
+byte _ctep_qr_background = 67;
+byte _ctep_packing_mon_comm_map = 68;
+byte _ctep_energy_mon_comm_map = 69;
+byte _ctep_total_mon_comm_map = 70;
+byte _ctep_packing_mon_comp_map = 71;
+byte _ctep_energy_mon_comp_map = 72;
+byte _ctep_total_mon_comp_map = 73;
+byte _ctep_packing_mon_chg_map= 74;
+byte _ctep_energy_mon_chg_map = 75;
+byte _ctep_total_mon_chg_map = 76;
+
+//LW_tpc plug detect
+byte _tpc_start_detect_btn = 77;
+byte _tpc_wait_plugin_btn= 78;
+
+byte _n1_jp_cha_dark = 96;
+byte _n2_jp_cha_dark = 97;
+byte _n1_jp_cha_light = 98;
+byte _n2_jp_cha_light = 99;
+byte _n1_jp_cha_dark_cmp = 100;
+byte _n2_jp_cha_dark_cmp = 101;
+byte _n1_jp_cha_light_cmp = 102;
+byte _n2_jp_cha_light_cmp = 103;

BIN
EVSE/Projects/DS60-120/Apps/Module_LcmControl


+ 86 - 13
EVSE/Projects/DS60-120/Apps/Module_LcmControl.c

@@ -44,7 +44,7 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
 			tm->tm_year+1900,tm->tm_mon+1,
@@ -1329,6 +1329,17 @@ void ProcessPageInfo()
 			{
 				ChangeDisplay2Value(__sel_gun_btn, _disappear);
 			}
+
+			//LW_tpc plug detect
+			if (ShmDcCommonData->TpcDetectFunction == YES)
+			{
+				if (ShmDcCommonData->_tpcPlugDetectState == _TPC_PLUG_DETECT_STATUS_NONE)
+					ChangeDisplay2Value ( __tpc_detect_map, _tpc_start_detect_btn );
+				else if (ShmDcCommonData->_tpcPlugDetectState == _TPC_PLUG_DETECT_STATUS_WAIT)
+					ChangeDisplay2Value ( __tpc_detect_map, _tpc_wait_plugin_btn );
+			}
+			else
+				ChangeDisplay2Value ( __tpc_detect_map, _disappear );
 		}
 			break;
 		case _LCM_AUTHORIZING:
@@ -1476,6 +1487,7 @@ void ProcessPageInfo()
 			}
 			else
 			{
+				// 超過一把槍, 把中間圖隱藏
 				if (_totalCount > 1)
 				{
 					gunTargetIndex = 2;
@@ -1488,7 +1500,7 @@ void ProcessPageInfo()
 			for(byte i = 0; i < _totalCount; i++)
 			{
 				if (_totalCount == 1 && acgunCount <= 0)
-					gunTargetIndex = 2;
+					gunTargetIndex = 1;
 				else
 					gunTargetIndex = i;
 
@@ -1498,17 +1510,57 @@ void ProcessPageInfo()
 					{
 						if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i && !isShowAc)
 						{
-							if (_currentPage == _LCM_COMPLETE)
-								ChangeDisplay2Value(__cmp_gun_type_index + (gunTargetIndex * 2), _chademo_light_cmp);
+							if (_totalCount >= 2 && ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI)
+							{
+								if (_currentPage == _LCM_COMPLETE)
+								{
+									if (i == 0)
+										ChangeDisplay2Value(__cmp_gun_type_index_jp + (gunTargetIndex * 2), _n1_jp_cha_light_cmp);
+									else
+										ChangeDisplay2Value(__cmp_gun_type_index_jp + (gunTargetIndex * 2), _n2_jp_cha_light_cmp);
+								}
+								else
+								{
+									if (i == 0)
+										ChangeDisplay2Value(__gun_type_index_jp + (gunTargetIndex * 2), _n1_jp_cha_light);
+									else
+										ChangeDisplay2Value(__gun_type_index_jp + (gunTargetIndex * 2), _n2_jp_cha_light);
+								}
+							}
 							else
-								ChangeDisplay2Value(__gun_type_index + (gunTargetIndex * 2), _chademo_light);
+							{
+								if (_currentPage == _LCM_COMPLETE)
+									ChangeDisplay2Value(__cmp_gun_type_index + (gunTargetIndex * 2), _chademo_light_cmp);
+								else
+									ChangeDisplay2Value(__gun_type_index + (gunTargetIndex * 2), _chademo_light);
+							}
 						}
 						else
 						{
-							if (_currentPage == _LCM_COMPLETE)
-								ChangeDisplay2Value(__cmp_gun_type_index + (gunTargetIndex * 2), _chademo_dark_cmp);
+							if (_totalCount >= 2 && ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_JARI)
+							{
+								if (_currentPage == _LCM_COMPLETE)
+								{
+									if (i == 0)
+										ChangeDisplay2Value(__cmp_gun_type_index_jp + (gunTargetIndex * 2), _n1_jp_cha_dark_cmp);
+									else
+										ChangeDisplay2Value(__cmp_gun_type_index_jp + (gunTargetIndex * 2), _n2_jp_cha_dark_cmp);
+								}
+								else
+								{
+									if (i == 0)
+										ChangeDisplay2Value(__gun_type_index_jp + (gunTargetIndex * 2), _n1_jp_cha_dark);
+									else
+										ChangeDisplay2Value(__gun_type_index_jp + (gunTargetIndex * 2), _n2_jp_cha_dark);
+								}
+							}
 							else
-								ChangeDisplay2Value(__gun_type_index + (gunTargetIndex * 2), _chademo_dark);
+							{
+								if (_currentPage == _LCM_COMPLETE)
+									ChangeDisplay2Value(__cmp_gun_type_index + (gunTargetIndex * 2), _chademo_dark_cmp);
+								else
+									ChangeDisplay2Value(__gun_type_index + (gunTargetIndex * 2), _chademo_dark);
+							}
 						}
 					}
 						break;
@@ -1584,7 +1636,7 @@ void ProcessPageInfo()
 								strcmp((char *)_chargingInfoData[i]->StartUserId, "") == 0 ||
 								ShmSysConfigAndInfo->SysConfig.StopChargingByButton == YES ||
 								_chargingInfoData[i]->isRemoteStart ||
-								ShmDcCommonData->_authWithCcidFlag [i] == _CCID_AUTHCOMP)
+								ShmDcCommonData->enObtainAuthorizbyCCID)
 							ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn);
 						else
 							ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
@@ -1858,6 +1910,15 @@ void DefaultIconStatus()
 	for(byte i = 0; i < 3; i++)
 		ChangeDisplay2Value(__gun_type_index + (i * 2), _disappear);
 
+	for(byte i = 0; i < 3; i++)
+		ChangeDisplay2Value(__cmp_gun_type_index + (i * 2), _disappear);
+
+	for(byte i = 0; i < 2; i++)
+		ChangeDisplay2Value(__gun_type_index_jp + (i * 2), _disappear);
+
+	for(byte i = 0; i < 2; i++)
+		ChangeDisplay2Value(__cmp_gun_type_index_jp + (i * 2), _disappear);
+
 	if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES || _totalCount == 1)
 		ChangeDisplay2Value(__sel_gun_btn, _disappear);
 	else
@@ -1874,6 +1935,12 @@ void DefaultIconStatus()
 		ChangeDisplay2Value(__logo_cmp, _disappear);
 	}
 
+	//LW_tpc plug detects
+	if (ShmDcCommonData->TpcDetectFunction == YES)
+		ChangeDisplay2Value(__tpc_detect_map, _tpc_start_detect_btn);
+	else
+		ChangeDisplay2Value(__tpc_detect_map, _disappear);
+
 	char _buf[3] = {0};
 	memcpy(_buf, &ShmSysConfigAndInfo->SysConfig.ModelName[12], 2);
 
@@ -1914,9 +1981,13 @@ int main(void)
 
 	Initialization();
 
-	//	ChangeToOtherPage(_LCM_IDLE);
-	//	ChangeDisplay2Value(__phihong_string, _disappear);
-	//	return -1;
+//	ChangeToOtherPage(_LCM_CHARGING);
+	//ChangeChargingPowerValue(1.1);
+	//ChangeChargingEnergyValue(3.225);
+//	ChangeDisplay2Value(__phihong_string, _disappear);
+
+	///ChangeDisplayMoneyInfo();
+//	ChangeToOtherPage(_LCM_INIT);
 
 	DefaultIconStatus();
 
@@ -1947,7 +2018,7 @@ int main(void)
 
 			if (_verShowCount > 0)
 			{
-				PRINTF_FUNC("LCM Version = V.%03d \n", ShmDcCommonData->LcmFwVersion);
+				//PRINTF_FUNC("LCM Version = V.%03d \n", ShmDcCommonData->LcmFwVersion);
 				_verShowCount--;
 			}
 
@@ -1979,11 +2050,13 @@ int main(void)
 
 				ChangeWarningFunc();
 			}
+
 			// 頁面資訊處理
 			ProcessPageInfo();
 
 			// 網路 - wifi - 連線訊號處理
 			RefreshConnStatus();
+
 			// 換頁處理
 			GetCurrentPage();
 			ChangeCurPage();

BIN
EVSE/Projects/DS60-120/Apps/Module_PrimaryComm


+ 3 - 5
EVSE/Projects/DS60-120/Apps/Module_PrimaryComm.c

@@ -99,7 +99,7 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
 			tm->tm_year+1900,tm->tm_mon+1,
@@ -403,9 +403,7 @@ void GetMeterConsumption(byte index)
 				// 最大充時,兩個都會累加,但只輸出給一槍使用
 				ShmCsuMeterData->_meter[index]._chargingValue += ShmCsuMeterData->_meter[index].newMeterValue - ShmCsuMeterData->_meter[index].curMeterValue;
 
-				if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
-					(ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
-					ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_RELAY_A_TO_M))
+				if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_NORMAL)
 				{
 					for (byte subIndex = 0; subIndex < gun_count; subIndex++)
 					{
@@ -667,7 +665,7 @@ int main(void)
 		// 模組更新 FW 後,需重新做
 		if(ShmPrimaryMcuData->SelfTest_Comp != PASS)
 		{
-			PRINTF_FUNC("(407) Get Fw and Hw Ver. \n");
+			//PRINTF_FUNC("(407) Get Fw and Hw Ver. \n");
 			GetFwAndHwVersion();
 			sleep(1);
 			ShmPrimaryMcuData->SelfTest_Comp = PASS;

BIN
EVSE/Projects/DS60-120/Apps/Module_PsuComm


ファイルの差分が大きいため隠しています
+ 415 - 574
EVSE/Projects/DS60-120/Apps/Module_PsuComm.c


+ 12 - 11
EVSE/Projects/DS60-120/Apps/Module_PsuComm.h

@@ -34,7 +34,10 @@ typedef unsigned char 		byte;
 typedef unsigned short 	word;
 typedef unsigned int 		unit;
 
-unsigned char _gunCount;
+#define PSU_CUR_GAP			20 	// 0.1A
+#define LOG_TIME			5000 // 1ms
+
+unsigned char _gunCountRecord;
 struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 bool isStartOutputSwitch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
@@ -43,6 +46,8 @@ struct timespec _derating_time;
 struct timespec _max_time;
 struct timespec _log_time;
 
+byte _delayToGetCap;
+
 byte _maxChargingStatus;
 bool isReadyToCharging = false;
 int preChargingTarget;
@@ -51,13 +56,9 @@ int preChargingCur;
 float toAverVolPoint;
 byte toAverVolCount;
 
-byte _delayCount;
+int _forceWaitToCompforMaxMode;
 
-//int connector_1[12];
-//int connector_2[12];
-//int connector[2][12];
-//byte conn_1_count = 0;
-//byte conn_2_count = 0;
+byte _delay2GetPsuTemp;
 
 enum _CHARGING_GUN_STATUS
 {
@@ -73,10 +74,10 @@ enum _PSU_CMD_SEQ
 	_PSU_CMD_VERSION	= 2,
 
 	_PSU_CMD_CAP		= 10,
-	_PSU_CMD_OUTPUT		= 11,
-	_PSU_CMD_IVAILIABLE	= 12,
-	_PSU_CMD_TEMP		= 13,
-	_PSU_CMD_GETCOUNT	= 14,
+	_PSU_CMD_IAVAILABLE	= 11,
+	_PSU_CMD_TEMP		= 12,
+	_PSU_CMD_GETCOUNT	= 13,
+	_PSU_CMD_OUTPUT_V	= 14,
 };
 
 enum _CHARGING_LOG_INDEX

BIN
EVSE/Projects/DS60-120/Apps/Module_SmartBox


+ 1475 - 0
EVSE/Projects/DS60-120/Apps/Module_SmartBox.c

@@ -0,0 +1,1475 @@
+/*
+ * Module_SmartBox.c
+ *
+ *  Created on: 2022年5月3日
+ *      Author: 7564
+ */
+
+#include "Module_SmartBox.h"
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+struct PsuData 					*ShmPsuData;
+struct DcCommonInformation		*ShmDcCommonData;
+struct SmartBoxData				*ShmSmartBoxData;
+
+struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+byte ConnectorUsingSeq[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY][4] =
+{{0, 2, 3, 1}, {1, 3, 2, 0}};
+
+struct timespec _log_time;
+
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	va_list args;
+	struct timeb  SeqEndTime;
+	struct tm *tm;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	ftime(&SeqEndTime);
+	SeqEndTime.time = time(NULL);
+	tm=localtime(&SeqEndTime.time);
+
+	if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
+	{
+		sprintf(Buf,"%02d:%02d:%02d:%03d - %s",
+			tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm, buffer);
+		printf("%s \n", Buf);
+	}
+	else
+	{
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
+			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
+			buffer,
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
+		system(Buf);
+	}
+
+	return rc;
+}
+
+void PRINTF_FUNC(char *string, ...)
+{
+	va_list args;
+	char buffer[4096];
+	va_start(args, string);
+	vsnprintf(buffer, sizeof(buffer), string, args);
+	va_end(args);
+
+	DEBUG_INFO("%s ", buffer);
+}
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//creat ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmSysConfigAndInfoKey NG %d \n");
+		#endif
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
+		#endif
+    	result = FAIL;
+   	}
+
+   	//creat ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmStatusCodeKey NG \n");
+		#endif
+   		result = FAIL;
+	}
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
+		#endif
+    	result = FAIL;
+   	}
+
+   	//creat ShmPsuData
+	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmPsuKey NG \n");
+		#endif
+		result = FAIL;
+	}
+	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmat ShmPsuData NG \n");
+		#endif
+		result = FAIL;
+	}
+
+	if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
+	{
+		#ifdef SystemLogMessage
+	   	DEBUG_ERROR("shmget ShmCommonKey NG \n");
+	   	#endif
+	   	result = FAIL;
+	}
+	else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		#ifdef SystemLogMessage
+	   	DEBUG_ERROR("shmat ShmDcCommonData NG \n");
+	   	#endif
+	   	result = FAIL;
+	}
+
+	if ((MeterSMId = shmget ( ShmSmartBoxKey, sizeof(struct SmartBoxData), IPC_CREAT | 0777 )) < 0)
+	{
+		#ifdef SystemLogMessage
+	   	DEBUG_ERROR("shmat ShmSmartBoxKey NG \n");
+	   	#endif
+		return FAIL;
+	}
+	else if ((ShmSmartBoxData = shmat ( MeterSMId, NULL, 0 )) == (void *) - 1)
+	{
+		#ifdef SystemLogMessage
+	   	DEBUG_ERROR("shmat ShmSmartBoxData NG \n");
+	   	#endif
+		return FAIL;
+	}
+
+    return result;
+}
+
+//==========================================
+// Public Function
+//==========================================
+bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
+{
+	for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < CCS_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < GB_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void Initialization()
+{
+	bool isPass = false;
+	while(!isPass)
+	{
+		isPass = true;
+		for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+		{
+			if (!FindChargingInfoData(_index, &chargingInfo[0]))
+			{
+				DEBUG_ERROR("SmartBox (main) : FindChargingInfoData false \n");
+				isPass = false;
+				break;
+			}
+		}
+		sleep(1);
+	}
+
+	for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+	{
+		ShmSmartBoxData->Dynamic4Fetch[_index].ShareGroup = NONE_GROUP_CAN_SELECTED;
+		ShmSmartBoxData->Dynamic4Fetch[_index].TargetRelay = NONE_RELAY_SELECTED;
+		ShmSmartBoxData->Dynamic4Fetch[_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_NONE;
+
+		ShmSmartBoxData->Dynamic4Release[_index].ReleaseGroup = NONE_GROUP_CAN_SELECTED;
+		ShmSmartBoxData->Dynamic4Release[_index].TargetRelay = NONE_RELAY_SELECTED;
+		ShmSmartBoxData->Dynamic4Release[_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
+
+		ShmSmartBoxData->ConnectorUsingGroupCount[_index] = 0;
+	}
+}
+
+void PrintfLog()
+{
+	if (ShmPsuData->Work_Step != _WORK_CHARGING)
+	{
+		PRINTF_FUNC ( "****************************************************************** \n" );
+		PRINTF_FUNC ( "SystemPresentPsuQuantity = %d \n", ShmPsuData->SystemPresentPsuQuantity);
+		PRINTF_FUNC ( "SystemAvailableCurrent = %d (A) \n", ShmPsuData->SystemAvailableCurrent / 10);
+		PRINTF_FUNC ( "SystemAvailablePower = %d (kw) \n", ShmPsuData->SystemAvailablePower / 10);
+		PRINTF_FUNC ( "GroupCount = %d \n", ShmPsuData->GroupCount );
+
+		for (int _count = 0; _count < ARRAY_SIZE(ConnectorUsingSeq[0]); _count ++)
+		{
+			PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
+			PRINTF_FUNC ( "Group Index = %d, UsingTarget for Gun-%d \n", _count, ShmPsuData->PsuGroup[_count].UsingTarget);
+			PRINTF_FUNC ( "GroupPresentPsuQuantity = %d \n", ShmPsuData->PsuGroup[_count].GroupPresentPsuQuantity );
+			PRINTF_FUNC ( "GroupTargetOutputVoltage = %d (V) \n", ShmPsuData->PsuGroup[_count].GroupTargetOutputVoltage / 10);
+			PRINTF_FUNC ( "GroupTargetOutputCurrent = %d (A) \n", ShmPsuData->PsuGroup[_count].GroupTargetOutputCurrent / 10);
+			PRINTF_FUNC ( "GroupAvailableCurrent = %d (A) \n", ShmPsuData->PsuGroup[_count].GroupAvailableCurrent / 10);
+			PRINTF_FUNC ( "GroupAvailablePower = %d (kw) \n", ShmPsuData->PsuGroup[_count].GroupAvailablePower / 10);
+			PRINTF_FUNC ( "GroupMaxVoltage = %d (V) \n", ShmPsuData->PsuGroup[_count].GroupMaxVoltage / 10);
+			PRINTF_FUNC ( "GroupPresentOutputVoltage = %.1f (V) \n", (double)ShmPsuData->PsuGroup[_count].GroupPresentOutputVoltage / 10);
+			PRINTF_FUNC ( "GroupPresentOutputCurrent = %.1f (A) \n", (double)ShmPsuData->PsuGroup[_count].GroupPresentOutputCurrent / 10);
+			PRINTF_FUNC ( "GroupPresentOutputPower = %d \n", ShmPsuData->PsuGroup[_count].GroupPresentOutputPower );
+			PRINTF_FUNC ( "TotalRatingPower = %f \n", (double)ShmPsuData->PsuGroup[_count].TotalRatingPower);
+			PRINTF_FUNC ( "TotalIAvailableCurrent = %f \n", (double)ShmPsuData->PsuGroup[_count].TotalIAvailableCurrent / 10);
+		}
+	}
+	else
+	{
+		for (byte conn = 0; conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; conn++)
+		{
+			byte totalUsingGpCount = 0;
+			byte totalQuantity = 0;
+			unsigned short _targetVol = 0 , _targetCur = 0;
+			unsigned short _avaCur = 0 , _avaPow = 0;
+			unsigned short _outputVol = 0 , _outputCur = 0;
+			unsigned short _ratingPow = 0;
+
+			for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount[conn]; gp++)
+			{
+				if (ShmPsuData->PsuGroup[ConnectorUsingSeq[conn][gp]].UsingTarget == GUN_LEFT)
+				{
+					totalUsingGpCount++;
+					byte tarGp = ConnectorUsingSeq[conn][gp];
+
+					totalQuantity += ShmPsuData->PsuGroup[tarGp].GroupPresentPsuQuantity;
+					_targetVol = ShmPsuData->PsuGroup[tarGp].GroupTargetOutputVoltage / 10;
+					_targetCur += ShmPsuData->PsuGroup[tarGp].GroupTargetOutputCurrent / 10;
+					_avaCur += ShmPsuData->PsuGroup[tarGp].GroupAvailableCurrent / 10;
+					_avaPow += ShmPsuData->PsuGroup[tarGp].GroupAvailablePower / 10;
+					_outputVol = (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputVoltage / 10;
+					_outputCur = (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputCurrent / 10;
+					_ratingPow += ShmPsuData->PsuGroup[tarGp].TotalRatingPower;
+				}
+			}
+
+			if (totalUsingGpCount > 0)
+			{
+				PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
+				PRINTF_FUNC ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount);
+				PRINTF_FUNC ( "totalQuantity = %d \n", totalQuantity);
+				PRINTF_FUNC ( "_targetVol = %d (V), _targetCur = %d (A) \n", _targetVol, _targetCur);
+				PRINTF_FUNC ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow);
+				PRINTF_FUNC ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur);
+				PRINTF_FUNC ( "_ratingPow = %d \n", _ratingPow);
+			}
+
+			for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount[conn]; gp++)
+			{
+				if (ShmPsuData->PsuGroup[ConnectorUsingSeq[conn][gp]].UsingTarget == GUN_RIGHT)
+				{
+					totalUsingGpCount++;
+					byte tarGp = ConnectorUsingSeq[conn][gp];
+
+					totalQuantity += ShmPsuData->PsuGroup [tarGp].GroupPresentPsuQuantity;
+					_targetVol = ShmPsuData->PsuGroup [tarGp].GroupTargetOutputVoltage / 10;
+					_targetCur += ShmPsuData->PsuGroup [tarGp].GroupTargetOutputCurrent / 10;
+					_avaCur += ShmPsuData->PsuGroup [tarGp].GroupAvailableCurrent / 10;
+					_avaPow += ShmPsuData->PsuGroup [tarGp].GroupAvailablePower / 10;
+					_outputVol = (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputVoltage / 10;
+					_outputCur = (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputCurrent / 10;
+					_ratingPow += ShmPsuData->PsuGroup [tarGp].TotalRatingPower;
+				}
+			}
+
+			if (totalUsingGpCount > 0)
+			{
+				PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
+				PRINTF_FUNC ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount);
+				PRINTF_FUNC ( "totalQuantity = %d \n", totalQuantity);
+				PRINTF_FUNC ( "_targetVol = %d (V), _targetCur = %d (A) \n", _targetVol, _targetCur);
+				PRINTF_FUNC ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow);
+				PRINTF_FUNC ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur);
+				PRINTF_FUNC ( "_ratingPow = %d \n", _ratingPow);
+			}
+		}
+	}
+}
+
+void GetSystemMaxVoltage()
+{
+	if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
+	{
+		int _sysVol = 0;
+
+		for (byte group = 0; group < ShmPsuData->GroupCount; group++)
+		{
+			if (ShmPsuData->PsuGroup[group].GroupMaxVoltage > _sysVol)
+				_sysVol = ShmPsuData->PsuGroup[group].GroupMaxVoltage;
+		}
+
+		for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
+		{
+			if (chargingInfo[gun_index]->MaximumChargingVoltage != _sysVol)
+			{
+				chargingInfo[gun_index]->MaximumChargingVoltage = _sysVol;
+			}
+		}
+	}
+}
+
+void GetTimespecFunc(struct timespec *time)
+{
+	clock_gettime(CLOCK_MONOTONIC, time);
+}
+
+long int GetTimeoutValue(struct timespec *startTime)
+{
+	struct timespec endTime;
+
+	clock_gettime(CLOCK_MONOTONIC, &endTime);
+	return 1000 * (endTime.tv_sec - startTime->tv_sec) + (endTime.tv_nsec - startTime->tv_nsec) / 1000000;
+}
+
+//==========================================
+// Relay Processing
+//==========================================
+void SmartRelayCheck()
+{
+	/*
+	---------------------------------------
+	G_0 -----------(R1)----------------> Gun - 0
+				| -> R3
+	G_2 --------|
+				| -> R4
+	G_3 --------|
+				| -> R5
+	G_1 -----------(R2)----------------> Gun - 1
+	---------------------------------------
+	R3 ON 時機 : G_2 屬於 Gun-0 輸出、G_0屬於 Gun - 1 輸出
+	R4 ON 時機 : G_3 屬於 Gun-0 輸出、G_2屬於 Gun - 1 輸出
+	R5 ON 時機 : G_3 屬於 Gun-1 輸出、G_1屬於 Gun - 0 輸出
+	-------------------------
+	掃描PSU四個群及兩輸出的ShareGroup內的值各屬於哪個輸出
+	*/
+	byte _buff[3] = {0};
+
+	for (byte group = 0; group < ShmPsuData->GroupCount; group++)
+	{
+		switch(group)
+		{
+			case _PSU_GROUP_INDEX_0:
+			{
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
+				{
+					// 如果是標準品
+					if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+					{
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+						_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+					}
+					else
+					{
+						// R3 ON
+						_buff[_RELAY_SWITCH_NAME_R3] = 0x01;
+					}
+				}
+			}
+				break;
+			case _PSU_GROUP_INDEX_2:
+			{
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
+				{
+					// R3 ON
+					_buff[_RELAY_SWITCH_NAME_R3] = 0x01;
+				}
+
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
+				{
+					// R4 ON
+					_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+				}
+			}
+				break;
+			case _PSU_GROUP_INDEX_3:
+			{
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
+				{
+					// R4 ON
+					_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+				}
+
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
+				{
+					// R5 ON
+					_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+				}
+			}
+				break;
+			case _PSU_GROUP_INDEX_1:
+			{
+				if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
+				{
+					// 如果是標準品
+					if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+					{
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+						_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+					}
+					else
+					{
+						// R5 ON
+						_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+					}
+				}
+			}
+				break;
+		}
+	}
+
+	for (byte _Conn = 0; _Conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _Conn++)
+	{
+		if (ShmSmartBoxData->Dynamic4Fetch[_Conn].FetchLoopStep >= _PSU_DYNAMIC_FETCH_STEP_RELAY)
+		{
+			byte targetGroup = ShmSmartBoxData->Dynamic4Fetch[_Conn].ShareGroup;
+
+			switch(targetGroup)
+			{
+				case _PSU_GROUP_INDEX_0:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// 如果是標準品
+						if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+						{
+							_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+							ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+						}
+						else
+						{
+							// R3 ON -- P
+							_buff[_RELAY_SWITCH_NAME_R3] = 0x01;
+							ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
+						}
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_2:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// R3 ON -- P
+						_buff[_RELAY_SWITCH_NAME_R3] = 0x01;
+						ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
+					}
+
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// R4 ON -- P
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+						ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_3:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// R4 ON -- P
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+						ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+					}
+
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// R5 ON -- P
+						_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+						ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_1:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// 如果是標準品
+						if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+						{
+							_buff[_RELAY_SWITCH_NAME_R4] = 0x01;
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+							ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+						}
+						else
+						{
+							// R5 ON -- P
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x01;
+							ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
+						}
+					}
+				}
+					break;
+			}
+		}
+
+		if (ShmSmartBoxData->Dynamic4Release[_Conn].ReleaseLoopStep >= _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF)
+		{
+			byte targetGroup = ShmSmartBoxData->Dynamic4Release[_Conn].ReleaseGroup;
+
+			switch(targetGroup)
+			{
+				case _PSU_GROUP_INDEX_0:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// R3 OFF
+						_buff[_RELAY_SWITCH_NAME_R3] = 0x00;
+						ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
+
+						// 如果是標準品
+						if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+						{
+							_buff[_RELAY_SWITCH_NAME_R4] = 0x00;
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x00;
+							ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+						}
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_2:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// R3 OFF
+						_buff[_RELAY_SWITCH_NAME_R3] = 0x00;
+						ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
+					}
+
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// R5 OFF
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x00;
+						ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_3:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// R4 OFF
+						_buff[_RELAY_SWITCH_NAME_R4] = 0x00;
+						ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+					}
+
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
+					{
+						// R5 OFF
+						_buff[_RELAY_SWITCH_NAME_R5] = 0x00;
+						ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
+					}
+				}
+					break;
+				case _PSU_GROUP_INDEX_1:
+				{
+					if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
+					{
+						// 如果是標準品
+						if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+						{
+							_buff[_RELAY_SWITCH_NAME_R4] = 0x00;
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x00;
+							ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
+						}
+						else
+						{
+							// R4 OFF
+							_buff[_RELAY_SWITCH_NAME_R5] = 0x00;
+							ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
+						}
+					}
+				}
+					break;
+			}
+		}
+	}
+
+	memcpy(ShmSmartBoxData->ParallelRelayStatus, _buff, sizeof(_buff));
+}
+
+//==========================================
+// Sub Processing
+//==========================================
+void Assign2ConnectorProcessing(byte _targetConn)
+{
+	// 根據現在該槍拿到的群數量, 依順去設定群的使用目標為左 /右槍
+	// 一旦設定該模塊目標為左 /右槍後,AssignedPwr2Connector function 會將該模塊的資訊給對應的左/右槍
+	for (byte aGp = 0; aGp < ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]; aGp++)
+	{
+		if (ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][aGp]].IsUsing == YES)
+		{
+			ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][aGp]].UsingTarget = _targetConn;
+		}
+	}
+}
+
+// 將_group該群的模塊配給_targetConn槍號
+void AddGroup2Connector(byte _targetConn, byte _group)
+{
+	ShmPsuData->PsuGroup[_group].IsUsing = YES;
+	if ((ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES && _targetConn == GUN_RIGHT) ||
+			(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD && ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn] > 0))
+		ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn] = 4;
+	else
+		ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]++;
+	// 對應到相對群
+	Assign2ConnectorProcessing(_targetConn);
+}
+
+// 將targetGp該群的模塊從_targetConn槍號移除
+bool ReleaseConnectorProcessing(byte _targetConn, byte targetGp)
+{
+	bool result = false;
+
+	if (ShmPsuData->PsuGroup[targetGp].PwSwitchStatus == _PSU_POWER_STATUS_OFF)
+	{
+		result = true;
+		ShmPsuData->PsuGroup[targetGp].UsingTarget = GUN_CHECK;
+		ShmPsuData->PsuGroup[targetGp].IsUsing = NO;
+		ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]--;
+	}
+
+	return result;
+}
+
+//==========================================
+// Fetch fork
+//==========================================
+void InitializeDynamicFetch(byte _targetConn)
+{
+	ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup = NONE_GROUP_CAN_SELECTED;
+	ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay = NONE_RELAY_SELECTED;
+	ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent = 0;
+	ShmSmartBoxData->SmartChk[_targetConn].IsFetchStart = NO;
+}
+
+void FetchLoopProcessing(byte _targetConn)
+{
+	byte targetGroup = ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup;
+	if (targetGroup == NONE_GROUP_CAN_SELECTED &&
+			ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep >= _PSU_DYNAMIC_FETCH_STEP_TG_VOL)
+	{
+		ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
+	}
+
+	// 用 target vol 比較好還是用當前火線電壓 ? 可以試試看~
+	float EvVoltage = chargingInfo[_targetConn]->EvBatterytargetVoltage * 10;
+
+	switch(ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep)
+	{
+		case _PSU_DYNAMIC_FETCH_STEP_NONE:
+		case _PSU_DYNAMIC_FETCH_STEP_WAIT:{ } break;
+		case _PSU_DYNAMIC_FETCH_STEP_TG_VOL:
+		{
+			// 該群升壓
+			if (ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage != 0)
+			{
+				PRINTF_FUNC("EV_ReqVoltage = %f, targetGroup = %d, Group_CurVoltage = %d \n",
+						EvVoltage, targetGroup, ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage);
+			}
+
+			if (EvVoltage <= PSU_MIN_VOL)
+			{
+				PRINTF_FUNC("***** FETCH_STEP_ABORT ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
+			}
+			else if (ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage >= EvVoltage - PSU_TG_VOL_GAP)
+			{
+				PRINTF_FUNC("***** FETCH_STEP_RELAY ***** (Gun - %d) \n", _targetConn);
+				ShmPsuData->PsuGroup[targetGroup].UsingTarget = _targetConn;
+				ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_RELAY;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_FETCH_STEP_RELAY:
+		{
+			// 搭上對應的 Relay
+			if (ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay < ARRAY_SIZE(ShmSmartBoxData->ParallelRelayStatus))
+			{
+				if (ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay] == YES)
+				{
+					if (ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay] == YES)
+					{
+						PRINTF_FUNC("***** FETCH_STEP_CUR_SHARE ***** (Gun - %d) \n", _targetConn);
+						ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_CUR_SHARE;
+					}
+				}
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_FETCH_STEP_CUR_SHARE:
+		{
+			// 均流 : 目標電流 = 當前電流 / (原本輸出群個數 + share group 個數)
+			PRINTF_FUNC("GroupPresent = %d (0.1A), ShareTarget = %d (0.1A), CurrentPresent = %.1f \n",
+					ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent,
+					ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent,
+					chargingInfo[_targetConn]->PresentChargingCurrent);
+
+			if ((ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent >= ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent - PSU_TG_CUR_GAP &&
+					ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent <= ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent + PSU_TG_CUR_GAP) ||
+					chargingInfo[_targetConn]->PresentChargingCurrent <= PSU_MIN_CUR)
+			{
+				PRINTF_FUNC("***** FETCH_STEP_WATI_FINISH ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_WATI_FINISH;
+			}
+
+		}
+			break;
+		case _PSU_DYNAMIC_FETCH_STEP_WATI_FINISH:
+		{
+			AddGroup2Connector(_targetConn, targetGroup);
+			GetTimespecFunc(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
+			PRINTF_FUNC("***** FETCH_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
+			ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup = NONE_GROUP_CAN_SELECTED;
+			ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
+		}
+			break;
+		case _PSU_DYNAMIC_FETCH_STEP_FINISH:
+		{
+			// 完成
+			int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
+
+			if (_t >= FETCH_FINISH_WAIT_TIME)
+			{
+				InitializeDynamicFetch(_targetConn);
+				PRINTF_FUNC("***** FETCH_STEP_NONE ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_NONE;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_FETCH_STEP_ABORT:
+		{
+			// 中斷
+			if (ShmPsuData->PsuGroup[targetGroup].IsUsing)
+			{
+				ShmPsuData->PsuGroup[targetGroup].IsUsing = NO;
+				ShmPsuData->PsuGroup[targetGroup].UsingTarget = GUN_CHECK;
+			}
+
+			GetTimespecFunc(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
+			ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
+		}
+			break;
+	}
+}
+
+byte CheckRemainPwrByConIndex(byte _targetConn)
+{
+	byte result = NONE_GROUP_CAN_SELECTED;
+
+	// 該槍已經使用的群數量
+	byte usingCount = ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn];
+
+	for (byte Gp = usingCount; Gp < ARRAY_SIZE(ConnectorUsingSeq[_targetConn]); Gp++)
+	{
+		// 判斷是否有該槍下一個可用群的狀態
+		if (ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][Gp]].IsUsing == NO &&
+				ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][Gp]].GroupPresentPsuQuantity > 0)
+		{
+			result = ConnectorUsingSeq[_targetConn][Gp];
+			break;
+		}
+	}
+
+	return result;
+}
+
+void Chk2StopFetchStep(byte _targetConn)
+{
+	// 開始流程後,就讓流程走完吧~
+	if (ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep > _PSU_DYNAMIC_FETCH_STEP_NONE &&
+			ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep < _PSU_DYNAMIC_FETCH_STEP_TG_VOL)
+	{
+		PRINTF_FUNC("***** FETCH_STEP_ABORT ***** (Gun - %d) \n", _targetConn);
+		ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
+	}
+}
+
+void FetchFork()
+{
+	pid_t fetchPid;
+
+	fetchPid = fork();
+
+	if(fetchPid > 0)
+	{
+		bool isPass = false;
+		struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+
+		while(!isPass)
+		{
+			isPass = true;
+			for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+			{
+				if (!FindChargingInfoData(_index, &_chargingData[0]))
+				{
+					DEBUG_ERROR("Smartbox (FetchFork) : FindChargingInfoData false \n");
+					isPass = false;
+					break;
+				}
+			}
+			sleep(1);
+		}
+
+		while(1)
+		{
+			for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
+			{
+				if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE ||
+						chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION ||
+						chargingInfo[gun_index]->SystemStatus == SYS_MODE_MAINTAIN ||
+						chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT)
+				{
+					ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = NO;
+
+					if (ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus != _CONNECTOR_STATUS_NONE)
+						ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_NONE;
+				}
+				// 對充電邏輯來說,充電槍只提需求
+				else if (chargingInfo[gun_index]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK &&
+						chargingInfo[gun_index]->SystemStatus <= SYS_MODE_REASSIGN)
+				{
+					// 判斷該群是否被使用中
+					if (ShmPsuData->PsuGroup[gun_index].IsUsing)
+					{
+						// 如果使用中 : 等待把這顆模塊切出
+						ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_WAIT;
+					}
+					else
+					{
+						// 直接同意該群後輸出
+						InitializeDynamicFetch(gun_index);
+						ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_USING;
+					}
+				}
+				else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_PREPARING)
+				{
+					// 這個階段只會拿到屬於該槍的模塊群
+					if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES && gun_index == GUN_RIGHT)
+					{
+						// 壁掛 : 強制使用第零群
+					    AddGroup2Connector(gun_index, _PSU_GROUP_INDEX_0);
+					}
+					else
+					{
+						if (!ShmPsuData->PsuGroup[gun_index].IsUsing)
+						{
+							// 第一個 : Gun index
+							// 第二個 : Psu Group index
+							AddGroup2Connector(gun_index, gun_index);
+						}
+					}
+				}
+				else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_CHARGING)
+				{
+					// 如果當前輸出接近實際可提供的能量 (距離 <= CAP_GAP_FETCH <3KW>)
+					// 不取 EvBatterytargetVoltage 原因是小板會將該值做不同的處理方式
+					float needPower = chargingInfo[gun_index]->PresentChargingVoltage *
+							chargingInfo[gun_index]->EvBatterytargetCurrent / 100;
+					// 判斷是否可以及需要提供多餘群輸出
+					byte chkRemainGp = NONE_GROUP_CAN_SELECTED;
+
+					if (ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup == NONE_GROUP_CAN_SELECTED)
+						chkRemainGp = CheckRemainPwrByConIndex(gun_index);
+					else
+						chkRemainGp = ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup;
+
+					ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch =
+							(needPower > 0 && needPower >= chargingInfo[gun_index]->RealRatingPower - CAP_GAP_FETCH) ? true : false;
+
+					if (ShmDcCommonData->systemType != _SYSTEM_TYPE_SIMPLE &&
+							ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_NONE &&
+							((ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch &&
+							chkRemainGp != NONE_GROUP_CAN_SELECTED &&
+							ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep <= _PSU_DYNAMIC_FETCH_STEP_WAIT) ||
+							ShmDcCommonData->smartFetchRun[gun_index])
+							)
+					{
+						if (!ShmSmartBoxData->SmartChk[gun_index].IsFetchStart)
+						{
+							// 判斷是否可以及需要提供多餘群輸出
+							PRINTF_FUNC("Fetch Target = %d, Target Group = %d \n", gun_index, chkRemainGp);
+							// 鎖定目標群,動態分配開始
+							// 該群模塊即被鎖定, 預防另外一群也進入相同邏輯,預防搶同一個群的情形
+							ShmPsuData->PsuGroup[chkRemainGp].IsUsing = YES;
+
+							ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup = chkRemainGp;
+							PRINTF_FUNC("***** FETCH_STEP_WAIT ***** (Gun - %d) \n", gun_index);
+							ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_WAIT;
+
+							// 倒數進入動態分配邏輯 - Fetch loop
+							ShmSmartBoxData->SmartChk [gun_index].IsFetchStart = YES;
+							// 條件成立, 倒數 FETCH_SMART_CHK_TIME <5s>
+							GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].FetchLoopTime);
+						}
+						else
+						{
+							if (ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep == _PSU_DYNAMIC_FETCH_STEP_WAIT)
+							{
+								int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].FetchLoopTime);
+
+								if (_t >= FETCH_SMART_CHK_TIME)
+								{
+									PRINTF_FUNC("***** FETCH_STEP_TG_VOL ***** (Gun - %d) \n", gun_index);
+									ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_TG_VOL;
+
+									ShmDcCommonData->smartFetchRun[gun_index] = NO;
+								}
+							}
+						}
+					}
+					else
+					{
+						// 動態分配條件中斷
+						Chk2StopFetchStep(gun_index);
+					}
+				}
+				FetchLoopProcessing(gun_index);
+			}
+
+			usleep(200000);
+		}
+	}
+}
+
+//==========================================
+// Release fork
+//==========================================
+void InitializeDynamicRelease(byte _targetConn)
+{
+	ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseGroup = NONE_GROUP_CAN_SELECTED;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay = NONE_RELAY_SELECTED;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCurCap = 0;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap = 0;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur = 0;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr = 0;
+	ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
+}
+
+byte CheckReleasePwrByConIndex(byte _targetConn)
+{
+	byte result = NONE_GROUP_CAN_SELECTED;
+
+	// 該槍已經使用的群數量
+	byte usingCount = ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn];
+
+	// 不可把最後一個也拿來釋放
+	if (usingCount - 1 > 0)
+		result = ConnectorUsingSeq[_targetConn][usingCount - 1];
+
+	return result;
+}
+
+void ReleaseLoopProcessing(byte _targetConn)
+{
+	byte targetGroup = ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseGroup;
+
+	switch(ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep)
+	{
+		case _PSU_DYNAMIC_RELEASE_STEP_NONE:
+		case _PSU_DYNAMIC_RELEASE_STEP_WAIT: {} break;
+		case _PSU_DYNAMIC_RELEASE_STEP_LIMIT:
+		{
+			// 應該要通知可輸出的能量與電流
+//			PRINTF_FUNC("_targetConn = %d, LimitCurCap = %.1f, LimitPwrCap = %.1f \n",
+//					_targetConn,
+//					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCurCap,
+//					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap);
+
+			// 通知可輸出的能量與電流
+//			PRINTF_FUNC("_targetConn = %d, LimitCur = %.1f, LimitPwr = %.1f \n",
+//					_targetConn,
+//					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur,
+//					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr);
+
+			// 需求能量與電流
+//			PRINTF_FUNC("_targetConn = %d, Req Power = %.1f (kw), Req Vol. = %.1f, Req Cur. = %.1f, Present Cur = %.1f \n",
+//					_targetConn,
+//					(chargingInfo[_targetConn]->EvBatterytargetVoltage * chargingInfo[_targetConn]->EvBatterytargetCurrent) / 100,
+//					chargingInfo[_targetConn]->EvBatterytargetVoltage,
+//					chargingInfo[_targetConn]->EvBatterytargetCurrent,
+//					chargingInfo[_targetConn]->PresentChargingCurrent);
+
+			// if the current and power limits are below their capacity
+			if ((ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur <= ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCurCap &&
+					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr <= ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap) ||
+					chargingInfo[_targetConn]->PresentChargingCurrent * 10 <= PSU_LIMIT_CUR)
+			{
+				PRINTF_FUNC("***** RELEASE_STEP_PWROFF ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_PWROFF;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_RELEASE_STEP_PWROFF:
+		{
+//			PRINTF_FUNC("targetGroup = %d, PresentChargingCurrent = %.1f, LimitCur = %.1f \n",
+//				_targetConn,
+//				chargingInfo[_targetConn]->PresentChargingCurrent,
+//				ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur / 10);
+
+			// if the output current is below their capacity for 5s
+			int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].ReleaseLoopTime);
+
+			if (chargingInfo[_targetConn]->PresentChargingCurrent <=
+					ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur &&
+					_t >= WAIT_FOR_LIMIT_STABLE)
+			{
+				PRINTF_FUNC("***** RELEASE_STEP_RELAYOFF ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF:
+		{
+			// 釋放對應的 Relay
+			PRINTF_FUNC("TargetRelay (%d), targetGroup = %d, ParallelRelayStatus = (%d), RcbParallelStatus = (%d) \n",
+					ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay, targetGroup,
+					ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay],
+					ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay]);
+
+			if (ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay < ARRAY_SIZE(ShmSmartBoxData->ParallelRelayStatus))
+			{
+				if (ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay] == NO)
+				{
+					if (ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay] == NO)
+					{
+						PRINTF_FUNC("***** RELEASE_STEP_WATI_FINISH ***** (Gun - %d) \n", _targetConn);
+						ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH;
+					}
+				}
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH:
+		{
+			if(ReleaseConnectorProcessing(_targetConn, targetGroup))
+			{
+				GetTimespecFunc ( & ShmSmartBoxData->SmartChk [_targetConn].ReleaseLoopTime );
+				PRINTF_FUNC("***** RELEASE_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
+				InitializeDynamicRelease(_targetConn);
+				ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_FINISH;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_RELEASE_STEP_FINISH:
+		{
+			// 完成
+			int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].ReleaseLoopTime);
+
+			if (_t >= RELEASE_FINISH_WAIT_TIME)
+			{
+				PRINTF_FUNC("***** RELEASE_STEP_NONE ***** (Gun - %d) \n", _targetConn);
+				ShmSmartBoxData->SmartChk[_targetConn].IsReleaseStart = NO;
+				ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
+			}
+		}
+			break;
+		case _PSU_DYNAMIC_RELEASE_STEP_ABORT:
+		{
+			GetTimespecFunc(& ShmSmartBoxData->SmartChk [_targetConn].ReleaseLoopTime);
+			PRINTF_FUNC("***** RELEASE_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
+			InitializeDynamicRelease(_targetConn);
+			ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_FINISH;
+		}
+			break;
+	}
+}
+
+void Chk2StopReleaseStep(byte _targetConn)
+{
+	// 開始流程後,就讓流程走完吧~
+	if (ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup > _PSU_DYNAMIC_RELEASE_STEP_NONE &&
+			ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup < _PSU_DYNAMIC_RELEASE_STEP_LIMIT)
+	{
+		PRINTF_FUNC ( "***** RELEASE_STEP_ABORT ***** (Gun - %d) \n", _targetConn );
+		//ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup = _PSU_DYNAMIC_RELEASE_STEP_ABORT;
+	}
+	else
+		ShmSmartBoxData->SmartChk[_targetConn].IsReleaseStart = NO;
+}
+
+void ReleaseFork()
+{
+	pid_t releasePid;
+
+	releasePid = fork();
+
+	if(releasePid > 0)
+	{
+		bool isPass = false;
+		struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+
+		while(!isPass)
+		{
+			isPass = true;
+			for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+			{
+				if (!FindChargingInfoData(_index, &_chargingData[0]))
+				{
+					DEBUG_ERROR("Smartbox (ReleaseFork) : FindChargingInfoData false \n");
+					isPass = false;
+					break;
+				}
+			}
+			sleep(1);
+		}
+
+		while(1)
+		{
+			for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
+			{
+				if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_CHARGING)
+				{
+					// 釋出多餘群 : 要判斷所要釋出群所能提供的最大能量 RealRatingPower
+					// 先找到是否有下一個要釋出的群
+					byte releaseGp = CheckReleasePwrByConIndex(gun_index);
+					if (releaseGp != NONE_GROUP_CAN_SELECTED)
+					{
+						unsigned short releasePwr = ShmPsuData->PsuGroup[releaseGp].TotalRatingPower * 10;
+						float needPower = chargingInfo[gun_index]->PresentChargingVoltage *
+									chargingInfo[gun_index]->EvBatterytargetCurrent / 100;
+
+						if (chargingInfo[gun_index]->Type != _Type_Test &&
+								ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep == _PSU_DYNAMIC_FETCH_STEP_NONE &&
+								(ShmSmartBoxData->AnotherConnectorStatus[gun_index].ConnectorStaus == _CONNECTOR_STATUS_WAIT ||
+								(ShmSmartBoxData->AnotherConnectorStatus[gun_index].NeedToFetch &&
+									SMART_MODE && chargingInfo[gun_index]->_TakePsuGpCount > ShmDcCommonData->halfGroupCount) ||
+								(chargingInfo[gun_index]->RealRatingPower > 0 && releasePwr > 0 &&
+									needPower < chargingInfo[gun_index]->RealRatingPower - releasePwr - CAP_GAP_RELEASE) ||
+									ShmDcCommonData->smartReleaseRun[gun_index])
+									)
+						{
+							//PRINTF_FUNC("RealRatingPower = %d \n", chargingInfo[gun_index]->RealRatingPower);
+							//PRINTF_FUNC("releasePwr = %d, needPower = %f \n", releasePwr, needPower);
+
+							if (ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_NONE)
+							{
+								if (!ShmSmartBoxData->SmartChk[gun_index].IsReleaseStart)
+								{
+									PRINTF_FUNC("***** Entry release chk (Gun_%d).. ***** \n", gun_index);
+									ShmSmartBoxData->SmartChk[gun_index].IsReleaseStart = YES;
+									ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable = chargingInfo[gun_index]->PresentChargingPower;
+									GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
+								}
+								else
+								{
+									int _delayt = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
+
+									// 每五秒看一次輸出能量是否穩定, 穩定則進入分配
+									if (_delayt >= RELEASE_STABLE_CHK_TIME)
+									{
+										if (chargingInfo[gun_index]->PresentChargingPower >
+												ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable + STABLE_CAP_GAP)
+										{
+											ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable = chargingInfo[gun_index]->PresentChargingPower;
+											GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
+										}
+										else
+										{
+											// 進入穩定
+											PRINTF_FUNC("***** RELEASE_STEP_WAIT ***** \n");
+											ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_WAIT;
+											GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
+										}
+									}
+								}
+							}
+							else if (ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_WAIT)
+							{
+								int _delayt = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
+
+								// 每五秒看一次輸出能量是否穩定, 穩定則進入分配
+								if (_delayt >= RELEASE_SMART_CHK_TIME)
+								{
+									PRINTF_FUNC("***** RELEASE_STEP_LIMIT ***** \n");
+									ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseGroup = releaseGp;
+									ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_LIMIT;
+									ShmDcCommonData->smartReleaseRun[gun_index] = NO;
+								}
+							}
+						}
+						else
+						{
+							// 動態分配條件中斷
+							Chk2StopReleaseStep(gun_index);
+						}
+					}
+				}
+				else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE ||
+						chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT ||
+						chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION ||
+						(chargingInfo[gun_index]->SystemStatus >= SYS_MODE_TERMINATING &&
+							chargingInfo[gun_index]->SystemStatus <= SYS_MODE_ALARM))
+				{
+					if (ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus == _CONNECTOR_STATUS_NONE)
+					{
+						byte totoalUsingGpCount = ShmSmartBoxData->ConnectorUsingGroupCount[gun_index];
+
+						for (byte _gp = 0; _gp < totoalUsingGpCount; _gp++)
+						{
+							PRINTF_FUNC("ConnectorUsingSeq[%d][%d] = %d \n", gun_index, _gp, ConnectorUsingSeq[gun_index][_gp]);
+							ReleaseConnectorProcessing(gun_index, ConnectorUsingSeq[gun_index][_gp]);
+						}
+
+						if (ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup != NONE_GROUP_CAN_SELECTED &&
+								ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep < _PSU_DYNAMIC_FETCH_STEP_FINISH)
+							ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
+
+						ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
+					}
+
+					if (ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch)
+						ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = NO;
+				}
+
+				ReleaseLoopProcessing(gun_index);
+			}
+
+			usleep(200000);
+		}
+	}
+}
+
+//==========================================
+// Main Function
+//==========================================
+void TakeAnotherGunStatus(byte target)
+{
+	byte another = 0;
+
+	if (target == 0)
+		another = 1;
+
+	ShmSmartBoxData->AnotherConnectorStatus[another].ConnectorStaus = ShmSmartBoxData->ConnectorStatus[target].ConnectorStaus;
+	ShmSmartBoxData->AnotherConnectorStatus[another].NeedToFetch = ShmSmartBoxData->ConnectorStatus[target].NeedToFetch;
+}
+
+void AssignedPwr2Connector()
+{
+	for(byte _gun = 0; _gun < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _gun++)
+	{
+		byte usingGroupCount = 0;
+		float availablePwr = 0, availableCur = 0, iAvailableCur = 0, totalPsuCount = 0, kwAvailablePwr = 0;
+		float outputVol = 0, outputCur = 0;
+		float limitCur = 0, limitPwr = 0;
+
+		for (byte group = 0; group < ShmPsuData->GroupCount; group++)
+		{
+			if (ShmPsuData->PsuGroup[group].UsingTarget == _gun)
+			{
+				usingGroupCount++;
+				if (group != ShmSmartBoxData->Dynamic4Fetch[_gun].ShareGroup &&
+						(group != ShmSmartBoxData->Dynamic4Release[_gun].ReleaseGroup ||
+							ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep <= _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH))
+				{
+					availablePwr += ShmPsuData->PsuGroup[group].GroupAvailablePower;
+					availableCur += ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
+					iAvailableCur += ShmPsuData->PsuGroup[group].TotalIAvailableCurrent;
+					totalPsuCount += ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
+					if (ShmPsuData->PsuGroup[group].TotalRatingPower <= 15 ||
+							ShmPsuData->PsuGroup[group].TotalRatingPower > 30)
+						kwAvailablePwr += (ShmPsuData->PsuGroup[group].GroupAvailablePower) / 10;
+					else
+						kwAvailablePwr += ShmPsuData->PsuGroup[group].TotalRatingPower;
+				}
+
+				// Release Loop 用 : 實際上~ 電流會飄 ....
+				// 這段, 只取還要留住的模塊輸出電流與能量就好
+				if (group != ShmSmartBoxData->Dynamic4Release[_gun].ReleaseGroup &&
+						ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_LIMIT)
+				{
+					limitCur += ShmPsuData->PsuGroup[group].GroupTargetOutputCurrent;
+					limitPwr += ShmPsuData->PsuGroup[group].TotalRatingPower;
+				}
+
+				outputCur += ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
+
+				if (outputVol < ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage ||
+						outputVol == 0)
+					outputVol = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+			}
+		}
+
+		chargingInfo[_gun]->AvailableChargingPower = availablePwr;
+		chargingInfo[_gun]->AvailableChargingCurrent = availableCur;
+		chargingInfo[_gun]->DeratingChargingCurrent = iAvailableCur;
+		chargingInfo[_gun]->_TotalPsuCount = totalPsuCount;
+		chargingInfo[_gun]->PresentChargingVoltage = outputVol / 10;
+		chargingInfo[_gun]->PresentChargingCurrent = outputCur / 10;
+		chargingInfo[_gun]->RealRatingPower = kwAvailablePwr * 10;
+		chargingInfo[_gun]->_TakePsuGpCount = usingGroupCount;
+
+		// 雙槍需要記得另外一把槍的狀態
+		if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1)
+			TakeAnotherGunStatus(_gun);
+
+		// 取 Release group 的最大電流
+		if (ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_LIMIT)
+		{
+			ShmSmartBoxData->Dynamic4Release[_gun].LimitCurCap = limitCur;
+			ShmSmartBoxData->Dynamic4Release[_gun].LimitPwrCap = limitPwr * 10;
+		}
+	}
+}
+
+void CollectGroupInformation(byte group)
+{
+	int _groupPower = 0 , _groupCurrent = 0 , _groupMaxVoltage = 0;
+	int Iavail = 0, Pavail = 0;
+	unsigned short _outputVolBuf = 0, _outputCurBuf = 0;
+
+	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index ++)
+	{
+		// Cap
+		_groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
+		_groupPower += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
+
+		if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentMaxOutputVoltage > _groupMaxVoltage)
+			_groupMaxVoltage = ShmPsuData->PsuGroup[group].PsuModule[index].PresentMaxOutputVoltage;
+
+		// Iavailable
+		Iavail += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
+		Pavail += ShmPsuData->PsuGroup[group].PsuModule[index].KwAvailablePower;
+
+		// output
+		_outputCurBuf += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
+
+		if (_outputVolBuf == 0 ||
+					(ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > PSU_MIN_VOL &&
+					_outputVolBuf < ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage))
+		{
+			_outputVolBuf = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
+		}
+	}
+
+	ShmPsuData->PsuGroup[group].GroupMaxVoltage = _groupMaxVoltage;
+	ShmPsuData->PsuGroup[group].GroupAvailableCurrent = _groupCurrent;
+	ShmPsuData->PsuGroup[group].GroupAvailablePower = _groupPower;
+
+	ShmPsuData->PsuGroup[group].TotalIAvailableCurrent = Iavail;
+	ShmPsuData->PsuGroup[group].TotalRatingPower = Pavail;
+
+	ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = _outputVolBuf;
+	ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = _outputCurBuf;
+}
+
+void CollectPsuInformation()
+{
+	int _sysPwr = 0, _sysCur = 0, _sysVol = 0;
+
+	for (byte group = 0; group < ShmPsuData->GroupCount; group++)
+	{
+		// 取群資訊
+		CollectGroupInformation(group);
+
+		// 整理系統資訊
+		_sysPwr += ShmPsuData->PsuGroup[group].GroupAvailablePower;
+		_sysCur += ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
+
+		if (ShmPsuData->PsuGroup[group].GroupMaxVoltage > _sysVol)
+			_sysVol = ShmPsuData->PsuGroup[group].GroupMaxVoltage;
+	}
+
+	// 系統,電壓,電流,能量
+	ShmPsuData->SystemAvailableCurrent = _sysCur;
+	ShmPsuData->SystemAvailablePower = _sysPwr;
+	GetSystemMaxVoltage();
+}
+
+//==========================================
+// Main Loop
+//==========================================
+int main(void)
+{
+	if(InitShareMemory() == FAIL)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("InitShareMemory NG\n");
+		#endif
+		if(ShmStatusCodeData != NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
+		}
+		sleep(5);
+		return 0;
+	}
+
+	Initialization();
+
+	// 對充電槍操作 : 將模塊切出來與補上剩餘的模塊功率
+	FetchFork();
+	ReleaseFork();
+
+	GetTimespecFunc(&_log_time);
+	while(1)
+	{
+		if (ShmPsuData->Work_Step >= GET_SYS_CAP)
+		{
+			// 收集來自 PSU 的資訊
+			CollectPsuInformation();
+			// 將群資訊分配到對應的使用中充電槍
+			AssignedPwr2Connector();
+
+			int time = GetTimeoutValue(&_log_time);
+
+			if (time < 0)
+				GetTimespecFunc(&_log_time);
+
+			// 低 Priority 的指令
+			if (time > 5000)
+			{
+				//PrintfLog();
+				GetTimespecFunc(&_log_time);
+			}
+		}
+
+		if (ShmDcCommonData->systemType != _SYSTEM_TYPE_SIMPLE &&
+				ShmPsuData->Work_Step == _WORK_CHARGING)
+		{
+			// 橋接控制
+			SmartRelayCheck();
+		}
+		usleep(50000);
+	}
+
+	return -1;
+}
+

+ 75 - 0
EVSE/Projects/DS60-120/Apps/Module_SmartBox.h

@@ -0,0 +1,75 @@
+/*
+ * Module_SmartBox.h
+ *
+ *  Created on: 2022年5月3日
+ *      Author: 7564
+ */
+
+#ifndef MODULE_SMARTBOX_H_
+#define MODULE_SMARTBOX_H_
+
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<linux/can.h>
+#include 	<linux/can/raw.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include   <stdio.h>      /*標準輸入輸出定義*/
+#include   <stdlib.h>     /*標準函數庫定義*/
+#include   <unistd.h>     /*Unix 標準函數定義*/
+#include   <fcntl.h>      /*檔控制定義*/
+#include   <termios.h>    /*PPSIX 終端控制定義*/
+#include   <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include	<math.h>
+#include	"../../define.h"
+#include 	<stdbool.h>
+
+#define ARRAY_SIZE(A)			(sizeof(A) / sizeof(A[0]))
+#define PASS					1
+#define FAIL					-1
+#define YES						1
+#define NO						0
+#define NONE_GROUP_CAN_SELECTED	255
+#define NONE_RELAY_SELECTED		255
+#define PSU_MIN_VOL				500	// 0.1V
+#define PSU_MIN_CUR				20	// 0.1A
+#define CAP_GAP_FETCH			30	// 0.1kw
+#define CAP_GAP_RELEASE			50	// 0.1kw
+#define STABLE_CAP_GAP			10	// 0.1kw
+#define SMART_MODE				1 	// 0 : FCFS, 1 : Average
+
+// Fetch Loop
+#define PSU_TG_VOL_GAP			100 // 0.1V
+#define PSU_TG_CUR_GAP			50 	// 0.1A
+// Fetch Loop End
+
+// Release Loop
+#define PSU_LIMIT_CUR			50 	// 0.1A
+// Release Loop End
+
+
+#define FETCH_SMART_CHK_TIME		5000	// 1ms
+#define FETCH_FINISH_WAIT_TIME		1000	// 1ms
+
+#define RELEASE_STABLE_CHK_TIME		5000	// 1ms
+#define RELEASE_SMART_CHK_TIME		2000	// 1ms
+#define WAIT_FOR_LIMIT_STABLE		2000	// 1ms
+#define RELEASE_FINISH_WAIT_TIME	1000	// 1ms
+
+#endif /* MODULE_SMARTBOX_H_ */

+ 1 - 1
EVSE/Projects/DS60-120/Apps/OutputTask.c

@@ -319,7 +319,7 @@ int main(void)
 //												0x01,
 //												0x01);
 					}
-					PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10);
+					PresentOutputVol(SYSTEM_CMD, VOLTAGE * 10, CURRENT * 10, 1);
 				}
 					break;
 				case CHARGING_MODE_TERMINATING:

BIN
EVSE/Projects/DS60-120/Apps/ReadCmdline


+ 344 - 39
EVSE/Projects/DS60-120/Apps/ReadCmdline.c

@@ -63,6 +63,9 @@ byte _curAutoRunCount = 0;
 byte _usingAutoRun = 0;
 struct timeval _autoTime;
 
+byte ConnectorUsingSeq[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY][4] =
+{{0, 2, 3, 1}, {1, 3, 2, 0}};
+
 struct timeb 					startChargingTime;
 struct timeb 					endChargingTime;
 int 							_presentChargingTimeBuf;
@@ -81,6 +84,7 @@ struct LedModuleData			*ShmLedModuleData;
 struct PsuData 					*ShmPsuData;
 struct DcCommonInformation		*ShmDcCommonData;
 struct OCPP16Data				*ShmOCPP16Data;
+struct SmartBoxData				*ShmSmartBoxData;
 
 struct ChargingInfoData 		*_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct ChargingInfoData 		*ac_chargingInfo[AC_QUANTITY];
@@ -245,6 +249,15 @@ int InitShareMemory()
    		result = FAIL;
    	}
 
+   	if ((MeterSMId = shmget ( ShmSmartBoxKey, sizeof(struct SmartBoxData), IPC_CREAT | 0777 )) < 0)
+   	{
+   		return FAIL;
+   	}
+   	else if ((ShmSmartBoxData = shmat ( MeterSMId, NULL, 0 )) == (void *) - 1)
+   	{
+   		return FAIL;
+   	}
+
    	if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
    	{
    		result = FAIL;
@@ -294,8 +307,8 @@ void PrintChargingMode(byte mode)
 {
 	switch(mode)
 	{
-		case _MAIN_CHARGING_MODE_MAX: printf("Charging mode = Max \n"); break;
-		case _MAIN_CHARGING_MODE_AVER: printf("Charging mode = Balance \n"); break;
+		case _MAIN_CHARGING_MODE_NORMAL: printf("Charging mode = Max \n"); break;
+		case _MAIN_CHARGING_MODE_BOTH: printf("Charging mode = Balance \n"); break;
 	}
 }
 
@@ -836,6 +849,196 @@ void GetAcInputVol()
 			ShmSysConfigAndInfo->SysInfo.InputVoltageT);
 }
 
+void GetSmartInformation(char *v1, char *v2, char *v3)
+{
+	if(strcmp(v1, "fe") == 0)
+	{
+		int tag = atoi(v2);
+
+		for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++)
+		{
+			if (!FindChargingInfoData(i, &_chargingData[0]))
+			{
+				printf ("FindChargingInfoData error\n");
+				continue;
+			}
+		}
+
+		float needPower = _chargingData[tag]->EvBatterytargetVoltage * _chargingData[tag]->EvBatterytargetCurrent / 100;
+		printf("needPower = %.1f (kw), RealRatingPower = %d \n", needPower / 10, _chargingData[tag]->RealRatingPower / 10);
+		printf("FetchLoopStep = %d \n", ShmSmartBoxData->Dynamic4Fetch[tag].FetchLoopStep);
+		printf("ShareGroup = %d \n", ShmSmartBoxData->Dynamic4Fetch[tag].ShareGroup);
+	}
+	else if (strcmp(v1, "re") == 0)
+	{
+		int tag = atoi(v2);
+
+		for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i ++)
+		{
+			if ( ! FindChargingInfoData ( i, & _chargingData [0] ))
+			{
+				printf ( "FindChargingInfoData error\n" );
+				continue;
+			}
+		}
+
+		printf("ReleaseGroup = %d \n", ShmSmartBoxData->Dynamic4Release[tag].ReleaseGroup);
+		printf("ReleaseLoopStep = %d \n", ShmSmartBoxData->Dynamic4Release[tag].ReleaseLoopStep);
+		printf("TargetRelay = %d \n", ShmSmartBoxData->Dynamic4Release[tag].TargetRelay);
+	}
+	else if (strcmp(v1, "relay") == 0)
+	{
+		printf("ParallelRelayStatus = [%d] [%d] [%d] \n",
+				ShmSmartBoxData->ParallelRelayStatus[0],
+				ShmSmartBoxData->ParallelRelayStatus[1],
+				ShmSmartBoxData->ParallelRelayStatus[2]);
+
+		printf("RcbParallelStatus = [%d] [%d] [%d] \n",
+				ShmSmartBoxData->RcbParallelStatus[0],
+				ShmSmartBoxData->RcbParallelStatus[1],
+				ShmSmartBoxData->RcbParallelStatus[2]);
+	}
+	else if (strcmp(v1, "using") == 0)
+	{
+		for (byte gp = 0; gp < ShmPsuData->GroupCount; gp++)
+		{
+			if (ShmPsuData->PsuGroup[gp].UsingTarget == GUN_LEFT)
+				printf ( "Group_%d IsUsing => Connector - 0 (Vol : %d (0.1V), Cur : %d (0.1A)) \n",
+						gp,
+						ShmPsuData->PsuGroup[gp].GroupPresentOutputVoltage,
+						ShmPsuData->PsuGroup[gp].GroupPresentOutputCurrent);
+			else if (ShmPsuData->PsuGroup[gp].UsingTarget == GUN_RIGHT)
+				printf ( "Group_%d IsUsing => Connector - 1 (Vol : %d (0.1V), Cur : %d (0.1A)) \n",
+						gp,
+						ShmPsuData->PsuGroup[gp].GroupPresentOutputVoltage,
+						ShmPsuData->PsuGroup[gp].GroupPresentOutputCurrent);
+			else
+				printf ( "Group_%d IsUsing = IDLE \n", gp);
+		}
+
+		for (byte conn = 0; conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; conn++)
+		{
+			if(ShmSmartBoxData->ConnectorStatus[conn].ConnectorStaus == _CONNECTOR_STATUS_NONE)
+				printf ( "Gun_%d Status = IDLE \n", conn);
+			else if (ShmSmartBoxData->ConnectorStatus[conn].ConnectorStaus == _CONNECTOR_STATUS_WAIT)
+				printf ( "Gun_%d Status = WAIT \n", conn);
+			else if(ShmSmartBoxData->ConnectorStatus[conn].ConnectorStaus == _CONNECTOR_STATUS_USING)
+				printf ( "Gun_%d Status = USING \n", conn);
+		}
+	}
+	else if (strcmp(v1, "info") == 0)
+	{
+		printf ( "****************************************************************** \n" );
+		printf ( "SystemPresentPsuQuantity = %d \n", ShmPsuData->SystemPresentPsuQuantity );
+		printf ( "SystemAvailableCurrent = %d (A) \n", ShmPsuData->SystemAvailableCurrent / 10 );
+		printf ( "SystemAvailablePower = %d (kw) \n", ShmPsuData->SystemAvailablePower / 10 );
+		printf ( "GroupCount = %d \n", ShmPsuData->GroupCount );
+
+		if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SMART)
+			printf ("System Type = Smart \n");
+		else if (ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+			printf ("System Type = Standard \n");
+		else if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SIMPLE)
+			printf ("System Type = WallMount / Moveable \n");
+
+
+		for (byte conn = 0; conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; conn++)
+		{
+			byte totalUsingGpCount = 0;
+			byte totalQuantity = 0;
+			unsigned short _targetVol = 0 , _targetCur = 0;
+			unsigned short _avaCur = 0 , _avaPow = 0;
+			unsigned short _outputVol = 0 , _outputCur = 0;
+			unsigned short _ratingPow = 0;
+
+			for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount[conn]; gp++)
+			{
+				if (ShmPsuData->PsuGroup[ConnectorUsingSeq[conn][gp]].UsingTarget == GUN_LEFT)
+				{
+					totalUsingGpCount++;
+					byte tarGp = ConnectorUsingSeq[conn][gp];
+
+					totalQuantity += ShmPsuData->PsuGroup[tarGp].GroupPresentPsuQuantity;
+					_targetVol = ShmPsuData->PsuGroup[tarGp].GroupTargetOutputVoltage / 10;
+					_targetCur += ShmPsuData->PsuGroup[tarGp].GroupTargetOutputCurrent / 10;
+					_avaCur += ShmPsuData->PsuGroup[tarGp].GroupAvailableCurrent / 10;
+					_avaPow += ShmPsuData->PsuGroup[tarGp].GroupAvailablePower / 10;
+					_outputVol = (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputVoltage / 10;
+					_outputCur += (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputCurrent / 10;
+					_ratingPow += ShmPsuData->PsuGroup[tarGp].TotalRatingPower;
+				}
+			}
+
+			if (!FindChargingInfoData (GUN_LEFT, & _chargingData [0]))
+			{
+				printf ( "FindChargingInfoData error\n" );
+				continue;
+			}
+
+			if (totalUsingGpCount > 0)
+			{
+				printf ( "----------------------------------------------------------------- \n" );
+				printf ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount);
+				printf ( "totalQuantity = %d \n", totalQuantity);
+				printf ( "_targetVol = %d (V), _targetCur = %d (A), _needPwr = %.1f (kw) \n", _targetVol, _targetCur,
+						(_chargingData[GUN_LEFT]->PresentChargingVoltage * _chargingData[GUN_LEFT]->PresentChargingCurrent) / 1000 );
+				printf ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow);
+				printf ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur);
+				printf ( "_ratingPow = %d (KW) \n", _ratingPow);
+			}
+		}
+
+		for (byte conn = 0; conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; conn ++)
+		{
+			byte totalUsingGpCount = 0;
+			byte totalQuantity = 0;
+			unsigned short _targetVol = 0 , _targetCur = 0;
+			unsigned short _avaCur = 0 , _avaPow = 0;
+			unsigned short _outputVol = 0 , _outputCur = 0;
+			unsigned short _ratingPow = 0;
+
+			for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount [conn]; gp ++)
+			{
+				if (ShmPsuData->PsuGroup [ConnectorUsingSeq [conn] [gp]].UsingTarget == GUN_RIGHT)
+				{
+					totalUsingGpCount ++;
+					byte tarGp = ConnectorUsingSeq [conn] [gp];
+
+					totalQuantity += ShmPsuData->PsuGroup [tarGp].GroupPresentPsuQuantity;
+					_targetVol = ShmPsuData->PsuGroup [tarGp].GroupTargetOutputVoltage / 10;
+					_targetCur += ShmPsuData->PsuGroup [tarGp].GroupTargetOutputCurrent / 10;
+					_avaCur += ShmPsuData->PsuGroup [tarGp].GroupAvailableCurrent / 10;
+					_avaPow += ShmPsuData->PsuGroup [tarGp].GroupAvailablePower / 10;
+					_outputVol = (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputVoltage / 10;
+					_outputCur += (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputCurrent / 10;
+					_ratingPow += ShmPsuData->PsuGroup [tarGp].TotalRatingPower;
+				}
+			}
+
+			if (!FindChargingInfoData (GUN_RIGHT, & _chargingData [0]))
+			{
+				printf ( "FindChargingInfoData error\n" );
+				continue;
+			}
+
+			if (totalUsingGpCount > 0)
+			{
+				printf ( "----------------------------------------------------------------- \n" );
+				printf ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount );
+				printf ( "totalQuantity = %d \n", totalQuantity );
+				printf ( "_targetVol = %d (V), _targetCur = %d (A), _needPwr = %.1f (kw) \n", _targetVol, _targetCur,
+						(_chargingData[GUN_RIGHT]->PresentChargingVoltage * _chargingData[GUN_RIGHT]->PresentChargingCurrent) / 1000 );
+				printf ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow );
+				printf ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur );
+				printf ( "_ratingPow = %d (KW) \n", _ratingPow );
+			}
+		}
+		printf ( "****************************************************************** \n" );
+		GetSmartInformation("using","","");
+		GetSmartInformation("relay","","");
+	}
+}
+
 void GetPsuInformation(char *v1, char *v2, char *v3)
 {
 	printf("**********************AC Contact needed*************************\n");
@@ -848,18 +1051,13 @@ void GetPsuInformation(char *v1, char *v2, char *v3)
 	}
 	else if(strcmp(v1, "ver") == 0)
 	{
-		for (int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
-		{
-			printf("Psu Index = %d, PriVersion = %s, SecVersion = %s \n",
-					i, ShmPsuData->PsuVersion[i].FwPrimaryVersion, ShmPsuData->PsuVersion[i].FwSecondVersion);
-		}
-
-		for (int i = 0; i < ShmPsuData->GroupCount; i++)
+		for(byte group = 0; group < ShmPsuData->GroupCount; group++)
 		{
-			for (int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
+			for (byte psuCount = 0; psuCount < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; psuCount++)
 			{
-				printf("Group Index = %d, Psu Index = %d, Version = %s \n",
-					i, j, ShmPsuData->PsuGroup[i].PsuModule[j].FwVersion);
+				printf("Group = %d, Psu Index = %d, FwVersion = %s \n",
+						group, psuCount,
+						ShmPsuData->PsuGroup[group].PsuModule[psuCount].FwVersion);
 			}
 		}
 	}
@@ -913,6 +1111,7 @@ void GetPsuInformation(char *v1, char *v2, char *v3)
 		{
 			ShmPsuData->Work_Step = mode;
 		}
+
 	}
 	else if (strcmp(v1, "out") == 0)
 	{
@@ -930,14 +1129,26 @@ void GetPsuInformation(char *v1, char *v2, char *v3)
 			_chargingData[0]->EvBatterytargetCurrent = cur;
 		}
 	}
-	else if (strcmp(v1, "force") == 0)
+	else if (strcmp(v1, "info") == 0)
 	{
-		ShmPsuData->Work_Step = _ALATON_MODE;
-		byte id = atof(v2);
+		int _tgGroup = atoi(v2);
+
+		if (_tgGroup < ShmPsuData->GroupCount)
+		{
+			printf("**************************************************************************** \n");
+			printf("Psu Group = %d \n", _tgGroup);
+			printf("GroupTargetOutputVoltage = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupTargetOutputVoltage);
+			printf("GroupTargetOutputCurrent = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupTargetOutputCurrent);
 
-		ShmDcCommonData->for_alston_test_1 = id;
+			printf("GroupAvailableCurrent = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupAvailableCurrent);
+			printf("GroupAvailablePower = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupAvailablePower);
+			printf("GroupPresentOutputVoltage = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupPresentOutputVoltage);
+			printf("GroupPresentOutputCurrent = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupPresentOutputCurrent);
+			printf("GroupPresentOutputPower = %d \n", ShmPsuData->PsuGroup[_tgGroup].GroupPresentOutputPower);
+			printf("TotalIAvailableCurrent = %d \n", ShmPsuData->PsuGroup[_tgGroup].TotalIAvailableCurrent);
+			printf("**************************************************************************** \n");
+		}
 	}
-	printf("*************************************************\n");
 }
 
 void GetConnectorCapInfo(char *v1)
@@ -978,10 +1189,29 @@ static void get_char(char *word)
     }
 }
 
+void GetNeedCount(byte *needGroupCount, float P1, float P2)
+{
+	byte G1_Need = P1 / 30 + (((int)P1 % 30 > 0) ? 1 : 0);
+	byte G2_Need = P2 / 30 + (((int)P2 % 30 > 0) ? 1 : 0);
+
+	// 總群數 >4
+	if (G1_Need + G2_Need > 4)
+	{
+		if (G1_Need > 2)
+			G1_Need = 2;
+
+		G2_Need = 4 - G1_Need;
+	}
+
+	*needGroupCount = G1_Need;
+	*(needGroupCount + 1) = G2_Need;
+}
+
 void AverageCharging(char *g1_vol, char *g1_cur, char *g2_vol, char *g2_cur)
 {
 	float _Voltage[2];
 	float _Current[2];
+	byte needGroupCount[2] = {0, 0};
 
 	_Voltage[0] = atof(g1_vol);
 	_Current[0] = atof(g1_cur);
@@ -989,8 +1219,11 @@ void AverageCharging(char *g1_vol, char *g1_cur, char *g2_vol, char *g2_cur)
 	_Voltage[1] = atof(g2_vol);
 	_Current[1] = atof(g2_cur);
 
-	printf ("g1_vol = %f, g1_cur = %f pow1 = %f (KW) \n", _Voltage[0], _Current[0], (_Voltage[0] * _Current[0]) / 1000);
-	printf ("g2_vol = %f, g2_cur = %f pow2 = %f (KW) \n", _Voltage[1], _Current[1], (_Voltage[1] * _Current[1]) / 1000);
+	printf ("g1_vol = %.1f, g1_cur = %.1f pow1 = %.1f (KW) \n", _Voltage[0], _Current[0], (_Voltage[0] * _Current[0]) / 1000);
+	printf ("g2_vol = %.1f, g2_cur = %.1f pow2 = %.1f (KW) \n", _Voltage[1], _Current[1], (_Voltage[1] * _Current[1]) / 1000);
+
+	GetNeedCount(needGroupCount, (_Voltage[0] * _Current[0]) / 1000, (_Voltage[1] * _Current[1]) / 1000);
+	printf ("needGroupCount[0] = %d, needGroupCount[1] = %d \n", needGroupCount[0], needGroupCount[1]);
 
 	if(_Voltage[0] > 1000 || _Voltage[0] < 50 ||
 			_Voltage[1] > 1000 || _Voltage[1] < 50)
@@ -1042,9 +1275,28 @@ void AverageCharging(char *g1_vol, char *g1_cur, char *g2_vol, char *g2_cur)
 
 						//等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
 				        printf ("wait find module\n");
+
+				        if (ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+				        {
+				            ShmSmartBoxData->ConnectorUsingGroupCount[gun_index] = 1;
+				        }
+				        else if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SMART)
+				        {
+				            ShmSmartBoxData->ConnectorUsingGroupCount[gun_index] = needGroupCount[gun_index];
+				        }
+
+						for (byte aGp = 0; aGp < ShmSmartBoxData->ConnectorUsingGroupCount [gun_index]; aGp ++)
+						{
+							if (ShmPsuData->PsuGroup [ConnectorUsingSeq [gun_index] [aGp]].GroupPresentPsuQuantity > 0)
+							{
+								ShmPsuData->PsuGroup [ConnectorUsingSeq [gun_index] [aGp]].IsUsing = YES;
+								ShmPsuData->PsuGroup [ConnectorUsingSeq [gun_index] [aGp]].UsingTarget = gun_index;
+							}
+						}
+						ShmSmartBoxData->ConnectorStatus [gun_index].ConnectorStaus = _CONNECTOR_STATUS_USING;
 				    }
 
-					ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER;
+					ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_BOTH;
 				    //清除 main timeout 機制
 					_chargingData[gun_index]->TimeoutFlag = 0;
 				}
@@ -1346,7 +1598,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	    ShmDcCommonData->StartToChargingFlag[_GunIndex] = 0x01;
                 _chargingData[_GunIndex]->SystemStatus = SYS_MODE_PREPARING;
     		}
-    		break;
+    			break;
 
     		case SYS_MODE_PREPARING:
     		{
@@ -1357,8 +1609,36 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	        printf ("[UnconditionalCharge - S_PREPARNIN]\n");
 
         	        //等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
-        	        printf ("wait find module\n");
+        	        printf ("wait find module : SystemType = %d \n", ShmDcCommonData->systemType);
 
+        	        if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SIMPLE)
+        	        {
+        	        	if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES && _GunIndex == GUN_RIGHT)
+        	        	{
+							// 直接用到第四個位置~ 第 0 群
+							ShmSmartBoxData->ConnectorUsingGroupCount[_GunIndex] = 4;
+        	        	}
+        	        	else
+        	        		ShmSmartBoxData->ConnectorUsingGroupCount[_GunIndex] = 1;
+        	        }
+        	        else if (ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
+        	        {
+        	        	ShmSmartBoxData->ConnectorUsingGroupCount[_GunIndex] = 4;
+        	        }
+        	        else if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SMART)
+        	        {
+        	        	ShmSmartBoxData->ConnectorUsingGroupCount[_GunIndex] = 4;
+        	        }
+
+        	        for (byte aGp = 0; aGp < ShmSmartBoxData->ConnectorUsingGroupCount[_GunIndex]; aGp++)
+        	        {
+        	        	if (ShmPsuData->PsuGroup[ConnectorUsingSeq[_GunIndex][aGp]].GroupPresentPsuQuantity > 0)
+        	        	{
+        	        		ShmPsuData->PsuGroup [ConnectorUsingSeq [_GunIndex] [aGp]].IsUsing = YES;
+        	        		ShmPsuData->PsuGroup[ConnectorUsingSeq[_GunIndex][aGp]].UsingTarget = _GunIndex;
+        	        	}
+        	        }
+        	        ShmSmartBoxData->ConnectorStatus[_GunIndex].ConnectorStaus = _CONNECTOR_STATUS_USING;
         	    }
     		    //main 會在此階段判斷以下資料跳到下一個 state
     		    //用來得知 AC 是否有搭上 (搭上模組的資訊才會出來) 因為每次  AC_Contactor
@@ -1376,7 +1656,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     		    _chargingData[_GunIndex]->Type = 9;
 
     		}
-    		break;
+    			break;
 
     		case SYS_MODE_PREPARE_FOR_EV:
     		{
@@ -1386,8 +1666,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
         	        printf ("[UnconditionalCharge - SYS_MODE_PREPARE_FOR_EV]\n");
         	        printf ("ReqVoltage = %f, ReqCurrent = %f \n", _Voltage * 10,_Current * 10);
-
         	    }
+
     		    //清除 main timeout 機制
     		    _chargingData[_GunIndex]->TimeoutFlag = 0;
     		    //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
@@ -1409,7 +1689,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     		        _chargingData[_GunIndex]->SystemStatus = SYS_MODE_PREPARE_FOR_EVSE;
     		    }
     		}
-    		break;
+    			break;
 
     		case SYS_MODE_PREPARE_FOR_EVSE:
     		{
@@ -1420,6 +1700,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	        printf ("[UnconditionalCharge - SYS_MODE_PREPARE_FOR_EVSE]\n");
 
         	    }
+
         	    //printf ("tar vol = %d \n", _Voltage);
         	    //printf ("tar cur = %d \n", _Current);
 
@@ -1459,7 +1740,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     		    }
 
     		}
-    		break;
+    			break;
 
     		case SYS_MODE_CHARGING:
     		{
@@ -1532,7 +1813,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 //    		    	gettimeofday(&_printf_time, NULL);
 //    		    }
     		}
-    		break;
+    			break;
 
      		case SYS_MODE_TERMINATING:
     		{
@@ -1550,7 +1831,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	    _chargingData[_GunIndex]->SystemStatus = SYS_MODE_COMPLETE;
         	    return;
     		}
-    		break;
+    			break;
 
     		case SYS_MODE_COMPLETE:
     		{
@@ -1565,7 +1846,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
         	    sleep(3);
         	    return;
     		}
-    		break;
+    			break;
     	}
 
     	char word[128];
@@ -1793,6 +2074,17 @@ int main(void)
 			// 取得 PSU 資訊
 			GetPsuInformation(newString[1], newString[2], newString[3]);
 		}
+		else if(strcmp(newString[0], "smart") == 0)
+		{
+			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
+			{
+				printf ("SMART : Param fail..Please retry again......\n");
+				continue;
+			}
+
+			// 取得 Smart 資訊
+			GetSmartInformation(newString[1], newString[2], newString[3]);
+		}
 		else if (strcmp(newString[0], "cap") == 0)
 		{
 			GetConnectorCapInfo(newString[1]);
@@ -1869,19 +2161,32 @@ int main(void)
 
 			printf ("_isAutoRunTest = %d \n", ShmDcCommonData->_isAutoRunTest);
 		}
+		else if (strcmp(newString[0], "fetch") == 0)
+		{
+			byte id = atof(newString[1]);
+
+			ShmDcCommonData->smartFetchRun[id] = YES;
+			printf("Fetch [%d] = %d ON \n", id, ShmDcCommonData->smartFetchRun[id]);
+		}
+		else if (strcmp(newString[0], "release") == 0)
+		{
+			byte id = atof(newString[1]);
+
+			ShmDcCommonData->smartReleaseRun[id] = YES;
+			printf("Release = %d ON \n", ShmDcCommonData->smartReleaseRun[id]);
+		}
 		else if (strcmp(newString[0], "test") == 0)
 		{
-			if (!FindChargingInfoData(1, &_chargingData[0]))
-			{
-				printf("FindChargingInfoData error\n");
-			}
+//			if (!FindChargingInfoData(1, &_chargingData[0]))
+//			{
+//				printf("FindChargingInfoData error\n");
+//			}
+			if (ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq)
+				ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq = false;
+			else
+				ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq = true;
 
-			// Test Command
-			ShmPsuData->PsuGroup[0].GroupErrorFlag.bits.PsuFailure = YES;
-			ShmPsuData->PsuStopChargeFlag = YES;
-			ShmDcCommonData->_isPsuErrorOccur = YES;
-//			ShmDcCommonData->Customer_SwipToChargingByTime += 10;
-//			printf("Charging Time = %u \n", ShmDcCommonData->Customer_SwipToChargingByTime);
+			printf("isReq = %d \n", ShmSysConfigAndInfo->SysInfo.bazel8.cmdPreAuth.isReq);
 		}
 		else if (strcmp(newString[0], "ocpp") == 0)
 		{

BIN
EVSE/Projects/DS60-120/Apps/UnsafetyOutputTask


+ 3 - 3
EVSE/Projects/DS60-120/Apps/internalComm.c

@@ -361,12 +361,12 @@ unsigned char Query_Relay_Output(unsigned char fd, unsigned char targetAddr, Rel
 		   (rx[3] == tx[3]))
 		{
 			Ret_Buf->relay_event.bits.AC_Contactor = (rx[6] >> 0) & 0x01;
-			Ret_Buf->relay_event.bits.CCS_Precharge = (rx[6] >> 1) & 0x01;
+			Ret_Buf->relay_event.bits.R3_BOTH_K1_K4 = (rx[6] >> 1) & 0x01;
 
 			Ret_Buf->relay_event.bits.Gun1_N = (rx[7] >> 0) & 0x01;
 			Ret_Buf->relay_event.bits.Gun1_P = (rx[7] >> 1) & 0x01;
-			Ret_Buf->relay_event.bits.Gun1_Parallel_N = (rx[7] >> 2) & 0x01;
-			Ret_Buf->relay_event.bits.Gun1_Parallel_P = (rx[7] >> 3) & 0x01;
+			Ret_Buf->relay_event.bits.R5_BOTH_K3_K6 = (rx[7] >> 2) & 0x01;
+			Ret_Buf->relay_event.bits.R4_BOTH_K2_K5 = (rx[7] >> 3) & 0x01;
 
 			Ret_Buf->relay_event.bits.Gun2_N = (rx[8] >> 0) & 0x01;
 			Ret_Buf->relay_event.bits.Gun2_P = (rx[8] >> 1) & 0x01;

+ 4 - 4
EVSE/Projects/DS60-120/Apps/internalComm.h

@@ -108,8 +108,8 @@ typedef struct RELAY
 		struct
 		{
 			unsigned char AC_Contactor :1;		//bit 0
-			unsigned char CCS_Precharge :1;	//bit 1
-			unsigned char :1;  				//bit 2 reserved
+			unsigned char R3_BOTH_K1_K4 :1;		//bit 1
+			unsigned char :1;  					//bit 2 reserved
 			unsigned char :1;					//bit 3 reserved
 			unsigned char :1;					//bit 4 reserved
 			unsigned char :1;					//bit 5 reserved
@@ -118,8 +118,8 @@ typedef struct RELAY
 
 			unsigned char Gun1_N :1;			//bit 0
 			unsigned char Gun1_P :1;			//bit 1
-			unsigned char Gun1_Parallel_N :1;  //bit 2
-			unsigned char Gun1_Parallel_P :1;	//bit 3
+			unsigned char R5_BOTH_K3_K6 :1;  	//bit 2 //Stardard : D-
+			unsigned char R4_BOTH_K2_K5 :1;		//bit 3 //Stardard : D+
 			unsigned char :1;					//bit 4 reserved
 			unsigned char :1;					//bit 5 reserved
 			unsigned char :1;					//bit 6 reserved

BIN
EVSE/Projects/DS60-120/Apps/main


ファイルの差分が大きいため隠しています
+ 387 - 137
EVSE/Projects/DS60-120/Apps/main.c


+ 2 - 1
EVSE/Projects/DS60-120/Apps/timeout.h

@@ -49,7 +49,7 @@ enum Timeout_flag
 	Timeout_EvseCompleteDet = 			9,
 	Timeout_ForCcsPrechargeDet = 		10,
 	Timeout_ReturnToChargingGunDet = 	11,
-	Timeout_AuthorizingForStop = 		12
+	Timeout_AuthorizingForStop = 		12,
 };
 
 // for timeout fork
@@ -64,5 +64,6 @@ unsigned char _ocppProfileChkFlag_2;
 unsigned char _ac_ocppProfileChkFlag;
 unsigned char _4gResetChkFlag;
 bool stopChargingChkByCard;
+struct timespec _tcpDetectStatus_time;
 
 #endif /* TIMEOUT_H_ */

BIN
EVSE/Projects/DS60-120/Images/FactoryDefaultConfig.bin


BIN
EVSE/Projects/DS60-120/Images/ramdisk.gz


BIN
EVSE/rootfs/bin/plcboot


BIN
EVSE/rootfs/bin/plcinit


BIN
EVSE/rootfs/bin/plctool


BIN
EVSE/rootfs/root/Module_Payment_Bazel8


BIN
EVSE/rootfs/root/Module_Payment_Enegate


BIN
EVSE/rootfs/root/Module_PowerSharing


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません