Explorar el Código

Merge remote-tracking branch 'origin/DD360Tcci'

Folus Wen hace 2 años
padre
commit
7e4481a08f
Se han modificado 31 ficheros con 2418 adiciones y 1416 borrados
  1. 230 180
      EVSE/Projects/DD360Tcci/Apps/CSU/RFID.c
  2. 152 138
      EVSE/Projects/DD360Tcci/Apps/CSU/main.c
  3. 3 2
      EVSE/Projects/DD360Tcci/Apps/CSU/main.h
  4. 34 3
      EVSE/Projects/DD360Tcci/Apps/Config.h
  5. 352 5
      EVSE/Projects/DD360Tcci/Apps/DataBase/DataBase.c
  6. 6 1
      EVSE/Projects/DD360Tcci/Apps/DataBase/DataBase.h
  7. 371 444
      EVSE/Projects/DD360Tcci/Apps/Define/define.h
  8. 331 49
      EVSE/Projects/DD360Tcci/Apps/ModuleDoComm/DoComm.c
  9. 18 4
      EVSE/Projects/DD360Tcci/Apps/ModuleDoComm/DoComm.h
  10. 2 1
      EVSE/Projects/DD360Tcci/Apps/ModuleEvComm/AbnormalCCS.c
  11. 191 69
      EVSE/Projects/DD360Tcci/Apps/ModuleEvComm/Module_EvTxComm.c
  12. 472 297
      EVSE/Projects/DD360Tcci/Apps/ModuleLcmCtrl/Module_LcmControl.c
  13. 43 154
      EVSE/Projects/DD360Tcci/Apps/ModuleLcmCtrl/Module_LcmControl.h
  14. 32 48
      EVSE/Projects/DD360Tcci/Apps/ModulePrimary/Module_PrimaryComm.c
  15. 3 0
      EVSE/Projects/DD360Tcci/Apps/ModuleUpdateFW/Module_UpdateFW.c
  16. 174 19
      EVSE/Projects/DD360Tcci/Apps/ReadCmdline.c
  17. BIN
      EVSE/Projects/DD360Tcci/Apps/UnsafetyOutputTask
  18. 4 2
      EVSE/Projects/DD360Tcci/Apps/timeout.h
  19. BIN
      EVSE/Projects/DD360Tcci/Images/ramdisk.gz
  20. BIN
      EVSE/Projects/DD360Tcci/output/FactoryConfig
  21. BIN
      EVSE/Projects/DD360Tcci/output/Module_ChkSysTask
  22. BIN
      EVSE/Projects/DD360Tcci/output/Module_DoComm
  23. BIN
      EVSE/Projects/DD360Tcci/output/Module_EvComm
  24. BIN
      EVSE/Projects/DD360Tcci/output/Module_EventLogging
  25. BIN
      EVSE/Projects/DD360Tcci/output/Module_InternalComm
  26. BIN
      EVSE/Projects/DD360Tcci/output/Module_LcmControl
  27. BIN
      EVSE/Projects/DD360Tcci/output/Module_PrimaryComm
  28. BIN
      EVSE/Projects/DD360Tcci/output/Module_UpdateFW
  29. BIN
      EVSE/Projects/DD360Tcci/output/ReadCmdline
  30. BIN
      EVSE/Projects/DD360Tcci/output/UnsafetyOutputTask
  31. BIN
      EVSE/Projects/DD360Tcci/output/main

+ 230 - 180
EVSE/Projects/DD360Tcci/Apps/CSU/RFID.c

@@ -16,7 +16,7 @@ static DcCommonInfo *ShmDcCommonData 			= NULL;
 static SelectGunInfo *ShmSelectGunInfo          = NULL;
 static struct SysInfoData *pSysInfo 			= NULL;
 #define PREAUTHMONEY	888
-bool isDeductDb_ready;
+bool isDb_ready;
 static RecordTransactionInfo LocalTransactionInfo;
 //------------------------------------------------------------------------------
 static char *rfidPortName = "/dev/ttyS2";
@@ -108,6 +108,28 @@ bool isAutorCompleteHandle(/*uint8_t *authorizeIndex*/)
     }*/
 }
 
+void showDeductInfo(RecordTransactionInfo* transactionInfo)
+{
+    char ApprovalNo[10];
+    char vemdata[65];
+    char cardno[21];
+    memset(ApprovalNo,'\0',sizeof(ApprovalNo));
+    memset(vemdata,'\0',sizeof(vemdata));
+    memset(cardno,'\0',sizeof(cardno));
+    memcpy(ApprovalNo,&transactionInfo->pCreditCard.ApprovalNo[0],9);
+    memcpy(vemdata,&transactionInfo->pCreditCard.VemData[0],64);
+    memcpy(cardno,&transactionInfo->pCreditCard.CardNo[0],20);
+    log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f Approva Num:[%s] VemData:[%s] CardNo:[%s]",
+    		transactionInfo->ConnectorID,
+            transactionInfo->TransactionId,
+            transactionInfo->DeductResult,
+            transactionInfo->IsDonateInvoice,
+            transactionInfo->Amount,
+            ApprovalNo,
+            vemdata,
+            cardno);
+}
+
 bool RfidStopCharging(void)
 {
     //當前沒有選槍
@@ -265,84 +287,110 @@ void ScannerCardProcess(int gunIndex)
         isCardScan = false;
     }
 }
+void storePayResult(uint8_t gunIndex)
+{
+    memset(&LocalTransactionInfo, 0x00, sizeof(RecordTransactionInfo));
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus > _TCC_PARKING_NONE) {
+        memcpy(&LocalTransactionInfo, &ShmDcCommonData->ParkingInfo[gunIndex] ,sizeof(RecordTransactionInfo));
+    } else
+        memcpy(&LocalTransactionInfo, &ShmDcCommonData->TransactionInfo[gunIndex] ,sizeof(RecordTransactionInfo));
+
+}
+void getPayResult(uint8_t gunIndex)
+{
 
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus > _TCC_PARKING_NONE) {
+        memcpy(&ShmDcCommonData->ParkingInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo));
+    } else {
+        memcpy(&ShmDcCommonData->TransactionInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo));
+    }
+}
 void WritePayResult(int result ,uint8_t gunIndex)
 {
-    memcpy(&ShmDcCommonData->TransactionInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo));
     if (result == TRUE)
         ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_PASS;
     else
         ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_FAIL;
 
-    log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f VemData:%s",
+    log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f VemData:%s Approve No:%s",
         gunIndex, ShmDcCommonData->TransactionInfo[gunIndex].TransactionId,
         ShmDcCommonData->TransactionInfo[gunIndex].DeductResult,
         ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice,
         ShmDcCommonData->TransactionInfo[gunIndex].Amount,
-        ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData);
-}
-void storePayResult(uint8_t gunIndex)
-{
-    memset(&LocalTransactionInfo, 0, sizeof(RecordTransactionInfo));
-    memcpy(&LocalTransactionInfo, &ShmDcCommonData->TransactionInfo[gunIndex] ,sizeof(RecordTransactionInfo));
-    //LocalTransactionInfo.Amount = ShmDcCommonData->finalcost[gunIndex];
-}
-void getPayResult(uint8_t gunIndex)
-{
-    memcpy(&ShmDcCommonData->TransactionInfo[gunIndex], &LocalTransactionInfo, sizeof(RecordTransactionInfo));
-    memset(&LocalTransactionInfo, 0, sizeof(RecordTransactionInfo));
+        ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData,
+        ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.ApprovalNo);
 }
+
 void PreAuthCompleteToCardReader(int fd,uint8_t gunIndex)
 {
     struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData();
 	int result = 0;
 
-    if (ShmDcCommonData->TransactionInfo[gunIndex].Amount > 0 && ShmDcCommonData->TransactionInfo[gunIndex].Amount < 1) {
+    storePayResult(gunIndex);
+    if (ShmDcCommonData->TransactionInfo[gunIndex].Amount > 0 && ShmDcCommonData->TransactionInfo[gunIndex].Amount < 1 &&
+        ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus == 0) {
         log_info("final cost less 1 : %f", ShmDcCommonData->TransactionInfo[gunIndex].Amount);
         ShmDcCommonData->TransactionInfo[gunIndex].Amount = 1;
     }
-    storePayResult(gunIndex);
 
-	result = CreditCardPreAuthComplete(fd,(int)ShmDcCommonData->TransactionInfo[gunIndex].Amount, &pSysConfig->ModelName[0],
+	result = CreditCardPreAuthComplete(fd,(int)LocalTransactionInfo.Amount, &pSysConfig->ModelName[0],
 											&ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData[0],
-											&ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard);
+											&ShmDcCommonData->TransactionInfo[gunIndex]);
+    getPayResult(gunIndex);
+
     //sleep(10);
 	if (result > 0 ) {
-		log_info("Credit Card Spend Money:%.1f", LocalTransactionInfo.Amount);
+		log_info("Credit Card Spend Money:%.1f", ShmDcCommonData->TransactionInfo[gunIndex].Amount);
 		pSysInfo->SystemPage = _PAGE_COMPLETE;
-        LocalTransactionInfo.DeductResult = _DEDUCT_COMPLETE_PASS;
+        ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_PASS;
 		WritePayResult(TRUE,gunIndex);
         ShmDcCommonData->PayPass_flag[gunIndex] = TRUE;
 	} else {
 		log_info("PAYING FAIL");
 		ShmDcCommonData->PayPass_flag[gunIndex] = FALSE;
 		pSysInfo->SystemPage = _PAGE_PAYFAIL;
-        LocalTransactionInfo.DeductResult = _DEDUCT_COMPLETE_FAIL;
+        ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_COMPLETE_FAIL;
 		WritePayResult(FALSE,gunIndex);
 	}
     ShmDcCommonData->TransactionInfo[gunIndex].IsUpload = FALSE;
+    //getPayResult(gunIndex);
+
     UpdateDeductInfoStatus(gunIndex, &ShmDcCommonData->TransactionInfo[gunIndex]);
 
+    ShmDcCommonData->PreAuth_Result = result;
 }
 int CreditCardCancelPreAuth(int fd, uint8_t gunIndex)
 {
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus) {
+        return;
+    }
     struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData();
-    ShmDcCommonData->PreAuth_Result = CreditCardPreAuthCancel(fd, PREAUTHMONEY, &pSysConfig->ModelName[0],
-        &ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.ApprovalNo[0],
-        &ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.CardNo[0],
-        &ShmDcCommonData->TransactionInfo[gunIndex].pCreditCard.VemData[0]);
+    storePayResult(gunIndex);
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus)
+        ShmDcCommonData->PreAuth_Result = CreditCardPreAuthCancel(fd, LocalTransactionInfo.Amount, &pSysConfig->ModelName[0],
+        &LocalTransactionInfo.pCreditCard.ApprovalNo[0],
+        &LocalTransactionInfo.pCreditCard.CardNo[0],
+        &LocalTransactionInfo.pCreditCard.VemData[0]);
+    else
+        ShmDcCommonData->PreAuth_Result = CreditCardPreAuthCancel(fd, PREAUTHMONEY, &pSysConfig->ModelName[0],
+        &LocalTransactionInfo.pCreditCard.ApprovalNo[0],
+        &LocalTransactionInfo.pCreditCard.CardNo[0],
+        &LocalTransactionInfo.pCreditCard.VemData[0]);
     //sleep(10);
     if (ShmDcCommonData->PreAuth_Result >= 0) {
         strcpy((char*)pSysConfig->UserId, "");
         //ShmDcCommonData->PayFinish[gunIndex] = TRUE;
         log_info("Gun%d Card Reader PreAuth Cancel Success",gunIndex);
-        ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_CANCEL;
+        LocalTransactionInfo.DeductResult = _DEDUCT_CANCEL;
     } else if (ShmDcCommonData->PreAuth_Result < 0) {
         log_info("Gun%d Card Reader PreAuth Cancel Failure",gunIndex);
-        ShmDcCommonData->TransactionInfo[gunIndex].DeductResult = _DEDUCT_PREAUTH;
+        LocalTransactionInfo.DeductResult = _DEDUCT_PREAUTH;
     }
-    ShmDcCommonData->TransactionInfo[gunIndex].IsUpload = FALSE;
-    UpdateDeductInfoStatus(gunIndex, &ShmDcCommonData->TransactionInfo[gunIndex]);
+    LocalTransactionInfo.IsUpload = FALSE;
+    getPayResult(gunIndex);
+
+    UpdateDeductInfoStatus(gunIndex, &LocalTransactionInfo);
+
     memset(&ShmDcCommonData->TransactionInfo[gunIndex], 0x00, sizeof(RecordTransactionInfo));
     ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE;
     return ShmDcCommonData->PreAuth_Result;
@@ -356,6 +404,7 @@ void ReDeductProcess(int fd)
     int rededuct_gunIndex[128];
     RecordTransactionInfo deductInfo[128];
     int rededuct_num = 0;
+    // 充電費補扣款
     rededuct_num = DB_GetMultiReDeductInfo(&rededuct_gunIndex[0], &deductInfo[0]);
 
     if (rededuct_num == 0) {
@@ -406,6 +455,41 @@ void ReDeductProcess(int fd)
             UpdateDeductInfoStatus(rededuct_gunIndex[j], &deductInfo[j]);
         }
     }
+    // 佔位費補扣款
+    /*
+    rededuct_num = DB_GetParkingDeductResult(&rededuct_gunIndex[0], &deductInfo[0]);
+
+    if (rededuct_num == 0) {
+        log_info("No Parking Rededuct Information");
+    } else {
+        ShmDcCommonData->CreditCardUpload = TRUE;
+        pSysInfo->SystemPage = _PAGE_PAYING;
+        log_info("Parking Rededuct Total Number:%d", rededuct_num);
+        for (j = rededuct_num-1; j >= 0 ; j--) {
+            sleep(3);
+
+            log_info("Start Parking Rededuct item [%d]",j);
+
+            result = CreditCardPreAuthComplete(fd, (int)deductInfo[j].Amount, &pSysConfig->ModelName[0],
+                &deductInfo[j].pCreditCard.VemData[0],
+                &ShmDcCommonData->ParkingInfo[0].pCreditCard);
+            if (result > 0) {
+                deductInfo[j].DeductResult = _DEDUCT_COMPLETE_PASS;
+                log_info("Backgroud Parking PreAuthComplete OK");
+            } else if (result < 0) {
+                deductInfo[j].DeductResult = _DEDUCT_COMPLETE_FAIL;
+                log_info("Backgroud Parking ID:%d Amount:%d VemData:%s PreAuthComplete fail",
+                    deductInfo[j].TransactionId,
+                    (int)deductInfo[j].Amount,
+                    deductInfo[j].pCreditCard.VemData);
+            }
+            
+            deductInfo[j].IsUpload = FALSE;
+            deductInfo[j].RedeductTime++;
+            UpdateParkingDeductInfo(rededuct_gunIndex[j], &deductInfo[j]);
+        }
+    }
+    */
     ShmDcCommonData->RoutineReduct = TRUE;
 }
 static int InitialRfidPort(void)
@@ -440,7 +524,52 @@ void RemoteStartCancelPreAuth(int sel_gun)
     memset(&ShmDcCommonData->TransactionInfo[sel_gun], 0x00, sizeof(RecordTransactionInfo));
     ShmDcCommonData->TransactionInfo[sel_gun].LineStatus = ShmDcCommonData->RedeductBill.LineStatus;
 }
+void PreAuthCreditCard(int fd, uint8_t gunIndex)
+{
+    struct SysConfigData* pSysConfig = (struct SysConfigData*)GetShmSysConfigData();
+    struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);;
+    int result = 0;
+    storePayResult(gunIndex);
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus)
+        result = CreditCardPreAuth(fd, LocalTransactionInfo.Amount,&pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard);
+    else
+        result = CreditCardPreAuth(fd, PREAUTHMONEY,&pSysConfig->ModelName[0], &LocalTransactionInfo.pCreditCard);
+    ShmDcCommonData->PreAuth_Result = result;
+    pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+    {
+        if (!checkRemoteStart(gunIndex)) {
+            if (!ShmDcCommonData->TradeCancel)
+                StopSystemTimeoutDet();
+            if (ShmDcCommonData->TradeCancel == FALSE && result > 0) {
+                pSysInfo->SystemPage = _PAGE_SENSING;
+            }
+        }
 
+        if (result > 0 && strcmp((char*)LocalTransactionInfo.pCreditCard.CardNo, "") != 0) {
+            log_info("Gun%d PreAuth card:%s", gunIndex, LocalTransactionInfo.pCreditCard.CardNo);
+            LocalTransactionInfo.DeductResult = _DEDUCT_PREAUTH;
+            LocalTransactionInfo.IsUpload = FALSE;
+            LocalTransactionInfo.ConnectorID = ShmDcCommonData->ConnectorID[gunIndex];
+            //log_info("Gun%d Line Status:%d", LocalTransactionInfo.LineStatus);
+            if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus)
+                InsertParkingDeductInfo(ShmDcCommonData->ConnectorID[gunIndex], &LocalTransactionInfo);
+            else {
+                ShmDcCommonData->AuthPass_flag[gunIndex] = TRUE;
+                strncpy((char*)pSysConfig->UserId, (char*)LocalTransactionInfo.pCreditCard.CardNo, 20);
+                InsertDeductInfo(ShmDcCommonData->ConnectorID[gunIndex], &LocalTransactionInfo);
+            }
+            getPayResult(gunIndex);
+            //log_info("Gun%d PreAuth OK",gunIndex);
+        } else if (result < 0) {
+            if (ShmDcCommonData->TradeCancel == FALSE && !checkRemoteStart(gunIndex))
+                pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
+            ShmDcCommonData->AuthPass_flag[gunIndex] = FALSE;
+            memset(&LocalTransactionInfo.pCreditCard, 0, sizeof(TransInfo));
+            log_info("Gun%d PreAuth Fail",gunIndex);
+        }
+        ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE;
+    }
+}
 void CreateRfidFork(void)
 {
     pid_t rfidRecPid;
@@ -463,9 +592,19 @@ void CreateRfidFork(void)
         ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
         struct ChargingInfoData *pDcChargingInfo = NULL;
         if (DeductDB_Open() != PASS) {
-            isDeductDb_ready = false;
+            isDb_ready = false;
+            log_info("DeductDB_Open Fail");
+            return;
+        } else {
+            isDb_ready = true;
+            //InsertDeductInfo(0, &ShmDcCommonData->TransactionInfo);
+        }
+        if (ParkingDB_Open() != PASS) {
+            isDb_ready = false;
+            log_info("ParkingDB_Open Fail");
+            return;
         } else {
-            isDeductDb_ready = true;
+            isDb_ready = true;
             //InsertDeductInfo(0, &ShmDcCommonData->TransactionInfo);
         }
         int gunIndex;
@@ -505,7 +644,6 @@ void CreateRfidFork(void)
                 }
 
                 if (ShmDcCommonData->StopCharge[gunIndex] == TRUE && pDcChargingInfo->Replug_flag == TRUE) {
-                    ShmDcCommonData->StopCharge[gunIndex] = FALSE;
                     // Remote Start of AutoStart ByPass Credit Card Reader
                     if (ShmDcCommonData->DebugFlag == TRUE ||
                         ShmDcCommonData->is_RemoteStart[gunIndex] == TRUE ||
@@ -522,10 +660,11 @@ void CreateRfidFork(void)
                     pSysInfo->CurGunSelected = gunIndex;
                     pSysInfo->SystemPage = _PAGE_PLUGOUT;
                     StopSystemTimeoutDet();
+                    ShmDcCommonData->StopCharge[gunIndex] = FALSE;
                 } else {
                     if (ShmDcCommonData->StopCharge[gunIndex] && ShmDcCommonData->finalcost_flag[gunIndex] &&
                         ShmDcCommonData->PreAuth_Config != _CREDITCARD_CANCEL) {
-                        ShmDcCommonData->StopCharge[gunIndex] = FALSE;
+
                         pSysInfo->CurGunSelected = gunIndex;
                         StopGunInfoTimeoutDet(gunIndex); //Timeout_FinalCost
 
@@ -535,6 +674,7 @@ void CreateRfidFork(void)
                             if (ShmDcCommonData->is_AutoStart[gunIndex]) {
                                 ShmDcCommonData->PayPass_flag[gunIndex] = TRUE;
                             }
+                            ShmDcCommonData->StopCharge[gunIndex] = FALSE;
                             continue;
                         }
 
@@ -549,80 +689,75 @@ void CreateRfidFork(void)
                                 ShmDcCommonData->PayPass_flag[gunIndex] = FALSE;
                             }
                         } else {
+                            ShmDcCommonData->PreAuth_Config = _CREDITCARD_PREAUTHCOMPLETE;
                             PreAuthCompleteToCardReader(fd, gunIndex);
+                             ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE;
                         }
