#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include /*Unix 標準函數定義*/ #include /*檔控制定義*/ #include /*PPSIX 終端控制定義*/ #include /*錯誤號定義*/ #include #include #include #include #include #include #include #include #include #include #include "../Config.h" #include "main.h" #include "../common.h" #include "../timeout.h" #include "../Log/log.h" #include "../DataBase/DataBase.h" #include "../Define/define.h" #include "../ShareMemory/shmMem.h" #include "../SelectGun/SelectGun.h" //------------------------------------------------------------------------------ static struct SysInfoData *pSysInfo = NULL; static struct SysConfigData *pSysConfig = NULL; static struct WARNING_CODE_INFO *pSysWarning = NULL; static struct AlarmCodeData *pAlarmCode = NULL; static struct FaultCodeData *pFaultCode = NULL; static struct InfoCodeData *pInfoCode = NULL; static struct PsuData *ShmPsuData = NULL; static struct CHAdeMOData *ShmCHAdeMOData = NULL; static struct GBTData *ShmGBTData = NULL; static struct CcsData *ShmCcsData = NULL; static struct PrimaryMcuData *ShmPrimaryMcuData = NULL; static struct FanModuleData *ShmFanModuleData = NULL; static struct RelayModuleData *ShmRelayModuleData = NULL; static struct LedModuleData *ShmLedModuleData = NULL; static struct OCPP16Data *ShmOCPP16Data = NULL; static struct OCPP20Data* ShmOCPP20Data = NULL; static DcCommonInfo *ShmDcCommonData = NULL; static struct ChargingInfoData *pDcChargingInfo = NULL; static struct ChargingInfoData *pAcChargingInfo = NULL; static struct timeb startChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; static struct timeb endChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; static SelectGunInfo *ShmSelectGunInfo = NULL; //Jerry add static EvBoardErrMsg gEvBoardErr = {0}; static ChillerTempErr gChillerTempErr = {0}; struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; #define DERATING_TARGET_LEVEL 5 // for initial index to check EV board type is correct uint8_t bd0_1_status = 0; uint8_t bd0_2_status = 0; uint8_t bd1_1_status = 0; uint8_t bd1_2_status = 0; char *fwVersion = "V2.23.00.0000.00"; // Phihong version char* DebugVersion = "V2.23.00"; // Software debug version //sqlite3 *localDb; bool isDb_ready; //------------------------------------------------------------------------------ void ClearDetectPluginFlag(int gunIndex); long long DiffTimebWithNow(struct timeb ST); uint8_t DetectBitValue(uint8_t _byte, uint8_t _bit); void SetBitValue(uint8_t *_byte, uint8_t _bit, uint8_t value); unsigned long GetTimeoutValue(struct timeval _sour_time); unsigned long GetClockTimeoutValue(struct timespec _start_time); void GetClockTime(struct timespec *_now_time, void *null); void gpio_set_value(unsigned int gpio, unsigned int value); void InformOcppErrOccur(uint8_t codeType); void RecordAlarmCode(uint8_t gunIndex, char *code); void ReleaseAlarmCode(uint8_t gunIndex); void ResetChargerAlarmCode(uint8_t gunIndex, char *code); void AdjustChargerCurrent(void); void UpdateErrorCodeToOcpp(uint8_t index); //------------------------------------------------------------------------------ //Primary.c extern void ChkPrimaryStatus(void); //RFID.c extern void CreateRfidFork(void); extern void ScannerCardProcess(int gunIndex); extern bool RfidStopCharging(void); extern bool GetIsCardScan(void); extern void SetIsCardScan(bool value); //SelfTest.c extern void SelfTestRun(void); //UpgradeFW.c /*extern void CheckFwUpdateFunction(void);*/ //Ethernet.c extern void InitEthernet(void); extern void GetMacAddress(void); //WatchDog.c extern void CreateWatchdog(void); extern void TryCloseWatchdog(void); extern void TryFeedWatchdog(void); //ZipFile.c extern void zipLogFiles(void); //------------------------------------------------------------------------------ //--- share memory value --- //------------------------------------------------------------------------------ static void changeLcmPage(uint8_t index) { pSysInfo->SystemPage = index; } static uint8_t getCurLcmPage(void) { return pSysInfo->SystemPage; } 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; } //------------------------------------------------------------------------------ void destroySelGun(uint8_t curGun) { uint8_t i = 0; uint8_t totalGun = pSysConfig->TotalConnectorCount; //for status timeout if (curGun == DESTROY_ALL_SEL) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE; ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE; log_info("destroy all gun = %d, %d", ShmSelectGunInfo->SelGunInfo.LeftGun, ShmSelectGunInfo->SelGunInfo.RightGun); for (i = 0; i < totalGun; i++) { StopGunInfoTimeoutDet(i); memset(&ShmSelectGunInfo->PricesInfo[i], 0, sizeof(PricesInfo)); } pSysInfo->CurGunSelected = 0; strcpy((char *)pSysConfig->UserId, ""); //changeLcmPage(_LCM_VIEW); return; } //for charging timeout or complete if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun != SEL_GUN_RELEASE)) { if (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM || ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR) { //changeLcmPage(_PAGE_SELECT_GUN); } ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_RELEASE; StopGunInfoTimeoutDet(LEFT_GUN_NUM); if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf != NO) { ClearAuthorizedFlag(); } log_info("destroy left gun, cur page = %d", getCurLcmPage()); if (getCurLcmPage() == pSysInfo->SystemPage) { log_info("clear left balance"); memset(&ShmSelectGunInfo->PricesInfo[curGun], 0, sizeof(PricesInfo)); ShmSelectGunInfo->PricesInfo[curGun].Balance = FAIL_BALANCE_PRICES; } } if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun != SEL_GUN_RELEASE)) { if (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM || ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR) { //changeLcmPage(_PAGE_SELECT_GUN); } ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_RELEASE; StopGunInfoTimeoutDet(RIGHT_GUN_NUM); if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf != NO) { ClearAuthorizedFlag(); } log_info("destroy right gun, cur page = %d", getCurLcmPage()); if (getCurLcmPage() == pSysInfo->SystemPage) { log_info("clear right balance"); memset(&ShmSelectGunInfo->PricesInfo[curGun], 0, sizeof(PricesInfo)); ShmSelectGunInfo->PricesInfo[curGun].Balance = FAIL_BALANCE_PRICES; } } } static int waitRightGunPlugIt(uint8_t curGun) { if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR)) { return PASS; } return FAIL; } static int waitLeftGunPlugIt(uint8_t curGun) { if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR)) { return PASS; } return FAIL; } void setSelGunWaitToAuthor(uint8_t curSel) { if (curSel == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_ATHOR; //log_info("setSelGunWaitToAuthor left"); StopGunInfoTimeoutDet(curSel); } else if (curSel == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_ATHOR; //log_info("setSelGunWaitToAuthor right"); StopGunInfoTimeoutDet(curSel); } } int getConfirmSelectedGun(uint8_t curSel) { if (((curSel == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun >= SEL_GUN_CONFIRM)) || ((curSel == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun >= SEL_GUN_CONFIRM))) { return PASS; } return FAIL; } void confirmSelGun(uint8_t selGun) { if (selGun == LEFT_GUN_NUM) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_CONFIRM; //printf("confirmSelGun left"); } else if (selGun == RIGHT_GUN_NUM) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_CONFIRM; //printf("confirmSelGun right"); } //changeLcmPage(_PAGE_PLUGIN); //StartGunInfoTimeoutDet(selGun, Timeout_SelectGun); //StartSystemTimeoutDet(Timeout_ReturnViewPage); } static void GetFirmwareVersion(void) { // Get CSU root file system version sprintf((char *)pSysInfo->CsuRootFsFwRev, fwVersion); sprintf((char*)ShmDcCommonData->DebugVersion, DebugVersion); uint8_t count = 0, chademo = 0, ccs = 0, gb = 0; for (uint8_t idx = 0; idx < 3; idx++) { if (pSysConfig->ModelName[7 + idx] == 'J') { chademo++; count++; } else if (pSysConfig->ModelName[7 + idx] == 'G') { gb++; count++; } else if (pSysConfig->ModelName[7 + idx] == 'U' || pSysConfig->ModelName[7 + idx] == 'V' || pSysConfig->ModelName[7 + idx] == 'E') { ccs++; count++; } } if (count == 1) { if (chademo > 0) { pSysInfo->CsuRootFsFwRev[7] = '1'; } else if (ccs > 0) { pSysInfo->CsuRootFsFwRev[7] = '2'; } else if (gb > 0) { pSysInfo->CsuRootFsFwRev[7] = '3'; } } else { if (chademo > 0 && ccs > 0) { pSysInfo->CsuRootFsFwRev[7] = '4'; } else if (chademo > 0 && gb > 0) { pSysInfo->CsuRootFsFwRev[7] = '5'; } else if (ccs > 0 && gb > 0) { pSysInfo->CsuRootFsFwRev[7] = '6'; } } // Get network option from model name switch (pSysConfig->ModelName[10]) { case 'B': case 'U': //Blue tooth pSysInfo->CsuRootFsFwRev[9] = '3'; break; case 'W': // WIFI pSysInfo->CsuRootFsFwRev[9] = '1'; break; case 'T': // 3G/4G pSysInfo->CsuRootFsFwRev[9] = '2'; break; case 'D': //DS60-120 add pSysInfo->CsuRootFsFwRev[9] = '5'; break; default: // LAN pSysInfo->CsuRootFsFwRev[9] = '0'; break; } // Get rating power from model name memcpy(&pSysInfo->CsuRootFsFwRev[10], &pSysConfig->ModelName[4], 0x03); // Get IEC or UL char _buf[3] = {0}; memcpy(_buf, &pSysConfig->ModelName[2], 2); if (strcmp(_buf, "YE") == EQUAL || strcmp(_buf, "YC") == EQUAL) { pSysInfo->ChargerType = _CHARGER_TYPE_IEC; log_info("IEC model"); } else if (strcmp(_buf, "WU") == EQUAL) { pSysInfo->ChargerType = _CHARGER_TYPE_UL; log_info("UL model"); } } static void checkGunOTPState(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //水冷機溫度檢測 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) { if (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP) { if (pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) { if (((gunIndex == 0) && ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0))) || ((gunIndex == 1) && ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0))) ) { RecordAlarmCode(gunIndex, "012323"); ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES; } else { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; } } else if (pDcChargingInfo->ChillerTemp != 0 && pDcChargingInfo->ChillerTemp < GUN_OTP_RECOVERY) { //ResetChargerAlarmCode(gunIndex, "012323"); ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; } ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO; } else { // 沒接上 Sensor or 異常 //RecordAlarmCode(gunIndex, "011038"); //ResetChargerAlarmCode(gunIndex, "012323"); ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; if (((gunIndex == 0) && ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0))) || ((gunIndex == 1) && ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0))) ) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES; } else { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO; } } if(pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES) { RecordAlarmCode(gunIndex, "011037"); } } switch (pDcChargingInfo->Type) { case _Type_Chademo: if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) { if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) { RecordAlarmCode(gunIndex, "012229"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) { //ResetChargerAlarmCode(gunIndex, "012229"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO; } ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO; } else { // 沒接上 Sensor or 異常 //RecordAlarmCode(gunIndex, "011018"); //ResetChargerAlarmCode(gunIndex, "012229"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES; if ((gunIndex == 0) && (strncmp((char *)&pSysConfig->ModelName[7], "J", 1) == 0)) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO; } else if ((gunIndex == 1) && ((strncmp((char *)&pSysConfig->ModelName[9], "J", 1) == 0) )) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO; } } break; case _Type_CCS_2: // CCS 不管甚麼輸出都會有槍溫偵測!!~ if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) { //ResetChargerAlarmCode(gunIndex, "011019"); if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) { RecordAlarmCode(gunIndex, "012230"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) { //ResetChargerAlarmCode(gunIndex, "012230"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO; } ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = NO; //ResetChargerAlarmCode(gunIndex, "011019"); } else { // 沒接上 Sensor or 異常 //RecordAlarmCode(gunIndex, "011019"); //ResetChargerAlarmCode(gunIndex, "012230"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = YES; } break; case _Type_GB: if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) { if (pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) { RecordAlarmCode(gunIndex, "012231"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < GUN_OTP_RECOVERY) { //ResetChargerAlarmCode(gunIndex, "012231"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO; } ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = NO; } else { // 沒接上 Sensor or 異常 //RecordAlarmCode(gunIndex, "011020"); //ResetChargerAlarmCode(gunIndex, "012231"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = YES; } break; } } bool checkGunTempFail(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); switch (pDcChargingInfo->Type) { case _Type_Chademo: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail) { RecordAlarmCode(gunIndex,"011018"); if (IntoChargeProcess(pDcChargingInfo->SystemStatus)) { setChargerMode(gunIndex,S_ALARM); } if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION ) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "011018", 6); setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; case _Type_CCS_2: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail) { RecordAlarmCode(gunIndex,"011019"); if (IntoChargeProcess(pDcChargingInfo->SystemStatus)) { setChargerMode(gunIndex,S_ALARM); } if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION ) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "011019", 6); setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; case _Type_GB: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail) { RecordAlarmCode(gunIndex,"011020"); if (IntoChargeProcess(pDcChargingInfo->SystemStatus)) { setChargerMode(gunIndex,S_ALARM); } if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION ) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "011020", 6); setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; } return FALSE; } static void collectError(uint8_t gunIndex) { gEvBoardErr.GunErrMessage |= ShmDcCommonData->ConnectErrList[gunIndex].GunErrMessage; gChillerTempErr.TempErrMsg |= ShmDcCommonData->ChillerTempErr[gunIndex].TempErrMsg; } static void checkGBTAlarmState(uint8_t gunType) { // GFD Trip if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 0)) { pAlarmCode->AlarmEvents.bits.GbGfdTrip = YES; } else { pAlarmCode->AlarmEvents.bits.GbGfdTrip = NO; } // UVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 1)) { pAlarmCode->AlarmEvents.bits.GbtOutputUVPFail = YES; } else { pAlarmCode->AlarmEvents.bits.GbtOutputUVPFail = NO; } // OTP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 2)) { pAlarmCode->AlarmEvents.bits.GbConnectorOTP = YES; } else { pAlarmCode->AlarmEvents.bits.GbConnectorOTP = NO; } // OVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 3)) { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = YES; } else { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = NO; } // GFD Warning if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 4)) { pAlarmCode->AlarmEvents.bits.GbGroundfaultWarning = YES; } else { pAlarmCode->AlarmEvents.bits.GbGroundfaultWarning = NO; } // Relay Welding if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 5)) { pFaultCode->FaultEvents.bits.GbOutputRelayWelding = YES; } else { pFaultCode->FaultEvents.bits.GbOutputRelayWelding = NO; } // Relay Driving if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 6)) { pFaultCode->FaultEvents.bits.GbOutputRelayDrivingFault = YES; } else { pFaultCode->FaultEvents.bits.GbOutputRelayDrivingFault = NO; } // Connect temp Sensor broken if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 7)) { pFaultCode->FaultEvents.bits.GbConnectorTempSensorBroken = YES; } else { pFaultCode->FaultEvents.bits.GbConnectorTempSensorBroken = NO; } } static void checkCCSAlarmState(uint8_t gunType) { // GFD Trip if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 0)) { pAlarmCode->AlarmEvents.bits.CcsGfdTrip = YES; } else { pAlarmCode->AlarmEvents.bits.CcsGfdTrip = NO; } // UVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 1)) { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = YES; } else { pAlarmCode->AlarmEvents.bits.CcsOutputUVPFail = NO; } // OTP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 2)) { pAlarmCode->AlarmEvents.bits.CcsConnectorOTP = YES; } else { pAlarmCode->AlarmEvents.bits.CcsConnectorOTP = NO; } // OVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 3)) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = YES; } else { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = NO; } // GFD Warning if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 4)) { pAlarmCode->AlarmEvents.bits.CcsGroundfaultWarning = YES; } else { pAlarmCode->AlarmEvents.bits.CcsGroundfaultWarning = NO; } // Relay Welding if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 5)) { pFaultCode->FaultEvents.bits.CcsOutputRelayWelding = YES; } else { pFaultCode->FaultEvents.bits.CcsOutputRelayWelding = NO; } // Relay Driving if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 6)) { pFaultCode->FaultEvents.bits.CcsOutputRelayDrivingFault = YES; } else { pFaultCode->FaultEvents.bits.CcsOutputRelayDrivingFault = NO; } // Connect temp Sensor broken if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 7)) { pFaultCode->FaultEvents.bits.CcsConnectorTempSensorBroken = YES; } else { pFaultCode->FaultEvents.bits.CcsConnectorTempSensorBroken = NO; } } static void checkChaDeMoAlarmState(uint8_t gunType) { // GFD Trip if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 0)) { pAlarmCode->AlarmEvents.bits.ChademoGfdTrip = YES; } else { pAlarmCode->AlarmEvents.bits.ChademoGfdTrip = NO; } // UVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 1)) { pAlarmCode->AlarmEvents.bits.ChademoOutputUVPFail = YES; } else { pAlarmCode->AlarmEvents.bits.ChademoOutputUVPFail = NO; } // OTP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 2)) { pAlarmCode->AlarmEvents.bits.ChademoConnectorOTP = YES; } else { pAlarmCode->AlarmEvents.bits.ChademoConnectorOTP = NO; } // OVP if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 3)) { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = YES; } else { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = NO; } // GFD Warning if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 4)) { pAlarmCode->AlarmEvents.bits.ChademoGroundWarning = YES; } else { pAlarmCode->AlarmEvents.bits.ChademoGroundWarning = NO; } // Relay Welding if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 5)) { pFaultCode->FaultEvents.bits.ChademoOutputRelayWelding = YES; } else { pFaultCode->FaultEvents.bits.ChademoOutputRelayWelding = NO; } // Relay Driving if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 6)) { pFaultCode->FaultEvents.bits.ChademoOutputRelayDrivingFault = YES; } else { pFaultCode->FaultEvents.bits.ChademoOutputRelayDrivingFault = NO; } // Connect temp Sensor broken if (DetectBitValue(gEvBoardErr.GunErrMessage >> (8 * gunType), 7)) { pFaultCode->FaultEvents.bits.ChademoConnectorTempSensorBroken = YES; } else { pFaultCode->FaultEvents.bits.ChademoConnectorTempSensorBroken = NO; } } static void checkChillerAlarmState(void) { if (DetectBitValue(gChillerTempErr.TempErrMsg, 0)) { pAlarmCode->AlarmEvents.bits.SystemChillerOTP = YES; } else { pAlarmCode->AlarmEvents.bits.SystemChillerOTP = NO; } if (DetectBitValue(gChillerTempErr.TempErrMsg, 1)) { pFaultCode->FaultEvents.bits.ChillerTempSensorBroken = YES; } else { pFaultCode->FaultEvents.bits.ChillerTempSensorBroken = NO; } } static void checkEvBoardAlarmState(uint8_t gunType) { switch (gunType) { case _Type_Chademo: checkChaDeMoAlarmState(gunType); break; case _Type_CCS_2: checkCCSAlarmState(gunType); break; case _Type_GB: checkGBTAlarmState(gunType); break; } } unsigned long GetTimeoutValue(struct timeval _sour_time) { struct timeval _end_time; gettimeofday(&_end_time, NULL); return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec; } void GetClockTime(struct timespec *_now_time, void *null) { clock_gettime(CLOCK_MONOTONIC, _now_time); } // return value unit: 1us unsigned long GetClockTimeoutValue(struct timespec _start_time) { struct timespec ts_end; unsigned long ret = 0; clock_gettime(CLOCK_MONOTONIC, &ts_end); ret = ((unsigned long)(ts_end.tv_sec - _start_time.tv_sec) * 1000000) + ((unsigned long)((ts_end.tv_nsec / 1000) - (_start_time.tv_nsec/ 1000))); return ret; } int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime, StopTime; StartTime = (unsigned int)ST.time; StopTime = (unsigned int)ET.time; //return (StopTime-StartTime)*1000+ET.millitm-ST.millitm; return (StopTime - StartTime); } bool CheckTimeOut(struct timeb ST) { struct timeb ET; unsigned int StartTime, StopTime; ftime(&ET); StartTime = (unsigned int) ST.time; StopTime = (unsigned int) ET.time; return (StopTime > StartTime) ? YES : NO; } void setChargerMode(uint8_t gunIndex, uint8_t mode) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); pDcChargingInfo->SystemStatus = mode; } long long DiffTimebWithNow(struct timeb ST) { //return milli-second struct timeb ET; long long StartTime, StopTime; ftime(&ET); StartTime = (long long)ST.time; StopTime = (long long)ET.time; return ((StopTime - StartTime) * 1000) + (ET.millitm - ST.millitm); } //========================================== // Log //========================================== void CheckFwSlotStatusLog(void) { if (bd0_1_status == 0 && bd0_2_status == 1) { log_info("Connector 1 : Chademo"); } else if (bd0_1_status == 1 && bd0_2_status == 0) { log_info("Connector 1 : CCS"); } else if (bd0_1_status == 1 && bd0_2_status == 1) { log_info("Connector 1 : GB"); } if (bd1_1_status == 0 && bd1_2_status == 1) { log_info("Connector 2 : Chademo"); } else if (bd1_1_status == 1 && bd1_2_status == 0) { log_info("Connector 2 : CCS"); } else if (bd1_1_status == 1 && bd1_2_status == 1) { log_info("Connector 2 : GB"); } } void CheckHwSlotStatusLog(uint8_t index) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); if (pDcChargingInfo->Type == _Type_Chademo) { log_info("Hw check : Connector %d, Type : Chademo, Evboard_id = %d ", index, pDcChargingInfo->Evboard_id); } else if (pDcChargingInfo->Type == _Type_CCS_2) { log_info("Hw check : Connector %d, Type : CCS, Evboard_id = %d ", index, pDcChargingInfo->Evboard_id); } else if (pDcChargingInfo->Type == _Type_GB) { log_info("Hw check : Connector %d, Type : GB, Evboard_id = %d ", index, pDcChargingInfo->Evboard_id); } } //================================= // LCM Page //================================= void ChangeLcmByIndex(uint8_t page_index) { if (pSysWarning->Level != WARN_LV_ER ) { pSysInfo->PageIndex = page_index; //log_info("LCM index:%d",pSysInfo->PageIndex); } } //====================================================== // Peripheral initial //====================================================== void InitGPIO() { /*****************0~3, 4 bank, bank x 32+ num*********************/ /***************************************************************/ /*************** GPIO 0 ***************************************/ /***************************************************************/ /* GPMC_AD8 => GPIO0_22 *//*ID BD1_1*/ system("echo 22 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio22/direction"); /* GPMC_AD9 => GPIO0_23 *//*ID BD1_2*/ system("echo 23 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio23/direction"); /* GPMC_AD10 => GPIO0_26 *//*IO BD1_1*/ system("echo 26 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio26/direction"); system("echo 1 > /sys/class/gpio/gpio26/value"); /* GPMC_AD11 => GPIO0_27 *//*IO BD1_2*/ system("echo 27 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio27/direction"); /* RMII1_REF_CLK => GPIO0_29 *//*USB 0 OCP detection*/ system("echo 29 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio29/direction"); /*XDMA_EVENT_INTR0 => GPIO0_19 *//*AM_RFID_RST*/ system("echo 19 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio19/direction"); system("echo 1 > /sys/class/gpio/gpio19/value"); /*XDMA_EVENT_INTR1 => GPIO0_20 *//*AM_RFID_ICC*/ system("echo 20 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio20/direction"); /***************************************************************/ /*************** GPIO 1 ***************************************/ /***************************************************************/ /* GPMC_AD12 => GPIO1_12 *//*ID BD2_1*/ system("echo 44 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio44/direction"); /* GPMC_AD13 => GPIO1_13 *//*ID BD2_2*/ system("echo 45 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio45/direction"); /* GPMC_AD14 => GPIO1_14 *//*IO BD2_1*/ system("echo 46 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio46/direction"); system("echo 0 > /sys/class/gpio/gpio46/value"); /* GPMC_AD15 => GPIO1_15 *//*IO BD2_2*/ system("echo 47 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio47/direction"); /***************************************************************/ /*************** GPIO 2 ***************************************/ /***************************************************************/ /*LCD_AC_BIAS_EN => GPIO2_25*//*RS-485 for module DE control*/ system("echo 89 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio89/direction"); system("echo 1 > /sys/class/gpio/gpio89/value"); /*LCD_HSYNC => GPIO2_23*//*RS-485 for module RE control*/ system("echo 87 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio87/direction"); system("echo 0 > /sys/class/gpio/gpio87/value"); /*LCD_PCLK => GPIO2_24*//*CCS communication board 1 proximity*/ system("echo 88 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio88/direction"); /*LCD_VSYNC => GPIO2_22*//*CCS communication board 2 proximity*/ system("echo 86 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio86/direction"); /***************************************************************/ /*************** GPIO 3 ***************************************/ /***************************************************************/ /*MCASP0_FSX => GPIO3_15*//*Emergency Stop button detect*/ system("echo 111 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio111/direction"); /*MCASP0_ACLKR => GPIO3_18*//*USB1 OCP detect*/ system("echo 114 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio114/direction"); /*MCASP0_AHCLKR => GPIO3_17*//*Emergency IO for AM3352 and STM32F407*/ system("echo 113 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio113/direction"); /*MCASP0_ACLKX => GPIO3_14*//*Ethernet PHY reset*/ system("echo 110 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio110/direction"); system("echo 0 > /sys/class/gpio/gpio110/value"); /* MCASP0_FSR => GPIO3_19 *//*SMR Enable control_1 for Pskill_1*/ system("echo 115 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio115/direction"); system("echo 0 > /sys/class/gpio/gpio115/value"); /* MCASP0_AXR0 => GPIO3_16 *//*CSU board function OK indicator.*/ system("echo 112 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio112/direction"); system("echo 1 > /sys/class/gpio/gpio112/value"); /* MCASP0_AXR1 => GPIO3_20 *//*SMR Enable control_2 for Pskill_2*/ system("echo 116 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio116/direction"); system("echo 0 > /sys/class/gpio/gpio116/value"); log_info("Initial GPIO OK"); return ; } int LoadSysConfigAndInfo() { int fd, wrd; unsigned char *buf; unsigned int ChkSum, ChkSumOrg; if ((buf = malloc(MtdBlockSize)) == NULL) { log_error("malloc buffer NG,rebooting.."); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); //================================================ // Load configuration from mtdblock10 //================================================ system("nanddump /dev/mtd10 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); log_error("open mtdblock10 NG,rebooting.."); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { free(buf); log_error("read SysConfigData data NG,rebooting.."); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); memcpy(&pSysConfig->ModelName, buf + (ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev)), ARRAY_SIZE(pSysConfig->ModelName)); memcpy(&pSysConfig->SerialNumber, buf + (ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev) + ARRAY_SIZE(pSysConfig->ModelName) + ARRAY_SIZE(pSysConfig->AcModelName)), ARRAY_SIZE(pSysConfig->SerialNumber)); //================================================ // Load configuration from mtdblock11 //================================================ if (ChkSum != ChkSumOrg) { log_error("Primary SysConfigData checksum NG, read backup"); system("nanddump /dev/mtd11 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); log_error("open mtdblock11 (backup) NG,rebooting.."); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { free(buf); log_error("read backup SysConfigData data NG,rebooting.."); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); //================================================ // Load configuration from mtdblock12 (Factory default) //================================================ if (ChkSum != ChkSumOrg) { log_warn("backup SysConfigData checksum NG, read Factory default"); system("nanddump /dev/mtd12 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { log_error("open mtdblock12 (Factory default) NG,rebooting.."); free(buf); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd = read(fd, buf, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { log_error("read factory default SysConfigData data NG,rebooting.."); free(buf); if (pAlarmCode != NULL) { pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum = 0; for (wrd = ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev); wrd < MtdBlockSize - 4; wrd++) { ChkSum += buf[wrd]; } memcpy(&ChkSumOrg, buf + (MtdBlockSize - 4), sizeof(ChkSumOrg)); memcpy(buf + (ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev)), &pSysConfig->ModelName, ARRAY_SIZE(pSysConfig->ModelName)); memcpy(buf + (ARRAY_SIZE(pSysConfig->CsuBootLoadFwRev) + ARRAY_SIZE(pSysConfig->ModelName) + ARRAY_SIZE(pSysConfig->AcModelName)), &pSysConfig->SerialNumber, ARRAY_SIZE(pSysConfig->SerialNumber)); if (ChkSum != ChkSumOrg) { log_warn("factory default SysConfigData checksum NG, restore factory default"); free(buf); system("cd /root;./FactoryConfig -m"); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } } } //load OK memcpy(pSysConfig, buf, sizeof(struct SysConfigData)); free(buf); system("rm -f /mnt/EvseConfig.bin"); // SysConfig in flash is empty (0xffffffff) if ((strlen((char *)pSysConfig->ModelName) > ARRAY_SIZE(pSysConfig->ModelName)) || (strlen((char *)pSysConfig->SerialNumber) > ARRAY_SIZE(pSysConfig->SerialNumber)) || (strlen((char *)pSysConfig->SystemId) > ARRAY_SIZE(pSysConfig->SystemId)) || (pSysConfig->Eth0Interface.EthDhcpClient == 0xff)) { if (strlen((char *)pSysConfig->ModelName) > ARRAY_SIZE(pSysConfig->ModelName)) { memset(pSysConfig->ModelName, 0x00, ARRAY_SIZE(pSysConfig->ModelName)); } if (strlen((char *)pSysConfig->SerialNumber) > ARRAY_SIZE(pSysConfig->SerialNumber)) { memset(pSysConfig->SerialNumber, 0x00, ARRAY_SIZE(pSysConfig->SerialNumber)); } if (strlen((char *)pSysConfig->SystemId) > ARRAY_SIZE(pSysConfig->SystemId)) { memset(pSysConfig->SystemId, 0x00, ARRAY_SIZE(pSysConfig->SystemId)); } if (pSysConfig->Eth0Interface.EthDhcpClient == 0xff) { log_info("Ethernet dhcp config is null."); } if (strlen((char *)pSysConfig->ModelName) == 0x00) { log_info("Model name over length."); } if (strlen((char *)pSysConfig->SerialNumber) == 0x00) { log_info("Model serial number over length."); } if (strlen((char *)pSysConfig->SystemId) == 0x00) { log_info("SystemId over length."); } system("cd /root;./FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } log_info("Load SysConfigData OK"); return PASS; } int Initialization(void) { uint8_t count = 0; uint8_t pinOut[2] = {116, 115}; // 初始化卡號驗證的 Flag ClearAuthorizedFlag(); for (count = 0; count < pSysConfig->TotalConnectorCount; count++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(count); // 初始化插槍驗證的 Flag ClearDetectPluginFlag(count); pDcChargingInfo->RemoteStartFlag = NO; if (pDcChargingInfo->Type == _Type_Chademo) { gpio_set_value(pinOut[count], 0x00); ShmCHAdeMOData->evse[pDcChargingInfo->type_index].SelfTest_Comp = NO; } else if (pDcChargingInfo->Type == _Type_GB) { gpio_set_value(pinOut[count], 0x00); ShmGBTData->evse[pDcChargingInfo->type_index].SelfTest_Comp = NO; } else if (pDcChargingInfo->Type == _Type_CCS_2) { //if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { //DS60-120 remove if (pSysConfig->TotalConnectorCount == 1) { gpio_set_value(pinOut[1], 0x01); } else { gpio_set_value(pinOut[count], 0x01); } ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].SelfTest_Comp = NO; //} } strcpy((char *)ShmOCPP16Data->StatusNotification[count].ErrorCode, "NoError"); } for (count = 0; count < pSysConfig->AcConnectorCount; count++) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(count); pAcChargingInfo->RemoteStartFlag = NO; if (pAcChargingInfo->Type == _Type_AC) { pAcChargingInfo->SelfTest_Comp = NO; strcpy((char *)ShmOCPP16Data->StatusNotification[count + pSysConfig->TotalConnectorCount].ErrorCode, "NoError"); } } return PASS; } bool InitialSystemDefaultConfig() { bool result = true; LoadSysConfigAndInfo(); InitGPIO(); InitEthernet(); GetMacAddress(); return result; } //顯示自檢錯誤原因,觸發對應的flag bool DisplaySelfTestFailReason() { bool result = false; uint8_t index = 0; // RB、FB、407、EV 小板中有些板子無回應 if (ShmRelayModuleData->SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.RelayboardStestFail = true; } if (ShmFanModuleData->SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.FanboardStestFail = true; } if (ShmPrimaryMcuData->SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.PrimaryStestFail = true; } if (ShmLedModuleData->SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.LedboardStestFail = true; } for (index = 0; index < pSysConfig->TotalConnectorCount; index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); if (pDcChargingInfo->Type == _Type_Chademo) { if (ShmCHAdeMOData->evse[pDcChargingInfo->type_index].SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.ChademoboardStestFail = true; } } else if (pDcChargingInfo->Type == _Type_GB) { if (ShmGBTData->evse[pDcChargingInfo->type_index].SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.GbtboardStestFail = true; } } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { if (ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.CCSboardStestFail = true; } } } } for (index = 0; index < pSysConfig->AcConnectorCount; index++) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(index); // 先借 GBT 顯示 if (pAcChargingInfo->SelfTest_Comp == NO) { pAlarmCode->AlarmEvents.bits.AcConnectorStestFail = true; } } if (pSysInfo->AcContactorStatus == NO) { #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox &&!defined DD360UCar // AC Contact 未搭上 pAlarmCode->AlarmEvents.bits.AcContactStestFail = true; result = true; #endif // !defined DD360 && !defined DD360Audi && !defined DD360ComBox } //else if (pAlarmCode->AlarmEvents.bits.PsuDipSwitchStestFail == YES) { //DS60-120 add // result = true; //} else if (ShmPsuData->SystemAvailablePower <= 0 && ShmPsuData->SystemAvailableCurrent <= 0) { // PSU 通訊問題 pAlarmCode->AlarmEvents.bits.PsuModuleStestFail = true; result = true; } return result; } //=============================================== // Common Detect Chk - Stop Charging ? //=============================================== int isEvBoardStopChargeFlag(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //printf("StopChargeFlag = %d", chargingInfo[gunIndex]->StopChargeFlag); return pDcChargingInfo->StopChargeFlag; } bool isEvBoardNormalStopChargeFlag(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return pDcChargingInfo->NormalStopChargeFlag; } //=============================================== // 掃描插槍狀況 //=============================================== void ClearDetectPluginFlag(int gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->RemoteStartFlag == YES) { pDcChargingInfo->RemoteStartFlag = NO; } ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit = NO; if (pSysInfo->OrderCharging != NO_DEFINE) { pSysInfo->OrderCharging = NO_DEFINE; } } void DetectPluginStart(int gunIndex) { //pSysInfo->WaitForPlugit = YES; ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit = YES; } bool isDetectPlugin(int gunIndex) { if (ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit == YES) { return true; } /* if (pSysInfo->WaitForPlugit == YES) { return true; } */ return false; } //=============================================== // Common Detect Chk - Chademo //=============================================== bool isEvGunLocked_chademo(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return (DetectBitValue(pDcChargingInfo->GunLocked , 0) == 0) ? NO : YES; } bool isEvContactorWelding_chademo(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return DetectBitValue(ShmCHAdeMOData->ev[pDcChargingInfo->type_index].EvDetection, 3); } bool isEvStopReq_chademo(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return DetectBitValue(ShmCHAdeMOData->ev[pDcChargingInfo->type_index].EvDetection, 4); } bool isEvStopCharging_chademo(uint8_t gunIndex) { if (isEvGunLocked_chademo(gunIndex) == NO) { // 無鎖槍 = 停止 //log_info("gun locked none (%d) ", gunIndex); return YES; } return NO; } uint8_t isPrechargeStatus_chademo(uint8_t gunIndex) { uint8_t result = 0x00; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); result = ShmCHAdeMOData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus; return result; } //=============================================== // Common Detect Chk - GB //=============================================== bool isEvGunLocked_gb(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return (DetectBitValue(pDcChargingInfo->GunLocked , 0) == 0) ? NO : YES; } bool isEvStopCharging_gb(uint8_t gunIndex) { if (isEvGunLocked_gb(gunIndex) == NO) { // 無鎖槍 = 停止 //log_info("gun locked none. "); return YES; } return NO; } uint8_t isPrechargeStatus_gb(uint8_t gunIndex) { uint8_t result = 0x00; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); result = ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus; return result; } //=============================================== // Common Detect Chk - CCS //=============================================== bool isEvGunLocked_ccs(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return (DetectBitValue(pDcChargingInfo->GunLocked , 0) == 0) ? NO : YES; } uint8_t isPrechargeStatus_ccs(uint8_t gunIndex) { //uint8_t result = 0x00; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); return ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus; } bool isEvStopCharging_ccs(uint8_t gunIndex) { if (isEvGunLocked_ccs(gunIndex) == NO) { // 無鎖槍 = 停止 //log_info("gun locked none. "); return YES; } return NO; } //=============================================== // Callback //=============================================== void DisplayChargingInfo() { uint8_t i = 0; log_info("*********** DisplayChargingInfo *********** "); for (i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); if (pDcChargingInfo->SystemStatus != S_IDLE && pDcChargingInfo->SystemStatus != S_RESERVATION) { ChangeGunSelectByIndex(i); return; } } if (pSysConfig->AcConnectorCount > 0 && pSysInfo->CurGunSelectedByAc == NO_DEFINE) { pAcChargingInfo = (struct ChargingInfoData*)GetAcChargingInfoData(0); if (pAcChargingInfo->SystemStatus >= S_PREPARNING && pAcChargingInfo->SystemStatus <= S_COMPLETE) { pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX; } } usleep(50000); systemPageRestoreInit(); } void _AutoReturnTimeout(int gunIndex) { log_info("*********** _AutoReturnTimeout(%d) *********** ", pSysInfo->PageIndex); if (pSysInfo->PageIndex == _PAGE_PRECHARGE) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); pDcChargingInfo->SystemStatus = S_ALARM; //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_PLUGOUT; ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL; ShmDcCommonData->PreAuth_Result = 0; //pSysInfo->SystemPage = _PAGE_PAYING; //StartGunInfoTimeoutDet(pSysInfo->CurGunSelected,Timeout_FinalCost); ClearDetectPluginFlag(gunIndex); } } void _SelfTestTimeout(void) { if (pSysInfo->BootingStatus != BOOT_COMPLETE) { for (uint8_t gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { setChargerMode(gunIndex, MODE_ALARM); } } ShmPsuData->Work_Step = _NO_WORKING; pSysInfo->SelfTestSeq = _STEST_FAIL; log_info("Self test timeout. "); } void _AuthorizedTimeout(void) { int i; //if (IsAuthorizingMode()) { log_info("*********** _AuthorizedTimeout *********** "); StopSystemTimeoutDet(); //isCardScan = false; SetIsCardScan(false); //StopSystemTimeoutDet(); StopGunInfoTimeoutDet(pSysInfo->CurGunSelected); ShmDcCommonData->TradeCancel = TRUE; ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL; ShmDcCommonData->PreAuth_Result = 0; pSysInfo->SystemPage = _PAGE_SENSING; StartSystemTimeoutDet(Timeout_TradeCancel); for (i = 0; i <= 30; i++) { if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_IDLE) break; sleep(1); } ShmDcCommonData->PreAuth_Result = 0; StopSystemTimeoutDet(); ClearDetectPluginFlag(pSysInfo->CurGunSelected); strcpy((char*)pSysConfig->UserId, ""); ClearAuthorizedFlag(); setChargerMode(pSysInfo->CurGunSelected, S_IDLE); // StartSystemTimeoutDet(Timeout_ReturnViewPage); //} } void _DetectPlugInTimeout(uint8_t gunIndex) { int i; log_info("*********** Gun%d _DetectPlugInTimeout *********** ",gunIndex); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); StopSystemTimeoutDet(); StopGunInfoTimeoutDet(gunIndex); if (pDcChargingInfo->RemoteStartFlag || pDcChargingInfo->isRemoteStart) { StopSystemTimeoutDet(); ClearDetectPluginFlag(gunIndex); strcpy((char*)pSysConfig->UserId, ""); setChargerMode(gunIndex, S_IDLE); return; } pSysInfo->CurGunSelected = gunIndex; ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL; ShmDcCommonData->PreAuth_Result = 0; pSysInfo->SystemPage = _PAGE_SENSING; ShmDcCommonData->TradeCancel = TRUE; StartSystemTimeoutDet(Timeout_TradeCancel); for(i=0;i<=30;i++) { if(ShmDcCommonData->PreAuth_Config == _CREDITCARD_IDLE) break; sleep(1); } ShmDcCommonData->PreAuth_Result = 0; if (pSysInfo->CurGunSelected == gunIndex) { systemPageRestoreInit(); } StopSystemTimeoutDet(); ClearDetectPluginFlag(gunIndex); strcpy((char *)pSysConfig->UserId, ""); setChargerMode(gunIndex, S_IDLE); //systemPageRestoreInit(); } void _DetectEvChargingEnableTimeout(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->Type == _Type_Chademo) { if (!isEvGunLocked_chademo(gunIndex)) { log_info("*********** _DetectEvChargingEnableTimeout (chademo) ***********"); } } else if (pDcChargingInfo->Type == _Type_GB) { if (!isEvGunLocked_ccs(gunIndex)) { log_info("*********** _DetectEvChargingEnableTimeout (gb) ***********"); } } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (!isEvGunLocked_ccs(gunIndex)) { log_info("*********** _DetectEvChargingEnableTimeout (ccs) ***********"); } } //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_MAINTAIN; ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(gunIndex); } void _DetectEvseChargingEnableTimeout(uint8_t gunIndex) { log_info("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********"); ChargingTerminalProcess(gunIndex); //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_MAINTAIN; _AutoReturnTimeout(gunIndex); } void _PrepareTimeout(uint8_t gunIndex) { log_info("*********** _PrepareTimeout ***********"); ChargingTerminalProcess(gunIndex); pAlarmCode->AlarmEvents.bits.PsuNoResource = YES; //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_MAINTAIN; _AutoReturnTimeout(gunIndex); } void _CcsPrechargeTimeout(uint8_t gunIndex) { log_info("*********** _CcsPrechargeTimeout ***********"); ChargingTerminalProcess(gunIndex); //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_MAINTAIN; } void _LinkErrorTimeout(uint8_t gunIndex) { log_info("*********** _LinkErrorTimeout ***********"); setChargerMode(pSysInfo->CurGunSelected, S_IDLE); systemPageRestoreInit(); } //=============================================== // 取得卡號與卡號驗證 //=============================================== void AuthorizingStart(void) { ShmOCPP16Data->SpMsg.bits.AuthorizeReq = YES; pSysInfo->AuthorizeFlag = YES; } void ClearAuthorizedFlag(void) { ShmOCPP16Data->SpMsg.bits.AuthorizeConf = NO; pSysInfo->AuthorizeFlag = NO; } bool isAuthorizedComplete(void) { if (pSysInfo->AuthorizeFlag == YES) { return false; } return true; } bool IsAuthorizingMode() { if (pSysInfo->AuthorizeFlag == NO) { return false; } return true; } //=============================================== // 紀錄 Alarm Code //=============================================== void ResetChargerAlarmCode(uint8_t gunIndex, char *code) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (strcmp(code, "012234") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO; } else if (strcmp(code, "012235") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO; } else if (strcmp(code, "012236") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO; } else if (strcmp(code, "012288") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = NO; } else if (strcmp(code, "012289") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO; } else if (strcmp(code, "012290") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = NO; } else if (strcmp(code, "012229") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = NO; } else if (strcmp(code, "012230") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = NO; } else if (strcmp(code, "012231") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = NO; } else if (strcmp(code, "011011") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO; } else if (strcmp(code, "011013") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO; } else if (strcmp(code, "011015") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO; } else if (strcmp(code, "011012") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO; } else if (strcmp(code, "011014") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO; } else if (strcmp(code, "011016") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO; } else if (strcmp(code, "011018") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = NO; } else if (strcmp(code, "011019") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = NO; } else if (strcmp(code, "011020") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = NO; } else if (strcmp(code, "012323") == EQUAL) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; } else if (strcmp(code, "011038") == EQUAL) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO; } if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012229", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012230", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012231", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011011", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011013", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011015", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011012", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011014", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011016", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011018", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011019", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011020", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL) { strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6); } } void RecordAlarmCode(uint8_t gunIndex, char *code) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6); } if (pDcChargingInfo->StopChargeFlag == NO) { log_info("RecordAlarmCode set Stop Charge Flag"); pDcChargingInfo->StopChargeFlag = YES; } } } void ReleaseAlarmCode(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { // return; //} switch (pDcChargingInfo->Type) { case _Type_Chademo: ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO; break; case _Type_CCS_2: ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO; break; case _Type_GB: ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO; break; } memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } //=============================================== // EmergencyStop and Charging Stop //=============================================== void ChargingTerminalProcess(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); //if (pDcChargingInfo->SystemStatus == S_CHARGING) //ShmDcCommonData->StopCharge[gunIndex] = TRUE; setChargerMode(gunIndex, MODE_TERMINATING); } void ChargingAlarmProcess(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); //if (pDcChargingInfo->SystemStatus == S_CHARGING) //ShmDcCommonData->StopCharge[gunIndex] = TRUE; UpdateErrorCodeToOcpp(gunIndex); setChargerMode(gunIndex, MODE_ALARM); } void AcChargingTerminalProcess(void) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); pAcChargingInfo->SystemStatus = MODE_TERMINATING; } void StopChargingProcessByString(uint8_t level) { if (level > pSysWarning->Level) { pSysWarning->Level = level; } } void ReleaseChargingProcessByString(uint8_t level) { if (level >= pSysWarning->Level) { pSysWarning->Level = WARN_LV_NL; } } // 一般錯誤停止充電處理函式 void BoardErrOccurByString(uint8_t index, char *code) { uint8_t level = 1; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); if ((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (strncmp(code, "023730", 6) == EQUAL && pInfoCode->InfoEvents.bits.ChademoChargerGetEmergencyStop == NO ) { pInfoCode->InfoEvents.bits.ChademoChargerGetEmergencyStop = YES; } ChargingTerminalProcess(index); } StopChargingProcessByString(level); } void ReleaseBoardErrOccurByString(uint8_t index, char *code) { bool isTrigger = false; uint8_t level = 1; if (strncmp(code, "023730", 6) == 0 && pInfoCode->InfoEvents.bits.ChademoChargerGetEmergencyStop == YES) { isTrigger = true; pInfoCode->InfoEvents.bits.ChademoChargerGetEmergencyStop = NO; } if (isTrigger) { ReleaseChargingProcessByString(level); } } // 急停狀況的停止充電處理函式 void EmcOccureByString(char *code) { uint8_t level = 2; // 嚴重的急停有以下幾種 : EMC 按鈕、Mainbreak、Dooropen // 其錯誤等級為 2 //DS60-120 remove if (strncmp(code, "012251", 6) == EQUAL || strncmp(code, "012252", 6) == EQUAL || strncmp(code, "012238", 6) == EQUAL || strncmp(code, "042251", 6) == EQUAL || strncmp(code, "042252", 6) == EQUAL || strncmp(code, "012304", 6) == EQUAL || strncmp(code, "042327", 6) == EQUAL || strncmp(code, "042328", 6) == EQUAL || strncmp(code, "042200", 6) == EQUAL || strncmp(code, "042201", 6) == EQUAL || strncmp(code, "042202", 6) == EQUAL || strncmp(code, "042267", 6) == EQUAL) { for (uint8_t gun = 0; gun < pSysConfig->TotalConnectorCount; gun++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun); //strncpy((char *)ShmOCPP16Data->StatusNotification[gun].VendorErrorCode, code, 6); if ((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_TERMINATING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { //ChargingTerminalProcess(gun); if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, code, 6); } ChargingAlarmProcess(gun); } } StopChargingProcessByString(level); InformOcppErrOccur(4); } } void ReleaseEmsOccureByString(uint8_t index, char *code) { bool isTrigger = false; uint8_t level = 2; if (strncmp(code, "042251", 6) == 0 ) { isTrigger = true; } else if (strncmp(code, "012251", 6) == 0 && pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES) { isTrigger = true; pAlarmCode->AlarmEvents.bits.EmergencyStopTrip = NO; } else if (strncmp(code, "012252", 6) == 0 && pAlarmCode->AlarmEvents.bits.DoorOpen == YES) { isTrigger = true; pAlarmCode->AlarmEvents.bits.DoorOpen = NO; } else if (strncmp(code, "012237", 6) == 0 && pAlarmCode->AlarmEvents.bits.SpdTrip == YES) { isTrigger = true; pAlarmCode->AlarmEvents.bits.SpdTrip = NO; } else if (strncmp(code, "012238", 6) == 0 && pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES) { isTrigger = true; pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip = NO; } if (isTrigger) { ReleaseChargingProcessByString(level); InformOcppErrOccur(6); } } static void checkOvpState(uint8_t gunIndex, uint8_t gunType) { switch(gunType) { case _Type_Chademo: if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP == YES) RecordAlarmCode(gunIndex, "012217"); break; case _Type_CCS_2: if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOVP == YES) RecordAlarmCode(gunIndex, "012219"); break; case _Type_GB: if(ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOVP == YES) RecordAlarmCode(gunIndex, "012221"); break; } } //=============================================== // 確認各小板偵測的錯誤狀況 //=============================================== void CheckErrorOccurStatus(uint8_t index) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); // RB if (pSysConfig->PhaseLossPolicy == YES) { if (pAlarmCode->AlarmEvents.bits.SystemL1InputUVP == YES || pAlarmCode->AlarmEvents.bits.SystemL2InputUVP == YES || pAlarmCode->AlarmEvents.bits.SystemL3InputUVP == YES) { if (pSysWarning->ExtraErrProcess == _EXTRA_ERR_PROCESS_NONE) { pSysWarning->ExtraErrProcess = _EXTRA_ERR_PROCESS_INUVP; StopChargingProcessByString(2); InformOcppErrOccur(13); } //DS60-120 add ----- if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { if (pAlarmCode->AlarmEvents.bits.SystemL1InputUVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012203", 6); } else if (pAlarmCode->AlarmEvents.bits.SystemL2InputUVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012204", 6); } else if (pAlarmCode->AlarmEvents.bits.SystemL3InputUVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012205", 6); } } log_info("1 CheckErrorOccurStatus"); pDcChargingInfo->StopChargeFlag = YES; //------------------------------------------------------------------ } else { if (pSysWarning->ExtraErrProcess == _EXTRA_ERR_PROCESS_INUVP) { pSysWarning->ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; ReleaseChargingProcessByString(2); InformOcppErrOccur(6); } } } else { if (pSysWarning->ExtraErrProcess == _EXTRA_ERR_PROCESS_INUVP) { pSysWarning->ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; ReleaseChargingProcessByString(2); InformOcppErrOccur(6); } } if (pAlarmCode->AlarmEvents.bits.SystemL1InputOVP == YES || pAlarmCode->AlarmEvents.bits.SystemL2InputOVP == YES || pAlarmCode->AlarmEvents.bits.SystemL3InputOVP == YES) { if (pSysWarning->ExtraErrProcess == _EXTRA_ERR_PROCESS_NONE) { pSysWarning->ExtraErrProcess = _EXTRA_ERR_PROCESS_INOVP; StopChargingProcessByString(2); InformOcppErrOccur(14); } //DS60-120 ----- if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { if (pAlarmCode->AlarmEvents.bits.SystemL1InputOVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012200", 6); } else if (pAlarmCode->AlarmEvents.bits.SystemL2InputOVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012201", 6); } else if (pAlarmCode->AlarmEvents.bits.SystemL3InputOVP == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012202", 6); } } log_info("2 CheckErrorOccurStatus"); pDcChargingInfo->StopChargeFlag = YES; //---------------------------------------------------------------------- } else { if (pSysWarning->ExtraErrProcess == _EXTRA_ERR_PROCESS_INOVP) { pSysWarning->ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; ReleaseChargingProcessByString(2); InformOcppErrOccur(6); } } checkOvpState(index, pDcChargingInfo->Type); //-------------------------------------------------------------------------- if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == 0) { //Primary if (pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012251", 6); } else if (pAlarmCode->AlarmEvents.bits.DoorOpen == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012252", 6); } else if (pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012238", 6); } else if (pAlarmCode->AlarmEvents.bits.DisconnectedFromDo == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "012304", 6); } else if (pInfoCode->InfoEvents.bits.BackendDisconnectedViaEthernet == YES) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "033900", 6); } //Chiller temperature //else if (pAlarmCode->AlarmEvents.bits.SystemChillerOTP == YES) { // memcpy(pDcChargingInfo->ConnectorAlarmCode, "012323", 6); //} else if (pFaultCode->FaultEvents.bits.ChillerTempSensorBroken == YES) { // memcpy(pDcChargingInfo->ConnectorAlarmCode, "011038", 6); //} } /* if (pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES || pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES || pAlarmCode->AlarmEvents.bits.DoorOpen == YES || pSysWarning->ExtraErrProcess != _EXTRA_ERR_PROCESS_NONE || pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == YES || pAlarmCode->AlarmEvents.bits.DisconnectedFromDo == YES || //Power cabinet alarm status ShmDcCommonData->PowerAlarmState.StatusBit.EmergencyStop == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DoorOpen == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DcInputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DcInputUVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL1InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL2InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL3InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.PsuFailure == YES ) { if ((pDcChargingInfo->SystemStatus > S_IDLE && pDcChargingInfo->SystemStatus < S_COMPLETE) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1 )) ChargingAlarmProcess(index); pSysWarning->Level = WARN_LV_ER; }*/ } //=============================================== // 確認 GPIO 狀態 //=============================================== void gpio_set_value(unsigned int gpio, unsigned int value) { int fd; char buf[MAX_BUF]; snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { perror("gpio/set-value"); return; } if (value) { write(fd, "1", 2); } else { write(fd, "0", 2); } close(fd); } int gpio_get_value(unsigned int gpio, unsigned int *value) { int fd; char buf[MAX_BUF]; char ch; snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_RDONLY); if (fd < 0) { perror("gpio/get-value"); return fd; } read(fd, &ch, 1); if (ch != '0') { *value = 1; } else { *value = 0; } close(fd); return 0; } void CheckGunTypeFromHw() { uint8_t i = 0; int pinIn[4] = {22, 23, 44, 45}; unsigned int gpioValue = 0; uint8_t tmp[2] = {0}; log_info("ModelName = %s", pSysConfig->ModelName); for (i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); switch (pinIn[i]) { //right slot case 22: bd1_1_status = gpioValue; break; case 23: bd1_2_status = gpioValue; break; //left slot case 44: bd0_1_status = gpioValue; break; case 45: bd0_2_status = gpioValue; break; } } //BD1(Left-CCS-CND1-SMR2-左槍), BD2(Right-CHADEMO-CND2-SMR1-右槍), CCS: 10 , CHAdeMO: 01 , GBT: 11 //CcsChargingData [0至1] 分別為 Right至Left //model name 槍順序左至右分別為Right至Left tmp[1] = (bd0_1_status << 4 | bd0_2_status); tmp[0] = (bd1_1_status << 4 | bd1_2_status); for (i = 0; i < 2; i++) { switch (tmp[i]) { case 0x01: log_info("BD%d(%s) = %s ", i + 1, i == 0 ? "Left" : "Right", "CHAdeMO"); break; case 0x10: log_info("BD%d(%s) = %s ", i + 1, i == 0 ? "Left" : "Right", "CCS"); break; case 0x11: log_info("BD%d(%s) = %s ", i + 1, i == 0 ? "Left" : "Right", "GBT"); break; case 0x00: log_info("BD%d(%s) = %s ", i + 1, i == 0 ? "Left" : "Right", "None"); break; } } } void CheckGpioInStatus() { int i = 0; int pinIn[2] = { 27, 47 };//{IO BD1_2, IO BD2_2} unsigned int gpioValue = 0; for (i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); if (gpioValue == 0x01) { switch (pinIn[i]) { // 小板緊急停止 case 47: for (i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); if (pDcChargingInfo->slotsIndex == 1) { if (pDcChargingInfo->Type == _Type_Chademo) { BoardErrOccurByString(i, "023730"); } else if (pDcChargingInfo->Type == _Type_CCS_2) { BoardErrOccurByString(i, "013627"); } break; } } break; case 27: for (i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); if (pDcChargingInfo->slotsIndex == 3) { if (pDcChargingInfo->Type == _Type_Chademo) { BoardErrOccurByString(i, "023730"); } else if (pDcChargingInfo->Type == _Type_CCS_2) { BoardErrOccurByString(i, "013627"); } break; } } break; } } else { switch (pinIn[i]) { // 小板解除緊急停止 case 47: for (i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); if (pDcChargingInfo->slotsIndex == 1) { if (pDcChargingInfo->Type == _Type_Chademo) { ReleaseBoardErrOccurByString(i, "023730"); } else if (pDcChargingInfo->Type == _Type_CCS_2) { ReleaseBoardErrOccurByString(i, "013627"); } break; } } break; case 27: for (i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i); if (pDcChargingInfo->slotsIndex == 3) { if (pDcChargingInfo->Type == _Type_Chademo) { ReleaseBoardErrOccurByString(i, "023730"); } else if (pDcChargingInfo->Type == _Type_CCS_2) { ReleaseBoardErrOccurByString(i, "013627"); } break; } } break; } } } } //=============================================== // Main process //=============================================== // 檢查 uint8_t 中某個 Bit 的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit uint8_t DetectBitValue(uint8_t _byte, uint8_t _bit) { uint8_t mask_table[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; return ( _byte & mask_table[_bit] ) != 0x00; } // 設定 Byte 中某個 Bit的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit // value : 修改的值為 0 or 1 void SetBitValue(uint8_t *_byte, uint8_t _bit, uint8_t value) { if (value == 1) { *_byte |= (1 << _bit); } else if (value == 0) { *_byte ^= (1 << _bit); } } uint8_t isModeChange(uint8_t gunIndex) { uint8_t result = NO; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->SystemStatus == pDcChargingInfo->PreviousSystemStatus) { return result; } pDcChargingInfo->PreviousSystemStatus = pDcChargingInfo->SystemStatus; ShmDcCommonData->SystemModeChange[gunIndex] = YES; //for Module_EvRxComm print temperature message return YES; } static int checkSlotGpioMappingGunType(uint8_t gunIndex, uint8_t gunType) { uint8_t slot1 = 0, slot2 = 0; if (gunIndex == 0) { slot1 = bd0_1_status; slot2 = bd0_2_status; } else if (gunIndex == 1) { slot1 = bd1_1_status; slot2 = bd1_2_status; } log_info("slot %d gpio1 = %d, gpio2 = %d, type = %d", gunIndex, slot1, slot2, gunType); switch (gunType) { case _Type_Chademo: if (slot1 != NO && slot2 != YES) { return FAIL; } break; case _Type_CCS_2: if (slot1 != YES && slot2 != NO) { return FAIL; } break; case _Type_GB: if (slot1 != YES && slot2 != YES) { return FAIL; } break; } return PASS; } bool CheckConnectorTypeStatus(void) { bool result = true; uint8_t gunIndex = 0; struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); struct ChargingInfoData *pDcChargingInfo = NULL; if (!MappingGunChargingInfo("CSU Task")) { log_error("CheckConnectorTypeStatus MappingGunChargingInfo failed"); return false; } // 偵測槍屬於哪個 slot : 可知道插在板上的Slot 0 或 1 是 Chademo 還是 CCS for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (checkSlotGpioMappingGunType(gunIndex, pDcChargingInfo->Type) == FAIL) { return false; } pDcChargingInfo->SystemStatus = S_BOOTING; switch (gunIndex) { case 0: if (pSysConfig->TotalConnectorCount == 1) { if ((bd0_1_status == YES || bd0_2_status == YES) && (bd1_1_status == NO && bd1_2_status == NO)) { pDcChargingInfo->Evboard_id = 0x01; } if ((bd0_1_status == NO && bd0_2_status == NO) && (bd1_1_status == YES || bd1_2_status == YES) ) { pDcChargingInfo->Evboard_id = 0x02; } break; } pDcChargingInfo->Evboard_id = 0x01; break; case 1: pDcChargingInfo->Evboard_id = 0x02; break; } CheckHwSlotStatusLog(gunIndex); if (pDcChargingInfo->Evboard_id == 0x00) { return false; } } AdjustChargerCurrent(); return result; } int SpawnTask(void) { if(SIMULATION) system("/root/simulation &"); sleep(2); system("/root/Module_EventLogging &"); system("/root/Module_PrimaryComm &"); system("/root/Module_EvComm &"); system("/root/Module_LcmControl &"); system("/root/Module_InternalComm &"); system("/root/Module_ProduceUtils &"); system("/root/Module_UpdateFW &"); system("/root/Module_DoComm &"); return PASS; } void KillTask(void) { //ChangeLcmByIndex(_LCM_ERROR); ChangeLcmByIndex(_PAGE_MAINTAIN); system("killall Module_EventLogging"); system("killall Module_PrimaryComm"); system("killall Module_EvComm"); system("killall Module_LcmControl"); system("killall Module_InternalComm"); system("killall Module_UpdateFW"); system("killall Module_ChkSysTask"); //system("killall Module_DoComm"); return ; } void KillTaskExceptPrimary(void) { //ChangeLcmByIndex(_LCM_ERROR); ChangeLcmByIndex(_PAGE_MAINTAIN); system("killall Module_EvComm"); system("killall Module_InternalComm"); return; } void KillAllTask(void) { //ChangeLcmByIndex(_LCM_ERROR); ChangeLcmByIndex(_PAGE_MAINTAIN); system("killall Module_EventLogging"); system("killall Module_PrimaryComm"); system("killall Module_EvComm"); system("killall Module_LcmControl"); system("killall Module_InternalComm"); system("killall Module_UpdateFW"); system("killall Module_ChkSysTask"); system("killall Module_DoComm"); return ; } void StartSystemTimeoutDet(uint8_t flag) { if (pSysInfo->SystemTimeoutFlag != flag) { //log_info("Set System Timeout Flag %d", flag); GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); } pSysInfo->SystemTimeoutFlag = flag; } void StopSystemTimeoutDet(void) { GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); pSysInfo->SystemTimeoutFlag = Timeout_None; } void StartGunInfoTimeoutDet(uint8_t gunIndex, uint8_t flag) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (gunIndex < pSysConfig->TotalConnectorCount) { if (pDcChargingInfo->TimeoutFlag != flag) { GetClockTime(&pDcChargingInfo->ConnectorTimeout, NULL); //log_info("Set Gun%d Timeout Flag %d", gunIndex, flag); } pDcChargingInfo->TimeoutFlag = flag; } } void StopGunInfoTimeoutDet(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (gunIndex < pSysConfig->TotalConnectorCount) { pDcChargingInfo->TimeoutFlag = Timeout_None; } } void CheckConnectionTimeout(void) { if (ShmSelectGunInfo->RemoteSetup.ConnectionTimeout != 0) { //Jerry add _connectionTimeout = ShmSelectGunInfo->RemoteSetup.ConnectionTimeout; } else { _connectionTimeout = CONN_PLUG_TIMEOUT; } return; } void _evccidlinktimeout(uint8_t gunIndex) { log_info("Getting EVCCID Timeout"); pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); pDcChargingInfo->isEVCCIDVerify = true; StopGunInfoTimeoutDet(gunIndex); destroySelGun(pSysInfo->CurGunSelected); systemPageRestoreInit(); } void CreateTimeoutFork(void) { pid_t timeoutPid; timeoutPid = fork(); if (timeoutPid == 0) { GetClockTime(&_cmdSubPriority_time, NULL); CheckConnectionTimeout(); //log_info("Timeout Fork Child's PID is %d", getpid()); while (1) { if ((GetClockTimeoutValue(_cmdSubPriority_time) / 1000) > 5000) { CheckConnectionTimeout(); GetClockTime(&_cmdSubPriority_time, NULL); } /* if (pSysInfo->SystemTimeoutFlag != 0) log_info("Timeout ***********SystemTimeoutFlag = %d(%d) ********",pSysInfo->SystemTimeoutFlag, GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL); */ // 系統 switch (pSysInfo->SystemTimeoutFlag) { case Timeout_SelftestChk: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= SELFTEST_TIMEOUT) { _SelfTestTimeout(); StopSystemTimeoutDet(); destroySelGun(DESTROY_ALL_SEL); //jerry add } break; case Timeout_ReturnViewPage: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_VIEWPAGE_TIMEOUT) { StopSystemTimeoutDet(); systemPageRestoreInit(); } break; case Timeout_Authorizing: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) { log_error("Authorizing Timeout"); _AuthorizedTimeout(); if (ShmSelectGunInfo->AuthorStateFromCabinet[pSysInfo->CurGunSelected] == YES) { //DoComm no ask cabinet balance ShmSelectGunInfo->AuthorStateFromCabinet[pSysInfo->CurGunSelected] = NO; pAlarmCode->AlarmEvents.bits.DisconnectedFromDo = ABNORMAL; log_error("Author timeout restart DoComm"); system("killall Module_DoComm"); } } break; case Timeout_WaitBalance: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= BALANCE_TIMEOUT) { log_error("Wait Balance timeout"); _AuthorizedTimeout(); if (ShmSelectGunInfo->AuthorStateFromCabinet[pSysInfo->CurGunSelected] == YES) { //DoComm no ask cabinet balance ShmSelectGunInfo->AuthorStateFromCabinet[pSysInfo->CurGunSelected] = NO; pAlarmCode->AlarmEvents.bits.DisconnectedFromDo = ABNORMAL; log_error("Author timeout restart DoComm"); system("killall Module_DoComm"); } } break; case Timeout_VerifyFail: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT) { log_info("Timeout_VerifyFail"); StopSystemTimeoutDet(); systemPageRestoreInit(); if (!ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].ParkingStatus) setChargerMode(pSysInfo->CurGunSelected, S_IDLE); ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].GetParkingBill = FALSE; } break; /* case Timeout_WaitPlug: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= _connectionTimeout) { _DetectPlugInTimeout(); destroySelGun(pSysInfo->CurGunSelected); } break; */ /* case Timeout_ReturnToChargingGunDet: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) { if (getCurLcmPage() != _LCM_VIEW && getCurLcmPage() != _LCM_DETAIL_VIEW ) { destroySelGun(pSysInfo->CurGunSelected); //jerry add } DisplayChargingInfo(); StopSystemTimeoutDet(); } break; */ case Timeout_ScanCard: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_SCANCARD_TIMEOUT) { log_info("Timeout_ScanCard"); strcpy((char *)pSysConfig->UserId, ""); ClearAuthorizedFlag(); StopSystemTimeoutDet(); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(pSysInfo->CurGunSelected); pDcChargingInfo->SystemStatus = S_IDLE; pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL; ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; } break; case Timeout_Terminating: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TERMINATING_TIMEOUT) { StopSystemTimeoutDet(); pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected); log_info("Terminating timeout"); setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE); } break; case Timeout_AddLine: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_ADDLINE_TIMEOUT) { log_info("Timeout_AddLine"); StopSystemTimeoutDet(); systemPageRestoreInit(); ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; } break; case Timeout_DonateComfirm: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_DONATECOMFIRM_TIMEOUT) { log_info("Timeout_DonateComfirm"); StopSystemTimeoutDet(); systemPageRestoreInit(); } break; case Timeout_SelectPayMode: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_SELECTPAY_TIMEOUT) { log_info("Timeout_SelectPayMode"); StopSystemTimeoutDet(); systemPageRestoreInit(); ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; } break; case Timeout_TradeCancel: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_TRADECANCEL_TIMEOUT) { log_info("Timeout_TradeCancel"); StopSystemTimeoutDet(); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(pSysInfo->CurGunSelected); setChargerMode(pSysInfo->CurGunSelected, MODE_IDLE); systemPageRestoreInit(); ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; ShmDcCommonData->pGunInfo[pSysInfo->CurGunSelected].GetParkingBill = FALSE; } break; case Timeout_LINEPAYING: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= TCC_LINEPAYING_TIMEOUT) { log_info("Timeout_LINEPAYING"); StopSystemTimeoutDet(); systemPageRestoreInit(); ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1; } break; } // 各槍 for (uint8_t gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); /* if (pDcChargingInfo->TimeoutFlag != 0) log_info("Timeout ***********GunTimeoutFlag = %d(%d) ********",pDcChargingInfo->TimeoutFlag, GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL); */ switch (pDcChargingInfo->TimeoutFlag) { case Timeout_AuthorizingForStop: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) { log_info("Gun %d Timeout_AuthorizingForStop", gunIndex); strcpy((char*)pSysConfig->UserId, ""); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); pDcChargingInfo->SystemStatus = S_IDLE; ClearAuthorizedFlag(); StopGunInfoTimeoutDet(gunIndex); if (pSysInfo->CurGunSelected == gunIndex) systemPageRestoreInit(); } break; case Timeout_WaitPlug: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= _connectionTimeout) { _DetectPlugInTimeout(gunIndex); destroySelGun(gunIndex); } break; case Timeout_EVCCID_Link: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= EVCCID_LINK_TIMEOUT) { _evccidlinktimeout(gunIndex); } break; case Timeout_LinkError: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= LINKERROR_TIMEOUT) { _LinkErrorTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); } break; case Timeout_Preparing: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= GUN_PREPARE_TIMEOUT) { _PrepareTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvChargingDet: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= GUN_EV_WAIT_TIMEOUT) { _DetectEvChargingEnableTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvseChargingDet: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= GUN_EVSE_WAIT_TIMEOUT) { _DetectEvseChargingEnableTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvseCompleteDet: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= GUN_COMP_WAIT_TIMEOUT) { StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_ForCcsPrechargeDet: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= GUN_PRECHARGING_TIMEOUT) { _CcsPrechargeTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_PlugOutGun: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= PLUGOUTGUN_TIMEOUT) { log_info("Gun[%d] Timeout_PlugOutGun",gunIndex); setChargerMode(gunIndex, MODE_IDLE); destroySelGun(gunIndex); //Jerry add StopGunInfoTimeoutDet(gunIndex); if (pSysInfo->CurGunSelected == gunIndex) systemPageRestoreInit(); } break; case Timeout_FinalCost: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_FINALCOST_TIMEOUT) { log_info("Gun[%d] Timeout_FinalCost",gunIndex); StopGunInfoTimeoutDet(gunIndex); if (ShmDcCommonData->finalcost_flag[gunIndex] == FALSE) { log_info("Not Get Final Cost"); ShmDcCommonData->PayPass_flag[gunIndex] = FALSE; if (pSysInfo->CurGunSelected == gunIndex) pSysInfo->SystemPage = _PAGE_PAYFAIL; } } break; case Timeout_LineReigster: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_LINEREGISTER_TIMEOUT) { log_info("Gun[%d] Timeout_LineReigster",gunIndex); StopGunInfoTimeoutDet(gunIndex); systemPageRestoreInit(); ShmDcCommonData->TransactionInfo[gunIndex].IsDonateInvoice = FALSE; 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); StopGunInfoTimeoutDet(gunIndex); ShmDcCommonData->is_exit[gunIndex] = TRUE; if (pSysInfo->CurGunSelected == gunIndex) pSysInfo->SystemPage = _PAGE_EXIT; StartGunInfoTimeoutDet(gunIndex, Timeout_PlugOutGun); } break; case Timeout_CompletPlugout: if (GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) / uSEC_VAL >= TCC_COMPLETE_PLUGOUT_TIMEOUT) { log_info("Gun[%d] Timeout_CompletePlugout", gunIndex); setChargerMode(gunIndex, MODE_IDLE); destroySelGun(gunIndex); //Jerry add 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); } } } void CheckFactoryConfigFunction(void) { char Buf[256] = {0}; if (pSysInfo->FactoryConfiguration) { sprintf(Buf, "cd /root;./FactoryConfig -m %s %s", pSysConfig->ModelName, pSysConfig->SerialNumber); system(Buf); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } } //=============================================== // Check reservation date is expired //=============================================== int isReservationExpired(uint8_t gunIndex) { int result = NO; struct tm expiredDate; struct timeb expiredTime; if (sscanf((char *) ShmOCPP16Data->ReserveNow[gunIndex].ExpiryDate, "%4d-%2d-%2dT%2d:%2d:%2d", &expiredDate.tm_year, &expiredDate.tm_mon, &expiredDate.tm_mday, &expiredDate.tm_hour, &expiredDate.tm_min, &expiredDate.tm_sec) == 6) { expiredDate.tm_year -= 1900; expiredDate.tm_mon -= 1; expiredTime.time = mktime(&expiredDate); if (!CheckTimeOut(expiredTime)) { result = YES; } } return result; } //=============================================== // OCPP //=============================================== void CheckOcppStatus(void) { bool canReset = true; //bool canHardReset = true; //DS60-120 add if (ShmOCPP16Data->SpMsg.bits.BootNotificationConf == YES) { ShmOCPP16Data->SpMsg.bits.BootNotificationConf = NO; } if (ShmOCPP16Data->MsMsg.bits.ResetReq == YES) { if (pSysWarning->Level != WARN_LV_ER) { for (uint8_t _index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index); if (pDcChargingInfo->SystemStatus != S_IDLE && pDcChargingInfo->SystemStatus != S_RESERVATION && pDcChargingInfo->SystemStatus != S_MAINTAIN) { canReset = false; if (pDcChargingInfo->SystemStatus >= S_REASSIGN && pDcChargingInfo->SystemStatus < S_TERMINATING) { //canHardReset = false; ChargingTerminalProcess(_index); //restartFlag = 1; } } } } if (canReset) { ShmOCPP16Data->MsMsg.bits.ResetReq = NO; sprintf((char *)ShmOCPP16Data->Reset.ResponseStatus, "Accepted"); if (strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL) { log_error("****** Hard Reboot ****** "); ShmOCPP16Data->MsMsg.bits.ResetConf = YES; sleep(3); system("reboot -f"); } else if (strcmp((char *)ShmOCPP16Data->Reset.Type, "Soft") == EQUAL) { log_error("****** Soft Reboot ****** "); ShmOCPP16Data->MsMsg.bits.ResetConf = YES; sleep(3); system("killall OcppBackend &"); KillAllTask(); TryCloseWatchdog(); system("/usr/bin/run_evse_restart.sh"); } } } } void OcppStopTransation(uint8_t gunIndex) { uint8_t _OcppGunIndex = gunIndex; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // 如果有 AC 槍,而現在是 DC 第二把槍進入充電 if (pSysConfig->AcConnectorCount == 1 && gunIndex == 1) { _OcppGunIndex = 2; } if (strcmp((char *)pDcChargingInfo->StartUserId, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag, (char *)pDcChargingInfo->StartUserId); } log_info("IdTag = %s ", ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[_OcppGunIndex].StopTransactionReq = YES; } bool OcppRemoteStop(uint8_t gunIndex) { uint8_t acDirIndex = pSysConfig->AcConnectorCount; // 有 AC 槍的話 if (acDirIndex > 0 && gunIndex > 0) { gunIndex += acDirIndex; } bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq; if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Remote"); ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO; } return result; } bool WifiScheduleStop(uint8_t gunIndex) { bool result = false; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); result = pDcChargingInfo->schedule.isTriggerStop; pDcChargingInfo->schedule.isTriggerStop = NO; return result; } void OcppRemoteStartChk() { if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING) { } else { // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 uint8_t acDirIndex = pSysConfig->AcConnectorCount; if (!isDetectPlugin(acDirIndex)) { for (uint8_t ac_index = 0; ac_index < pSysConfig->AcConnectorCount; ac_index++) { pAcChargingInfo = (struct ChargingInfoData*)GetAcChargingInfoData(ac_index); if (ShmOCPP16Data->CsMsg.bits[acDirIndex].RemoteStartTransactionReq == YES) { if (pAcChargingInfo->SystemStatus == S_IDLE || pAcChargingInfo->SystemStatus == S_RESERVATION) { ShmOCPP16Data->CsMsg.bits[acDirIndex].RemoteStartTransactionReq = NO; pAcChargingInfo->RemoteStartFlag = YES; pSysInfo->OrderCharging = YES; //pSysInfo->OrderCharging = DEFAULT_AC_INDEX; ShmOCPP16Data->CsMsg.bits[pSysConfig->TotalConnectorCount + ac_index].RemoteStartTransactionReq = NO; DetectPluginStart(acDirIndex); return; } ShmOCPP16Data->CsMsg.bits[acDirIndex].RemoteStartTransactionReq = NO; } } } //uint8_t threeGunIndex = 0; //uint8_t dcIndex = 0; //bool isGunUsingStatus = false; for (uint8_t _index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index); /* // 如果有 AC 槍,且 DC 槍也有兩把 if (acDirIndex == 1 && _index == 1) { threeGunIndex = 1; } if (ShmOCPP16Data->CsMsg.bits[_index + threeGunIndex].RemoteStartTransactionReq == YES) { dcIndex = _index; } if (pDcChargingInfo->SystemStatus != S_IDLE) { isGunUsingStatus = true; } if (pDcChargingInfo->RemoteStartFlag == YES) { //_remotestarting = true; } } // 如果是雙槍單模,只認閒置狀態的槍,如果有預約~ 則預約也算被使用 if (isGunUsingStatus && pSysInfo->IsAlternatvieConf) { if (dcIndex == 0) { threeGunIndex = 0; } ShmOCPP16Data->CsMsg.bits[dcIndex + threeGunIndex].RemoteStartTransactionReq = NO; return; } if (dcIndex == 0) { threeGunIndex = 0; } */ pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index); if (ShmOCPP16Data->CsMsg.bits[_index].RemoteStartTransactionReq == YES && !isDetectPlugin(_index)) { if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) { pDcChargingInfo->RemoteStartFlag = YES; ShmDcCommonData->is_RemoteStart[_index] = TRUE; //pSysInfo->OrderCharging = YES; //pDcChargingInfo->SystemStatus = S_AUTHORIZING; //pSysInfo->OrderCharging = gunIndex; ShmOCPP16Data->CsMsg.bits[_index].RemoteStartTransactionReq = NO; DetectPluginStart(_index); setSelGunWaitToAuthor(_index); log_info("Ocpp Remote Start Gun%d Pass", _index); } ShmOCPP16Data->CsMsg.bits[_index].RemoteStartTransactionReq = NO; } } } } void ChkOcppStatus(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->SystemStatus == S_IDLE && ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowReq = NO; if (isReservationExpired(gunIndex)) { log_error("***************ChkOcppStatus : OcppReservedStatus******************** "); pDcChargingInfo->ReservationId = ShmOCPP16Data->ReserveNow[gunIndex].ReservationId; pDcChargingInfo->SystemStatus = S_RESERVATION; } ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES; } if (pDcChargingInfo->SystemStatus == S_RESERVATION && ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationReq = NO; if (isReservationExpired(gunIndex)) { log_error("***************ChkOcppStatus : Cancel OcppReservedStatus******************** "); pDcChargingInfo->ReservationId = 0; pDcChargingInfo->SystemStatus = S_IDLE; } ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationConf = YES; } if (ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq == YES) { log_error("***************ChkOcppStatus : OcppChangeAvailability******************** "); ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq = NO; if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex].Type, "Operative") == EQUAL) { if (isDb_ready) { DB_Update_Operactive(gunIndex, true); } pDcChargingInfo->IsAvailable = YES; if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION || pDcChargingInfo->SystemStatus == S_MAINTAIN) { setChargerMode(gunIndex, MODE_IDLE); } } else if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex].Type, "Inoperative") == EQUAL) { if (isDb_ready) { DB_Update_Operactive(gunIndex, false); } pDcChargingInfo->IsAvailable = NO; if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION || pDcChargingInfo->SystemStatus == S_MAINTAIN) { setChargerMode(gunIndex, MODE_MAINTAIN); } } } if (ShmOCPP16Data->CsMsg.bits[gunIndex].UnlockConnectorReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex].UnlockConnectorReq = NO; if (pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && // DS60-120 add || pDcChargingInfo->SystemStatus <= S_CHARGING) { // 充電中,需停止充電 strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "UnlockCommand"); ChargingTerminalProcess(gunIndex); } strcpy((char *)ShmOCPP16Data->UnlockConnector[gunIndex].ResponseStatus, "Unlocked"); ShmOCPP16Data->CsMsg.bits[gunIndex].UnlockConnectorConf = YES; } } bool CheckBackendChargingTimeout(uint8_t gunIndex) { bool result = false; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) { if (pSysConfig->MaxChargingDuration > 0) { if (pDcChargingInfo->PresentChargedDuration > (pSysConfig->MaxChargingDuration * 60)) { result = true; } } } return result; } bool CheckBackendChargingEnergy(uint8_t gunIndex) { bool result = false; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pSysConfig->AuthorisationMode == AUTH_MODE_ENABLE) { if (pSysConfig->MaxChargingEnergy > 0) { if (pDcChargingInfo->PresentChargedEnergy > pSysConfig->MaxChargingEnergy) { result = true; } } } return result; } void InformOcppErrOccur(uint8_t codeType) { char _error[25]; switch (codeType) { case 4: strcpy(_error, "InternalError"); break; case 6: strcpy(_error, "NoError"); break; case 7: strcpy(_error, "OtherError"); break; case 13: strcpy(_error, "UnderVoltage"); break; case 14: strcpy(_error, "OverVoltage"); break; } for (uint8_t gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode, _error); } } //=============================================== // Config process //=============================================== /* void AddPlugInTimes(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->Type == _Type_Chademo) { pSysConfig->ChademoPlugInTimes += 1; } else if (pDcChargingInfo->Type == _Type_CCS_2) { pSysConfig->Ccs2PlugInTimes += 1; } else if (pDcChargingInfo->Type == _Type_GB) { pSysConfig->GbPlugInTimes += 1; } }*/ void ChangeStartOrStopDateTime(uint8_t isStart, uint8_t gunIndex) { char cmdBuf[32]; struct timeb csuTime; struct tm *tmCSU; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); ftime(&csuTime); tmCSU = localtime(&csuTime.time); sprintf(cmdBuf, "%04d-%02d-%02d %02d:%02d:%02d", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); if (isStart) { strcpy((char *)pDcChargingInfo->StartDateTime, cmdBuf); } else { strcpy((char *)pDcChargingInfo->StopDateTime, cmdBuf); } } void ChangeGunSelectByIndex(uint8_t sel) { pSysInfo->CurGunSelected = sel; pSysInfo->CurGunSelectedByAc = NO_DEFINE; } void CheckIsAlternatvieByModelName() { if (pSysConfig->ModelName[1] == 'W') { //DS60-120 // 壁掛 pSysInfo->IsAlternatvieConf = YES; } else { pSysInfo->IsAlternatvieConf = NO; } } void StopProcessingLoop() { log_info("Stop Processing...."); for (;;) { CheckFactoryConfigFunction(); //CheckFwUpdateFunction(); if (pSysWarning->Level == WARN_LV_ER) { ChkPrimaryStatus(); if (pSysWarning->Level == WARN_LV_NL) { log_info("Soft reboot for retry self-tets (Primary). "); KillAllTask(); sleep(3); TryCloseWatchdog(); system("/usr/bin/run_evse_restart.sh"); return; } } sleep(1); TryFeedWatchdog(); } } bool IsConnectorWholeIdle() { bool result = true; for (uint8_t count = 0; count < pSysConfig->TotalConnectorCount; count++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(count); if (pDcChargingInfo->SystemStatus != S_IDLE && pDcChargingInfo->SystemStatus != S_RESERVATION) { result = false; break; } } for (uint8_t count = 0; count < pSysConfig->AcConnectorCount; count++) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(count); if (pAcChargingInfo->SystemStatus != S_IDLE && pAcChargingInfo->IsErrorOccur == NO) { result = false; break; } } return result; } void ClearAlarmCodeWhenAcOff() { if (!pSysInfo->AcContactorStatus) { pAlarmCode->AlarmEvents.bits.PsuNoResource = NO; } } //========================================== // Check Smart Charging Profile //========================================== int GetStartScheduleTime(uint8_t *time) { int result = -1; struct tm tmScheduleStart; struct timeb tbScheduleStart; if ((sscanf((char *)time, "%4d-%2d-%2dT%2d:%2d:%2d", &tmScheduleStart.tm_year, &tmScheduleStart.tm_mon, &tmScheduleStart.tm_mday, &tmScheduleStart.tm_hour, &tmScheduleStart.tm_min, &tmScheduleStart.tm_sec) == 6)) { tmScheduleStart.tm_year -= 1900; tmScheduleStart.tm_mon -= 1; tbScheduleStart.time = mktime(&tmScheduleStart); tbScheduleStart.millitm = 0; result = DiffTimebWithNow(tbScheduleStart) / 1000; } return result; } void CheckSmartChargeProfile(uint8_t _index) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index); if (ShmOCPP16Data->CSUMsg.bits[_index].ChargingProfileConf == YES) { // Get Charging Profile ShmOCPP16Data->CSUMsg.bits[_index].ChargingProfileConf = NO; if (strcmp((char *)ShmOCPP16Data->SmartChargingProfile[_index].ChargingProfileKind, "Absolute") == EQUAL && ShmOCPP16Data->SmartChargingProfile[_index].ChargingProfileId == YES //DS60-120 add ) { int _time = GetStartScheduleTime(ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.StartSchedule); uint8_t _startCount = NO_DEFINE; uint8_t _maxCount = ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod); for (uint8_t _count = 0; _count < _maxCount; _count++) { // 預設最小輸出電流 (MIN_OUTPUT_CUR) A if (_time >= ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_count].StartPeriod) { if ((_count == 0 && ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_count].Limit >= MIN_OUTPUT_CUR) || ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_count].Limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } log_info("_startCount = %d ", _startCount); if (_startCount < _maxCount) { //DS60-120 add log_info("Profile Limit = %f ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit); pDcChargingInfo->ChargingProfilePower = ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * AC_OUTPUT_VOL; if (pDcChargingInfo->EvBatterytargetVoltage > 0 && pDcChargingInfo->PresentChargingVoltage > 0) { pDcChargingInfo->ChargingProfileCurrent = (pDcChargingInfo->ChargingProfilePower / pDcChargingInfo->PresentChargingVoltage) * 10; } else { pDcChargingInfo->ChargingProfileCurrent = 0; } } else { pDcChargingInfo->ChargingProfilePower = -1; pDcChargingInfo->ChargingProfileCurrent = -1; } } else { pDcChargingInfo->ChargingProfilePower = -1; pDcChargingInfo->ChargingProfileCurrent = -1; } log_info("ChargingProfilePower = %f ", pDcChargingInfo->ChargingProfilePower); log_info("ChargingProfileCurrent = %f ", pDcChargingInfo->ChargingProfileCurrent); } } void ChargingProfileFlat(uint8_t _index) { if (ShmOCPP16Data->CSUMsg.bits[_index].ChargingProfileConf == NO) { if (ShmOCPP16Data->CSUMsg.bits[_index].ChargingProfileReq == NO) { ShmOCPP16Data->CSUMsg.bits[_index].ChargingProfileReq = YES; } } } /* void CheckReturnToChargingConn() { if ((pSysConfig->TotalConnectorCount + pSysConfig->AcConnectorCount) > 1 && pSysInfo->PageIndex != _LCM_START_AUTHORIZING && pSysInfo->PageIndex != _LCM_START_AUTHORIZE_FAIL && pSysInfo->PageIndex != _LCM_WAIT_PLUGIN) { bool isReturnTimeout = false; for (uint8_t count = 0; count < pSysConfig->TotalConnectorCount; count++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(count); // 如果選的 DC 槍在充電~ 則 DC 槍不改變 if (count == pSysInfo->CurGunSelected) { if ((pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && pDcChargingInfo->SystemStatus <= S_COMPLETE) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ) { isReturnTimeout = false; break; } } else if (count != pSysInfo->CurGunSelected) { if ((pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && pDcChargingInfo->SystemStatus <= S_COMPLETE) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } } // AC 槍 if (!isReturnTimeout && pSysConfig->AcConnectorCount > 0) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected); pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); // 沒有選中 AC,且 AC 在充電中 if (pSysInfo->CurGunSelectedByAc == NO_DEFINE && (pAcChargingInfo->SystemStatus >= S_PREPARNING && pAcChargingInfo->SystemStatus <= S_COMPLETE)) { // 當前 DC 充電槍在 idle 狀態 if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } else if (pSysInfo->CurGunSelectedByAc == DEFAULT_AC_INDEX && ((pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && pDcChargingInfo->SystemStatus <= S_COMPLETE) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1))) { // 當前 DC 充電槍在 idle 狀態 if (pAcChargingInfo->SystemStatus == S_IDLE || pAcChargingInfo->SystemStatus == S_RESERVATION) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } } if (!isReturnTimeout) { StopSystemTimeoutDet(); } } } bool GetStartChargingByAlterMode(uint8_t _gun) { bool result = true; if (pSysConfig->TotalConnectorCount == 2 && pSysInfo->IsAlternatvieConf == YES) { for (uint8_t _select = 0; _select < pSysConfig->TotalConnectorCount; _select++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_select); if (_select != _gun) { if (pDcChargingInfo->SystemStatus != S_IDLE && pDcChargingInfo->SystemStatus != S_RESERVATION) { result = false; break; } } } } return result; } */ void TheEndCharging(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); ftime(&endChargingTime[gunIndex]); if (pDcChargingInfo->PresentChargedDuration != 0) { pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]); } pDcChargingInfo->isRemoteStart = NO; if (pDcChargingInfo->TimeoutFlag != Timeout_FinalCost) StopGunInfoTimeoutDet(gunIndex); //StartGunInfoTimeoutDet(gunIndex, Timeout_EvseCompleteDet); ChangeStartOrStopDateTime(NO, gunIndex); DB_Insert_Record(gunIndex); } void UpdateErrorCodeToOcpp(uint8_t index) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); //log_info("%d = ConnectorAlarmCode = %s", index, pDcChargingInfo->ConnectorAlarmCode); //log_info("%d = EvConnAlarmCode = %s", index, pDcChargingInfo->EvConnAlarmCode); if (strcmp((char *)pDcChargingInfo->ConnectorAlarmCode, "") != EQUAL) { //if (strlen((char *)pDcChargingInfo->ConnectorAlarmCode) == EQUAL) { strcpy((char *)ShmOCPP16Data->StatusNotification[index].ErrorCode, "InternalError"); strcpy((char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode, (char *)pDcChargingInfo->ConnectorAlarmCode); } else if (strcmp((char *)pDcChargingInfo->EvConnAlarmCode, "") != EQUAL) { //} else if (strlen((char *)pDcChargingInfo->EvConnAlarmCode) == EQUAL) { strcpy((char *)ShmOCPP16Data->StatusNotification[index].ErrorCode, "OtherError"); strcpy((char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode, (char *)pDcChargingInfo->EvConnAlarmCode); } //log_info("Gun %d = VendorErrorCode = %s", index, (char *)ShmOCPP16Data->StatusNotification[index].VendorErrorCode); } void AdjustChargerCurrent() { pSysConfig->RatingCurrent = ShmPsuData->SystemAvailableCurrent / 10; // 設定的電流~ 如超過可輸出的電流,則 bypass if (pSysConfig->RatingCurrent < pSysConfig->MaxChargingCurrent || pSysConfig->RatingCurrent == 0) { pSysConfig->MaxChargingCurrent = 0; } log_info("PSU : MaxChargingPower = %d, MaxChargingCurrent = %d", ShmPsuData->SystemAvailablePower / 10, ShmPsuData->SystemAvailableCurrent / 10 ); log_info("Config : ChargingPower = %d, ChargingCurrent = %d", pSysConfig->MaxChargingPower, pSysConfig->MaxChargingCurrent ); } void ResetDetAlarmStatus(uint8_t gun) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun); if (pDcChargingInfo->Type == _Type_Chademo) { if (pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP == YES) { pAlarmCode->AlarmEvents.bits.SystemChademoOutputOVP = NO; } } else if (pDcChargingInfo->Type == _Type_GB) { if (pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP == YES) { pAlarmCode->AlarmEvents.bits.SystemGbOutputOVP = NO; } } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP == YES) { pAlarmCode->AlarmEvents.bits.SystemCcsOutputOVP = NO; } } } static void autoStartCharging(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if ( (pSysInfo->SystemPage >= _PAGE_AUTHORIZE && pSysInfo->SystemPage <= _PAGE_SENSING) || (pDcChargingInfo->isEVCCIDVerify && strcmp( (char *)pSysConfig->UserId , "" ) != EQUAL)) { return; } if ((pDcChargingInfo->ConnectorPlugIn == YES) && (pDcChargingInfo->SystemStatus == S_IDLE ) ) { if(!pSysConfig->AuthorisationMode) { /* if (pSysConfig->isAuthrizeByEVCCID && !pDcChargingInfo->isEVCCIDVerify && pDcChargingInfo->Type == _Type_CCS_2) { // LCM show linking pic. & timeout 2 min if( pSysInfo->CurGunSelected == gunIndex ) { systemPageRestoreInit(); pSysInfo->SystemPage = _LCM_PRECHARGE; } StartGunInfoTimeoutDet(gunIndex,Timeout_EVCCID_Link); // Getting EVCCID if( strcmp( (char *)pDcChargingInfo->EVCCID, "" ) != EQUAL ) { log_info("Authorizing EVCCID"); StopSystemTimeoutDet(); strcpy((char *)pSysConfig->UserId, (char *)pDcChargingInfo->EVCCID); ChangeGunSelectByIndex(gunIndex); confirmSelGun(gunIndex); pDcChargingInfo->isEVCCIDVerify = true; pSysInfo->SystemPage = _LCM_START_AUTHORIZING; log_info("Get User(%d) ID:%s",gunIndex,pSysConfig->UserId); setChargerMode(gunIndex, MODE_AUTHORIZING); } } else return; */ } else { strcpy((char *)&pSysConfig->UserId, "AutoStartCharging"); ChangeGunSelectByIndex(gunIndex); confirmSelGun(gunIndex); ShmDcCommonData->TradeCancel = FALSE; ShmDcCommonData->is_AutoStart[gunIndex] = TRUE; pSysInfo->SystemPage = _PAGE_SENSING; ShmDcCommonData->AuthPass_flag[gunIndex] = TRUE; //setChargerMode(gunIndex, MODE_AUTHORIZING); log_info("Get User(%d) ID:%s",gunIndex,pSysConfig->UserId); sleep(1); //讓其他task有時間執行 } } } static bool PrecheckIsPass(uint8_t gunIndex) { bool result = true; // relay welding or driving 是反向 result = !ShmDcCommonData->GunRelayWeldingOccur[gunIndex]; return result; } static void ReviewCriticalAlarm(void) { if ( pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES || pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES || pAlarmCode->AlarmEvents.bits.DoorOpen == YES || pSysWarning->ExtraErrProcess != _EXTRA_ERR_PROCESS_NONE || pAlarmCode->AlarmEvents.bits.PsuFailureAlarm == YES || pAlarmCode->AlarmEvents.bits.DisconnectedFromDo == YES || //Power cabinet alarm status ShmDcCommonData->PowerAlarmState.StatusBit.EmergencyStop == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DoorOpen == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DcInputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.DcInputUVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL1InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL2InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.SystemL3InputOVP == YES || ShmDcCommonData->PowerAlarmState.StatusBit.PsuFailure == YES ) { pSysWarning->Level = WARN_LV_ER; } else { if (ShmSelectGunInfo->EthDevStatus.Backend == 0 || ShmSelectGunInfo->EthDevStatus.Backend == 2 ) { pInfoCode->InfoEvents.bits.BackendDisconnectedViaEthernet = TRUE; if (ShmDcCommonData->DebugFlag || pSysConfig->AuthorisationMode) { pSysWarning->Level = WARN_LV_NL; } else { pSysWarning->Level = WARN_LV_ER; return; } } else if (ShmSelectGunInfo->EthDevStatus.Backend == 1) { pInfoCode->InfoEvents.bits.BackendDisconnectedViaEthernet = FALSE; } pSysWarning->Level = WARN_LV_NL; } } static void CheckRelayWeldingOrDrivingFault(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // relay welding fault then stop the charging process. uint8_t faultCode = RELAY_STATUS_ERROR_NONE; //static uint8_t drivingCount = 0; if (gunIndex == 0) { if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_WELDING; } else if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->CheckRelayStatus[RELAY_SMR1_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_DRIVING; } } else if (gunIndex == 1) { if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR2_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->CheckRelayStatus[RELAY_SMR2_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_WELDING; } else if (ShmDcCommonData->CheckRelayStatus[RELAY_SMR2_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->CheckRelayStatus[RELAY_SMR2_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_DRIVING; } } if (pSysConfig->TotalConnectorCount >= 2 && !pSysInfo->IsAlternatvieConf) { // 橋接 if (ShmDcCommonData->CheckRelayStatus[RELAY_PARA_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->CheckRelayStatus[RELAY_PARA_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_WELDING; } else if (ShmDcCommonData->CheckRelayStatus[RELAY_PARA_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->CheckRelayStatus[RELAY_PARA_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_DRIVING; } } if (faultCode == RELAY_STATUS_ERROR_WELDING) { // welding if (pDcChargingInfo->Type == _Type_Chademo) { RecordAlarmCode(gunIndex, "011011"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = YES; } else if (pDcChargingInfo->Type == _Type_GB) { RecordAlarmCode(gunIndex, "011015"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = YES; } else if (pDcChargingInfo->Type == _Type_CCS_2) { RecordAlarmCode(gunIndex, "011013"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = YES; } ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = YES; //EmcOccureByString(""); } else if (faultCode == RELAY_STATUS_ERROR_DRIVING) { //if (drivingCount++ != 2) { // return; //} // driving if (pDcChargingInfo->Type == _Type_Chademo) { RecordAlarmCode(gunIndex, "011012"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = YES; } else if (pDcChargingInfo->Type == _Type_GB) { RecordAlarmCode(gunIndex, "011016"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = YES; } else if (pDcChargingInfo->Type == _Type_CCS_2) { RecordAlarmCode(gunIndex, "011014"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = YES; } ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = YES; //EmcOccureByString(""); } else { ShmDcCommonData->GunRelayWeldingOccur[gunIndex] = NO; ShmDcCommonData->GunRelayDrivingOccur[gunIndex] = NO; //drivingCount = 0; } } static void isChargingAverageState(void) { if (pSysInfo->MainChargingMode != _MAIN_CHARGING_MODE_AVER) { pSysInfo->ReAssignedFlag = _REASSIGNED_NONE; return; } // 均充 -> 最大充 if (pSysInfo->BridgeRelayStatus == NO) { if (pSysInfo->ReAssignedFlag == _REASSIGNED_NONE) { log_info("=============Smart Charging============= Step 11 "); pSysInfo->ReAssignedFlag = _REASSIGNED_PREPARE_A_TO_M; } } else if (pSysInfo->ReAssignedFlag != _REASSIGNED_COMP && pSysInfo->ReAssignedFlag != _REASSIGNED_WAITING) { log_info("=============Smart Charging============= Step 14 "); pSysInfo->ReAssignedFlag = _REASSIGNED_WAITING; } else if (pSysInfo->ReAssignedFlag == _REASSIGNED_COMP) { pSysInfo->MainChargingMode = _MAIN_CHARGING_MODE_MAX; pSysInfo->ReAssignedFlag = _REASSIGNED_NONE; } } bool Taskconutstring(char *src, char *taskname) { bool result = false; if (src == NULL || strlen(src) == 0) return result; if (strstr(src, taskname) != NULL && strstr(src, "grep") == NULL && strstr(src, "[") == NULL) { result = true; } return result; } int GetProcessCount(char *procName) { int result = 0; FILE *fp; char cmd[256]; char buf[256]; sprintf(cmd, "ps -ef |grep %s", procName); fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if (Taskconutstring(buf, procName)) result++; } } pclose(fp); return result; } void CheckTaskAlive() { pid_t Pid = fork(); if ( Pid == 0 ) { //log_info("CheckTaskAlive fork Child's PID is %d", getpid()); while(1) { sleep(3); unsigned char count = GetProcessCount("Module_ChkSysTask"); if( count != 1 ) { system("pkill Module_ChkSysTask"); sleep(10); //log_info("Create Check System Task"); system("/root/Module_ChkSysTask &"); } } return; } log_info("Create Check Systam fork:%d",Pid); return; } /** * [checkPileEndGfdResult 確認充電樁GFD狀態] * @Author Jerry * @DateTime 2021-07-01 * @param gunIndex [當前的槍] * @param gunType [槍的類型] * @param sysStatus [槍的系統狀態] */ static void checkPileEndGfdResult(uint8_t gunIndex, uint8_t gunType, uint8_t sysStatus) { switch (gunType) { case _Type_Chademo: // 檢查樁端的 GFD 結果 if (sysStatus == S_PREPARING_FOR_EVSE && isPrechargeStatus_chademo(gunIndex) >= 6 ) { // 當前操作的槍號,進入 Charging setChargerMode(gunIndex, MODE_CHARGING); } if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(gunIndex, "012234"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO; } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) { // GFD 警告 //RecordAlarmCode(gunIndex, "012296"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = YES; } else { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO; } break; case _Type_GB: // 檢查樁端的 GFD 結果 //if (isPrechargeStatus_gb(gunIndex) > 5 && isPrechargeStatus_gb(gunIndex) < 9) { if (sysStatus == S_PREPARING_FOR_EVSE && isPrechargeStatus_gb(gunIndex) >= 6) { setChargerMode(gunIndex, MODE_CHARGING); } if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(gunIndex, "012236"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = YES; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO; } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) { // GFD 警告 //RecordAlarmCode(gunIndex, "012298"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = YES; } else { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = NO; } break; case _Type_CCS_2: // 檢查樁端的 GFD 結果 if (sysStatus == S_PREPARING_FOR_EVSE && (pDcChargingInfo->GroundFaultStatus == GFD_PASS || pDcChargingInfo->GroundFaultStatus == GFD_WARNING) ) { setChargerMode(gunIndex, MODE_CCS_PRECHARGE_STEP0); } if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(gunIndex, "012235"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO; } else if (pDcChargingInfo->GroundFaultStatus == GFD_WARNING) { // GFD 警告 //RecordAlarmCode(gunIndex, "012297"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = YES; } else { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = NO; } break; } } static void checkEvBoardReqStop(uint8_t sysStatus, uint8_t gunIndex) { uint8_t evBoardStopState = 0; if ((evBoardStopState = isEvBoardStopChargeFlag(gunIndex)) > 0) { // 板端要求停止 (錯誤) if (sysStatus != S_CCS_PRECHARGE_ST0 && sysStatus != S_CCS_PRECHARGE_ST1) { if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "EVDisconnected"); } } if (evBoardStopState == EV_BOARD_STOP_CHARGING) { log_info("EV Board Stop Charging with some error"); ChargingAlarmProcess(gunIndex); } else if (evBoardStopState == POWER_CABINET_STOP_CHARGING) { log_info("Power Cabient Stop Charging"); ChargingTerminalProcess(gunIndex); } } else if (isEvBoardNormalStopChargeFlag(gunIndex) == YES) { // 板端要求停止 (正常) if (sysStatus != S_CCS_PRECHARGE_ST0 && sysStatus != S_CCS_PRECHARGE_ST1) { if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "EVDisconnected"); } } log_info("EV Board Normal Stop Charging"); ChargingTerminalProcess(gunIndex); } else if (OcppRemoteStop(gunIndex) == YES || WifiScheduleStop(gunIndex)) { // 後臺要求停止 log_info("OCPP Stop Charging"); ChargingTerminalProcess(gunIndex); } } static void checkOCPPReqStop(uint8_t gunIndex) { if (OcppRemoteStop(gunIndex) == YES || WifiScheduleStop(gunIndex) || CheckBackendChargingTimeout(gunIndex) || CheckBackendChargingEnergy(gunIndex) || strcmp((char *)ShmOCPP16Data->StartTransaction[gunIndex].ResponseIdTagInfo.Status, "Invalid") == EQUAL) { // 後臺要求停止 ChargingTerminalProcess(gunIndex); } } void ResetIdleData(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data(); ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo(); float powerconsumption = ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption; pDcChargingInfo->PresentChargedDuration = 0; pDcChargingInfo->RemainChargingDuration = 0; pDcChargingInfo->PresentChargingVoltage = 0;//DS60-120 add pDcChargingInfo->PresentChargingCurrent = 0;//DS60-120 add pDcChargingInfo->RemoteStartFlag = NO; pDcChargingInfo->Replug_flag = FALSE; strcpy((char *)pDcChargingInfo->StartDateTime, ""); strcpy((char *)pDcChargingInfo->StopDateTime, ""); strcpy((char *)pDcChargingInfo->StartUserId, ""); strcpy((char *)pSysConfig->UserId, ""); strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, ""); ClearDetectPluginFlag(gunIndex); //Jerry add memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo)); memset(&ShmDcCommonData->TransactionInfo[gunIndex], 0, sizeof(RecordTransactionInfo)); memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo)); ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = powerconsumption; ShmDcCommonData->finalcost_flag[gunIndex] = FALSE; ShmDcCommonData->AuthPass_flag[gunIndex] = FALSE; ShmDcCommonData->PayPass_flag[gunIndex] = FALSE; ShmDcCommonData->OperateIDLE[gunIndex] = 1; ShmDcCommonData->is_RemoteStart[gunIndex] = FALSE; ShmDcCommonData->is_AutoStart[gunIndex] = FALSE; ShmDcCommonData->is_exit[gunIndex] = FALSE; ShmDcCommonData->StopCharge[gunIndex] = FALSE; ShmDcCommonData->is_plugout[gunIndex] = FALSE; if (pDcChargingInfo->deratingByConnOtp.deratingIndex != 0) { pDcChargingInfo->deratingByConnOtp.deratingIndex = 0; } ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES; destroySelGun(gunIndex); ResetDetAlarmStatus(gunIndex); //recovery OVP status code if (ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] == YES) { ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] = NO; } //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, ""); ReleaseAlarmCode(gunIndex); if (pSysInfo->SystemPage != _PAGE_SELECT_GUN && pSysInfo->SystemPage != _PAGE_SELECT_PAY && pSysInfo->CurGunSelected == gunIndex) { systemPageRestoreInit(); } } void CheckErrorCode(uint8_t gunIndex) { /* struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (gunIndex == pSysInfo->CurGunSelected) { pSysInfo->SystemPage = _PAGE_MAINTAIN; } else if (pSelectedDcChargingInfo->SystemStatus != S_IDLE && pSelectedDcChargingInfo->SystemStatus != S_RESERVATION && pSelectedDcChargingInfo->SystemStatus != S_MAINTAIN && pSelectedDcChargingInfo->SystemStatus != S_FAULT) { if (pSelectedDcChargingInfo->SystemStatus == S_CHARGING) { if(ShmDcCommonData->PayPass_flag[gunIndex] == FALSE) pSysInfo->SystemPage = _PAGE_PAYING; else pSysInfo->SystemPage = _PAGE_COMPLETE; } else { systemPageRestoreInit(); } } */ ClearDetectPluginFlag(gunIndex); if (pDcChargingInfo->SystemStatus != S_FAULT) { UpdateErrorCodeToOcpp(gunIndex); setChargerMode(gunIndex, MODE_FAULT); } } void AuthorizeStopCharging(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); checkOCPPReqStop(gunIndex); //RfidStopCharging(); } void SetNatural300AGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp) { deratingByConnOtp->isNeedDerating = YES; deratingByConnOtp->deratingTargetCurrent[0] = 5000; deratingByConnOtp->deratingTargetCurrent[1] = 3000; deratingByConnOtp->deratingTargetCurrent[2] = 1000; deratingByConnOtp->deratingTargetCurrent[3] = 0; deratingByConnOtp->deratingTargetCurrent[4] = 0; } void SetLiquidCoolGunOTPValue(struct DERATING_BY_OTP* deratingByConnOtp) { deratingByConnOtp->isNeedDerating = YES; deratingByConnOtp->deratingTargetCurrent[0] = 5000; deratingByConnOtp->deratingTargetCurrent[1] = 4000; deratingByConnOtp->deratingTargetCurrent[2] = 3000; deratingByConnOtp->deratingTargetCurrent[3] = 0; deratingByConnOtp->deratingTargetCurrent[4] = 0; } void SetCHAdeMoTypeKOTPValue(struct DERATING_BY_OTP* deratingByConnOtp) { deratingByConnOtp->isNeedDerating = YES; deratingByConnOtp->deratingTargetRate[0] = 1; deratingByConnOtp->deratingTargetRate[1] = 0.8; deratingByConnOtp->deratingTargetRate[2] = 0.8; deratingByConnOtp->deratingTargetRate[3] = 0; deratingByConnOtp->deratingTargetRate[4] = 0; memset(&deratingByConnOtp->deratingTargetCurrent[0], 0, sizeof(deratingByConnOtp->deratingTargetCurrent)); } void SetCHAdeMoTypeSJOTPValue(struct DERATING_BY_OTP* deratingByConnOtp) { deratingByConnOtp->isNeedDerating = YES; deratingByConnOtp->deratingTargetCurrent[0] = 2000; deratingByConnOtp->deratingTargetCurrent[1] = 1250; deratingByConnOtp->deratingTargetCurrent[2] = 1250; deratingByConnOtp->deratingTargetCurrent[3] = 0; deratingByConnOtp->deratingTargetCurrent[4] = 0; } void SetCHAdeMoTypeOOTPValue(struct DERATING_BY_OTP* deratingByConnOtp) { deratingByConnOtp->isNeedDerating = YES; deratingByConnOtp->deratingTargetCurrent[0] = 3500; deratingByConnOtp->deratingTargetCurrent[1] = 2000; deratingByConnOtp->deratingTargetCurrent[2] = 2000; deratingByConnOtp->deratingTargetCurrent[3] = 0; deratingByConnOtp->deratingTargetCurrent[4] = 0; } static void SetGunTypeOTPValue(void) { //struct ChargingInfoData* chargingData_2 = NULL; uint8_t Gun1Type = 0; uint8_t Gun2Type = 0; int i,cnt; if (pSysConfig->TotalConnectorCount == 1) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(0); Gun1Type = pSysConfig->ModelName[7]; Gun2Type = pSysConfig->ModelName[7]; switch (Gun1Type) { case 'K': SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp); break; case 'S': SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp); break; case 'I': case 'Q': SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp); break; case 'O': SetCHAdeMoTypeOOTPValue(&pDcChargingInfo->deratingByConnOtp); break; // 水冷 case 'V': case 'F': SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp); break; default: pDcChargingInfo->deratingByConnOtp.isNeedDerating = NO; } if (pDcChargingInfo->deratingByConnOtp.isNeedDerating) { log_info("------------ Gun0 - Type:%c Derating info (OTP)-----------", Gun1Type); if (pDcChargingInfo->deratingByConnOtp.deratingTargetRate[0] != 0) { for (cnt = 0; cnt < DERATING_TARGET_LEVEL; cnt++) { if (pDcChargingInfo->deratingByConnOtp.deratingTargetRate[cnt] != 0) { log_info(" (Pwr) count = %d, valut = %.1f ", cnt, pDcChargingInfo->deratingByConnOtp.deratingTargetRate[cnt]); } } } else if (pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[0] != 0) { for (cnt = 0; cnt < DERATING_TARGET_LEVEL; cnt++) { if (pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[cnt] != 0) { log_info(" (Cur) count = %d, valut = %.1f ", cnt, pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[cnt]); } } } } } 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); switch (i == 0 ? Gun1Type : Gun2Type) { case 'K': SetCHAdeMoTypeKOTPValue(&pDcChargingInfo->deratingByConnOtp); break; case 'S': SetCHAdeMoTypeSJOTPValue(&pDcChargingInfo->deratingByConnOtp); break; // 風冷300A case 'I': case 'Q': SetNatural300AGunOTPValue(&pDcChargingInfo->deratingByConnOtp); break; case 'O': SetCHAdeMoTypeOOTPValue(&pDcChargingInfo->deratingByConnOtp); break; // 水冷 case 'V': case 'F': SetLiquidCoolGunOTPValue(&pDcChargingInfo->deratingByConnOtp); break; default: pDcChargingInfo->deratingByConnOtp.isNeedDerating = NO; } if (pDcChargingInfo->deratingByConnOtp.isNeedDerating) { log_info("------------ Gun%d - Type:%c Derating info (OTP)-----------",i, i == 0 ? Gun1Type : Gun2Type); if (pDcChargingInfo->deratingByConnOtp.deratingTargetRate[0] != 0) { for (cnt = 0; cnt < DERATING_TARGET_LEVEL; cnt++) { if (pDcChargingInfo->deratingByConnOtp.deratingTargetRate[cnt] != 0) { log_info(" (Pwr) count = %d, valut = %.1f ", cnt, pDcChargingInfo->deratingByConnOtp.deratingTargetRate[cnt]); } } } else if (pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[0] != 0) { for (cnt = 0; cnt < DERATING_TARGET_LEVEL; cnt++) { if (pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[cnt] != 0) { log_info(" (Cur) count = %d, valut = %.1f ", cnt, pDcChargingInfo->deratingByConnOtp.deratingTargetCurrent[cnt]); } } } } } } } void showversion() { char str[10240]; int len = 0; uint8_t index = 0; len += sprintf(&str[len],"\n=========== Dispenser info =========== \n"); len += sprintf(&str[len],"SW Version = %s\n", fwVersion); len += sprintf(&str[len],"Debug Version = %s\n",DebugVersion); len += sprintf(&str[len],"ModelName = %s\n", pSysConfig->ModelName); len += sprintf(&str[len],"Relay Board FW Rev = %s\n", pSysInfo->RelayModuleFwRev); len += sprintf(&str[len],"Fan Board FW Rev = %s\n", pSysInfo->FanModuleFwRev); len += sprintf(&str[len],"Primary FW Rev = %s\n", pSysInfo->CsuPrimFwRev); len += sprintf(&str[len],"LED FW Rev = %s\n", pSysInfo->LedModuleFwRev); for (index = 0; index < pSysConfig->TotalConnectorCount; index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); if (pDcChargingInfo->Type == _Type_Chademo) { len += sprintf(&str[len],"CHAdeMO[%d] FW Rev = %s\n", index, ShmCHAdeMOData->evse[pDcChargingInfo->type_index].version); } else if (pDcChargingInfo->Type == _Type_GB) { len += sprintf(&str[len],"GBT[%d] FW Rev = %s\n", index, ShmGBTData->evse[pDcChargingInfo->type_index].version); } else if (pDcChargingInfo->Type == _Type_CCS_2) { len += sprintf(&str[len],"CCS[%d] FW Rev = %s\n", index, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].version); } } len += sprintf(&str[len],"==================================== "); log_info("%s",str); } void ParkingProcess(int gunIndex) { if (pSysInfo->CurGunSelected != gunIndex) return; // 取得佔位費資訊過場畫面 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_SENSING && 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 _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 _PAGE_AUTHORIZE: StopGunInfoTimeoutDet(gunIndex); break; 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; case _PAGE_AUTHORIZE_FAIL: StartSystemTimeoutDet(Timeout_VerifyFail); break; case _PAGE_PLUGOUT: StopGunInfoTimeoutDet(gunIndex); break; } } int main(void) { bool isModelNameMatch = true; uint8_t _ocppProfileChkFlag; uint8_t gunIndex = 0; if (CreateAllCsuShareMemory() == FAIL) { log_error("create share memory error"); return FAIL; } ClearAllShmMemParameter(); pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo(); pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData(); pFaultCode = (struct FaultCodeData *)GetShmFaultCodeData(); pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData(); ShmPsuData = (struct PsuData *)GetShmPsuData(); ShmCHAdeMOData = (struct CHAdeMOData *)GetShmCHAdeMOData(); ShmGBTData = (struct GBTData *)GetShmGBTData(); ShmCcsData = (struct CcsData *)GetShmCcsData(); ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData(); ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData(); ShmRelayModuleData = (struct RelayModuleData *)GetShmRelayModuleData(); ShmLedModuleData = (struct LedModuleData *)GetShmLedModuleData(); ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data(); ShmOCPP20Data = (struct OCPP20Data*)GetShmOCPP20Data(); ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData(); ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo(); ShmSysConfigAndInfo = (struct SysConfigAndInfo *)GetShmSysConfigAndInfo(); ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData(); log_info(" ********************************************************"); log_info(" ****************** FileSystem Boot up *****************"); log_info(" ********************************************************"); log_info(" ****************** Project:DD360Tcc *****************"); log_info(" ********************************************************"); if (!InitialSystemDefaultConfig()) { log_error("InitialSystemDefaultConfig NG "); //StopProcessingLoop(); sleep(5); system("reboot -f"); } CheckGunTypeFromHw(); CheckIsAlternatvieByModelName(); InitialShareMemoryInfo(); GetFirmwareVersion(); if (!CheckConnectorTypeStatus()) { isModelNameMatch = false; } Initialization(); SpawnTask(); log_info("Spawned all Task"); if (!isModelNameMatch) { pAlarmCode->AlarmEvents.bits.ModelNameNoneMatchStestFail = YES; //ChangeLcmByIndex(_LCM_ERROR); ChangeLcmByIndex(_PAGE_MAINTAIN); // Module Name 與硬體對應不正確 log_error("Module Name & HW info none match. "); sleep(3); KillAllTask(); StopProcessingLoop(); } CreateTimeoutFork(); log_info("Start self test... "); SelfTestRun(); StopSystemTimeoutDet(); log_info("Self test finished : SelfTestSeq = %d, Work_Step = %d ", pSysInfo->SelfTestSeq, ShmPsuData->Work_Step); if (pSysInfo->SelfTestSeq == _STEST_FAIL || ShmPsuData->Work_Step == _NO_WORKING || pInfoCode->InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES ) { ChangeLcmByIndex(_PAGE_MAINTAIN); for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { setChargerMode(gunIndex, MODE_MAINTAIN); } } else { for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { setChargerMode(gunIndex, MODE_IDLE); } } // Local DB if (DB_Open() != PASS) { log_info("DB_Open fail. "); isDb_ready = false; } else { isDb_ready = true; for (int _index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index); pDcChargingInfo->IsAvailable = DB_Get_Operactive(_index); } DB_Reboot_Record(); } if (PowerDB_Open() != PASS) { log_info("Power DB_Open fail. "); isDb_ready = false; } else { int _retry = 0; isDb_ready = true; for (int _index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index); while (_retry < 3) { if (DB_Get_PowerConsumption(_index)) { break; } else { sleep(1); _retry++; if (_retry == 3) { DB_Insert_PowerConsumption(_index, 0); } } } // while } // for } log_info("===== Create DB End ===== "); ChangeLcmByIndex(_PAGE_IDLE); sleep(1); //***** 須新增的偵測 *****// // 1. Thernal - 控制風扇轉速 // 2. ouput fuse - 控制風扇轉速 CreateRfidFork(); // Main loop CheckFwSlotStatusLog(); //AdjustChargerCurrent(); GetClockTime(&_cmdMainPriority_time, NULL); // GunIndexInfo *pGunIndexInfo = (GunIndexInfo *)GetGunIndexInfo(); CheckTaskAlive(); CreateWatchdog(); SetGunTypeOTPValue(); showversion(); ShmDcCommonData->ParkingLeaveTime = 15; //結束充電15分鐘後開始計算佔位費 ShmDcCommonData->SaleLeaveTime = 10; //結算佔位費後開始計算10分鐘 struct ChargingInfoData *pDcInfo = NULL; for (;;) { CheckOcppStatus(); ChkPrimaryStatus(); if ((IsConnectorWholeIdle() || //(pSysInfo->PageIndex == _LCM_ERROR)) && (pSysInfo->PageIndex == _PAGE_MAINTAIN)) ) { CheckFactoryConfigFunction(); //CheckFwUpdateFunction(); } // OCPP 邏輯 OcppRemoteStartChk(); // 當 AC 沒有搭上時,清除一些錯誤碼 ClearAlarmCodeWhenAcOff(); if ((GetClockTimeoutValue(_cmdMainPriority_time) / 1000) > 5000) { for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE && pDcChargingInfo->SystemStatus <= S_CHARGING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (pDcChargingInfo->SystemStatus == S_CHARGING && _ocppProfileChkFlag == 12) { ChargingProfileFlat(gunIndex); _ocppProfileChkFlag = 0; } else if (pDcChargingInfo->SystemStatus != S_CHARGING) { ChargingProfileFlat(gunIndex); _ocppProfileChkFlag = 0; } else { _ocppProfileChkFlag++; } } checkGunOTPState(gunIndex); //check gun OTP } GetClockTime(&_cmdMainPriority_time, NULL); } gEvBoardErr.GunErrMessage = 0; //清除系統執行中的錯誤訊息 gChillerTempErr.TempErrMsg = 0;//清除系統執行中的錯誤訊息 for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // 重新收集各槍的錯誤狀態 collectError(gunIndex); checkEvBoardAlarmState(pDcChargingInfo->Type); } checkChillerAlarmState(); // 確認當前錯誤 Level = 2 ? ReviewCriticalAlarm(); for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); CheckGpioInStatus(); CheckErrorOccurStatus(gunIndex); // 確認 Relay Welding or Driving Fault CheckRelayWeldingOrDrivingFault(gunIndex); ChkOcppStatus(gunIndex); if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE && pDcChargingInfo->SystemStatus <= S_CHARGING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { CheckSmartChargeProfile(gunIndex); } switch (pDcChargingInfo->SystemStatus) { case S_IDLE: if (isModeChange(gunIndex)) { log_info("============================= S_IDLE(%x) ============================= ", gunIndex); ResetIdleData(gunIndex); } isChargingAverageState(); // For RemoteStart Using if (pDcChargingInfo->RemoteStartFlag == YES && pDcChargingInfo->IsAvailable) { log_info("-------- IDLE Remote Start(%d) --------", gunIndex); //ChangeGunSelectByIndex(gunIndex); setChargerMode(gunIndex, MODE_AUTHORIZING); break; } autoStartCharging(gunIndex); // 讀卡邏輯 if (!ShmDcCommonData->TradeCancel && pSysInfo->CurGunSelected == gunIndex) ScannerCardProcess(gunIndex); if (pSysInfo->SystemPage == _PAGE_SELECT_GUN || pSysInfo->SystemPage == _PAGE_IDLE) { //ShmDcCommonData->LineStatus[gunIndex] = 0; StopGunInfoTimeoutDet(gunIndex); } if (pSysInfo->CurGunSelected == gunIndex) { 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"); } } } } // 檢查預約 if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) { setChargerMode(gunIndex, MODE_RESERVATION); } goto CheckStatus; break; case S_RESERVATION: if (isModeChange(gunIndex)) { log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex); ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES; } if (pDcChargingInfo->RemoteStartFlag == YES && pDcChargingInfo->IsAvailable) { log_info("-------- S_RESERVATION Remote Start(%d) --------", gunIndex); //ChangeGunSelectByIndex(gunIndex); setChargerMode(gunIndex, MODE_AUTHORIZING); break; } // 讀卡邏輯 if (!ShmDcCommonData->TradeCancel && pSysInfo->CurGunSelected == gunIndex) ScannerCardProcess(gunIndex); // 檢查預約 if (!ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) { setChargerMode(gunIndex, MODE_IDLE); } goto CheckStatus; break; case S_FAULT: if (isModeChange(gunIndex)) { if (pDcChargingInfo->SystemStatus == S_FAULT) { log_info("============================= S_FAULT(%x) ============================= ", gunIndex); //pSysInfo->SystemPage = _LCM_ERROR; //pSysInfo->SystemPage = _PAGE_MAINTAIN; } } CheckStatus: if (pDcChargingInfo->IsAvailable == NO) { setChargerMode(gunIndex, MODE_MAINTAIN); break; } // Refresh Error Status if (pSysWarning->Level == WARN_LV_ER) { CheckErrorCode(gunIndex); if (pSysInfo->CurGunSelected == gunIndex) pSysInfo->SystemPage = _PAGE_MAINTAIN; continue; } if (checkGunTempFail(gunIndex)) { break; } if (PrecheckIsPass(gunIndex) == false) { log_error("Relay welding"); setChargerMode(gunIndex, MODE_FAULT); if (gunIndex == pSysInfo->CurGunSelected) { //pSysInfo->SystemPage = _LCM_ERROR; pSysInfo->SystemPage = _PAGE_MAINTAIN; } break; } if (pDcChargingInfo->SystemStatus == S_FAULT) { setChargerMode(gunIndex, MODE_IDLE); systemPageRestoreInit(); } break; case S_AUTHORIZING: if (isModeChange(gunIndex)) { log_info("============================= S_AUTHORIZING(%x) ============================= ", gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_AuthorizingForStop); } if (pSysInfo->CurGunSelected == gunIndex) ScannerCardProcess(gunIndex); if (pSysInfo->SystemPage == _PAGE_PLUGIN && ShmDcCommonData->TradeCancel == FALSE) { pDcChargingInfo->Replug_flag = TRUE; StopSystemTimeoutDet(); } if (isDetectPlugin(gunIndex)) { StartGunInfoTimeoutDet(gunIndex, Timeout_WaitPlug); // 卡號驗證成功後,等待充電槍插入充電車 if (pDcChargingInfo->RemoteStartFlag == YES) { if (pDcChargingInfo->ConnectorPlugIn == YES && pDcChargingInfo->IsAvailable ) { log_info("-------- S_AUTHORIZING Remote Start(%d) --------", gunIndex); pDcChargingInfo->RemoteStartFlag = NO; pDcChargingInfo->isRemoteStart = YES; //DS60-120 //ChangeGunSelectByIndex(gunIndex); //AddPlugInTimes(gunIndex); setChargerMode(gunIndex, MODE_REASSIGN_CHECK); strcpy((char *)pDcChargingInfo->StartUserId, ""); ClearDetectPluginFlag(gunIndex); continue; } } else if (pSysInfo->OrderCharging == NO_DEFINE) { if (pDcChargingInfo->ConnectorPlugIn == YES && pDcChargingInfo->IsAvailable && pDcChargingInfo->SystemStatus == S_AUTHORIZING && ShmDcCommonData->AuthPass_flag[gunIndex] == TRUE && (waitRightGunPlugIt(gunIndex) == PASS || waitLeftGunPlugIt(gunIndex) == PASS) ) { log_info("-------- RFID/Auto Start(%d) --------", gunIndex); //ChangeGunSelectByIndex(gunIndex); //AddPlugInTimes(gunIndex); pDcChargingInfo->isRemoteStart = NO; strcpy((char *)pDcChargingInfo->StartUserId, (char *)pSysConfig->UserId); log_info("index = %d, CardNumber = %s ", gunIndex, pDcChargingInfo->StartUserId); strcpy((char *)pSysConfig->UserId, ""); // 當前操作的槍號,進入 Preparing setChargerMode(gunIndex, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(gunIndex); continue; } } if (!GetIsCardScan() && pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_AUTHORIZE_FAIL && pSysInfo->SystemPage != _PAGE_SENSING) { pSysInfo->SystemPage = _PAGE_PLUGIN; } else if (!GetIsCardScan() && pSysInfo->SystemPage == _PAGE_IDLE && pDcChargingInfo->RemoteStartFlag == YES) { pSysInfo->CurGunSelected = gunIndex; } } else if (ShmDcCommonData->AuthPass_flag[gunIndex] && pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_AUTHORIZE_FAIL) { pSysInfo->SystemPage = _PAGE_SENSING; } break; case S_REASSIGN_CHECK: { if (isModeChange(gunIndex)) { log_info("============================= S_REASSIGN_CHECK(%x) ============================= ", gunIndex); if (pSysInfo->OrderCharging != NO_DEFINE) { pSysInfo->OrderCharging = NO_DEFINE; pDcChargingInfo->_SaftyDetect = FALSE; } pDcChargingInfo->Replug_flag = TRUE; StopSystemTimeoutDet(); StopGunInfoTimeoutDet(gunIndex); } setChargerMode(gunIndex, S_PREPARNING); if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } } break; case S_PREPARNING: if (isModeChange(gunIndex)) { log_info("============================= S_PREPARNING(%x) ============================= ", gunIndex); StopGunInfoTimeoutDet(gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_Preparing); } if (ShmPsuData->SystemPresentPsuQuantity > 0 && ShmPsuData->SystemAvailablePower > 10 && GetClockTimeoutValue(pDcChargingInfo->ConnectorTimeout) >= 1000000) { setChargerMode(gunIndex, MODE_PREPARE_FOR_EV); } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } break; case S_PREPARING_FOR_EV: // 等待車端的通訊 (EV 小板),待車端回報後,開始樁端的測試 if (isModeChange(gunIndex)) { log_info("============================= S_PREPARING_FOR_EV(%x) ============================= ", gunIndex); log_info("Waitting for Gun locked."); StopGunInfoTimeoutDet(gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_EvChargingDet); } if (pDcChargingInfo->Type == _Type_Chademo) { if (isEvGunLocked_chademo(gunIndex) == YES) { log_info("Gun Locked"); setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } else if (pDcChargingInfo->Type == _Type_GB) { if (isEvGunLocked_gb(gunIndex) == YES) { log_info("Gun Locked"); setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (isEvGunLocked_ccs(gunIndex) == YES) { log_info("Gun Locked"); setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } break; case S_PREPARING_FOR_EVSE: // Ground fault test, 等待 Relay Board 通訊及測試,並將狀態回報, CSU 確認 Pass 後,開始進入充電 if (isModeChange(gunIndex)) { log_info("============================= S_PREPARING_FOR_EVSE(%x) ============================= ", gunIndex); StopGunInfoTimeoutDet(gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_EvseChargingDet); } checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus); checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } break; case S_CCS_PRECHARGE_ST0: if (isModeChange(gunIndex)) { log_info("============================= CCS Precharge Processing 1(%x) ============================= ", gunIndex); StopGunInfoTimeoutDet(gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_ForCcsPrechargeDet); } if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(gunIndex, "012235"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES; } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); // 等待 EV 小板 (CCS) 通知可以開始 Precharge // 切換 D+ Relay to Precharge Relay if (isPrechargeStatus_ccs(gunIndex) == 39 || isPrechargeStatus_ccs(gunIndex) == 40) { if ((pDcChargingInfo->RelayKPK2Status == YES || pDcChargingInfo->PantographFlag == YES) && pDcChargingInfo->PrechargeStatus != PRECHARGE_READY) //if (pDcChargingInfo->PrechargeStatus != PRECHARGE_PRERELAY_PASS) { pDcChargingInfo->PrechargeStatus = PRECHARGE_READY; } } else if (isPrechargeStatus_ccs(gunIndex) == 45 || isPrechargeStatus_ccs(gunIndex) == 46 ) { setChargerMode(gunIndex, MODE_CCS_PRECHARGE_STEP1); } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } break; case S_CCS_PRECHARGE_ST1: if (isModeChange(gunIndex)) { log_info("============================= CCS Precharge Processing 2(%x) ============================= ", gunIndex); } if (pDcChargingInfo->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(gunIndex, "012235"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES; } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); // 等待小板通知進入充電 // 切換 D+ Relay to Precharge Relay if (pDcChargingInfo->RelayK1K2Status == YES || pDcChargingInfo->PantographFlag == YES) { pDcChargingInfo->PrechargeStatus = PRECHARGE_READY; // pSysInfo->CurGunSelected = gunIndex; setChargerMode(gunIndex, MODE_CHARGING); } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PRECHARGE; } break; case S_CHARGING: // 剛進入充電狀態,等待 EV 小板要求的輸出電流後開始輸出 if (isModeChange(gunIndex)) { log_info("============================= S_CHARGING(%x) ============================= ", gunIndex); StopGunInfoTimeoutDet(gunIndex); ftime(&startChargingTime[gunIndex]); strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].ResponseIdTagInfo.Status, ""); //DS60-120 add ChangeStartOrStopDateTime(YES, gunIndex); pDcChargingInfo->Replug_flag = FALSE; ShmDcCommonData->finalcost_flag[gunIndex] = FALSE; ShmDcCommonData->TransactionInfo[gunIndex].isIntoCharge = TRUE; ShmDcCommonData->RecordEnergyTime[gunIndex] = time((time_t*)NULL); UpdateDeductInfoStatus(gunIndex, &ShmDcCommonData->TransactionInfo[gunIndex]); } if (ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionConf) { ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionConf = NO; } ftime(&endChargingTime[gunIndex]); pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]); ShmDcCommonData->TransactionInfo[gunIndex].Energy = pDcChargingInfo->PresentChargedEnergy; // 每秒紀錄使用電量到資料庫內 if ((time((time_t*)NULL) - ShmDcCommonData->RecordEnergyTime[gunIndex]) >= 1) { ShmDcCommonData->RecordEnergyTime[gunIndex] = time((time_t*)NULL); UpdateDeductInfoStatus(gunIndex, &ShmDcCommonData->TransactionInfo[gunIndex]); } if ((time((time_t*)NULL) - ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime) >= 5) { ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL); if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0) DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus); checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); // Check Stop Charging AuthorizeStopCharging(gunIndex); if (pSysInfo->SystemPage == _PAGE_STOP_CONFIRM_LEFT || pSysInfo->SystemPage == _PAGE_STOP_CONFIRM_RIGHT) break; // LCM => Charging if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_IDLE && pSysInfo->SystemPage != _PAGE_SELECT_GUN) { pSysInfo->SystemPage = _PAGE_CHARGING; } break; case S_TERMINATING: if (isModeChange(gunIndex)) { log_info("============================= S_TERMINATING(%x) ============================= ", gunIndex); if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); } ShmDcCommonData->StopCharge[gunIndex] = TRUE; if (ShmDcCommonData->is_AutoStart[gunIndex]) { ShmDcCommonData->finalcost_flag[gunIndex] = TRUE; ShmDcCommonData->PayPass_flag[gunIndex] = TRUE; } if (ShmDcCommonData->finalcost_flag[gunIndex] == FALSE && pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PAYING; } StartSystemTimeoutDet(Timeout_Terminating); StartGunInfoTimeoutDet(gunIndex, Timeout_FinalCost); ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL); if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0) DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } // For Precharging timeout if (pDcChargingInfo->Type == _Type_Chademo) { if (isEvStopCharging_chademo(gunIndex) == YES || isPrechargeStatus_chademo(gunIndex) <= 0) { setChargerMode(gunIndex, MODE_COMPLETE); } } else if (pDcChargingInfo->Type == _Type_GB) { if (isEvStopCharging_gb(gunIndex) == YES || isPrechargeStatus_gb(gunIndex) <= 0) { setChargerMode(gunIndex, MODE_COMPLETE); } } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (isEvStopCharging_ccs(gunIndex) == YES && (isPrechargeStatus_ccs(gunIndex) >= 53 || isPrechargeStatus_ccs(gunIndex) == 0 || isPrechargeStatus_ccs(gunIndex) == 13 || isPrechargeStatus_ccs(gunIndex) == 14) ) { setChargerMode(gunIndex, MODE_COMPLETE); } } if (pDcChargingInfo->Replug_flag == TRUE && pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PLUGOUT; break; } if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_PAYING && pSysInfo->SystemPage != _PAGE_SENSING) { if (ShmDcCommonData->PayPass_flag[gunIndex] == TRUE) pSysInfo->SystemPage = _PAGE_COMPLETE; else pSysInfo->SystemPage = _PAGE_PAYFAIL; } break; case S_COMPLETE: if (isModeChange(gunIndex)) { log_info ("============================= S_COMPLETE(%x) ============================= ", gunIndex); if (strcmp((char *)pDcChargingInfo->StartDateTime, "") != EQUAL) { OcppStopTransation(gunIndex); } TheEndCharging(gunIndex); if (pDcChargingInfo->Replug_flag != TRUE && pSysInfo->SystemPage != _PAGE_PLUGOUT) StopSystemTimeoutDet(); if (ShmDcCommonData->is_AutoStart[gunIndex] == TRUE && pSysInfo->CurGunSelected == gunIndex) pSysInfo->SystemPage = _PAGE_COMPLETE; } //if (pSysInfo->SystemPage == _LCM_ERROR) { if (pSysInfo->SystemPage == _PAGE_MAINTAIN) { break; } if (pSysInfo->CurGunSelected == gunIndex && ShmDcCommonData->is_exit[gunIndex]) { pSysInfo->SystemPage = _PAGE_EXIT; break; } if (pDcChargingInfo->ConnectorPlugIn == NO && pSysInfo->SystemPage != _PAGE_PAYING && pSysInfo->SystemPage != _PAGE_SENSING) { if (pSysInfo->CurGunSelected == gunIndex) { StartGunInfoTimeoutDet(gunIndex, Timeout_ExitPage); } if (pDcChargingInfo->TimeoutFlag != Timeout_ExitPage && pDcChargingInfo->TimeoutFlag != Timeout_FinalCost) { 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; } if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_PAYING && pSysInfo->SystemPage != _PAGE_SENSING) { if (ShmDcCommonData->PayPass_flag[gunIndex] == TRUE) pSysInfo->SystemPage = _PAGE_COMPLETE; else pSysInfo->SystemPage = _PAGE_PAYFAIL; } break; case S_ALARM: if (isModeChange(gunIndex)) { log_info("============================= S_ALARM(%x) ============================= ", gunIndex); if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); } UpdateErrorCodeToOcpp(gunIndex); if (strcmp((char *)pDcChargingInfo->StartDateTime, "") != EQUAL) { OcppStopTransation(gunIndex); } TheEndCharging(gunIndex); StopGunInfoTimeoutDet(gunIndex); ShmDcCommonData->StopCharge[gunIndex] = TRUE; if (ShmDcCommonData->is_AutoStart[gunIndex]) { ShmDcCommonData->finalcost_flag[gunIndex] = TRUE; ShmDcCommonData->PayPass_flag[gunIndex] = TRUE; } if (pDcChargingInfo->Replug_flag == TRUE) { } else { StartGunInfoTimeoutDet(gunIndex, Timeout_FinalCost); if(ShmDcCommonData->finalcost_flag[gunIndex] == FALSE && pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_PAYING; } } ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL); if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0) DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } if (pSysWarning->Level == WARN_LV_ER) { pSysInfo->SystemPage = _PAGE_MAINTAIN; continue; } if (pSysInfo->CurGunSelected == gunIndex && ShmDcCommonData->is_exit[gunIndex]) { pSysInfo->SystemPage = _PAGE_EXIT; break; } if (pDcChargingInfo->ConnectorPlugIn == NO && pSysInfo->SystemPage != _PAGE_PAYING && pSysInfo->SystemPage != _PAGE_SENSING) { if (pSysInfo->CurGunSelected == gunIndex) { StartGunInfoTimeoutDet(gunIndex, Timeout_ExitPage); } if (pDcChargingInfo->TimeoutFlag != Timeout_ExitPage && pDcChargingInfo->TimeoutFlag != Timeout_FinalCost) { 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; } if (pSysInfo->CurGunSelected == gunIndex && pSysInfo->SystemPage != _PAGE_PAYING ) { if (ShmDcCommonData->PayPass_flag[gunIndex] == TRUE) pSysInfo->SystemPage = _PAGE_COMPLETE; else pSysInfo->SystemPage = _PAGE_PAYFAIL; } break; case S_MAINTAIN: if (isModeChange(gunIndex)) { log_info("============================= S_MAINTAIN(%x) ============================= ", gunIndex); pSysInfo->SystemPage = _PAGE_MAINTAIN; if (pSysInfo->FirmwareUpdate == YES) { pSysInfo->SystemPage = _PAGE_MAINTAIN; continue; } if (pDcChargingInfo->IsAvailable == NO) { log_info("Gun%d is not availbale"); break; } if (pSysWarning->Level != WARN_LV_ER) { if (!DisplaySelfTestFailReason()) { //DS60-120 add log_info("Soft reboot for retry self-tets. "); sleep(3); system("killall OcppBackend &"); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); } } sleep(3); if (pSysWarning->Level == WARN_LV_ER) { //DS60-120 add KillTaskExceptPrimary(); } else { KillTask(); } /* if (pSysInfo->SelfTestSeq == _STEST_FAIL) StopProcessingLoop(); */ } if (pSysInfo->SelfTestSeq == _STEST_FAIL && pSysInfo->SystemTimeoutFlag != Timeout_SelftestChk) { SelfTestRun(); StopSystemTimeoutDet(); sleep(3); break; } if (pDcChargingInfo->IsAvailable && pSysInfo->SelfTestSeq == _STEST_COMPLETE) { setChargerMode(gunIndex, MODE_IDLE); } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_MAINTAIN; } break; case S_UPDATE: if (isModeChange(gunIndex)) { log_info("============================= S_UPDATE ============================= "); } if (pSysInfo->FirmwareUpdate == YES) { pSysInfo->SystemPage = _PAGE_MAINTAIN; continue; } else { } break; default: if (isModeChange(gunIndex)) { log_info("============================= UNKONWN (%x) ============================= ", gunIndex); } if (pSysConfig->TotalConnectorCount >= 2) { pDcInfo = (struct ChargingInfoData *)GetDcChargingInfoData((gunIndex ? LEFT_GUN_NUM : RIGHT_GUN_NUM)); } else { pDcInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); } if (pSysInfo->SelfTestSeq != _STEST_FAIL && !IntoOperateProcess(pDcInfo->SystemStatus)) { log_info("Gun%d into UNKOWN status, Dispenser will soft reset",gunIndex); TryCloseWatchdog(); system("/usr/bin/run_evse_restart.sh"); } }//switch }//for //if (pSysInfo->SystemPage != _LCM_VIEW) //ChangeLcmByIndex(pSysInfo->SystemPage); TryFeedWatchdog(); usleep(WHILE_LOOP_TIME); } return FAIL; }