+                        ShmDcCommonData->StopCharge[gunIndex] = FALSE;
                     }
                 }
 			} // for
-            /*
-            if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_SALE) {
+            if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_SALE /*&& ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].isParking*/) {
                 sel_gun = pSysInfo->CurGunSelected;
-                memset(&ShmDcCommonData->TransactionInfo[sel_gun], 0, sizeof(RecordTransactionInfo));
-                CreditCardSale(fd, 1, &pSysConfig->ModelName[0], &ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard);
-                log_info("TransDate:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.TransDate);
-                log_info("TransTime:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.TransTime);
-                log_info("ROC:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.ROC);
-                log_info("ApprovalNo:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.ApprovalNo);
-                log_info("StoreId:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.StoreId);
-                log_info("RRN:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.RRN);
-
-                log_info("CardNo:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.CardNo);
-                log_info("TransAmount:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.TransAmount);
-                log_info("VemData:[%s]", ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.VemData);
+                ShmDcCommonData->PreAuth_Result = 0;
+                ShmDcCommonData->PreAuth_Result = CreditCardSale(fd,(int)ShmDcCommonData->ParkingInfo[sel_gun].Amount,
+                                                &pSysConfig->ModelName[0],
+                                                &ShmDcCommonData->ParkingInfo[sel_gun].pCreditCard);
+                StopSystemTimeoutDet(); //Timeout_ScanCard
+                if (ShmDcCommonData->PreAuth_Result > 0 ) {
+                    log_info("Gun%d Parking Fee PreAuthComplete Success",sel_gun);
+                    pSysInfo->SystemPage = _PAGE_PLUGIN;
+                    ShmDcCommonData->ParkingInfo[sel_gun].IsUpload = FALSE;
+                    //ShmDcCommonData->pGunInfo[sel_gun].GetParkingBill = FALSE;
+                    ShmDcCommonData->ParkingInfo[sel_gun].DeductResult = _DEDUCT_SALE_PASS;
+                    InsertParkingDeductInfo(ShmDcCommonData->ConnectorID[sel_gun], &ShmDcCommonData->ParkingInfo[sel_gun]);
+                } else {
+                    log_info("Gun%d Parking Fee PreAuthComplete Fail",sel_gun);
+                    if (!ShmDcCommonData->TradeCancel) {
+                        pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
+                    }
+                }
+                ShmDcCommonData->PreAuth_Result = 0;
                 ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE;
-            } else*/ if(ShmDcCommonData->PreAuth_Config == _CREDITCARD_CANCEL) {
+            } else if(ShmDcCommonData->PreAuth_Config == _CREDITCARD_CANCEL) {
                 // 取消預授權
                 CreditCardCancelPreAuth(fd,pSysInfo->CurGunSelected);
-            // 預授權
-            } else if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_PREAUTH /* && ShmDcCommonData->GetCardNo[pSysInfo->CurGunSelected]*/) {
+            } else if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_PREAUTH ) {
+                // 預授權
                 sel_gun = pSysInfo->CurGunSelected;
-                donate = (int)ShmDcCommonData->TransactionInfo[sel_gun].IsDonateInvoice;
-                linestatus = (int)ShmDcCommonData->TransactionInfo[sel_gun].LineStatus;
-                memset(&ShmDcCommonData->TransactionInfo[sel_gun], 0x00, sizeof(RecordTransactionInfo));
-                ShmDcCommonData->TransactionInfo[sel_gun].IsDonateInvoice = (unsigned char)donate;
-                ShmDcCommonData->TransactionInfo[sel_gun].LineStatus = linestatus;
-        		result = CreditCardPreAuth(fd, PREAUTHMONEY,&pSysConfig->ModelName[0], &ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard);
-                
-                pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(sel_gun);
-                {
-                    if (!checkRemoteStart(sel_gun)) {
-                        if (!ShmDcCommonData->TradeCancel)
-                            StopSystemTimeoutDet();
-                        if (ShmDcCommonData->TradeCancel == FALSE && result > 0) {
-                            pSysInfo->SystemPage = _PAGE_SENSING;
-                        }
-                        /*
-                        if (result > 0) {
-                            storePayResult(sel_gun);
-                            log_info("sleep");
-                            sleep(3);
-                            log_info("Wake");
-                            getPayResult(sel_gun);
-                        }*/
+                PreAuthCreditCard(fd,sel_gun);
+                // 佔位費預授權並扣款
+                /*
+                if (ShmDcCommonData->PreAuth_Result > 0 ) {
+                        log_info("Gun%d Parking Fee PreAuthComplete Success",sel_gun);
+                        pSysInfo->SystemPage = _PAGE_PLUGIN;
+                        StartSystemTimeoutDet(Timeout_ReturnViewPage);
+                } else {
+                    log_info("Gun%d Parking Fee PreAuthComplete Fail",sel_gun);
+                    if (!ShmDcCommonData->TradeCancel) {
+                        pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
+                        StartSystemTimeoutDet(Timeout_VerifyFail);
                     }
-                    ShmDcCommonData->PreAuth_Result = result;
-
-                    //result = 1;
-                    if (result > 0 && strcmp((char*)ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.CardNo, "") != 0) {
-
-                        ShmDcCommonData->AuthPass_flag[sel_gun] = TRUE;
-                        strncpy((char*)pSysConfig->UserId, (char*)ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard.CardNo, 20);
-                        log_info("Gun%d Authorize card:%s", sel_gun, pSysConfig->UserId);
-                        ShmDcCommonData->TransactionInfo[sel_gun].DeductResult = _DEDUCT_PREAUTH;
-                        ShmDcCommonData->TransactionInfo[sel_gun].IsUpload = FALSE;
-                        ShmDcCommonData->TransactionInfo[sel_gun].ConnectorID = ShmDcCommonData->ConnectorID[sel_gun];
-                        //log_info("Gun%d Line Status:%d", ShmDcCommonData->TransactionInfo[sel_gun].LineStatus);
-                        InsertDeductInfo(ShmDcCommonData->ConnectorID[sel_gun], &ShmDcCommonData->TransactionInfo[sel_gun]);
-                        //log_info("Gun%d PreAuth OK",sel_gun);
-                    } else if (result < 0) {
-                        if (ShmDcCommonData->TradeCancel == FALSE && !checkRemoteStart(sel_gun))
+                }
+                
+                if (ShmDcCommonData->pGunInfo[sel_gun].ParkingStatus && ShmDcCommonData->PreAuth_Result > 0 &&
+                    !ShmDcCommonData->TradeCancel && ShmDcCommonData->PreAuth_Config != _CREDITCARD_CANCEL ) {
+                    ShmDcCommonData->PreAuth_Result = 0;
+                    sleep(10);
+                    PreAuthCompleteToCardReader(fd, sel_gun);
+                    if (ShmDcCommonData->PreAuth_Result > 0 ) {
+                        log_info("Gun%d Parking Fee PreAuthComplete Success",sel_gun);
+                        pSysInfo->SystemPage = _PAGE_PLUGIN;
+                        StartSystemTimeoutDet(Timeout_ReturnViewPage);
+                    } else {
+                        log_info("Gun%d Parking Fee PreAuthComplete Fail",sel_gun);
+                        if (!ShmDcCommonData->TradeCancel) {
                             pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
-                        ShmDcCommonData->AuthPass_flag[sel_gun] = FALSE;
-                        memset(&ShmDcCommonData->TransactionInfo[sel_gun].pCreditCard, 0, sizeof(TransInfo));
-                        log_info("Gun%d PreAuth Fail",sel_gun);
+                            StartSystemTimeoutDet(Timeout_VerifyFail);
+                        }
                     }
-                    ShmDcCommonData->PreAuth_Config = _CREDITCARD_IDLE;
-                }
+                    ShmDcCommonData->PreAuth_Result = 0;
+                }*/
             }
 
             // 每30分鐘檢查補扣款
@@ -666,91 +801,6 @@ void CreateRfidFork(void)
             if (tm->tm_hour == 16 && tm->tm_min == 0) {
                 ShmDcCommonData->RoutineSettlement = FALSE;
             }
-            /*
-            // 刷卡判斷
-            if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING ||
-                    !pSysConfig->isRFID) {
-                continue;
-            }
-
-            if (getRequestCardSN(fd, 0, &rfid) == false) {
-                continue;
-            }
-
-            //log_info("Get Card..-%s- ", pSysConfig->UserId);
-            if (strlen((char *)pSysConfig->UserId) != 0) {
-                continue;
-            }
-
-            if (pSysConfig->RfidCardNumEndian == RFID_ENDIAN_LITTLE) {
-                switch (rfid.snType) {
-                case RFID_SN_TYPE_6BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[0], rfid.currentCard[1],
-                            rfid.currentCard[2], rfid.currentCard[3],
-                            rfid.currentCard[4], rfid.currentCard[5]);
-                    break;
-                case RFID_SN_TYPE_7BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[0], rfid.currentCard[1],
-                            rfid.currentCard[2], rfid.currentCard[3],
-                            rfid.currentCard[4], rfid.currentCard[5],
-                            rfid.currentCard[6]);
-                    break;
-                case RFID_SN_TYPE_10BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[0], rfid.currentCard[1],
-                            rfid.currentCard[2], rfid.currentCard[3],
-                            rfid.currentCard[4], rfid.currentCard[5],
-                            rfid.currentCard[6], rfid.currentCard[7],
-                            rfid.currentCard[8], rfid.currentCard[9]);
-                    break;
-                case RFID_SN_TYPE_4BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X",
-                            rfid.currentCard[0], rfid.currentCard[1],
-                            rfid.currentCard[2], rfid.currentCard[3]);
-                    break;
-                }
-            } else if (pSysConfig->RfidCardNumEndian == RFID_ENDIAN_BIG) {
-                switch (rfid.snType) {
-                case RFID_SN_TYPE_6BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[5], rfid.currentCard[4],
-                            rfid.currentCard[3], rfid.currentCard[2],
-                            rfid.currentCard[1], rfid.currentCard[0]);
-                    break;
-                case RFID_SN_TYPE_7BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[6], rfid.currentCard[5],
-                            rfid.currentCard[4], rfid.currentCard[3],
-                            rfid.currentCard[2], rfid.currentCard[1],
-                            rfid.currentCard[0]);
-                    break;
-                case RFID_SN_TYPE_10BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
-                            rfid.currentCard[9], rfid.currentCard[8],
-                            rfid.currentCard[7], rfid.currentCard[6],
-                            rfid.currentCard[5], rfid.currentCard[4],
-                            rfid.currentCard[3], rfid.currentCard[2],
-                            rfid.currentCard[1], rfid.currentCard[0]);
-                    break;
-                case RFID_SN_TYPE_4BYTE:
-                    sprintf((char *) pSysConfig->UserId,
-                            "%02X%02X%02X%02X",
-                            rfid.currentCard[3], rfid.currentCard[2],
-                            rfid.currentCard[1], rfid.currentCard[0]);
-                    break;
-                }
-            }
-            log_info("card number = %s", pSysConfig->UserId);
-            */
         }
     }
 }

+ 152 - 138
EVSE/Projects/DD360Tcci/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.19.00.0000.00"; // Phihong version
-char* DebugVersion = "V2.19.00";      // Software debug version
+char *fwVersion = "V2.20.00.0000.00"; // Phihong version
+char* DebugVersion = "V2.20.03";      // Software debug version
 //sqlite3 *localDb;
 bool isDb_ready;
 
@@ -2581,8 +2581,10 @@ void CreateTimeoutFork(void)
                     log_info("Timeout_VerifyFail");
                     StopSystemTimeoutDet();
                     systemPageRestoreInit();
-                    setChargerMode(pSysInfo->CurGunSelected, S_IDLE);
+                    if (!ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].ParkingStatus)
+                        setChargerMode(pSysInfo->CurGunSelected, S_IDLE);
                     ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1;
+                    ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].GetParkingBill = FALSE;
                 }
                 break;
                 /*
@@ -2661,6 +2663,8 @@ void CreateTimeoutFork(void)
                     setChargerMode(pSysInfo->CurGunSelected, MODE_IDLE);
                     systemPageRestoreInit();
                     ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1;
+                    ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].GetParkingBill = FALSE;
+
                 }
                 break;
             case Timeout_LINEPAYING:
@@ -2680,7 +2684,7 @@ void CreateTimeoutFork(void)
                 if (pDcChargingInfo->TimeoutFlag != 0)
                 log_info("Timeout ***********GunTimeoutFlag = %d(%d) ********",pDcChargingInfo->TimeoutFlag,
                         GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL);
-                */        
+                */       
                 switch (pDcChargingInfo->TimeoutFlag) {
 
                 case Timeout_AuthorizingForStop:
@@ -2783,6 +2787,16 @@ void CreateTimeoutFork(void)
                         ShmDcCommonData->OperateIDLE[gunIndex] = 1;
                 	}
                 	break;
+                case Timeout_ParkingBill:
+                	if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_PARKINGBILL_TIMEOUT) {
+                        log_info("Gun[%d] Timeout_LineReigster",gunIndex);
+                		StopGunInfoTimeoutDet(gunIndex);
+                        systemPageRestoreInit();
+                		ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = FALSE;
+                        ShmDcCommonData->OperateIDLE[gunIndex] = 1;
+                        ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill = FALSE;
+                	}
+                	break;
                 case Timeout_ExitPage:
                     if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_EXITPAGE_TIMEOUT) {
                         log_info("Gun[%d] Timeout_ExitPage", gunIndex);
@@ -2801,6 +2815,36 @@ void CreateTimeoutFork(void)
                         StopGunInfoTimeoutDet(gunIndex);
                     }
                     break;
+                case Timeout_WaitParkingInfo:
+                    if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= WAIT_PARKING_INFO_TIMEOUT) {
+                        log_info("Gun[%d] Timeout_WaitParkingInfo", gunIndex);
+                        StopGunInfoTimeoutDet(gunIndex);
+                        systemPageRestoreInit();
+                        ShmDcCommonData->OperateIDLE[gunIndex] = 1;
+                        ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill = FALSE;
+
+                    }
+                    break;
+                case Timeout_ParkingSelect:
+                    if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_PARK_SELECTPAY_TIMEOUT) {
+                        log_info("Gun[%d] Timeout_ParkingSelect", gunIndex);
+                        StopGunInfoTimeoutDet(gunIndex);
+                        systemPageRestoreInit();
+                        ShmDcCommonData->OperateIDLE[gunIndex] = 1;
+                        ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill = FALSE;
+
+                    }
+                    break;
+                case Timeout_ParkingLeave:
+                    if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_EXITPAGE_TIMEOUT) {
+                        log_info("Gun[%d] Timeout_ParkingLeave", gunIndex);
+                        StopGunInfoTimeoutDet(gunIndex);
+                        systemPageRestoreInit();
+                        ShmDcCommonData->OperateIDLE[gunIndex] = 1;
+                        ShmDcCommonData->pGunInfo[gunIndex].isParking = FALSE;
+                        ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill = FALSE;
+                    }
+                    break;                    
                 }
             }
             sleep(1);
@@ -3571,6 +3615,7 @@ static void autoStartCharging(uint8_t gunIndex)
             ShmDcCommonData->AuthPass_flag[gunIndex] = TRUE;
             //setChargerMode(gunIndex, MODE_AUTHORIZING);
             log_info("Get User(%d) ID:%s",gunIndex,pSysConfig->UserId);
+            sleep(1);   //讓其他task有時間執行
         }
     }
 }
@@ -4044,127 +4089,75 @@ void showversion()
     len += sprintf(&str[len],"==================================== ");
     log_info("%s",str);
 }
-void SetNatural200AGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
-{
-    memset(&deratingByConnOtp->deratingTargetRate[0], 200, sizeof(deratingByConnOtp->deratingTargetRate));
-}
-void SetNatural300AGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
-{
-    deratingByConnOtp->deratingTargetCurrent[0] = 500;
-    deratingByConnOtp->deratingTargetCurrent[1] = 300;
-    deratingByConnOtp->deratingTargetCurrent[2] = 100;
-    deratingByConnOtp->deratingTargetCurrent[3] = 100;
-    deratingByConnOtp->deratingTargetCurrent[4] = 100;
-}
-void SetLiquidCoolGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
-{
-    deratingByConnOtp->deratingTargetCurrent[0] = 500;
-    deratingByConnOtp->deratingTargetCurrent[1] = 400;
-    deratingByConnOtp->deratingTargetCurrent[2] = 300;
-    deratingByConnOtp->deratingTargetCurrent[3] = 300;
-    deratingByConnOtp->deratingTargetCurrent[4] = 300;
-}
-void SetCHAdeMoTypeJOTPValue(uint8_t regulation,struct DERATING_BY_OTP* deratingByConnOtp)
-{
-    if (regulation == 'J') {
-        memset(&deratingByConnOtp->deratingTargetRate[0], 125, sizeof(deratingByConnOtp->deratingTargetRate));
-    } else {
-        memset(&deratingByConnOtp->deratingTargetRate[0], 120, sizeof(deratingByConnOtp->deratingTargetRate));
-    }
-}
-void SetCHAdeMoTypeKOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
-{
-    memset(&deratingByConnOtp->deratingTargetRate[0], 200, sizeof(deratingByConnOtp->deratingTargetRate));
-}
 
-void SetCHAdeMoTypeSJOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+void ParkingProcess(int gunIndex)
 {
-    deratingByConnOtp->deratingTargetRate[0] = 1;
-    deratingByConnOtp->deratingTargetRate[1] = 0.8;
-}
+    if (pSysInfo->CurGunSelected != gunIndex)
+        return;
 
-static void SetGunTypeOTPValue(void)
-{
-    //struct ChargingInfoData* chargingData_2 = NULL;
-    uint8_t Gun1Type = 0;
-    uint8_t Gun2Type = 0;
-    int i;
-    if (pSysConfig->TotalConnectorCount == 1) {
-        pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(0);
-        Gun1Type = pSysConfig->ModelName[7];
-        Gun2Type = pSysConfig->ModelName[7];
-
-        switch (Gun1Type) {
-        //CHAdeMo
-        case 'J':
-            SetCHAdeMoTypeJOTPValue(pSysConfig->ModelName[3], &pDcChargingInfo->deratingByConnOtp);
+    // 取得佔位費資訊過場畫面
+    if (ShmDcCommonData->pGunInfo[gunIndex].ParkingStatus == _TCC_PARKING_NONE) {
+        return;
+    } else if (!ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill &&
+        pSysInfo->SystemPage != _PAGE_IDLE &&
+        pSysInfo->SystemPage != _PAGE_SELECT_GUN &&
+        pSysInfo->SystemPage != _PAGE_COMPLETE &&
+        pSysInfo->SystemPage != _PAGE_PAYFAIL &&
+        pSysInfo->SystemPage != _PAGE_PLUGOUT &&
+        pSysInfo->SystemPage != _PAGE_PLUGIN) {
+        pSysInfo->SystemPage = _PAGE_PAYING;
+        StartGunInfoTimeoutDet(gunIndex, Timeout_WaitParkingInfo);
+
+        return;
+    }
+    if (ShmDcCommonData->pGunInfo[gunIndex].GetParkingBill && pSysInfo->SystemPage == _PAGE_PAYING) {
+            pSysInfo->SystemPage = _PAGE_BILL;
+    }
+    switch (pSysInfo->SystemPage) {
+        case _PAGE_BILL:
+        case _PAGE_DONATE_LEFT:
+        case _PAGE_DONATE_RIGHT:
+        case _PAGE_SELECT_PAY:
+            StartGunInfoTimeoutDet(gunIndex, Timeout_ParkingSelect);
             break;
-        case 'K':
-            SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp);
+        case _PAGE_ADD_FRIEND:
+            StartGunInfoTimeoutDet(gunIndex, Timeout_ParkingBill);
+            if (ShmDcCommonData->ParkingInfo[gunIndex].LineStatus == _LINE_PARKING_INVOICE) {
+                ShmDcCommonData->ParkingInfo[gunIndex].IsDonateInvoice = FALSE;
+                pSysInfo->SystemPage = _PAGE_SELECT_PAY;
+                StopGunInfoTimeoutDet(gunIndex);
+                log_info("Change to Select Pay Page");
+            } else if (ShmDcCommonData->ParkingInfo[gunIndex].LineStatus == _LINE_PARKING_DONATE) {
+                ShmDcCommonData->ParkingInfo[gunIndex].IsDonateInvoice = TRUE;
+                pSysInfo->SystemPage = _PAGE_SELECT_PAY;
+                StopGunInfoTimeoutDet(gunIndex);
+                log_info("Change to Select Pay Page");
+            }
             break;
-        case 'S':
-            SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
+        case _PAGE_AUTHORIZE:
+            StopGunInfoTimeoutDet(gunIndex);
             break;
-        // 風冷200A以下
-        case 'U':
-        case 'E':
-        case 'M':
-        case 'N':
-            SetNatural200AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+        case _PAGE_PLUGIN:
+            StartGunInfoTimeoutDet(gunIndex,Timeout_ParkingLeave);
+            /*
+            if (pDcChargingInfo->ConnectorPlugIn == NO ) {
+                if (pSysInfo->CurGunSelected == gunIndex) {
+                    StartGunInfoTimeoutDet(gunIndex, Timeout_ExitPage);
+                }
+                if (pDcChargingInfo->TimeoutFlag != Timeout_ExitPage) {
+                    StartGunInfoTimeoutDet(gunIndex, Timeout_CompletPlugout);
+                }
+            }
+            */
             break;
-        // 風冷300A
-        case 'T':
-        case 'D':
-            SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+        case _PAGE_AUTHORIZE_FAIL:
+            StartSystemTimeoutDet(Timeout_VerifyFail);
             break;
-        // 水冷
-        case 'V':
-        case 'F':
-        case 'P':
-        case 'R':
-            SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+        case _PAGE_PLUGOUT:
+            StopGunInfoTimeoutDet(gunIndex);
             break;
-        }
-
-    } else if (pSysConfig->TotalConnectorCount == 2) {
-        Gun1Type = pSysConfig->ModelName[7];
-        Gun2Type = pSysConfig->ModelName[9];
-        for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
-            pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i);
-            pDcChargingInfo->deratingByConnOtp.isNeedDerating = GUNOTPDERATING;
-            switch (i == 0 ? Gun1Type : Gun2Type) {
-                //CHAdeMo
-            case 'J':
-                SetCHAdeMoTypeJOTPValue(pSysConfig->ModelName[3], &pDcChargingInfo->deratingByConnOtp);
-                break;
-            case 'K':
-                SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp);
-                break;
-            case 'S':
-                SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
-                break;
-                // 風冷200A以下
-            case 'U':
-            case 'E':
-            case 'M':
-            case 'N':
-                SetNatural200AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
-                break;
-                // 風冷300A
-            case 'T':
-            case 'D':
-                SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
-                break;
-                // 水冷
-            case 'V':
-            case 'F':
-            case 'P':
-            case 'R':
-                SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
-                break;
-            }
-        }
     }
+
 }
 
 int main(void)
@@ -4319,6 +4312,9 @@ int main(void)
 
     showversion();
 
+    ShmDcCommonData->ParkingLeaveTime = 15; //結束充電15分鐘後開始計算佔位費
+    ShmDcCommonData->SaleLeaveTime = 10;    //結算佔位費後開始計算10分鐘
+
     for (;;) {
 
         CheckOcppStatus();
@@ -4327,8 +4323,7 @@ int main(void)
 
         if ((IsConnectorWholeIdle() ||
                 //(pSysInfo->PageIndex == _LCM_ERROR)) &&
-                (pSysInfo->PageIndex == _PAGE_MAINTAIN)) &&
-                (pSysInfo->SystemTimeoutFlag != Timeout_ReturnToChargingGunDet)
+                (pSysInfo->PageIndex == _PAGE_MAINTAIN))
            ) {
             CheckFactoryConfigFunction();
 
@@ -4423,26 +4418,34 @@ int main(void)
 				}
 
                 if (pSysInfo->CurGunSelected == gunIndex) {
-                    if (pSysInfo->SystemPage == _PAGE_BILL) {
-                        StartSystemTimeoutDet(Timeout_AddLine);
-                        if (/*ShmDcCommonData->LineStatus[gunIndex] == 1 ||*/ ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_ADD_FRIEND) {
-                            pSysInfo->SystemPage = _PAGE_ADD_FRIEND;
-                            log_info("Change to Add Line Friend Page");
-                        }
-                    } else if (pSysInfo->SystemPage == _PAGE_ADD_FRIEND) {
-                        StopSystemTimeoutDet();
-                        StartGunInfoTimeoutDet(gunIndex, Timeout_LineReigster);
-                        if (ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_CREDITCARD_INVOICE) {
-                            StopGunInfoTimeoutDet(gunIndex);
-                            pSysInfo->SystemPage = _PAGE_SELECT_PAY;
-                            ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = FALSE;
-                            log_info("Change to Select Pay Page");
-                        }
-                        if (ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_CREDITCARD_DONATE) {
-                            StopGunInfoTimeoutDet(gunIndex);
-                            pSysInfo->SystemPage = _PAGE_SELECT_PAY;
-                            ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = TRUE;
-                            log_info("Change to Select Pay Page");
+                    if (ShmDcCommonData->pGunInfo[gunIndex].isParking) {
+                        // 佔位費流程
+                        ParkingProcess(gunIndex);
+                    } else {
+                        // 一般充電流程
+                        if (pSysInfo->SystemPage == _PAGE_BILL) {
+                            StartSystemTimeoutDet(Timeout_AddLine);
+                            /*
+                            if (ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_ADD_FRIEND) {
+                                pSysInfo->SystemPage = _PAGE_ADD_FRIEND;
+                                log_info("Change to Add Line Friend Page");
+                            }
+                            */
+                        } else if (pSysInfo->SystemPage == _PAGE_ADD_FRIEND) {
+                            StopSystemTimeoutDet();
+                            StartGunInfoTimeoutDet(gunIndex, Timeout_LineReigster);
+                            if (ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_CREDITCARD_INVOICE) {
+                                StopGunInfoTimeoutDet(gunIndex);
+                                pSysInfo->SystemPage = _PAGE_SELECT_PAY;
+                                ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = FALSE;
+                                log_info("Change to Select Pay Page");
+                            }
+                            if (ShmDcCommonData->TransactionInfo[gunIndex].LineStatus == _LINE_CREDITCARD_DONATE) {
+                                StopGunInfoTimeoutDet(gunIndex);
+                                pSysInfo->SystemPage = _PAGE_SELECT_PAY;
+                                ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = TRUE;
+                                log_info("Change to Select Pay Page");
+                            }
                         }
                     }
                 }
@@ -4480,7 +4483,7 @@ int main(void)
                         //pSysInfo->SystemPage = _PAGE_MAINTAIN;
                     }
                 }
-            CheckStatus:
+CheckStatus:
                 if (pDcChargingInfo->IsAvailable == NO) {
                     setChargerMode(gunIndex, MODE_MAINTAIN);
                     break;
@@ -4864,6 +4867,11 @@ int main(void)
 
                 }
 
+                if (ShmDcCommonData->pGunInfo[gunIndex].isParking) {
+                    ParkingProcess(gunIndex);
+                    break;
+                }
+
                 if (pDcChargingInfo->Replug_flag == TRUE && pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->SystemPage = _PAGE_PLUGOUT;
                     break;
@@ -4931,6 +4939,12 @@ int main(void)
                         StartGunInfoTimeoutDet(gunIndex, Timeout_CompletPlugout);
                     }
                 }
+
+                if (ShmDcCommonData->pGunInfo[gunIndex].isParking) {
+                    ParkingProcess(gunIndex);
+                    break;
+                }
+
                 if (pDcChargingInfo->Replug_flag == TRUE && pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->SystemPage = _PAGE_PLUGOUT;
                     break;

+ 3 - 2
EVSE/Projects/DD360Tcci/Apps/CSU/main.h

@@ -33,7 +33,7 @@
 #define AUTHORIZE_FAIL_TIMEOUT                  (5)
 #define AUTHORIZE_STOP_TIMEOUT                  (30)
 #define LINKERROR_TIMEOUT						(120)
-#define RETURN_TO_CHARGING_PAGE                 (30)
+#define WAIT_PARKING_INFO_TIMEOUT               (10)
 #define GUN_PREPARE_TIMEOUT                     (30)
 #define GUN_EV_WAIT_TIMEOUT                     (120)
 #define GUN_EVSE_WAIT_TIMEOUT                   (60)
@@ -41,7 +41,7 @@
 #define GUN_PRECHARGING_TIMEOUT                 (60)
 #define EVCCID_LINK_TIMEOUT                     (120)
 #define CONN_PLUG_TIMEOUT                       (40)
-#define DETAILVIEW_TIMEOUT                      (30)
+#define TCC_PARK_SELECTPAY_TIMEOUT              (30)
 #define TERMINATING_TIMEOUT                     (120)
 #define WHILE_LOOP_TIME                         (10000)
 #define PRECHARGING_TTIMEOUT                    (60)
@@ -57,6 +57,7 @@
 #define TCC_ISPLUGOUT_TIMEOUT                   (3)
 #define TCC_LINEPAYING_TIMEOUT                  (5)
 #define TCC_COMPLETE_PLUGOUT_TIMEOUT            (120)
+#define TCC_PARKINGBILL_TIMEOUT			    	(120)
 
 //#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)

+ 34 - 3
EVSE/Projects/DD360Tcci/Apps/Config.h

@@ -305,6 +305,8 @@ enum _CREDIT_DEDUCT_STATUS {
     _DEDUCT_COMPLETE_PASS = 1,
     _DEDUCT_CANCEL,
     _DEDUCT_PREAUTH,
+    _DEDUCT_SALE_FAIL,
+    _DEDUCT_SALE_PASS,
     _DEDUCT_REMOTESTART,
 };
 enum _LINE_STATUS {
@@ -316,10 +318,14 @@ enum _LINE_STATUS {
     _LINE_PAY_INVOICE = 7,
     _LINE_PAY_DONATE,
     _LINE_PAY_OPERATE,
+    _LINE_PARKING_INVOICE,
+    _LINE_PARKING_DONATE,
+    _LINE_PARKING_ONLINE_PASS = 12,
+    _LINE_PARKING_ONLINE_FAIL,
 };
 enum _DERATING_TEMP {
-    _DERATING_80 = 140,
-    _DERATING_85 = 145,
+    STAGE1_GUN_DERATING_TEMP = 140,
+    STAGE2_GUN_DERATING_TEMP = 145,
 };
 //------------------------------------------------------------------------------
 //struct StructMeter {
@@ -445,8 +451,14 @@ typedef struct StGunInfo {
     char ChargeStartTime[32];
     char ChargeStopTime[32];
     char ChargeDuration[32];
+
+
     uint8_t withChiller;      //是否有水冷機
     uint8_t WaitForPlugit;    // 等待插槍FLAG
+    uint8_t isParking;        // 進入佔位狀態
+    uint8_t ParkingStatus;    // 佔位狀態
+    uint8_t GetParkingBill;   // 得到Parking Bill
+    uint8_t ReqParkingBill;   // 要求主櫃對後臺要Parking Bill
 } GunInfo;
 
 typedef struct Psu_VersionInfo{
@@ -461,6 +473,16 @@ enum _LCM_UPGRADE_RESULT {
     _LCM_UPGRADE_RESULT_FAIL,
 };
 
+enum _TCC_PARKING_STATUS {
+    _TCC_PARKING_NONE = 0,
+    _TCC_PARKING_OCCUPENCY,
+    _TCC_PARKING_OCCUPENCY_Ready,
+    _TCC_PARKING_REQ_PARKING_FEE,
+    _TCC_WAIT_PAY,
+    _TCC_ONLINEPAY_PASS,
+    _TCC_ONLINEPAY_FAIL,
+};
+
 typedef struct stTransInfo
 {
 	unsigned char TransDate[6];	//交易日期
@@ -489,6 +511,11 @@ typedef struct stRecordTransactionInfo
     float prices;
     int RedeductTime;
     int LineStatus;                        // Line State
+    unsigned char OccupancySN[36];
+    int ParkingDuration;
+    char ParkingStartTime[32];
+    time_t ParkingStopTime;
+    int ParkingCntDownFlag;
 }RecordTransactionInfo;
 
 typedef struct stPriceBillInfo {
@@ -552,6 +579,7 @@ typedef struct StDcCommonInfo {
 
     RecordTransactionInfo TransactionInfo[2];
     RecordTransactionInfo RedeductBill;
+    RecordTransactionInfo ParkingInfo[2];
     PriceBillInfo PriceBill;
 
     int UnionSettlement;
@@ -562,7 +590,6 @@ typedef struct StDcCommonInfo {
     int RoutineReupload;
     int TZOffset;
     int DebugFlag;
-    int chillerCtrl;
     int is_RemoteStart[2];
     int is_AutoStart[2];
     time_t RecordEnergyTime[2];
@@ -582,6 +609,10 @@ typedef struct StDcCommonInfo {
     uint8_t lcmtest;
     char DebugVersion[32];
     uint8_t BackLight;
+    float ParkingRate;
+    int ParkingLeaveTime;
+    int SaleLeaveTime;
+    int netdump; //印出網路封包
 } DcCommonInfo;
 
 #endif /* CONFIG_H_ */

+ 352 - 5
EVSE/Projects/DD360Tcci/Apps/DataBase/DataBase.c

@@ -12,10 +12,12 @@
 //------------------------------------------------------------------------------
 #define DB_FILE                                 "/Storage/ChargeLog/localCgargingRecord.db"
 #define DEDUCT_FILE                 			"/Storage/ChargeLog/CreditCardRecord.db"
+#define PARKINGDEDUCT_FILE                 		"/Storage/ChargeLog/ParkingCreditCardRecord.db"
 #define POWER_FILE                 			    "/Storage/ChargeLog/PowerConsumption.db"
 //------------------------------------------------------------------------------
 static sqlite3 *localDb;
 static sqlite3 *deductDb;
+static sqlite3 *parkingDb;
 static sqlite3* powerDb;
 static DcCommonInfo* ShmDcCommonData = NULL;
 //------------------------------------------------------------------------------
@@ -498,11 +500,11 @@ int UpdateDeductInfoStatus(int gunIndex, RecordTransactionInfo *deductInfo)
     int result = PASS;
     char *errMsg = NULL;
     char sqlStr[1024] = {0};
-    char vemData[65] = {0};
-    memset(vemData, '\0', 65);
-    strncpy(vemData, (char*)&deductInfo->pCreditCard.VemData,64);
+    char ApprovalNo[10] = {0};
+    memset(ApprovalNo, '\0', 10);
+    strncpy(ApprovalNo, (char*)&deductInfo->pCreditCard.ApprovalNo,9);
 
-    sprintf(sqlStr, "update report_credit_deduct set isUpload = %d , isIntoCharge = %d, amount = %.1f, txId = %d, isDeductResult = %d, Energy = %.4f, lineSn = %d, RedeductTime = %d where vemData = '%s'; ",
+    sprintf(sqlStr, "update report_credit_deduct set isUpload = %d , isIntoCharge = %d, amount = %.1f, txId = %d, isDeductResult = %d, Energy = %.4f, lineSn = %d, RedeductTime = %d where approvalNo = '%s'; ",
                     (int)deductInfo->IsUpload,
                     (int)deductInfo->isIntoCharge,
                     deductInfo->Amount,
@@ -511,7 +513,7 @@ int UpdateDeductInfoStatus(int gunIndex, RecordTransactionInfo *deductInfo)
                     deductInfo->Energy,
                     deductInfo->LineStatus,
                     deductInfo->RedeductTime,
-                    vemData);
+                    ApprovalNo);
 
     //log_info("%s",sqlStr);
 
@@ -916,5 +918,350 @@ int DB_Get_PowerConsumption(uint8_t gunIndex)
         sqlite3_close(powerDb);
     }
 
+    return result;
+}
+
+int ParkingDB_Open(void)
+{
+	int result = PASS;
+	char* errMsg = NULL;
+	char* createDeductInfoSql="CREATE TABLE IF NOT EXISTS report_Parking_deduct("
+					      	  "idx integer primary key AUTOINCREMENT, "
+							  "gun_index text, "
+                              "vemData text, "
+                              "OccupancySN text, "
+                              "duration text, "
+                              "creditNo text, "
+                              "amount text, "
+                              "storeId text, "
+                              "approvalNo text, "
+                              "RRN text, "
+                              "ROC text, "
+                              "isDonateInvoice text, "
+                              "isDeductResult text, "
+                              "isUpload text, "
+                              "lineSn text, "
+                              "StartTime text, "
+                              "RedeductTime "
+						  	  ");";
+	if(sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+	{
+		result = FAIL;
+		log_info("Can't open Parking deduct database: %s", sqlite3_errmsg(parkingDb));
+		sqlite3_close(parkingDb);
+	}
+	else
+	{
+		//log_info("Deduct database open successfully.");
+		if (sqlite3_exec(parkingDb, createDeductInfoSql, 0, 0, &errMsg) != SQLITE_OK)
+		{
+			result = FAIL;
+			log_info("Create Parking deduct info table error message: %s", errMsg);
+		}
+		else
+		{
+			log_info("Opened Parking deduct info table successfully");
+		}
+       
+		sqlite3_close(parkingDb);
+	}
+
+	return result;
+}
+
+int InsertParkingDeductInfo(int gunIndex, RecordTransactionInfo *deductInfo)
+{
+    int result = PASS;
+    char *errMsg = NULL;
+    char sqlStr[1024] = {0};
+    char approNo[13];
+    char carNo[21];
+    char OccupancySN[37];
+    char storeId[18];
+    char RRN[12];
+    char ROC[12];
+    char lineSn[20];
+    char _time[33];
+    char vemData[65];
+
+    memset(approNo, '\0', sizeof(approNo));
+    memset(carNo, '\0', sizeof(carNo));
+    memset(OccupancySN, '\0', sizeof(OccupancySN));
+    memset(storeId, '\0', sizeof(storeId));
+    memset(RRN, '\0', sizeof(RRN));
+    memset(ROC, '\0', sizeof(ROC));
+    memset(lineSn, '\0', sizeof(lineSn));
+    memset(_time,'\0',sizeof(_time));
+    memset(vemData,'\0',sizeof(vemData));
+
+    strncpy(approNo, (char *)&deductInfo->pCreditCard.ApprovalNo,9);
+    strncpy(carNo, (char *)&deductInfo->pCreditCard.CardNo,20);
+    strncpy(OccupancySN, (char *)&deductInfo->OccupancySN,36);
+    strncpy(storeId, (char *)&deductInfo->pCreditCard.StoreId,18 );
+    strncpy(RRN,(char *)&deductInfo->pCreditCard.RRN,12);
+    strncpy(ROC,(char *)&deductInfo->pCreditCard.ROC,12);
+    strncpy(_time,(char *)&deductInfo->ParkingStartTime,33);
+    strncpy(vemData,(char *)&deductInfo->pCreditCard.VemData,64);
+
+    //sprintf(reportDate, "%s%s", deductInfo->pCreditCard.TransDate, deductInfo->pCreditCard.TransTime);
+
+	sprintf(sqlStr, "insert into report_Parking_deduct(gun_index, vemData, OccupancySN, duration, creditNo, amount, storeId, approvalNo, RRN, ROC, isDonateInvoice, isDeductResult, isUpload, lineSn, StartTime, RedeductTime) "
+				    "values('%d', '%s', '%s', '%d', '%s', '%.1f', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%s', '%d');",
+                    gunIndex,
+                    vemData,
+				    OccupancySN,
+                    deductInfo->ParkingDuration,
+                    carNo,
+                    deductInfo->Amount,
+					storeId,
+                    approNo,
+				    RRN,
+				    ROC,
+                    (int)deductInfo->IsDonateInvoice,
+                    (int)deductInfo->DeductResult,
+                    (int)deductInfo->IsUpload,
+                    deductInfo->LineStatus,
+                    _time,
+                    deductInfo->RedeductTime);
+
+    //log_info("%s",sqlStr);
+
+    if (sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+    {
+        result = FAIL;
+        log_info( "Can't open deduct database: %s", sqlite3_errmsg(parkingDb));
+        sqlite3_close(parkingDb);
+    }
+    else
+    {
+        //log_info( "Local event record database open successfully.");
+        if (sqlite3_exec(parkingDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
+        {
+            result = FAIL;
+            log_info( "Insert deduct record error message: %s", errMsg);
+        }
+        else
+        {
+            //log_info( "Insert local event record successfully");
+        }
+
+
+        sprintf(sqlStr, "delete from report_Parking_deduct where idx < (select idx from report_Parking_deduct order by idx desc limit 1)-10000;");
+        if (sqlite3_exec(parkingDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
+        {
+            result = FAIL;
+            log_info("delete deduct record error message: %s", errMsg);
+        }
+        else
+        {
+            //log_info("delete local charging record successfully");
+        }
+
+        sqlite3_close(parkingDb);
+    }
+
+    return result;
+}
+
+// return quantity of DeductInfo
+int DB_GetParkingDeductUpload(int *gunIndex, RecordTransactionInfo *deductInfo)
+{
+    char *errMsg = NULL;
+    char sqlStr[1024];
+    char **rs;
+    int rows = 0, cols = 0;
+
+    sprintf(sqlStr, "select * from report_Parking_deduct where isUpload = 0;");
+
+    if (sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+    {
+        log_info("Can't open parking database: %s", sqlite3_errmsg(parkingDb));
+        sqlite3_close(parkingDb);
+    }
+    else
+    {
+        sqlite3_get_table(parkingDb, sqlStr, &rs, &rows, &cols, &errMsg);
+
+        if (rows > 0)
+        {
+            for (int idxRow = 1; idxRow <= rows; idxRow++)
+            {
+                //gunIndex[idxRow - 1] = atoi(rs[(idxRow * cols) + 1]);
+                deductInfo[idxRow - 1].ConnectorID = atoi(rs[(idxRow * cols) + 1]);
+                // GetDeductTime(rs[(idxRow * cols) + 1], deductInfo);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.VemData, rs[(idxRow * cols) + 2],64);
+                memcpy((char*)&deductInfo[idxRow - 1].OccupancySN, rs[(idxRow * cols) + 3],36);
+                deductInfo[idxRow - 1].ParkingDuration = atoi(rs[(idxRow * cols) + 4]);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.CardNo, rs[(idxRow * cols) + 5],20);
+                deductInfo[idxRow - 1].Amount = atoi(rs[(idxRow * cols) + 6]);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.StoreId, rs[(idxRow * cols) + 7],18);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.ApprovalNo, rs[(idxRow * cols) + 8],9);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.RRN, rs[(idxRow * cols) + 9],12);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.ROC, rs[(idxRow * cols) + 10],12);
+                deductInfo[idxRow - 1].IsDonateInvoice = atoi(rs[(idxRow * cols) + 11]);
+                deductInfo[idxRow - 1].DeductResult = atoi(rs[(idxRow * cols) + 12]);
+                deductInfo[idxRow - 1].IsUpload = atoi(rs[(idxRow * cols) + 13]);
+                deductInfo[idxRow - 1].LineStatus = atoi(rs[(idxRow * cols) + 14]);
+                memcpy((char*)&deductInfo[idxRow - 1].ParkingStartTime, rs[(idxRow * cols) + 15],32);
+                deductInfo[idxRow - 1].RedeductTime = atoi(rs[(idxRow * cols) + 16]);
+                if(idxRow >= 128)
+                {
+                	rows = 128;
+                	break;
+                }
+            }
+        }
+
+        sqlite3_free_table(rs);
+        sqlite3_close(parkingDb);
+    }
+
+    return rows;
+}
+
+int DB_GetParkingDeductResult(int *gunIndex, RecordTransactionInfo *deductInfo)
+{
+    char *errMsg = NULL;
+    char sqlStr[1024];
+    char **rs;
+    int rows = 0, cols = 0;
+
+    sprintf(sqlStr, "select * from report_Parking_deduct where isDeductResult = 0 OR isDeductResult = 3;");
+
+    if (sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+    {
+        log_info("Can't open parking database: %s", sqlite3_errmsg(parkingDb));
+        sqlite3_close(parkingDb);
+    }
+    else
+    {
+        sqlite3_get_table(parkingDb, sqlStr, &rs, &rows, &cols, &errMsg);
+
+        if (rows > 0)
+        {
+            for (int idxRow = 1; idxRow <= rows; idxRow++)
+            {
+                //gunIndex[idxRow - 1] = atoi(rs[(idxRow * cols) + 1]);
+                deductInfo[idxRow - 1].ConnectorID = atoi(rs[(idxRow * cols) + 1]);
+                // GetDeductTime(rs[(idxRow * cols) + 1], deductInfo);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.VemData, rs[(idxRow * cols) + 2],64);
+                memcpy((char*)&deductInfo[idxRow - 1].OccupancySN, rs[(idxRow * cols) + 3],36);
+                deductInfo[idxRow - 1].ParkingDuration = atoi(rs[(idxRow * cols) + 4]);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.CardNo, rs[(idxRow * cols) + 5],20);
+                deductInfo[idxRow - 1].Amount = atoi(rs[(idxRow * cols) + 6]);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.StoreId, rs[(idxRow * cols) + 7],18);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.ApprovalNo, rs[(idxRow * cols) + 8],9);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.RRN, rs[(idxRow * cols) + 9],12);
+                memcpy((char*)&deductInfo[idxRow - 1].pCreditCard.ROC, rs[(idxRow * cols) + 10],12);
+                deductInfo[idxRow - 1].IsDonateInvoice = atoi(rs[(idxRow * cols) + 11]);
+                deductInfo[idxRow - 1].DeductResult = atoi(rs[(idxRow * cols) + 12]);
+                deductInfo[idxRow - 1].IsUpload = atoi(rs[(idxRow * cols) + 13]);
+                deductInfo[idxRow - 1].LineStatus = atoi(rs[(idxRow * cols) + 14]);
+                memcpy((char*)&deductInfo[idxRow - 1].ParkingStartTime, rs[(idxRow * cols) + 15],10);
+                deductInfo[idxRow - 1].RedeductTime = atoi(rs[(idxRow * cols) + 16]);
+                if(idxRow >= 128)
+                {
+                	rows = 128;
+                	break;
+                }
+            }
+        }
+
+        sqlite3_free_table(rs);
+        sqlite3_close(parkingDb);
+    }
+
+    return rows;
+}
+
+
+int UpdateParkingUpload(char* OccupancySN,int is_upload)
+{
+    int result = PASS;
+    char* errMsg = NULL;
+    char sqlStr[1024] = { 0 };
+
+    if (strcmp((char*)OccupancySN,"") == EQUAL) {
+        log_info("OccupancySN is NULL");
+        return;
+    }
+    char SN[37];
+    memset(SN,'\0',sizeof(SN));
+    memcpy((char*)SN,OccupancySN,36);
+    
+    sprintf(sqlStr, "update report_Parking_deduct set IsUpload = %d where OccupancySN = '%s'; ",
+            is_upload,
+            SN);
+
+    //log_info("%s",sqlStr);
+
+    if (sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+    {
+        result = FAIL;
+        log_info("Can't open parking database: %s", sqlite3_errmsg(parkingDb));
+        sqlite3_close(parkingDb);
+    } else
+    {
+        //log_info( "Local event record database open successfully.");
+        if (sqlite3_exec(parkingDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
+        {
+            result = FAIL;
+            log_info("update parkingDB record error message: %s!", errMsg);
+        } else
+        {
+            //log_info( "update deduct record successfully");
+        }
+
+        sqlite3_close(parkingDb);
+    }
+
+    return result;
+}
+
+int UpdateParkingDeductInfo(int gunIndex, RecordTransactionInfo *deductInfo)
+{
+
+    int result = PASS;
+    char *errMsg = NULL;
+    char sqlStr[1024] = {0};
+    char OccupancySN[37] = {0};
+    memset(OccupancySN, '\0', 37);
+    strncpy(OccupancySN, (char*)&deductInfo->OccupancySN,36);
+    if (strcmp((char*)deductInfo->OccupancySN,"") == EQUAL) {
+        log_info("OccupancySN is NULL");
+        return;
+    }
+
+    sprintf(sqlStr, "update report_Parking_deduct set isUpload = %d ,amount = %.1f, isDeductResult = %d, RedeductTime = %d where OccupancySN = '%s'; ",
+                    (int)deductInfo->IsUpload,
+                    deductInfo->Amount,
+                    (int)deductInfo->DeductResult,
+                    deductInfo->RedeductTime,
+                    deductInfo->OccupancySN);
+
+    //  log_info("%s",sqlStr);
+
+    if (sqlite3_open(PARKINGDEDUCT_FILE, &parkingDb))
+    {
+        result = FAIL;
+        log_info( "Can't open deduct database: %s", sqlite3_errmsg(parkingDb));
+        sqlite3_close(parkingDb);
+    }
+    else
+    {
+        //log_info( "Local event record database open successfully.");
+        if (sqlite3_exec(parkingDb, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
+        {
+            result = FAIL;
+            log_info( "update deduct record error message: %s!", errMsg);
+        }
+        else
+        {
+            //log_info( "update deduct record successfully");
+        }
+
+        sqlite3_close(parkingDb);
+    }
+
     return result;
 }

+ 6 - 1
EVSE/Projects/DD360Tcci/Apps/DataBase/DataBase.h

@@ -28,5 +28,10 @@ int UpdateRedeuctBill(int Txid, float amount);
 int DB_GetMultiDeductInfo(int deductResult, int uploadState, int *gunIndex, RecordTransactionInfo *deductInfo);
 int DB_GetMultiReDeductInfo(int *gunIndex, RecordTransactionInfo *deductInfo);
 int DB_GetMultiReUploadDeduct(int *gunIndex, RecordTransactionInfo *deductInfo);
-
+int ParkingDB_Open(void);
+int InsertParkingDeductInfo(int gunIndex, RecordTransactionInfo *deductInfo);
+int DB_GetParkingDeductUpload(int *gunIndex, RecordTransactionInfo *deductInfo);
+int DB_GetParkingDeductResult(int *gunIndex, RecordTransactionInfo *deductInfo);
+int UpdateParkingUpload(char* OccupancySN,int is_upload);
+int UpdateParkingDeductInfo(int gunIndex, RecordTransactionInfo *deductInfo);
 #endif /* _DATA_BASE_H_ */

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 371 - 444
EVSE/Projects/DD360Tcci/Apps/Define/define.h


+ 331 - 49
EVSE/Projects/DD360Tcci/Apps/ModuleDoComm/DoComm.c

@@ -85,7 +85,25 @@ static int DiffTimeb(struct timeb ST, struct timeb ET)
 
     return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm;
 }
-
+static void systemPageRestoreInit(void)
+{
+    int is_idle = TRUE;
+    int gunIndex;
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
+        pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
+        // 檢查電樁狀態是否為idle狀態
+        if ((pDcChargingInfo->SystemStatus >= S_AUTHORIZING &&
+            pDcChargingInfo->SystemStatus <= S_RESERVATION) ||
+            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
+                pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST0)) {
+            is_idle = FALSE;
+        }
+    }
+    if (is_idle)
+        pSysInfo->SystemPage = _PAGE_IDLE;
+    else
+        pSysInfo->SystemPage = _PAGE_SELECT_GUN;
+}
 /**
  * [hexdump : check data]
  * @Author   Jerry
@@ -201,7 +219,11 @@ static void setTcpStatus(uint8_t setValue)
 static int sendTcpSocket(int fd, uint8_t *data, uint16_t dataLen)
 {
     int size = -1;
-
+    if (ShmDcCommonData->netdump) {
+        printf("\nTx Data:\t");
+        for(int i = 0 ; i < dataLen ; i++)
+            printf("[0x%2x] ",data[i]);
+    }
     size = send(fd, data, dataLen , 0);
     if ((size < 0) || (errno == EAGAIN)) {
         if (size < 0) {
@@ -216,7 +238,11 @@ static int recvTcpSocket(int fd, uint8_t *data, uint16_t dataLen)
 {
     int size = -1;
     uint8_t *pdata = (uint8_t *)data;
-
+    if (ShmDcCommonData->netdump) {
+        printf("\nRx Data:\t");
+        for(int i = 0 ; i < dataLen ; i++)
+            printf("[0x%2x] ",data[i]);
+    }
     size = recv(fd, pdata, dataLen, MSG_WAITALL);
     if ((errno == EAGAIN) || (size < 0)) {
         log_error("Receive Socket Size = %d, EAGAIN error %d:%s", size, errno, strerror(errno));
@@ -820,11 +846,20 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
             break;
         case MISC_CMD_LINE_STATUS_REQ:
             LineStatusCode[plugNum] = value;
-            ShmDcCommonData->TransactionInfo[plugNum].LineStatus = value;
-            log_info("Gun %d Line Status Code: %d", plugNum, LineStatusCode[plugNum]);
-            if (ShmDcCommonData->TransactionInfo[plugNum].LineStatus != value &&
-                strcmp((char*)ShmDcCommonData->TransactionInfo[plugNum].pCreditCard.VemData, "") != 0) {
-                UpdateDeductInfoStatus(plugNum,&ShmDcCommonData->TransactionInfo[plugNum]);
+            if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus) {
+                ShmDcCommonData->ParkingInfo[plugNum].LineStatus = value;
+                log_info("Gun %d Line Status Code: %d", plugNum, LineStatusCode[plugNum]);
+                if (ShmDcCommonData->ParkingInfo[plugNum].LineStatus != value &&
+                    strcmp((char*)ShmDcCommonData->ParkingInfo[plugNum].pCreditCard.ApprovalNo, "") != 0) {
+                    UpdateDeductInfoStatus(plugNum,&ShmDcCommonData->ParkingInfo[plugNum]);
+                }
+            } else {
+                ShmDcCommonData->TransactionInfo[plugNum].LineStatus = value;
+                log_info("Gun %d Line Status Code: %d", plugNum, LineStatusCode[plugNum]);
+                if (ShmDcCommonData->TransactionInfo[plugNum].LineStatus != value &&
+                    strcmp((char*)ShmDcCommonData->TransactionInfo[plugNum].pCreditCard.ApprovalNo, "") != 0) {
+                    UpdateDeductInfoStatus(plugNum,&ShmDcCommonData->TransactionInfo[plugNum]);
+                }
             }
             break;
         case MISC_CMD_LED_INTENSITY:
@@ -850,6 +885,31 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
             gMoreInfoReq[plugNum].bits.ChargingBill = YES;
             ShmDcCommonData->PriceBill.gunIndex = plugNum;
             break;
+        case MISC_CMD_PAKING_PRICES:
+            prices = transPricesUnit((int)value);
+            log_info("parking prices = %.2f", prices);
+            if (prices > 0)
+                ShmDcCommonData->ParkingRate = prices;
+            break;
+        case MISC_CMD_PARKING_STATUS:
+            if (gMoreInfoReq[plugNum].bits.ParkingReq != value) {
+                if (value == 0x0001 && pSysInfo->CurGunSelected == plugNum &&
+                    (pSysInfo->SystemPage >= _PAGE_BILL && pSysInfo->SystemPage <= _PAGE_CHARGING ||
+                    pSysInfo->SystemPage ==  _PAGE_DONATE_RIGHT)) {
+                    //log_info("Gun%d already enter charging operate. Don't Enter Parking mode!",plugNum);
+                    return FAIL;
+                }
+                if (value) {
+                    ShmDcCommonData->pGunInfo[plugNum].isParking = TRUE;
+                } else {
+                    log_info("Clear Parking Bill information");
+                    memset(&ShmDcCommonData->ParkingInfo[plugNum], 0, sizeof(RecordTransactionInfo));
+                    ShmDcCommonData->pGunInfo[plugNum].GetParkingBill = FALSE;
+                }
+                log_info("Parking Request %s",value ? "ON" : "OFF");
+            }
+            gMoreInfoReq[plugNum].bits.ParkingReq = value;
+            break;
         default:
             clearMiscCommand();
             break;
@@ -864,8 +924,6 @@ void AddDispenserReq(uint8_t* buff, MiscCommand* req)
     buff[0] = (req->CMD >> 8) & 0xFF;
     buff[1] = req->CMD & 0xFF;
 
-
-
     buff[2] = req->Value[0];
     buff[3] = req->Value[1];
     buff[4] = req->Value[2];
@@ -897,6 +955,20 @@ static int chargingbillHandle(uint8_t* data, uint8_t gunIndex)
         UpdateRedeuctBill(ShmDcCommonData->PriceBill.TransactionId, ShmDcCommonData->PriceBill.TotalCost);
 }
 
+static int parkingbillHandle(uint8_t* data, uint8_t gunIndex)
+{
+
+    ParkingBillInfo* pBillInfo = (ParkingBillInfo*)&data[0];
+
+    ShmDcCommonData->ParkingInfo[gunIndex].Amount = transPricesUnit(ntohl(pBillInfo->ParkingFee));
+    ShmDcCommonData->ParkingInfo[gunIndex].ParkingDuration = ntohl(pBillInfo->Duration);
+    strcpy((char*)ShmDcCommonData->ParkingInfo[gunIndex].ParkingStartTime, (char*)&data[8]);
+    log_info("Gun%d Parking Bill: Amount:[%.2f], Duration:[%d], Start Time[%s]", gunIndex,
+                                                ShmDcCommonData->ParkingInfo[gunIndex].Amount,
+                                                ShmDcCommonData->ParkingInfo[gunIndex].ParkingDuration,
+                                                ShmDcCommonData->ParkingInfo[gunIndex].ParkingStartTime);
+}
+
 static int chargingcapabilityHandle(uint8_t *data, uint8_t plugNum)
 {
     uint8_t addr = 0;
@@ -1473,6 +1545,50 @@ static int responsePackeHandle(int fd, uint8_t *pResult, uint8_t plugNum, uint8_
         }
         chargingbillHandle(pCsuResult->Data.Data, plugNum);
         break;
+    case REG_PARKING_STATUS:
+        if (pCsuResult->Data.Result == COMMAND_RESULT_NG) {
+            return COMMAND_RESULT_NG;
+        }
+        char cmd[37];
+        memset(cmd,'\0',sizeof(cmd));
+        memcpy(cmd,&pCsuResult->Data.Data[1],36);
+        if (memcmp(ShmDcCommonData->ParkingInfo[plugNum].OccupancySN,&pCsuResult->Data.Data[1],36) != EQUAL) {
+            memcpy(ShmDcCommonData->ParkingInfo[plugNum].OccupancySN,&pCsuResult->Data.Data[1],36);
+        }
+        if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus != pCsuResult->Data.Data[0]) {
+            if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus)
+                ShmDcCommonData->pGunInfo[plugNum].isParking = TRUE;
+            ShmDcCommonData->pGunInfo[plugNum].ParkingStatus = pCsuResult->Data.Data[0];
+            log_info("Gun%d Parking STATUS is [%d] SN:[%s]",plugNum,pCsuResult->Data.Data[0],cmd);
+            if (!ShmDcCommonData->pGunInfo[plugNum].ParkingStatus) {
+                //if (pSysInfo->CurGunSelected == plugNum)
+                //    systemPageRestoreInit();
+                gMoreInfoReq[plugNum].bits.ParkingReq = FALSE;
+                ShmDcCommonData->pGunInfo[plugNum].GetParkingBill = FALSE;
+                memset(&ShmDcCommonData->ParkingInfo[plugNum],0,sizeof(RecordTransactionInfo));
+                ShmDcCommonData->ParkingInfo[plugNum].IsUpload = TRUE;
+            } else {
+                if (pSysInfo->SystemPage >= _PAGE_BILL && pSysInfo->SystemPage <= _PAGE_PLUGIN) {
+                    if (pSysInfo->CurGunSelected == plugNum) {
+                        if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus == _TCC_PARKING_OCCUPENCY) {
+                            systemPageRestoreInit();
+                        } else if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus == _TCC_ONLINEPAY_PASS) {
+                            pSysInfo->SystemPage = _PAGE_PLUGIN;
+                        } else if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus == _TCC_ONLINEPAY_FAIL) {
+                            pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
+                        }
+                    }
+                }
+            }
+        }
+
+        break;
+    case REG_PARKING_BILL:
+        if (pCsuResult->Data.Result == COMMAND_RESULT_NG) {
+            return COMMAND_RESULT_NG;
+        }
+        parkingbillHandle(pCsuResult->Data.Data, plugNum);
+        break;
     default:
         break;
     }
@@ -1548,7 +1664,7 @@ static int writeDispenserRequest(int fd, uint8_t id, uint8_t gunIndex)
     int ret = PASS;
     int count = 0;
     MiscCommand dispenserReq;
-    uint8_t data[6] = { 0 };
+    uint8_t data[12] = { 0 };
     if (gConnectorActReq[gunIndex].bits.ChargingCancel)
     {
         dispenserReq.CMD = DISPENSER_REQ_CHARGING_CANCEL;
@@ -1556,18 +1672,27 @@ static int writeDispenserRequest(int fd, uint8_t id, uint8_t gunIndex)
         dispenserReq.Value[1] = 0;
         dispenserReq.Value[2] = 0;
         dispenserReq.Value[3] = 1;
-        AddDispenserReq(data, &dispenserReq);
+        AddDispenserReq(&data[count*6], &dispenserReq);
         count++;
         //log_info("Write Gun %d CHARGING_CANCEL", gunIndex);
     }
+    if (gConnectorActReq[gunIndex].bits.ParkingBillReq) {
+        dispenserReq.CMD = DISPENSER_REQ_PARKING_BILL;
+        dispenserReq.Value[0] = 0;
+        dispenserReq.Value[1] = 0;
+        dispenserReq.Value[2] = 0;
+        dispenserReq.Value[3] = 1;
+        AddDispenserReq(&data[count*6], &dispenserReq);
+        count++;
+    }
 
     if ((ret = composeSocketData(fd,
-        id,
-        OP_WRITE_DATA,
-        REG_DISPENSER_REQUEST,
-        (count * 6),
-        &data[0])) == FAIL) {
-        return ret;
+                                id,
+                                OP_WRITE_DATA,
+                                REG_DISPENSER_REQUEST,
+                                (count * 6),
+                                &data[0])) == FAIL) {
+                                return ret;
     }
     return ret;
 }
@@ -1619,6 +1744,38 @@ static int readChargingBill(int fd,int gunID)
     return ret;
 }
 
+static int readParkingStatus(int fd, int gunID)
+{
+    int ret = PASS;
+
+    if ((ret = composeSocketData(fd,
+                                gunID,
+                                OP_READ_DATA,
+                                REG_PARKING_STATUS,
+                                0,
+                                NULL)) == FAIL) {
+        return ret;
+    }
+
+    return ret;
+}
+
+static int readParkingBill(int fd, int gunID)
+{
+    int ret = PASS;
+
+    if ((ret = composeSocketData(fd,
+                                gunID,
+                                OP_READ_DATA,
+                                REG_PARKING_BILL,
+                                0,
+                                NULL)) == FAIL) {
+        return ret;
+    }
+
+    return ret;
+}
+
 static int readChargerStationInfo(int fd)
 {
     int ret = PASS;
@@ -1634,16 +1791,42 @@ static int readChargerStationInfo(int fd)
 
     return ret;
 }
+void showDeductInfo(RecordTransactionInfo* transactionInfo)
+{
+    char ApprovalNo[10];
+    char vemdata[65];
+    char cardno[21];
+    char OccupancySN[37];
+    memset(ApprovalNo,'\0',sizeof(ApprovalNo));
+    memset(vemdata,'\0',sizeof(vemdata));
+    memset(cardno,'\0',sizeof(cardno));
+    memset(OccupancySN,'\0',sizeof(OccupancySN));
+    memcpy(ApprovalNo,&transactionInfo->pCreditCard.ApprovalNo[0],9);
+    memcpy(vemdata,&transactionInfo->pCreditCard.VemData[0],64);
+    memcpy(cardno,&transactionInfo->pCreditCard.CardNo[0],20);
+    memcpy(OccupancySN,&transactionInfo->OccupancySN[0],36);
+    log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f Approva Num:[%s] VemData:[%s] CardNo:[%s] OccupancySN:[%s]",
+    		transactionInfo->ConnectorID,
+            transactionInfo->TransactionId,
+            transactionInfo->DeductResult,
+            transactionInfo->IsDonateInvoice,
+            transactionInfo->Amount,
+            ApprovalNo,
+            vemdata,
+            cardno,
+            OccupancySN);
+}
+
 
 static int writeDeductInfo(int fd, uint8_t id,uint8_t gunIndex, RecordTransactionInfo *transactionInfo)
 {
     int ret = PASS;
     if (ShmDcCommonData->DebugFlag &&
-        strcmp((char*)transactionInfo->pCreditCard.VemData ,"") == EQUAL) {
+        strcmp((char*)transactionInfo->pCreditCard.ApprovalNo ,"") == EQUAL) {
         return ret;
     }
 
-    uint8_t dataBuf[104] = {0};
+    uint8_t dataBuf[139] = {0};
     //int i;
 
     memset((char *)dataBuf, 0x00, sizeof(dataBuf));
@@ -1660,10 +1843,13 @@ static int writeDeductInfo(int fd, uint8_t id,uint8_t gunIndex, RecordTransactio
     dataBuf[7] = (amount >> 16) & 0xFF;
     dataBuf[8] = (amount >> 8) & 0xFF;
     dataBuf[9] = (amount & 0xFF);
-    memcpy((char *)&dataBuf[10], transactionInfo->pCreditCard.ApprovalNo,9);
-    memcpy((char *)&dataBuf[19], transactionInfo->pCreditCard.VemData, 64);
-    memcpy((char*)&dataBuf[83], transactionInfo->pCreditCard.CardNo, 20);
+    memcpy((char *)&dataBuf[10], &transactionInfo->pCreditCard.ApprovalNo[0],9);
+    memcpy((char *)&dataBuf[19], &transactionInfo->pCreditCard.VemData[0], 64);
+    memcpy((char*)&dataBuf[83], &transactionInfo->pCreditCard.CardNo[0], 20);
+    memcpy((char*)&dataBuf[103], &transactionInfo->OccupancySN[0], 36);
 
+    showDeductInfo(transactionInfo);
+    /*
     log_info("Gun[%d] TransactionId:%d DeductResult:%d IsDonateInvoice:%d Amount:%f Approva Num:'%s' VemData:'%s' CardNo:'%s'",
     		transactionInfo->ConnectorID,
             transactionInfo->TransactionId,
@@ -1673,13 +1859,14 @@ static int writeDeductInfo(int fd, uint8_t id,uint8_t gunIndex, RecordTransactio
             transactionInfo->pCreditCard.ApprovalNo,
             transactionInfo->pCreditCard.VemData,
             transactionInfo->pCreditCard.CardNo);
+            */
     // copy deduct result to dataBuf here
 
     if ((ret = composeSocketData(fd,
                                  id,
                                  OP_WRITE_DATA,
                                  REG_DEDUCT_INFO,
-                                 104,
+                                 139,
                                  &dataBuf[0])) == FAIL) {
         return ret;
     }
@@ -2214,6 +2401,29 @@ static void checkAuthorProcess(int fd, uint8_t plugNum)
         }
     }
 }
+void SetDispenserReq(uint8_t plugNum)
+{
+    if (gConnectorActReq[plugNum].bits.ChargingCancel != ShmDcCommonData->OperateIDLE[plugNum]) {
+        gConnectorActReq[plugNum].bits.ChargingCancel = ShmDcCommonData->OperateIDLE[plugNum];
+        memset(&ShmDcCommonData->ParkingInfo[plugNum],0,sizeof(RecordTransactionInfo));
+    }
+    if (gConnectorActReq[plugNum].bits.ParkingBillReq != ShmDcCommonData->pGunInfo[plugNum].ReqParkingBill) {
+        gConnectorActReq[plugNum].bits.ParkingBillReq = ShmDcCommonData->pGunInfo[plugNum].ReqParkingBill;
+    }
+}
+void clearDispenserReq(uint8_t plugNum)
+{
+    gConnectorActReq[plugNum].Value = 0;
+    if (gConnectorActReq[plugNum].bits.ChargingCancel != ShmDcCommonData->OperateIDLE[plugNum]) {
+        ShmDcCommonData->OperateIDLE[plugNum] = 0;
+        ShmDcCommonData->TransactionInfo[plugNum].LineStatus = _LINE_INIT;
+        log_info("Gun%d Return Cancel OK", plugNum);
+    }
+    if (gConnectorActReq[plugNum].bits.ParkingBillReq != ShmDcCommonData->pGunInfo[plugNum].ReqParkingBill) {
+        ShmDcCommonData->pGunInfo[plugNum].ReqParkingBill = 0;
+        log_info("Gun%d Parking Bill Requset OK", plugNum);
+    }
+}
 
 static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg)
 {
@@ -2273,7 +2483,7 @@ static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg
 					log_info("Gun %d get final cost %f", plugNum, ShmDcCommonData->TransactionInfo[plugNum].Amount);
                     if (ShmDcCommonData->is_AutoStart[plugNum] || ShmDcCommonData->is_RemoteStart[plugNum]) {
                         ShmDcCommonData->PayPass_flag[plugNum] = TRUE;
-                        if (pSysInfo->CurGunSelected == plugNum)
+                        if (pSysInfo->CurGunSelected == plugNum && !ShmDcCommonData->pGunInfo[plugNum].isParking)
                             pSysInfo->SystemPage = _PAGE_COMPLETE;
                     } else {
                         UpdateDeductInfoStatus(plugNum, &ShmDcCommonData->TransactionInfo[plugNum]);
@@ -2301,18 +2511,42 @@ static int messageTrigger(int fd, uint8_t plugNum, uint8_t gunID, uint8_t curReg
             curReg = REG_DISPENSER_REQUEST;
             break;
         case REG_DISPENSER_REQUEST:
-            gConnectorActReq[plugNum].bits.ChargingCancel = ShmDcCommonData->OperateIDLE[plugNum];
+            SetDispenserReq(plugNum);
             if (gConnectorActReq[plugNum].Value != 0)
             {
                 if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME ||
                     DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) {
-
                     if (writeDispenserRequest(fd, gunID, plugNum) == PASS)
                     {
-                        gConnectorActReq[plugNum].Value = 0;
-                        log_info("Gun %d CHARGING_CANCEL OK", plugNum);
-                        ShmDcCommonData->OperateIDLE[plugNum] = 0;
-                        ShmDcCommonData->TransactionInfo[plugNum].LineStatus = _LINE_INIT;
+                        clearDispenserReq(plugNum);
+                    }
+                    ftime(&gRegTimeUp[plugNum][curReg]);
+                }
+            }
+            curReg = REG_PARKING_STATUS;
+            break;
+        case REG_PARKING_STATUS:
+            if (gMoreInfoReq[plugNum].bits.ParkingReq) {
+                if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME ||
+                    DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) {
+                    readParkingStatus(fd, gunID);
+
+                    ftime(&gRegTimeUp[plugNum][curReg]);
+                }
+            }
+            curReg = REG_PARKING_BILL;
+            break;
+        case REG_PARKING_BILL:
+            if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus == _TCC_WAIT_PAY && ShmDcCommonData->pGunInfo[plugNum].GetParkingBill == FALSE) {
+                if (DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) > LOOP_RETRY_TIME ||
+                    DiffTimeb(gRegTimeUp[plugNum][curReg], NowTime) < 0) {
+                    //log_info("Ask Parking Bill ");
+                    if (readParkingBill(fd, gunID) == PASS)
+                    {
+                        ShmDcCommonData->pGunInfo[plugNum].GetParkingBill = TRUE;
+                        if (pSysInfo->CurGunSelected == plugNum && pSysInfo->SystemPage == _PAGE_PAYING &&
+                             ShmDcCommonData->pGunInfo[plugNum].ReqParkingBill)
+                            pSysInfo->SystemPage = _PAGE_BILL;
                     }
                     ftime(&gRegTimeUp[plugNum][curReg]);
                 }
@@ -2515,7 +2749,7 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
     int j;
     struct timeb AuthNowTime = {0};
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
-    int reupload_gunIndex[128];
+    int reupload_gunIndex[128] = {0};
     RecordTransactionInfo reuploadInfo[128];
     int reupload_num = 0;
     struct timeb SeqEndTime;
@@ -2555,19 +2789,35 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
         SeqEndTime.time = time(NULL);
         tm = localtime(&SeqEndTime.time);
         
-        if ((pSysInfo->SystemPage == _PAGE_IDLE || pSysInfo->SystemPage == _PAGE_SELECT_GUN)) {
+        if ((pSysInfo->SystemPage == _PAGE_IDLE || pSysInfo->SystemPage == _PAGE_SELECT_GUN) &&
+            !ShmDcCommonData->pGunInfo[plugNum].isParking) {
             ftime(&AuthNowTime);
             if (DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) > LOOP_RETRY_TIME ||
                 DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) < 0
                 ) {
+                // 充電費補上傳
                 reupload_num = DB_GetMultiReUploadDeduct(&reupload_gunIndex[0], &reuploadInfo[0]);
                 if (reupload_num >= 1 && reuploadInfo[0].ConnectorID != 0) {
 
                     if (writeDeductInfo(fd, reuploadInfo[0].ConnectorID, reupload_gunIndex[0], &reuploadInfo[0]) == PASS) {
-                        reuploadInfo[0].IsUpload = YES;
+                        reuploadInfo[0].IsUpload = TRUE;
                         UpdateDeductInfoStatus(&reupload_gunIndex[0], &reuploadInfo[0]);
                     } else
-                        log_info("Reupload fail");
+                        log_info("Charging Information Reupload fail");
+
+                }
+                usleep(100);
+                // 佔位費補上傳
+                memset(reuploadInfo,0,sizeof(RecordTransactionInfo)*128);
+                reupload_num = DB_GetParkingDeductUpload(&reupload_gunIndex[0], &reuploadInfo[0]);
+                if (reupload_num >= 1 && reuploadInfo[0].ConnectorID != 0) {
+                    showDeductInfo(&reuploadInfo[0]);
+                    if (writeDeductInfo(fd, reuploadInfo[0].ConnectorID, reupload_gunIndex[0], &reuploadInfo[0]) == PASS) {
+                        reuploadInfo[0].IsUpload = YES;
+                        log_info("OccupancySN:[%s] upload set:%d",reuploadInfo[0].OccupancySN,reuploadInfo[0].IsUpload);
+                        UpdateParkingUpload(&reuploadInfo[0].OccupancySN[0],YES);
+                    } else
+                        log_info("Parking Information Reupload fail");
 
                 }
                 ftime(&gRegTimeUp[plugNum][REG_DEDUCT_INFO]);
@@ -2853,24 +3103,54 @@ static int networkCreatePorcess(void)
     return fd;
 }
 
-void CreditCardProcess(int fd,int plugNum,int gunID, RecordTransactionInfo *pInfo)
+void CreditCardProcess(int fd,int plugNum,int gunID,bool isPark, RecordTransactionInfo *pInfo)
 {
+    struct timeb AuthNowTime = {0};
+    //佔位費處理
+    if (isPark) {
+        if (pInfo->IsUpload == TRUE || (strcmp((char*)pInfo->pCreditCard.ApprovalNo,"") == 0))
+            return;
+        ftime(&AuthNowTime);
+        if (DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) > LOOP_RETRY_TIME * 5 ||
+            DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) < 0
+            ) {
+                if (writeDeductInfo(fd, gunID, plugNum, pInfo) == PASS) {
+                    pInfo->IsUpload = TRUE;
+                    UpdateParkingUpload(pInfo->OccupancySN,YES);
+                } else {
+                    log_info("Gun%d Write Deduct fail",plugNum);
+                }
+                ftime(&gRegTimeUp[plugNum][REG_DEDUCT_INFO]);
+            }
+
+        return;
+    }
+
+    // 充電費處理
     if (pInfo->IsUpload == TRUE || (strcmp((char*)pInfo->pCreditCard.VemData,"") == 0) ||
         pSysInfo->SystemPage == _PAGE_SENSING || ShmDcCommonData->is_RemoteStart[plugNum])
         return;
-    if (ShmDcCommonData->TransactionInfo[plugNum].ConnectorID != 0) {
-        if (writeDeductInfo(fd, gunID, plugNum, &ShmDcCommonData->TransactionInfo[plugNum]) == PASS) {
-            ShmDcCommonData->TransactionInfo[plugNum].IsUpload = YES;
-            UpdateDeductInfoStatus(plugNum, &ShmDcCommonData->TransactionInfo[plugNum]);
 
-            if (ShmDcCommonData->TransactionInfo[plugNum].DeductResult == _DEDUCT_CANCEL) {
-                memset(&ShmDcCommonData->TransactionInfo[plugNum].pCreditCard, 0x00, sizeof(TransInfo));
-            }
+    if (pInfo->ConnectorID != 0) {
+        ftime(&AuthNowTime);
+        if (DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) > LOOP_RETRY_TIME * 5 ||
+            DiffTimeb(gRegTimeUp[plugNum][REG_DEDUCT_INFO], AuthNowTime) < 0
+            ) {
+                if (writeDeductInfo(fd, gunID, plugNum, pInfo) == PASS) {
+                    pInfo->IsUpload = TRUE;
 
-            log_info("writeDeductInfo finish");
-        } else {
-            log_info("Write Deduct fail");
-        }
+                    UpdateDeductInfoStatus(plugNum, pInfo);
+
+                    if (pInfo->DeductResult == _DEDUCT_CANCEL) {
+                        memset(&pInfo->pCreditCard, 0x00, sizeof(TransInfo));
+                    }
+
+                    log_info("Gun%d writeDeductInfo finish",plugNum);
+                } else {
+                    log_info("Gun%d Write Deduct fail",plugNum);
+                }
+                ftime(&gRegTimeUp[plugNum][REG_DEDUCT_INFO]);
+            }
     }
 }
 int main(int argc, char *argv[])
@@ -2935,8 +3215,10 @@ int main(int argc, char *argv[])
                 //gunID : connector Id from power cabinet, 1 = left gun, 2 = right gun,
                 gunID = gDoCommGblData.ConnectorID[plugNum];
                 systemStatusProcess(fd, totalConnCount, plugNum, gunID);
-
-                CreditCardProcess(fd, plugNum,gunID, &ShmDcCommonData->TransactionInfo[plugNum]);
+                if (ShmDcCommonData->pGunInfo[plugNum].ParkingStatus)
+                    CreditCardProcess(fd, plugNum,gunID,TRUE, &ShmDcCommonData->ParkingInfo[plugNum]);
+                else
+                    CreditCardProcess(fd, plugNum,gunID,FALSE, &ShmDcCommonData->TransactionInfo[plugNum]);
 
                 initDone = messageTrigger(fd,
                                           plugNum,

+ 18 - 4
EVSE/Projects/DD360Tcci/Apps/ModuleDoComm/DoComm.h

@@ -16,7 +16,7 @@
 #define TFTP_PULL_CMD                           "tftp"
 #define SIGTERM_MSG                             "SegmentFault.~~~~\n"
 
-#define MAX_REGISTER_NUM                        40
+#define MAX_REGISTER_NUM                        45
 
 #define CHECK_NETWORK_FAIL_COUNT                10//10
 #define CONNECT_SERVER_FAIL_COUNT               3//5
@@ -100,6 +100,9 @@
 #define REG_POWER_CONSUMPTION_INFO              0x24
 #define REG_READ_CHARGING_TIMESTAMP             0x25
 #define REG_CHARGING_BILL                       0x26
+#define REG_PARKING_STATUS                      0x27
+#define REG_PARKING_BILL                        0x28
+
 //------------------------------------------------------------------------------
 //--- dispenser result ---
 //------------------------------------------------------------------------------
@@ -133,6 +136,8 @@
 #define MISC_CMD_LED_INTENSITY                  (0x000E)
 #define MISC_CMD_AC_CONTACTOR                   (0x000F)
 #define MISC_CMD_TIME_OFFSET                    (0x0010)
+#define MISC_CMD_PAKING_PRICES                  (0x0011)
+#define MISC_CMD_RFID_ENDIAN                    (0x0012)
 
 #define MISC_CMD_HARDWARE_REBOOT                (0x0101)
 #define MISC_CMD_SOFTWARE_RESTART               (0x0102)
@@ -149,13 +154,14 @@
 #define MISC_CMD_USER_PRICE_REQ                 (0x010D)
 #define MISC_CMD_RECEIPT_REQ                    (0x010E)
 #define MISC_CMD_CHARGING_BILL                  (0x010F)
+#define MISC_CMD_PARKING_STATUS                 (0x0110)
 
 #define ST_UPDATE_FIRMWARE                      (0x01)
 #define ST_NO_UPDATE_FIRMWARE                   (0x02)
 
 #define LCM_PAGE_REMOTE_START_NO_ID             (0x0001)
 #define DISPENSER_REQ_CHARGING_CANCEL           (0x0001)
-
+#define DISPENSER_REQ_PARKING_BILL              (0x0002)
 #define UPLOAD_DEDUCT_DB						(0x5656)
 
 
@@ -168,7 +174,8 @@ typedef union
     struct
     {
         unsigned int ChargingCancel : 1; // 0: no effect, 1: charging cancel request
-        unsigned int res : 31;
+        unsigned int ParkingBillReq : 1; // 0: no effect, 1: Parking Bill Request
+        unsigned int res : 30;
     }bits;
 } ConnectorActReqVar;
 
@@ -203,7 +210,8 @@ typedef union
         unsigned int StationInfoReq:1;              // 0: no effect,                1: need to request StationInfo
         unsigned int FinalCostReq:1;                // 0: no effect,                1: need to request FinalCost
         unsigned int ChargingBill:1;                // 0: no effect,                1: need to request ChargineBill
-        unsigned int res:27;
+        unsigned int ParkingReq : 1;                // 0: no effect,                1: need to request Parking
+        unsigned int res:26;
     } bits;
 } MoreInfoReq;
 
@@ -339,6 +347,12 @@ typedef struct StChargingBillInfo {
     int ParkingFee;
     uint32_t RemainAmount;
 } ChargingBillInfo;
+
+typedef struct StParkingBillInfo {
+    int ParkingFee;
+    int Duration;
+} ParkingBillInfo;
+
 #pragma pack(pop)
 
 #endif /* _DO_COMM_H_ */

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

@@ -17,7 +17,8 @@ void ClearAbnormalStatus_CCS(uint8_t gun_index)
     struct InfoCodeData *pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData();
     struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
     struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun_index);
-
+    memset(code, '\n', sizeof(code));
+    
     if (strncmp((char *)pDcChargingInfo->EvConnAlarmCode, "", 6) == EQUAL) {
         return;
     }

+ 191 - 69
EVSE/Projects/DD360Tcci/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -37,7 +37,7 @@ static struct GBTData *ShmGBTData = NULL;
 static struct CcsData *ShmCcsData = NULL;
 static DcCommonInfo *ShmDcCommonData = NULL;
 static SelectGunInfo *ShmSelectGunInfo = NULL;
-
+uint8_t deratingIndex[2];
 // 限制最大充電電壓,因應不同 type 槍線來限制
 // Chademo : 500V, 125A,
 // GB : 750, 120A
@@ -140,6 +140,131 @@ int InitCanBus(void)
     return s0;
 }
 
+void SetNatural200AGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    memset(&deratingByConnOtp->deratingTargetRate[0], 200, sizeof(deratingByConnOtp->deratingTargetRate));
+}
+void SetNatural300AGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    deratingByConnOtp->deratingTargetCurrent[0] = 500;
+    deratingByConnOtp->deratingTargetCurrent[1] = 300;
+    deratingByConnOtp->deratingTargetCurrent[2] = 100;
+    deratingByConnOtp->deratingTargetCurrent[3] = 100;
+    deratingByConnOtp->deratingTargetCurrent[4] = 100;
+}
+void SetLiquidCoolGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    deratingByConnOtp->deratingTargetCurrent[0] = 500;
+    deratingByConnOtp->deratingTargetCurrent[1] = 400;
+    deratingByConnOtp->deratingTargetCurrent[2] = 300;
+    deratingByConnOtp->deratingTargetCurrent[3] = 300;
+    deratingByConnOtp->deratingTargetCurrent[4] = 300;
+}
+void SetCHAdeMoTypeJOTPValue(uint8_t regulation, struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    if (regulation == 'J') {
+        memset(&deratingByConnOtp->deratingTargetRate[0], 125, sizeof(deratingByConnOtp->deratingTargetRate));
+    }
+    else {
+        memset(&deratingByConnOtp->deratingTargetRate[0], 120, sizeof(deratingByConnOtp->deratingTargetRate));
+    }
+}
+void SetCHAdeMoTypeKOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    memset(&deratingByConnOtp->deratingTargetRate[0], 200, sizeof(deratingByConnOtp->deratingTargetRate));
+}
+
+void SetCHAdeMoTypeSJOTPValue(struct DERATING_BY_OTP* deratingByConnOtp)
+{
+    deratingByConnOtp->deratingTargetRate[0] = 1;
+    deratingByConnOtp->deratingTargetRate[1] = 0.8;
+}
+
+static void SetGunTypeOTPValue(void)
+{
+    struct ChargingInfoData* pDcChargingInfo = NULL;
+    uint8_t Gun1Type = 0;
+    uint8_t Gun2Type = 0;
+    int i;
+    if (pSysConfig->TotalConnectorCount == 1) {
+        pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(0);
+        Gun1Type = pSysConfig->ModelName[7];
+        Gun2Type = pSysConfig->ModelName[7];
+
+        switch (Gun1Type) {
+            //CHAdeMo
+        case 'J':
+            SetCHAdeMoTypeJOTPValue(pSysConfig->ModelName[3], &pDcChargingInfo->deratingByConnOtp);
+            break;
+        case 'K':
+            SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
+        case 'S':
+            SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
+            // 風冷200A以下
+        case 'U':
+        case 'E':
+        case 'M':
+        case 'N':
+            SetNatural200AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
+            // 風冷300A
+        case 'T':
+        case 'D':
+            SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
+            // 水冷
+        case 'V':
+        case 'F':
+        case 'P':
+        case 'R':
+            SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+            break;
+        }
+
+    }
+    else if (pSysConfig->TotalConnectorCount == 2) {
+        Gun1Type = pSysConfig->ModelName[7];
+        Gun2Type = pSysConfig->ModelName[9];
+        for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
+            pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i);
+            pDcChargingInfo->deratingByConnOtp.isNeedDerating = GUNOTPDERATING;
+            switch (i == 0 ? Gun1Type : Gun2Type) {
+                //CHAdeMo
+            case 'J':
+                SetCHAdeMoTypeJOTPValue(pSysConfig->ModelName[3], &pDcChargingInfo->deratingByConnOtp);
+                break;
+            case 'K':
+                SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
+            case 'S':
+                SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
+                // 風冷200A以下
+            case 'U':
+            case 'E':
+            case 'M':
+            case 'N':
+                SetNatural200AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
+                // 風冷300A
+            case 'T':
+            case 'D':
+                SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
+                // 水冷
+            case 'V':
+            case 'F':
+            case 'P':
+            case 'R':
+                SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp);
+                break;
+            }
+        }
+    }
+}
+
 float GetMaxChargingVol(uint8_t index)
 {
     return maxChargingVol[index];
@@ -337,70 +462,44 @@ static void GetMaxVolAndCurMethod(uint8_t index, float *vol, float *cur)
         *cur = pDcChargingInfo->ChargingProfileCurrent;
     }
 }
-void checkEachGunTypeOTP(int gunIndex, uint8_t Type, int derate_idx, struct DERATING_BY_OTP* deratingByConnOtp)
+
+void GetOtpPwrOrCurMethod(struct ChargingInfoData* chargingData, float* pow, float* cur)
 {
-    struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
-    deratingByConnOtp->deratingIndex = derate_idx;
-    /*
-    log_info("RealMaxCurrent:[%.1f], AvailableChargingCurrent:[%.1f], BatteryTargetCurrent:[%.1f]",
-        pDcChargingInfo->RealMaxCurrent,
-        pDcChargingInfo->AvailableChargingCurrent,
-        pDcChargingInfo->EvBatterytargetCurrent);
-
-    log_info("RealMaxPower:[%.1f], AvailableChargingPower:[%.1f], BatteryTargetPower:[%.1f]",
-        pDcChargingInfo->RealMaxPower,
-        pDcChargingInfo->AvailableChargingPower,
-        pDcChargingInfo->EvBatterytargetVoltage * pDcChargingInfo->EvBatterytargetCurrent);
-    */
-    switch (Type) {
-    case 'S':
-        // Derate by power
-        if (pDcChargingInfo->RealMaxPower > pDcChargingInfo->AvailableChargingPower) {
-            pDcChargingInfo->RealMaxPower = pDcChargingInfo->AvailableChargingPower * deratingByConnOtp->deratingTargetRate[derate_idx];
-            log_info("Max Power derating to %.1f", pDcChargingInfo->RealMaxPower);
-        }
-        break;
-    default:
-        // Derate by current
-        if (pDcChargingInfo->RealMaxCurrent > deratingByConnOtp->deratingTargetCurrent[derate_idx]) {
-            pDcChargingInfo->RealMaxCurrent = deratingByConnOtp->deratingTargetCurrent[derate_idx];
-            log_info("Max Current derating to %.1f", pDcChargingInfo->RealMaxCurrent);
-        }
+    if (((chargingData->ConnectorTemp >= STAGE1_GUN_DERATING_TEMP &&
+        chargingData->ConnectorTemp < STAGE2_GUN_DERATING_TEMP) ||
+        (chargingData->ChillerTemp >= STAGE1_GUN_DERATING_TEMP &&
+            chargingData->ChillerTemp < STAGE2_GUN_DERATING_TEMP)) &&
+        chargingData->deratingByConnOtp.deratingIndex < 1)
+    {
+        chargingData->deratingByConnOtp.deratingIndex = 1;
+    }
+    else if ((chargingData->ConnectorTemp >= STAGE2_GUN_DERATING_TEMP ||
+        chargingData->ChillerTemp >= STAGE2_GUN_DERATING_TEMP) &&
+        chargingData->ConnectorTemp != UNDEFINED_TEMP &&
+        chargingData->ChillerTemp != UNDEFINED_TEMP &&
+        chargingData->deratingByConnOtp.deratingIndex < 2)
+    {
+        chargingData->deratingByConnOtp.deratingIndex = 2;
     }
-}
-static void CheckGunTypeOTP(void)
-{
-    uint8_t GunType = 0;
-    int derate_idx;
-    int i;
 
-    for (i = 0; i < pSysConfig->TotalConnectorCount; i++) {
-        if (pSysConfig->TotalConnectorCount == 1) {
-            GunType = pSysConfig->ModelName[7];
-        } else if (pSysConfig->TotalConnectorCount == 2) {
-            GunType = (i == 0 ? pSysConfig->ModelName[7] : pSysConfig->ModelName[9]);
-        }
-        struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i);
-        if (pDcChargingInfo->deratingByConnOtp.isNeedDerating) {
-            if (pDcChargingInfo->ConnectorTemp >= _DERATING_85) {
-                derate_idx = 2;
-            } else if (pDcChargingInfo->ConnectorTemp >= _DERATING_80) {
-                derate_idx = 1;
-            } else {
-                derate_idx = 0;
-            }
-            if (derate_idx != 0) {
-                checkEachGunTypeOTP(i, GunType, derate_idx, &pDcChargingInfo->deratingByConnOtp);
-            }
-        }
+    if (chargingData->deratingByConnOtp.deratingTargetRate[chargingData->deratingByConnOtp.deratingIndex] != 0)
+    {
+        *pow *= chargingData->deratingByConnOtp.deratingTargetRate[chargingData->deratingByConnOtp.deratingIndex];
     }
-}
+    else if (chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex] != 0)
+    {
+        if (*cur > chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex])
+            *cur = chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex];
+    }
+}   
+
 static void SetPresentChargingOutputCap(void)
 {
     float pow1 = 0, cur1 = 0;
     float pow2 = 0, cur2 = 0;
     struct ChargingInfoData *chargingData_1 = NULL;
     struct ChargingInfoData *chargingData_2 = NULL;
+    struct PrimaryMcuData* ShmPrimaryMcuData = (struct PrimaryMcuData*)GetShmPrimaryMcuData();
 
     if (pSysConfig->TotalConnectorCount == 1) {
         chargingData_1 = (struct ChargingInfoData *)GetDcChargingInfoData(0);
@@ -438,6 +537,14 @@ static void SetPresentChargingOutputCap(void)
         }
     }
 
+    if (chargingData_1->deratingByConnOtp.isNeedDerating) {
+        GetOtpPwrOrCurMethod(chargingData_1, &pow1, &cur1);
+        if (deratingIndex[0] != chargingData_1->deratingByConnOtp.deratingIndex) {
+            log_info("Gun0 Derating Index Set %d", chargingData_1->deratingByConnOtp.deratingIndex);
+            deratingIndex[0] = chargingData_1->deratingByConnOtp.deratingIndex;
+        }
+    }
+
     pow2 = chargingData_2->AvailableChargingPower;
     cur2 = chargingData_2->AvailableChargingCurrent;
     /*
@@ -461,7 +568,23 @@ static void SetPresentChargingOutputCap(void)
             }
         }
     }
-
+    if (chargingData_2->deratingByConnOtp.isNeedDerating) {
+        GetOtpPwrOrCurMethod(chargingData_2, &pow2, &cur2);
+        if (deratingIndex[1] != chargingData_2->deratingByConnOtp.deratingIndex) {
+            log_info("Gun1 Derating Index Set %d", chargingData_2->deratingByConnOtp.deratingIndex);
+            deratingIndex[1] = chargingData_2->deratingByConnOtp.deratingIndex;
+        }
+    }
+    if (ShmPrimaryMcuData->InputDet.bits.Ac_Drop == ABNORMAL) {
+        if (cur1 > 1500) {
+            log_info("Gun0 chiller alarm set current less than 150A");
+            cur1 = 1500;
+        }
+        if (cur2 > 1500) {
+            log_info("Gun1 chiller alarm set current less than 150A");
+            cur2 = 1500;
+        }
+    }
     //DS60-120 add
     if ((LogInfo[0][EV_LOG_OUTPUT_CAP_POW] <= pow1 - 5 ||
             LogInfo[0][EV_LOG_OUTPUT_CAP_POW] >= pow1 + 5) ||
@@ -473,30 +596,27 @@ static void SetPresentChargingOutputCap(void)
              LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] >= cur2 + 5)
        ) {
         //log_info("----------------------------------------------------- ");
-        log_info("To EV PW_1 = %.1f, Cur_1 = %.1f, Vol_1 = %.1f, PW_2 = %.1f, Cur_2 = %.1f, Vol_2 = %.1f",
-                 pow1 / 10, cur1 / 10, chargingData_1->FireChargingVoltage, pow2 / 10, cur2 / 10, chargingData_2->FireChargingVoltage);
+        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;
         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;
+        chargingData_1->RealMaxCurrent = cur1;
+        chargingData_1->RealMaxPower = pow1;
 
+        if (pSysConfig->TotalConnectorCount == 2) {
+            chargingData_2->RealMaxCurrent = cur2;
+            chargingData_2->RealMaxPower = pow2;
+        }
+    }
     if (pSysConfig->TotalConnectorCount == 2) {
         chargingData_2->RealMaxCurrent = cur2;
         chargingData_2->RealMaxPower = pow2;
     }
-
-    //CheckGunTypeOTP();
-
-    SetPresentOutputCapacity(chargingData_1->RealMaxPower,
-        chargingData_1->RealMaxCurrent,
-        chargingData_2->RealMaxPower,
-        chargingData_2->RealMaxCurrent);
+    SetPresentOutputCapacity(pow1, cur1, pow2, cur2);
 }
 /*
 static uint8_t waitPsuVolwithRealyVol(uint8_t gunIndex)
@@ -794,6 +914,8 @@ int main(int argc, char *argv[])
     
     CANReceiver(CanFd);
 
+    //SetGunTypeOTPValue();
+
     rtc = GetRtcInfoForEpoch();
 
     while (isContinue) {

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 472 - 297
EVSE/Projects/DD360Tcci/Apps/ModuleLcmCtrl/Module_LcmControl.c


+ 43 - 154
EVSE/Projects/DD360Tcci/Apps/ModuleLcmCtrl/Module_LcmControl.h

@@ -107,6 +107,14 @@
 #define _Icon_Uploading         0x1070
 #define _Icon_DAKAWelcome       0x1072
 #define _Icon_PreAuthWord       0x1074
+#define _Icon_ParkingInfo		0x1076
+#define _Icon_ParkingLeave		0x1078
+#define _Icon_CompleteBtn		0x107A
+#define _Icon_ParkingCntDw_BG	0x107C
+#define _Icon_ParkingCntDw_Tens	0x107E
+#define _Icon_ParkingCntDw_Digits	0x1080
+#define _Icon_ScanCntDw_BG		0x1082
+#define _Icon_ParkingCntDw_Hun  0x1084
 
 #define _String_Date			0x3000
 #define _String_Tempture		0x3010
@@ -120,12 +128,11 @@
 #define _String_ParkRate		0x3090
 #define _String_Carbon			0x30A0
 #define _QRCode_Service			0x30B0
-#define _Strting_Warming0		0x30C0
-#define _Strting_Warming1		0x30D0
-#define _Strting_Warming2		0x30E0
-#define _Strting_Warming3		0x30F0
-#define _Strting_Warming4		0x3100
-
+#define _String_ParkingStartTime 0x30C0
+#define _String_ParkingDuration	0x30D0
+#define _String_ParkingFee		0x30E0
+#define _String_ParkingLeaveTime	0x30F0
+#define _String_SaleLeaveTime	0x3100
 
 #define _Touch_IDLE				0x1500
 #define _Touch_Select_Left		0x1502
@@ -140,155 +147,10 @@
 #define _Touch_Stop_Confirm		0x1514
 #define _Touch_Stop_Cancel		0x1516
 #define _Touch_Pay_CreditCard	0x1518
-#define _Touch_Pay_Icash		0x151A
-#define _Touch_Pay_LinePay		0x151C
+#define _Touch_Pay_LinePay		0x151A
+#define _Touch_Parking_Complete	0x151C
 
 enum _TCC_ICON_LIST_ {
-	/*
-    _ICON_Empty 			= 0,
-	_ICON_StatusInit,
-	_ICON_StatusAuthorize,
-	_ICON_StatusCharge,
-	_ICON_StatusComplete,
-	_ICON_AllIdle,
-	_ICON_LeftGunSelect,
-	_ICON_RightGunSelect,
-	_ICON_AllSelect,
-	_ICON_TCCare,
-	_ICON_StartTouch,
-
-	_ICON_Furthure 			= 15,
-	_ICON_Weather,
-	_ICON_Welcome,
-	_ICON_QRCode,
-	_ICON_exclamation,
-	_ICON_plugin,
-	_ICON_Plugout,
-	_ICON_Return,
-	_ICON_PrepareCharge,
-
-	_ICON_min 				= 26,
-	_ICON_Rate_13,
-	_ICON_Complete,
-	_ICON_kg,
-	_ICON_Rate_14,
-	_ICON_Exit,
-	_ICON_HaveANiceDay,
-	_ICON_HaveANiceTrip,
-	_ICON_SaftDrive,
-	_ICON_Charging,
-
-	_ICON_Battery_0 		= 40,
-	_ICON_Battery_1,
-	_ICON_Battery_2,
-	_ICON_Battery_3,
-	_ICON_Battery_4,
-	_ICON_Battery_5,
-	_ICON_Battery_6,
-	_ICON_Battery_7,
-	_ICON_Battery_8,
-	_ICON_Battery_9,
-	_ICON_Battery_10,
-	_ICON_Battery_11,
-	_ICON_Battery_12,
-	_ICON_Battery_13,
-	_ICON_Battery_14,
-	_ICON_Battery_15,
-	_ICON_Battery_16,
-	_ICON_Battery_17,
-	_ICON_Battery_18,
-	_ICON_Battery_19,
-	_ICON_Battery_20,
-	_ICON_Battery_21,
-	_ICON_Battery_22,
-	_ICON_Battery_23,
-	_ICON_Battery_24,
-	_ICON_Battery_25,
-	_ICON_Battery_26,
-	_ICON_Battery_27,
-	_ICON_Battery_28,
-	_ICON_Battery_29,
-	_ICON_Battery_30,
-	_ICON_Battery_31,
-	_ICON_Battery_32,
-	_ICON_Battery_33,
-	_ICON_Battery_34,
-	_ICON_Battery_35,
-	_ICON_Battery_36,
-	_ICON_Weather_Sun,
-	_ICON_Weather_Cloudy,
-	_ICON_Weather_Rain,
-	_ICON_Weather_Thunder,
-	_ICON_Weather_Snow,
-	_ICON_Weather_Fog,
-
-	_ICON_PrePare_1   = 86,
-	_ICON_PrePare_2,
-	_ICON_PrePare_3,
-	_ICON_PrePare_4,
-	_ICON_PrePare_5,
-	_ICON_PrePare_6,
-	_ICON_PrePare_7,
-	_ICON_PrePare_8,
-	_ICON_PrePare_9,
-	_ICON_PrePare_10,
-	_ICON_PrePare_11,
-	_ICON_PrePare_12,
-	_ICON_PrePare_13,
-	_ICON_PrePare_14,
-	_ICON_Left_CCS1_Off,
-	_ICON_Left_CCS2_Off,
-	_ICON_Left_CHAdeMO_Off,
-	_ICON_Left_CCS1_ON,
-	_ICON_Left_CCS2_ON,
-	_ICON_Left_CHAdeMO_ON,
-	_ICON_Right_CCS1_Off,
-	_ICON_Right_CCS2_Off,
-	_ICON_Right_CHAdeMo_Off,
-	_ICON_Right_CCS1_ON,
-	_ICON_Right_CCS2_ON,
-	_ICON_Right_CHAdeMO_ON,
-	_ICON_WARMING,
-	_ICON_SELECT_TEXT,
-	_ICON_MONDAY,
-	_ICON_TUESDAY,
-	_ICON_WENSDAY,
-	_ICON_THRUDAY,
-	_ICON_FRIDAY,
-	_ICON_SATURDAY,
-	_ICON_SUNDAY,
-	_ICON_LOCATION_TAIPEI,
-
-	_ICON_PAYFAIL = 126,
-	_ICON_PROGREEPAY_1,
-	_ICON_PROGREEPAY_2,
-	_ICON_PROGREEPAY_3,
-	_ICON_PROGREEPAY_4,
-	_ICON_PROGREEPAY_5,
-	_ICON_PROGREEPAY_6,
-	_ICON_PROGREEPAY_7,
-	_ICON_PROGREEPAY_8,
-	_ICON_PROGREEPAY_9,
-	_ICON_PROGREEPAY_10,
-	_ICON_PROGREEPAY_11,
-	_ICON_PROGREEPAY_12,
-	_ICON_PROGREEPAY_13,
-	_ICON_PROGREEPAY_14,
-	_ICON_PROGREEPAY_15,
-	_ICON_STOPSERVICE,
-	_ICON_WELCOMELEFTCCS1,
-	_ICON_WELCOMELEFTCCS2,
-	_ICON_WELCOMELEFTCHADEMO,
-	_ICON_WELCOMERIGHTCCS1,
-	_ICON_WELCOMERIGHTCCS2,
-	_ICON_WELCOMERIGHTCHADEMO,
-	_ICON_PAYFAILLEFTCCS1,
-	_ICON_PAYFAILLEFTCCS2,
-	_ICON_PAYFAILLETCHADEMO,
-	_ICON_PAYFAILRIGHTCCS1,
-	_ICON_PAYFAILRIGHTCCS2,
-	_ICON_PAYFAILRIGHTCHADEMO,
-	*/
 	_ICON_Empty 			= 0,
 	_TCC_Week_Monday,
 	_TCC_Week_Tuesday,
@@ -305,7 +167,7 @@ enum _TCC_ICON_LIST_ {
 	_TCC_Thunder,
 	_TCC_Fog,
 	_TCC_Taipei_ZhongShan,
-	_TCC_Hualien_Xiulin,
+	_TCC_Scan_CntDw_BG,
 	_TCC_Welcom_Coffee,
 	_TCC_SelectLeft_CCS1,
 	_TCC_SelectLeft_CCS2,
@@ -384,6 +246,33 @@ enum _TCC_ICON_LIST_ {
 	_TCC_ShowRightGunReservation_CCS1,
 	_TCC_ShowRightGunReservation_CCS2,
 	_TCC_ShowRightGunReservation_CHAdeMo,
+	_TCC_LeftParkingIdle,
+	_TCC_RightParkingIdle,
+	_TCC_LeftParkingSel,
+	_TCC_RightParkingSel,
+	_TCC_ParkingInfo,
+	_TCC_ParkingLine,
+	_TCC_ParkingDonate,
+	_TCC_ParkingFee,
+	_TCC_ParkingLeave,
+	_TCC_NoParkingComplete,
+	_TCC_ParkingComplete,
+	_TCC_LinePaying,
+	_TCC_ParkingCntDown_BG,
+	_TCC_ParkingCD_0,
+	_TCC_ParkingCD_1,
+	_TCC_ParkingCD_2,
+	_TCC_ParkingCD_3,
+	_TCC_ParkingCD_4,
+	_TCC_ParkingCD_5,
+	_TCC_ParkingCD_6,
+	_TCC_ParkingCD_7,
+	_TCC_ParkingCD_8,
+	_TCC_ParkingCD_9,
+	_TCC_WaitParkInfo,
+	_TCC_ParkingCntDown_BG3,
+	_TCC_ICON_SelectChargeMode,
+	_TCC_ICON_SelectPayMode,
 };
 
 

+ 32 - 48
EVSE/Projects/DD360Tcci/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -44,7 +44,7 @@ static struct SysInfoData *pSysInfo = NULL;
 static struct AlarmCodeData *pAlarmCode = NULL;
 static struct FaultCodeData *pFaultCode = NULL;
 static struct PrimaryMcuData *ShmPrimaryMcuData;
-static DcCommonInfo* ShmDcCommonData = NULL;
+static DcCommonInfo *ShmDcCommonData = NULL;
 
 const char *priPortName = "/dev/ttyS1";
 uint8_t gun_count; //DS60-120 add
@@ -84,6 +84,7 @@ void GetInputGpioStatus(int fd)
     }
 
     ShmPrimaryMcuData->InputDet.bits.SpdDetec = gpio_in.SPD;
+    ShmPrimaryMcuData->InputDet.bits.Ac_Drop = ~gpio_in.AC_Drop; // Chiller Alarm ping
 
     if (gpio_in.Emergency_Btn && (EmgBtn_flag != gpio_in.Emergency_Btn))
     {
@@ -139,7 +140,7 @@ void GetInputGpioStatus(int fd)
             Door_count = 0;
             Door_flag = gpio_in.Door_Open;
         }
-    } else {
+    } else { 
         Door_flag = gpio_in.Door_Open;
         Door_count = 0;
     }
@@ -208,77 +209,60 @@ static void checkChillerStatus(Gpio_out *gpio)
         pGpio->AC_Connector = 0x00;
         return;
     }
-
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++) {
+    // 設定chiller 開關
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
         if (!ShmDcCommonData->pGunInfo[gunIndex].withChiller)
             continue;
         pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
         pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
 
-        if((pDcChargingInfo->SystemStatus > S_AUTHORIZING && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
-            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))
-        {
+        if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) ||
+            (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
             pChillerInfo->ChillerSwitch = YES;
             pChillerInfo->ChillerOnTime = time((time_t *)NULL);
-        }
-        else
-        {
-            if(pChillerInfo->ChillerSwitch == YES)
-            {
+        } else {
+            if(pChillerInfo->ChillerSwitch == YES) {
                 //10分鐘後停止
-                if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600)
-                {
+                if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600) {
                     pChillerInfo->ChillerSwitch = NO;
-                    ShmFanModuleData->SetFan1Speed = 0;
                 }
-            }
-            else
-            {
+            } else {
                 pChillerInfo->ChillerSwitch = NO;
                 ShmFanModuleData->SetFan1Speed = 0;
             }
         }
-/*
-        if ((pDcChargingInfo->PresentChargingCurrent) >= 150) { //當前電壓於150A,打開水冷機
-            pChillerInfo->ChillerSwitch = YES;
-            pChillerInfo->ChillerOnTime = time((time_t *)NULL);
-        } else {
-            if (pChillerInfo->ChillerSwitch == YES) {
-                if ((pDcChargingInfo->PresentChargingCurrent) >= 100) { //判斷如果還是大於100A不變動
-                    pChillerInfo->ChillerSwitch = YES;
-                    pChillerInfo->ChillerOnTime = time((time_t *)NULL);
-                } else {
-                    if ((time((time_t *)NULL) - pChillerInfo->ChillerOnTime) >= 600) { //5分鐘後停止
-                        pChillerInfo->ChillerSwitch = NO;
-                    } else {
-                        pChillerInfo->ChillerSwitch = YES;
-                    }
-                }
-            } else {
-                pChillerInfo->ChillerSwitch = NO;
-            }
+        // 檢查Chiller溫度點,若小於零下時開啟heater,大於10度時關閉heater
+        if (pDcChargingInfo->ChillerTemp < 60) {
+            pGpio->AC_Breaker = YES;
+        } else if(pDcChargingInfo->ChillerTemp > 70) {
+            pGpio->AC_Breaker = NO;
         }
-*/
+        //log_info("Set Heater %s", pGpio->AC_Breaker ? "ON" : "OFF");
     }
 
     uint8_t _chillerNeedOn = NO;
-    for (gunIndex = 0; gunIndex < chillerCount; gunIndex++)
+    for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++)
     {
-        pChillerInfo = (ChillerInfo *)&fChillerInfo[gunIndex];
-        if(pChillerInfo->ChillerSwitch == YES)
-        {
+        pChillerInfo = (ChillerInfo*)&fChillerInfo[gunIndex];
+        if (pChillerInfo->ChillerSwitch == YES) {
             _chillerNeedOn = YES;
             ShmFanModuleData->SetFan1Speed = 7000;
-
         }
     }
+    /*
+    if (ShmDcCommonData->debugflag == YES)
+        _chillerNeedOn = ShmDcCommonData->chillerCtrl;
+    */
+    if (ShmPrimaryMcuData->InputDet.bits.Ac_Drop == ABNORMAL) {
+        _chillerNeedOn = NO;
+    }
 
-    if(_chiller.ChillerSwitch != _chillerNeedOn)
-    {
+    if(_chiller.ChillerSwitch != _chillerNeedOn) {
         log_info("Chiller Need Turn %s", _chillerNeedOn == YES ? "ON" : "OFF");
     }
     _chiller.ChillerSwitch = _chillerNeedOn;
     pGpio->AC_Connector = _chiller.ChillerSwitch;//Chiller ON/OFF Control, "0: Chiller disable, 1: Chiller enable"
+
 }
 
 void SetOutputGpio(int fd, uint8_t outputValue)
@@ -312,7 +296,7 @@ void SetOutputGpio(int fd, uint8_t outputValue)
 
     checkChillerStatus(&gpio);
 
-    gpio.AC_Breaker = 0x00;
+    //gpio.AC_Breaker = 0x00;
 
     Config_Gpio_Output(fd, OP_ADDR_IO_EXTEND, &gpio);
 }
@@ -411,6 +395,7 @@ unsigned long GetClockTimeoutValue(struct timespec _start_time)
 
     return ret;
 }
+
 static bool IsPrimaryProcessNeedPause(void)
 {
     bool _pause = false;
@@ -459,7 +444,7 @@ int main(void)
     pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
     pFaultCode = (struct FaultCodeData *)GetShmFaultCodeData();
     ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
-    ShmDcCommonData = (DcCommonInfo*)GetShmDcCommonData();
+    ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
 
     Uart1Fd = InitComPort();
     //log_info("407 Port id = %d ", Uart1Fd);
@@ -490,7 +475,6 @@ int main(void)
             sleep(1);
             continue;
         }
-
         if (ShmPrimaryMcuData->SelfTest_Comp != PASS) {
             //log_info("(407) Get Fw and Hw Ver. ");
             GetFwAndHwVersion(Uart1Fd);

+ 3 - 0
EVSE/Projects/DD360Tcci/Apps/ModuleUpdateFW/Module_UpdateFW.c

@@ -228,8 +228,11 @@ bool CreateBufferForLcmFile(char *file)
 
 unsigned long long getAvailableMemory()
 {
+    system("pkill ntpd");
+    sleep(1);
     long pages = sysconf(_SC_AVPHYS_PAGES);
     long page_size = sysconf(_SC_PAGE_SIZE);
+    log_info("Avaiable Memory size:%.1f MB",pages*page_size/(1024*1024));
     return pages * page_size;
 }
 

+ 174 - 19
EVSE/Projects/DD360Tcci/Apps/ReadCmdline.c

@@ -44,7 +44,7 @@
 #include "Config.h"
 #include "./CSU/main.h"
 #include "./DataBase/DataBase.h"
-
+#include "./ModuleEvComm/Module_EvComm.h"
 //------------------------------------------------------------------------------
 #define CMD_KEY_WAIT                                (1)
 #define CMD_KEY_DONT_WAIT                           (0)
@@ -544,18 +544,7 @@ void GetGunSelectedNum(char *v1)
         }
     }
 }
-void writeChillerStatus(char* v1)
-{
-    if (ShmDcCommonData->DebugFlag == YES) {
-        ShmDcCommonData->chillerCtrl = atoi(newString[1]);
-        if (ShmDcCommonData->chillerCtrl)
-            printf("Chiller set on\n");
-        else
-            printf("Chiller set off\n");
-    }
-    else
-        printf("Please open Debug mode\n");
-}
+
 void writeBackLight(char* v1)
 {
     uint8_t light = atoi(v1);
@@ -764,6 +753,102 @@ static void setConfirmSelGun(uint8_t selGun)
     }
 }
 
+
+static float ReadAdcVolt(uint8_t AdcChannel)
+{
+    //AIN0=CCS GUN Temp 1
+    //AIN1=CCS GUN Temp 2
+    //AIN2=CCS_Proximity/2
+    //AIN3=pilot voltage
+    int fd = -1;
+    uint8_t str[64] = { 0 };
+    uint8_t AdcValue[8] = { '\0' };
+
+    if (AdcChannel > 7) {
+        return -1;
+    }
+
+    sprintf((char*)str, "/sys/bus/iio/devices/iio\:device0/in_voltage%d_raw", AdcChannel);
+    fd = open((char*)str, O_RDONLY);
+    read(fd, AdcValue, 4);
+
+    close(fd);
+
+    return (1.8 * atoi((char*)&AdcValue[0])) / 4095;
+    //return (1.8 * atoi((char *)&AdcValue)) / 4095;
+}
+
+static void getChillerTemperature(struct ChargingInfoData* chargingData)
+{
+    uint8_t i = 0;
+    float adcVoltage = 0.0;
+    ChillerTemp pChillerTemp;
+    uint8_t maxTemp;
+    for (i = 0; i < 4; i++) {
+        adcVoltage = 0.0;
+        adcVoltage = ReadAdcVolt(i);
+        if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40
+            pChillerTemp.Temp[i] = ((adcVoltage - 0.908) * 500) + 60;
+            //log_info("1 adcVoltage = %f", (adcVoltage - 0.9) * 500);
+        } else if ((adcVoltage <= 1.07) && (adcVoltage > 0.9)) {
+            pChillerTemp.Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60;
+            //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500);
+        } else {
+            pChillerTemp.Temp[i] = UNDEFINED_TEMP;
+        }
+    }
+    maxTemp = pChillerTemp.Temp[0];
+    memcpy((char*)ShmDcCommonData->SystemTemp, (char*)pChillerTemp.Temp, sizeof(ChillerTemp));
+    for (i = 1; i < 4; i++) {
+        if (pChillerTemp.Temp[i] > pChillerTemp.Temp[i - 1] && pChillerTemp.Temp[i] != UNDEFINED_TEMP) {
+            maxTemp = pChillerTemp.Temp[i];
+        }
+    }
+    chargingData->ChillerTemp = maxTemp;
+}
+
+void GetOtpPwrOrCurMethod(struct ChargingInfoData* chargingData, float* pow, float* cur)
+{
+    for(int i = 0 ; i < 4 ; i++) {
+        if (ShmDcCommonData->SystemTemp[i] >= STAGE1_GUN_DERATING_TEMP &&
+            ShmDcCommonData->SystemTemp[i] < STAGE2_GUN_DERATING_TEMP && 
+            chargingData->deratingByConnOtp.deratingIndex < 1) {
+            chargingData->deratingByConnOtp.deratingIndex = 1;
+        } else if (ShmDcCommonData->SystemTemp[i] >= STAGE2_GUN_DERATING_TEMP &&
+            ShmDcCommonData->SystemTemp[i] != UNDEFINED_TEMP &&
+            chargingData->deratingByConnOtp.deratingIndex < 2) {
+            chargingData->deratingByConnOtp.deratingIndex = 2;
+        }
+    }
+    /*
+    if (((chargingData->ConnectorTemp >= STAGE1_GUN_DERATING_TEMP &&
+        chargingData->ConnectorTemp < STAGE2_GUN_DERATING_TEMP) ||
+        (chargingData->ChillerTemp >= STAGE1_GUN_DERATING_TEMP &&
+            chargingData->ChillerTemp < STAGE2_GUN_DERATING_TEMP)) &&
+        chargingData->deratingByConnOtp.deratingIndex < 1)
+    {
+        chargingData->deratingByConnOtp.deratingIndex = 1;
+    } else if ((chargingData->ConnectorTemp >= STAGE2_GUN_DERATING_TEMP ||
+        chargingData->ChillerTemp >= STAGE2_GUN_DERATING_TEMP) &&
+        chargingData->ConnectorTemp != UNDEFINED_TEMP &&
+        chargingData->ChillerTemp != UNDEFINED_TEMP &&
+        chargingData->deratingByConnOtp.deratingIndex < 2)
+    {
+        chargingData->deratingByConnOtp.deratingIndex = 2;
+    }
+    */
+    if (chargingData->deratingByConnOtp.deratingTargetRate[chargingData->deratingByConnOtp.deratingIndex] != 0)
+    {
+        *pow *= chargingData->deratingByConnOtp.deratingTargetRate[chargingData->deratingByConnOtp.deratingIndex];
+    } else if (chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex] != 0)
+    {
+        if (*cur > (chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex]/10)) {
+            *cur = chargingData->deratingByConnOtp.deratingTargetCurrent[chargingData->deratingByConnOtp.deratingIndex]/10;
+
+        }
+    }
+}
+
 void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 {
     int _GunIndex;
@@ -773,7 +858,11 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     int isContinue = 1;
     float _Voltage;
     float _Current;
+    float deratingPower;
+    float deratingCurrent;
+    int derating_index = 0;
     uint8_t PreviousSystemStatus[2] = {0xff};
+    int idx;
     char *usageMsg = "Usage:\n"
                      "       strchg <index> <voltage> <current>    ex: strchg 0 150 2\n"
                      "       chg    <voltage> <current>            ex: chg 500 100\n"
@@ -833,6 +922,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 printf ("[UnconditionalCharge - S_IDLE]\n");
                 pDcChargingInfo->Type = 9;
                 ShmDcCommonData->AuthPass_flag[curGun] = TRUE;
+                sleep(1);
 
             }
             if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf == 1) {
@@ -843,7 +933,6 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             break;
 
         case S_PREPARNING:
-            ShmDcCommonData->chillerCtrl = TRUE;
 
             if (PreviousSystemStatus[curGun] != pDcChargingInfo->SystemStatus) {
                 PreviousSystemStatus[curGun] = pDcChargingInfo->SystemStatus;
@@ -986,6 +1075,33 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 //                      pDcChargingInfo->EvBatterytargetVoltage,
 //                      pDcChargingInfo->EvBatterytargetCurrent);
             //ev task do this
+            for (idx = 0; idx < pSysConfig->TotalConnectorCount; idx++) {
+                struct ChargingInfoData* pInfo = (struct ChargingInfoData*)GetDcChargingInfoData(idx);
+                if (pInfo->deratingByConnOtp.isNeedDerating) {
+                    deratingCurrent = pInfo->EvBatterytargetCurrent;
+                    deratingPower = pInfo->AvailableChargingPower;
+
+                    getChillerTemperature(pInfo);
+                    GetOtpPwrOrCurMethod(pInfo, &deratingPower, &deratingCurrent);
+                    if (derating_index != pDcChargingInfo->deratingByConnOtp.deratingIndex) {
+                        printf("Change Derating Index:%d\n", pInfo->deratingByConnOtp.deratingIndex);
+                        derating_index = pInfo->deratingByConnOtp.deratingIndex;
+                    }
+                    if (pInfo->EvBatterytargetCurrent != deratingCurrent ||
+                        pInfo->AvailableChargingPower != deratingPower) {
+                        pInfo->EvBatterytargetCurrent = deratingCurrent;
+                        pInfo->AvailableChargingPower = deratingPower;
+                        printf("Derating Current:%.3f Power:%.3f\n", pInfo->EvBatterytargetCurrent, pInfo->AvailableChargingPower);
+                    }
+                }
+                if (ShmPrimaryMcuData->InputDet.bits.Ac_Drop == ABNORMAL) {
+                    if (pInfo->EvBatterytargetCurrent > 1500) {
+                        pInfo->EvBatterytargetCurrent = 1500;
+                        printf("Chiller alarm limit target Current under 150A");
+                    }
+                }
+            } // for
+
             pDcChargingInfo->PresentChargingPower =
                 ((float)((pDcChargingInfo->PresentChargingVoltage) *
                          (pDcChargingInfo->PresentChargingCurrent)) / 1000);
@@ -1036,11 +1152,12 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
             pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(curGun);
             pDcChargingInfo->PresentChargingPower = 0;
-            ShmDcCommonData->chillerCtrl = FALSE;
 
             if (stopChg == pSysConfig->TotalConnectorCount) {
                 ShmDcCommonData->DebugFlag = FALSE;
                 system("/root/Module_EvComm &");
+                ShmFanModuleData->TestFanSpeed = 0;
+
                 sleep(3);
 
                 for (_GunIndex = 0; _GunIndex < pSysConfig->TotalConnectorCount; _GunIndex++) {
@@ -1313,7 +1430,42 @@ static void writeGunAndChillerTemp(void)
         usleep(sleepTime);
     }//while
 }
-
+void writeParking(char* idx,char* _status)
+{
+    int gun = atoi(idx);
+    int status = atoi(_status);
+    ShmDcCommonData->pGunInfo[gun].ParkingStatus = status;
+    switch(status) {
+        case _TCC_PARKING_NONE:
+            printf("Gun%d Parking status set _TCC_PARKING_NONE\n",gun);
+            break;
+        case _TCC_PARKING_OCCUPENCY:
+            printf("Gun%d Parking status set _TCC_PARKING_OCCUPENCY\n",gun);
+            break;
+        case _TCC_PARKING_REQ_PARKING_FEE:
+            printf("Gun%d Parking status set _TCC_PARKING_REQ_PARKING_FEE\n",gun);
+            break;
+        case _TCC_WAIT_PAY:
+            printf("Gun%d Parking status set _TCC_WAIT_PAY\n",gun);
+            break;
+        default:
+            printf("Enter Error data!!");
+    }
+}
+void writeParkBill(char* gun) {
+    ShmDcCommonData->pGunInfo[atoi(gun)].GetParkingBill = TRUE;
+    ShmDcCommonData->pGunInfo[atoi(gun)].isParking = TRUE;
+    ShmDcCommonData->ParkingInfo[atoi(gun)].Amount = 99;
+    ShmDcCommonData->ParkingInfo[atoi(gun)].ParkingDuration = 999;
+    sprintf((char *)ShmDcCommonData->ParkingInfo[atoi(gun)].OccupancySN,"1213241433");
+    sprintf((char *)ShmDcCommonData->ParkingInfo[atoi(gun)].ParkingStartTime,"3:30 PM");
+    if (pSysInfo->CurGunSelected == atoi(gun) && pSysInfo->SystemPage == _PAGE_PAYING)
+        pSysInfo->SystemPage = _PAGE_BILL;
+}
+void SetNetDump(char* _set) {
+    ShmDcCommonData->netdump = atoi(_set);
+    printf("Print Net package %d\n",ShmDcCommonData->netdump);
+}
 int main(void)
 {
     uint8_t _GunIndex = 0;
@@ -1339,7 +1491,6 @@ int main(void)
                      "       tempR                             : print connector header and chiller temperature\r\n"
     			     "       btnl                              : press left button\n"
     			  	 "       btnr                              : press right button\n"
-                     "       chiller                           : set chiller on/off\n"
                      "       settlement                        : Credit Card UnionSettlement\n"
                      "       rededuct                          : Credit Card rededuct\n"
                      "       preauth                           : Credit Card PreAuth\n"
@@ -1532,8 +1683,6 @@ int main(void)
             ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL;
         } else if (strcmp(newString[0], "sale") == 0) {
             ShmDcCommonData->PreAuth_Config = _CREDITCARD_SALE;
-        } else if (strcmp(newString[0], "chiller") == 0) { //測試槍頭和水冷機溫度
-            writeChillerStatus(newString[1]);
         } else if (strcmp(newString[0], "tccdev") == 0) { //Open TCC DEV
             writeTccdev();
         } else if (strcmp(newString[0], "lcmtest") == 0) { 
@@ -1549,6 +1698,12 @@ int main(void)
             setbilltest(newString[1], newString[2]);
         } else if (strcmp(newString[0], "backlight") == 0) { //測試槍頭和水冷機溫度
             writeBackLight(newString[1]);
+        } else if (strcmp(newString[0], "park") == 0) {
+            writeParking(newString[1],newString[2]);
+        } else if (strcmp(newString[0], "parkbill") == 0) {
+            writeParkBill(newString[1]);
+        } else if (strcmp(newString[0], "netdump") == 0) {
+            SetNetDump(newString[1]);
         } else {
             printf("%s\n", usageMsg);
         }

BIN
EVSE/Projects/DD360Tcci/Apps/UnsafetyOutputTask


+ 4 - 2
EVSE/Projects/DD360Tcci/Apps/timeout.h

@@ -45,13 +45,13 @@ enum Timeout_flag {
     Timeout_EvseChargingDet        = 8,
     Timeout_EvseCompleteDet        = 9,
     Timeout_ForCcsPrechargeDet     = 10,
-    Timeout_ReturnToChargingGunDet = 11,
+    Timeout_WaitParkingInfo        = 11,
     Timeout_AuthorizingForStop     = 12,
     Timeout_SelectGun              = 13,
     Timeout_WaitBalance            = 14,
     Timeout_EVCCID_Link            = 15,
 	Timeout_LinkError              = 16,
-	Timeout_DetailView             = 17,
+	Timeout_ParkingSelect          = 17,
 	Timeout_Terminating            = 18,
 	Timeout_PlugOutGun             = 19,
 	Timeout_AddLine				   = 20,
@@ -65,6 +65,8 @@ enum Timeout_flag {
     Timeout_TradeCancel            = 28,
     Timeout_LINEPAYING             = 29,
     Timeout_CompletPlugout         = 30,
+    Timeout_ParkingBill            = 31,
+    Timeout_ParkingLeave           = 32,
 };
 
 //------------------------------------------------------------------------------

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


BIN
EVSE/Projects/DD360Tcci/output/FactoryConfig


BIN
EVSE/Projects/DD360Tcci/output/Module_ChkSysTask


BIN
EVSE/Projects/DD360Tcci/output/Module_DoComm


BIN
EVSE/Projects/DD360Tcci/output/Module_EvComm


BIN
EVSE/Projects/DD360Tcci/output/Module_EventLogging


BIN
EVSE/Projects/DD360Tcci/output/Module_InternalComm


BIN
EVSE/Projects/DD360Tcci/output/Module_LcmControl


BIN
EVSE/Projects/DD360Tcci/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360Tcci/output/Module_UpdateFW


BIN
EVSE/Projects/DD360Tcci/output/ReadCmdline


BIN
EVSE/Projects/DD360Tcci/output/UnsafetyOutputTask


BIN
EVSE/Projects/DD360Tcci/output/main


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio