#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 = "V1.24.01.0000.00"; char* DebugVersion = "V1.24.1"; //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); void GetClockTime(struct timespec *_now_time, void *null); unsigned long GetClockTimeoutValue(struct timespec _start_time); 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 PrimaryLedIndicatorCtrlFork(void); extern void ChkPrimaryStatus(void); //RFID.c extern void CreateRfidFork(void); extern void ScannerCardProcess(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) { #if defined DD360Audi pSysInfo->SystemPage = _LCM_SELECT_GUN; return; #endif //defined DD360Audi pSysInfo->SystemPage = _LCM_NONE; } static void connectorPageRestoreIdle(void) { #if defined DD360Audi pSysInfo->ConnectorPage = _LCM_SELECT_GUN; return; #endif //defined DD360Audi pSysInfo->ConnectorPage = _LCM_IDLE; } //------------------------------------------------------------------------------ void destroySelGun(uint8_t curGun) { uint8_t i = 0; uint8_t totalGun = pSysConfig->TotalConnectorCount; #if !defined DD360Audi return; #endif //!defined DD360Audi //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_SELECT_GUN); 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) { #ifdef DD360Audi changeLcmPage(_LCM_SELECT_GUN); #endif } 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) { #ifdef DD360Audi changeLcmPage(_LCM_SELECT_GUN); #endif } 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 !defined DD360Audi return PASS; #endif //!defined DD360Audi if ((curGun == RIGHT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_ATHOR)) { return PASS; } return FAIL; } static int waitLeftGunPlugIt(uint8_t curGun) { #if !defined DD360Audi return PASS; #endif //!defined DD360Audi if ((curGun == LEFT_GUN_NUM) && (ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_ATHOR)) { return PASS; } return FAIL; } void setSelGunWaitToAuthor(uint8_t curSel) { #if !defined DD360Audi return; #endif //!defined DD360Audi if (curSel == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_ATHOR; //printf("setSelGunWaitToAuthor left"); StopGunInfoTimeoutDet(curSel); } else if (curSel == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_ATHOR; //printf("setSelGunWaitToAuthor right"); StopGunInfoTimeoutDet(curSel); } } int getConfirmSelectedGun(uint8_t curSel) { #if !defined DD360Audi return PASS; #endif //!defined DD360Audi 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 !defined DD360Audi return; #endif //!defined DD360Audi if (selGun == LEFT_GUN_NUM) { ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_CONFIRM; StopGunInfoTimeoutDet(selGun); //printf("confirmSelGun left"); } else if (selGun == RIGHT_GUN_NUM) { ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_CONFIRM; StopGunInfoTimeoutDet(selGun); //printf("confirmSelGun right"); } // AUDI_LCM_CHANGE changeLcmPage(_LCM_IDLE); StartGunInfoTimeoutDet(selGun, Timeout_SelectGun); } 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"); } } bool isCharging(uint8_t status) { if ((status >= S_REASSIGN_CHECK && status <= S_CHARGING) || status == S_CCS_PRECHARGE_ST0 || status == S_CCS_PRECHARGE_ST1 ) { return TRUE; } return FALSE; } static void checkGunOTPState(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //log_info("OTP:%d OTPR%d",pSysInfo->OTPTemp,pSysInfo->OTPTempR); //水冷機溫度檢測 if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) { if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) { // 單水冷機 // Chiller OTP if (pDcChargingInfo->ChillerTemp == UNDEFINED_TEMP) { // 溫度為255時判斷Sensor fail ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES; } else { //判斷OTP if ((ShmDcCommonData->SystemTemp[0] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[0] != UNDEFINED_TEMP) || (ShmDcCommonData->SystemTemp[1] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[1] != UNDEFINED_TEMP)) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES; RecordAlarmCode(gunIndex, "012323"); } else if (ShmDcCommonData->SystemTemp[0] != 0 && ShmDcCommonData->SystemTemp[0] < pSysInfo->OTPTempR && ShmDcCommonData->SystemTemp[1] != 0 && ShmDcCommonData->SystemTemp[1] < pSysInfo->OTPTempR) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; } //判斷Tube OTP if ((ShmDcCommonData->SystemTemp[2] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[2] != UNDEFINED_TEMP)|| (ShmDcCommonData->SystemTemp[3] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[3] != UNDEFINED_TEMP)) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES; RecordAlarmCode(gunIndex, "012332"); } else if (ShmDcCommonData->SystemTemp[2] != 0 && ShmDcCommonData->SystemTemp[2] < pSysInfo->OTPTempR && ShmDcCommonData->SystemTemp[3] != 0 && ShmDcCommonData->SystemTemp[3] < pSysInfo->OTPTempR) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO; } ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO; } } else { // 雙水冷機 if (pDcChargingInfo->ChillerTemp == UNDEFINED_TEMP) { // 溫度為255時判斷Sensor fail ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES; } else { //判斷OTP if (ShmDcCommonData->SystemTemp[gunIndex*2] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[gunIndex*2] != UNDEFINED_TEMP) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES; RecordAlarmCode(gunIndex, "012323"); } else if (ShmDcCommonData->SystemTemp[gunIndex*2] != 0 && ShmDcCommonData->SystemTemp[gunIndex*2] < pSysInfo->OTPTempR) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = NO; } if (ShmDcCommonData->SystemTemp[gunIndex*2+1] >= pSysInfo->OTPTemp && ShmDcCommonData->SystemTemp[gunIndex*2+1] != UNDEFINED_TEMP) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = YES; RecordAlarmCode(gunIndex, "012332"); } else if (ShmDcCommonData->SystemTemp[gunIndex*2+1] != 0 && ShmDcCommonData->SystemTemp[gunIndex*2+1] < pSysInfo->OTPTempR) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTubeOTP = NO; } ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = NO; } } if (pFaultCode->FaultEvents.bits.CcsLiquidChillerWaterLevelFault == YES) { RecordAlarmCode(gunIndex, "011037"); } } switch (pDcChargingInfo->Type) { case _Type_Chademo: if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) { if (pDcChargingInfo->ConnectorTemp >= pSysInfo->OTPTemp) { RecordAlarmCode(gunIndex, "012229"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < pSysInfo->OTPTempR) { //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 >= pSysInfo->OTPTemp) { RecordAlarmCode(gunIndex, "012230"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < pSysInfo->OTPTempR) { //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 >= pSysInfo->OTPTemp) { RecordAlarmCode(gunIndex, "012231"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES; } else if (pDcChargingInfo->ConnectorTemp != 0 && pDcChargingInfo->ConnectorTemp < pSysInfo->OTPTempR) { //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; } } 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; } #if 0 //uint8_t gunIndex = 0; //for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == YES) { pAlarmCode->AlarmEvents.bits.SystemChillerOTP = YES; //log_info("SystemChillerOTP = %d", pAlarmCode->AlarmEvents.bits.SystemChillerOTP); return ABNORMAL; } else { pAlarmCode->AlarmEvents.bits.SystemChillerOTP = NO; } if (ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == YES) { pFaultCode->FaultEvents.bits.ChillerTempSensorBroken = YES; return ABNORMAL; } else { pFaultCode->FaultEvents.bits.ChillerTempSensorBroken = NO; } //} // return NORMAL; #endif //0 } 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 || page_index == _LCM_COMPLETE || page_index == _LCM_FIX ) { pSysInfo->PageIndex = page_index; } } //====================================================== // 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"); #if defined DD360 || defined DD360Audi || defined DD360ComBox return ; #endif //defined DD360 || defined DD360Audi || defined DD360ComBox /* (C14) EMU0.gpio3[7] */ /*CP open/short feature enable/disable, pull low for default enable*/ system("echo 103 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio103/direction"); system("echo 0 > /sys/class/gpio/gpio103/value"); /* (B14) EMU1.gpio3[8] */ /*4G module reset, pull high to reset when entry kernel, after Application start, it should be pull low.*/ system("echo 104 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio104/direction"); system("echo 0 > /sys/class/gpio/gpio104/value"); } 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(); // system("echo 1 > /sys/class/gpio/gpio110/value"); //reset PHY // sleep(3); // system("/sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 down"); // sleep(1); // system("/sbin/ifconfig eth1 192.168.0.10 netmask 255.255.255.0 up"); 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 // AC Contact 未搭上 pAlarmCode->AlarmEvents.bits.AcContactStestFail = true; result = true; #endif // !defined DD360 && !defined DD360Audi && !defined DD360ComBox } else if (ShmPsuData->SystemAvailablePower <= 0 && ShmPsuData->SystemAvailableCurrent <= 0) { // PSU 通訊問題 pAlarmCode->AlarmEvents.bits.PsuModuleStestFail = true; result = true; } return result; } #if 0 //not use int StoreUsrConfigData(struct SysConfigData *UsrData) { int result = PASS; int fd, wrd; unsigned int i, Chk; uint8_t *ptr, *BufTmp; Chk = 0; ptr = (uint8_t *)UsrData; if ((BufTmp = malloc(MtdBlockSize)) != NULL) { memset(BufTmp, 0, MtdBlockSize); memcpy(BufTmp, ptr, sizeof(struct SysConfigData)); for (i = 0; i < MtdBlockSize - 4; i++) { Chk += *(ptr + i); } memcpy(BufTmp + MtdBlockSize - 4, &Chk, 4); fd = open("/dev/mtdblock10", O_RDWR); if (fd > 0) { wrd = write(fd, BufTmp, MtdBlockSize); close(fd); if (wrd >= MtdBlockSize) { fd = open("/dev/mtdblock11", O_RDWR); if (fd > 0) { wrd = write(fd, BufTmp, MtdBlockSize); close(fd); if (wrd < MtdBlockSize) { log_error("write /dev/mtdblock11(backup) NG"); result = FAIL; } } else { log_error("open /dev/mtdblock11(backup) NG"); result = FAIL; } } else { log_error("write /dev/mtdblock10 NG"); result = FAIL; } } else { log_error("open /dev/mtdblock10 NG"); result = FAIL; } } else { log_error("alloc BlockSize NG"); result = FAIL; } if (BufTmp != NULL) { free(BufTmp); } return result; } #endif //0 //=============================================== // 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) { if (pSysConfig->TotalConnectorCount == 1 && gunIndex == RIGHT_GUN_NUM) return; ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit = NO; //DS60-120 add pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if (pDcChargingInfo->RemoteStartFlag == YES) { pDcChargingInfo->RemoteStartFlag = NO; } if (pSysInfo->OrderCharging != NO_DEFINE) { pSysInfo->OrderCharging = NO_DEFINE; } } void DetectPluginStart(int gunIndex) { //pSysInfo->WaitForPlugit = YES; if (pSysConfig->TotalConnectorCount == 1 && gunIndex == RIGHT_GUN_NUM) return; ShmDcCommonData->pGunInfo[gunIndex].WaitForPlugit = YES; log_info("Gun%d start detect plug in",gunIndex); } bool isDetectPlugin(int gunIndex) { if (pSysConfig->TotalConnectorCount == 1 && gunIndex == RIGHT_GUN_NUM) return false; 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); pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); if (pSysInfo->PageIndex == _LCM_WAIT_FOR_PLUG) { if (pDcChargingInfo->RemoteStartFlag) { ClearDetectPluginFlag(gunIndex); } else { ClearDetectPluginFlag(0); ClearDetectPluginFlag(1); } } else if (pSysInfo->PageIndex == _LCM_AUTHORIZ_COMP) { if (pDcChargingInfo->RemoteStartFlag) { DetectPluginStart(gunIndex); } else { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(LEFT_GUN_NUM); if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) DetectPluginStart(LEFT_GUN_NUM); if (pSysConfig->TotalConnectorCount > 1) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(RIGHT_GUN_NUM); if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) DetectPluginStart(RIGHT_GUN_NUM); } } } usleep(50000); systemPageRestoreInit(); } 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. "); sleep(3); system("/usr/bin/run_evse_restart.sh"); } void _AuthorizedTimeout(void) { if (IsAuthorizingMode()) { log_info("*********** _AuthorizedTimeout *********** "); //isCardScan = false; SetIsCardScan(false); pSysInfo->SystemPage = _LCM_AUTHORIZ_FAIL; //ChangeLcmByIndex(_LCM_AUTHORIZ_FAIL); strcpy((char *)pSysConfig->UserId, ""); ClearAuthorizedFlag(); } } void _DetectPlugInTimeout(int gunIndex) { strcpy((char *)pSysConfig->UserId, ""); uint8_t is_remote = NO; for (int i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i); if (pDcChargingInfo->RemoteStartFlag) { //此停止為remote start停止 is_remote = YES; break; } } if (is_remote) { // Remote start進入充電 log_info("Clear Gun%d Remote start detect plugin flag",gunIndex); StopGunInfoTimeoutDet(gunIndex); ClearDetectPluginFlag(gunIndex); } else { log_info("Clear Gun%d RFID detect plugin flag", gunIndex); // 刷卡進入充電 ClearDetectPluginFlag(LEFT_GUN_NUM); ClearDetectPluginFlag(RIGHT_GUN_NUM); StopGunInfoTimeoutDet(LEFT_GUN_NUM); StopGunInfoTimeoutDet(RIGHT_GUN_NUM); } sleep(1); //等待DoComm回報插槍訊號給主櫃 #if defined DD360Audi //pSysInfo->SystemPage = _LCM_COMPLETE; setChargerMode(gunIndex, S_TERMINATING); #elif DD360 || DD360Combox setChargerMode(gunIndex, S_IDLE); #endif 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) ***********"); } } ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(gunIndex); } void _DetectEvseChargingEnableTimeout(uint8_t gunIndex) { log_info("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********"); //if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS) { #if defined DD360Audi //pSysInfo->SystemPage = _LCM_COMPLETE; setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING); #elif DD360 || DD360Combox setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE); #endif _AutoReturnTimeout(gunIndex); } } void _PrepareTimeout(uint8_t gunIndex) { log_info("*********** _PrepareTimeout ***********"); #if defined DD360Audi //pSysInfo->SystemPage = _LCM_COMPLETE; setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING); #elif DD360 || DD360Combox setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE); #endif pAlarmCode->AlarmEvents.bits.PsuNoResource = YES; _AutoReturnTimeout(gunIndex); } void _CcsPrechargeTimeout(uint8_t gunIndex) { log_info("*********** _CcsPrechargeTimeout ***********"); #if defined DD360Audi //pSysInfo->SystemPage = _LCM_COMPLETE; setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING); #elif DD360 || DD360Combox setChargerMode(pSysInfo->CurGunSelected, S_COMPLETE); pSysInfo->SystemPage = _LCM_COMPLETE; return; #endif } //=============================================== // 取得卡號與卡號驗證 //=============================================== 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, "", 6) != EQUAL) { // if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail == NO && // ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail == NO && // ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP == NO && // ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail == NO // ) { // strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6); // } //} if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012229", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012230", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012231", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011011", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011013", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011015", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011012", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011014", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011016", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011018", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011019", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011020", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL) { strncpy((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6); } } 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) { pDcChargingInfo->StopChargeFlag = YES; } } #if 0 if (strcmp(code, "012234") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = YES; } else if (strcmp(code, "012235") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdTrip = YES; } else if (strcmp(code, "012236") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdTrip = YES; } else if (strcmp(code, "012288") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSUvpFail = YES; } else if (strcmp(code, "012289") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = YES; } else if (strcmp(code, "012290") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTUvpFail = YES; } else if (strcmp(code, "012229") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOTP = YES; } else if (strcmp(code, "012230") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectOTP = YES; } else if (strcmp(code, "012231") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectOTP = YES; } else if (strcmp(code, "012296") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = YES; } else if (strcmp(code, "012297") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSGfdWarning = YES; } else if (strcmp(code, "012298") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTGfdWarning = YES; } else if (strcmp(code, "011011") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = YES; } else if (strcmp(code, "011013") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = YES; } else if (strcmp(code, "011015") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = YES; } else if (strcmp(code, "011012") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = YES; } else if (strcmp(code, "011014") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = YES; } else if (strcmp(code, "011016") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = YES; } else if (strcmp(code, "011018") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail = YES; } else if (strcmp(code, "011019") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail = YES; } else if (strcmp(code, "011020") == EQUAL) { ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail = YES; } else if (strcmp(code, "012323") == EQUAL) { if ((gunIndex == 0) && ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)) ) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES; } else if ((gunIndex == 1) && ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)) ) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerOTP = YES; } } else if (strcmp(code, "011038") == EQUAL) { if ((gunIndex == 0) && ((strncmp((char *)&pSysConfig->ModelName[7], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[7], "F", 1) == 0)) ) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES; } else if ((gunIndex == 1) && ((strncmp((char *)&pSysConfig->ModelName[9], "V", 1) == 0) || (strncmp((char *)&pSysConfig->ModelName[9], "F", 1) == 0)) ) { ShmDcCommonData->ChillerTempErr[gunIndex].StatusBit.ChillerTempSensorFail = YES; } } #endif } void ReleaseAlarmCode(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "", 6) == EQUAL) { // return; //} #if 0 // 回 idle 後主要清除 GFD Trip、UVP、OVP、GFD Warning if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } #endif switch (pDcChargingInfo->Type) { case _Type_Chademo: ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdTrip = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaUvpFail = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectOVP = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaGfdWarning = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO; #if 0 if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012234", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012289", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012217", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012296", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } #endif break; case _Type_CCS_2: 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; #if 0 if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012235", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012288", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012219", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012297", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } #endif break; case _Type_GB: 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; #if 0 if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012236", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012290", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012221", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012298", 6) == EQUAL) { memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } #endif break; } #if 0 //system alarm if (strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012251", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012252", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012238", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012304", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "012323", 6) == EQUAL || strncmp((char *)pDcChargingInfo->ConnectorAlarmCode, "011038", 6) == EQUAL ) { memset(pDcChargingInfo->ConnectorAlarmCode, 0, sizeof(pDcChargingInfo->ConnectorAlarmCode)); } #endif memcpy(pDcChargingInfo->ConnectorAlarmCode, "", 6); } //=============================================== // EmergencyStop and Charging Stop //=============================================== void ChargingTerminalProcess(uint8_t gunIndex) { setChargerMode(gunIndex, MODE_TERMINATING); } void ChargingAlarmProcess(uint8_t gunIndex) { 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 #if defined DD360 ||defined DD360Audi || defined DD360ComBox //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, "042200", 6) == EQUAL || strncmp(code, "042201", 6) == EQUAL || strncmp(code, "042202", 6) == EQUAL || strncmp(code, "042267", 6) == EQUAL) #endif //defined DD360 || defined DD360Audi { 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); } } #if defined DD360 ||defined DD360Audi || defined DD360ComBox StopChargingProcessByString(level); InformOcppErrOccur(4); #endif //defined DD360 || defined DD360Audi } } 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; } else if (strncmp(code, "012348", 6) == 0 && pAlarmCode->AlarmEvents.bits.ChillerAlarmFail == YES) { isTrigger = true; pAlarmCode->AlarmEvents.bits.ChillerAlarmFail = 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); } //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); //} } } //=============================================== // 確認 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 &"); if (pSysConfig->ModelName[3] == 'P') system("/root/Module_DcMeter &"); system("/root/Module_DoComm &"); return PASS; } void KillTask(void) { ChangeLcmByIndex(_LCM_FIX); 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"); if (pSysConfig->ModelName[3] == 'P') system("killall Module_DcMeter"); //system("killall Module_DoComm"); return ; } void KillTaskExceptPrimary(void) { ChangeLcmByIndex(_LCM_FIX); system("killall Module_EvComm"); system("killall Module_InternalComm"); if (pSysConfig->ModelName[3] == 'P') system("killall Module_DcMeter"); #if defined DD360 || defined DD360Audi || defined DD360ComBox return; #endif //defined DD360 || defined DD360Audi || defined DD360ComBox system("killall Module_PsuComm"); system("killall Module_4g &"); system("killall Module_Wifi &"); } void KillAllTask(void) { ChangeLcmByIndex(_LCM_FIX); 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"); if (pSysConfig->ModelName[3] == 'P') system("killall Module_DcMeter"); #if defined DD360 || defined DD360Audi || defined DD360ComBox system("killall Module_DoComm"); return ; #endif //defined DD360 || defined DD360Audi || defined DD360ComBox system("killall Module_PsuComm"); system("killall OcppBackend &"); system("killall Module_4g &"); system("killall Module_Wifi &"); } void StartSystemTimeoutDet(uint8_t flag) { if (pSysInfo->SystemTimeoutFlag != flag) { GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL); //log_info("Start System Timeout: %d",flag); } 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) { gettimeofday(&pDcChargingInfo->TimeoutTimer, NULL); //log_info("Start Gun%d Info timeout: %d",gunIndex,flag); } pDcChargingInfo->TimeoutFlag = flag; } } void checkLanguagePageTimeout(void) { int is_idle = TRUE; for (int i = 0; i < pSysConfig->TotalConnectorCount; i++) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(i); if (pDcChargingInfo->SystemStatus != S_IDLE) is_idle = FALSE; } if (is_idle) pSysInfo->SystemPage = _PAGE_VIEW; else pSysInfo->SystemPage = _PAGE_SELECT_PAY; } void StopGunInfoTimeoutDet(uint8_t gunIndex) { if (gunIndex < pSysConfig->TotalConnectorCount) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); pDcChargingInfo->TimeoutFlag = Timeout_None; } } void CheckConnectionTimeout(void) { #if defined DD360 || defined DD360Audi || defined DD360ComBox if (ShmSelectGunInfo->RemoteSetup.ConnectionTimeout != 0) { //Jerry add _connectionTimeout = ShmSelectGunInfo->RemoteSetup.ConnectionTimeout; } else { _connectionTimeout = CONN_PLUG_TIME_OUT; } return; #endif //defined DD360 || defined DD360Audi || defined DD360ComBox if (system("pidof -s OcppBackend > /dev/null") != 0) { _connectionTimeout = CONN_PLUG_TIME_OUT; } else { if (strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData, "") != 0) { _connectionTimeout = atoi((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData); if (_connectionTimeout <= 0) { _connectionTimeout = CONN_PLUG_TIME_OUT; } } else { _connectionTimeout = CONN_PLUG_TIME_OUT; } } } void _evccidlinktimeout(uint8_t gunIndex) { log_info("Getting EVCCID Timeout"); pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); pDcChargingInfo->isEVCCIDVerify = true; StopGunInfoTimeoutDet(gunIndex); destroySelGun(pSysInfo->CurGunSelected); connectorPageRestoreIdle(); } void CreateTimeoutFork(void) { pid_t timeoutPid; timeoutPid = fork(); if (timeoutPid == 0) { gettimeofday(&_cmdSubPriority_time, NULL); CheckConnectionTimeout(); log_info("Timeout Fork Child's PID is %d", getpid()); while (1) { if ((GetTimeoutValue(_cmdSubPriority_time) / 1000) > 5000) { CheckConnectionTimeout(); gettimeofday(&_cmdSubPriority_time, NULL); } //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) { log_error("Timeout_ReturnViewPage"); StopSystemTimeoutDet(); pSysInfo->SystemPage = _PAGE_VIEW; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected); if (pDcChargingInfo->SystemStatus == S_AUTHORIZING || pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) { setChargerMode(pSysInfo->CurGunSelected, MODE_IDLE); } } break; case Timeout_helpPage: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= HELP_PAGE_TIMEOUT) { StopSystemTimeoutDet(); pSysInfo->SystemPage = ShmDcCommonData->previousPage; } break; case Timeout_LanguagePage: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= LANGUAGE_PAGE_TIMEOUT) { StopSystemTimeoutDet(); checkLanguagePageTimeout(); } break; case Timeout_Authorizing: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) { log_error("Authorizing Timeout"); _AuthorizedTimeout(); StopSystemTimeoutDet(); destroySelGun(pSysInfo->CurGunSelected); 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"); //sleep(1); //system("/root/Module_DoComm &"); } } break; case Timeout_WaitBalance: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= BALANCE_TIMEOUT) { log_error("Wait Balance timeout"); _AuthorizedTimeout(); StopSystemTimeoutDet(); destroySelGun(pSysInfo->CurGunSelected); 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) { _AutoReturnTimeout(pSysInfo->CurGunSelected); StopSystemTimeoutDet(); destroySelGun(pSysInfo->CurGunSelected); 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"); //sleep(1); //system("/root/Module_DoComm &"); } } break; case Timeout_VerifyComp: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_COMP_TIMEOUT) { _AutoReturnTimeout(pSysInfo->CurGunSelected); StopSystemTimeoutDet(); } break; case Timeout_ReturnToChargingGunDet: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) { #if defined DD360Audi if (getCurLcmPage() != _LCM_PRE_CHARGE && getCurLcmPage() != _LCM_CHARGING && getCurLcmPage() != _LCM_COMPLETE) { destroySelGun(pSysInfo->CurGunSelected); //jerry add } #endif //defined DD360Audi DisplayChargingInfo(); StopSystemTimeoutDet(); } break; case Timeout_AuthorizingForStop: if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) { strcpy((char *)pSysConfig->UserId, ""); ClearAuthorizedFlag(); StopSystemTimeoutDet(); } break; } // 各槍 for (uint8_t gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); //log_info("Timeout ***********Gun %d TimeoutFlag = %d(%d) ********",gunIndex,pDcChargingInfo->TimeoutFlag, // GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL); switch (pDcChargingInfo->TimeoutFlag) { case Timeout_EVCCID_Link: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= EVCCID_LINK_TIMEOUT) { _evccidlinktimeout(gunIndex); } break; case Timeout_WaitPlug: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= _connectionTimeout) { log_info("*********** Gun%d _DetectPlugInTimeout *********** ", gunIndex); _DetectPlugInTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); } break; case Timeout_Preparing: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_PREPARE_TIMEOUT) { _PrepareTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvChargingDet: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_EV_WAIT_TIMEOUT) { _DetectEvChargingEnableTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvseChargingDet: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_EVSE_WAIT_TIMEOUT) { _DetectEvseChargingEnableTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_EvseCompleteDet: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_COMP_WAIT_TIMEOUT) { StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_ForCcsPrechargeDet: if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= GUN_PRECHARGING_TIMEOUT) { _CcsPrechargeTimeout(gunIndex); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } break; case Timeout_SelectGun: //Jerry add if (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL >= SEL_GUN_TIMEOUT) { log_info("Timeout_SelectGun"); StopGunInfoTimeoutDet(gunIndex); destroySelGun(gunIndex); //jerry add } 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 OcppStartTransation(uint8_t gunIndex) { #if defined DD360 || defined DD360Audi || defined DD360ComBox return; #endif //defined DD360 || defined DD360Audi || defined DD360ComBox 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->StartTransaction[_OcppGunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, (char *)pDcChargingInfo->StartUserId); } log_info("IdTag = %s ", ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[_OcppGunIndex].StartTransactionReq = YES; } 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; for (uint8_t ac_index = 0; ac_index < pSysConfig->AcConnectorCount; ac_index++) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(ac_index); if (!isDetectPlugin(acDirIndex)) { 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 (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) { if (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) { pDcChargingInfo->RemoteStartFlag = YES; pSysInfo->OrderCharging = YES; //pSysInfo->OrderCharging = gunIndex; ShmOCPP16Data->CsMsg.bits[_index].RemoteStartTransactionReq = NO; DetectPluginStart(_index); #if defined DD360Audi setSelGunWaitToAuthor(_index); //Jerry add #endif //defined DD360Audi } 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_info("***************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_info("***************ChkOcppStatus : Cancel OcppReservedStatus******************** "); pDcChargingInfo->ReservationId = 0; pDcChargingInfo->SystemStatus = S_IDLE; } ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationConf = YES; } if (ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq == YES) { log_info("***************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; } } } /*else if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) { // 隨插即充電的要看 offline if (pSysConfig->OfflineMaxChargeDuration > 0) { if (pDcChargingInfo->PresentChargedDuration > (pSysConfig->OfflineMaxChargeDuration * 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; } } }/* else if (pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE) { // 隨插即充電的要看 offline if (pSysConfig->OfflineMaxChargeEnergy > 0) { if (pDcChargingInfo->PresentChargedEnergy > (pSysConfig->OfflineMaxChargeEnergy)) { 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 (strcmp((char *)pSysConfig->ModelName, "DWWU301J0UT1PH") == EQUAL || strcmp((char *)pSysConfig->ModelName, "DWYE301J0ET1PH") == EQUAL || strcmp((char *)pSysConfig->ModelName, "DSYE301J3EW2PH") == EQUAL || strcmp((char *)pSysConfig->ModelName, "DWYC301J0UW1PH") == EQUAL) { */ if (pSysConfig->ModelName[1] == 'W') { //DS60-120 // 壁掛 pSysInfo->IsAlternatvieConf = YES; } else { pSysInfo->IsAlternatvieConf = NO; } } void StopProcessingLoop() { 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 task processing //========================================== void CheckTask() { /*+++ 20200908, vern, disable it for DD360 +++*/ #if 0 if (pSysConfig->ModelName[10] == 'T') { if (system("pidof -s Module_4g > /dev/null") != 0) { log_error("Module_4g not running, restart it."); system("/root/Module_4g &"); } } else if (pSysConfig->ModelName[10] == 'W') { if (system("pidof -s Module_Wifi > /dev/null") != 0) { log_error("Module_Wifi not running, restart it."); system("/root/Module_Wifi &"); } } if (strcmp((char *)pSysConfig->OcppServerURL, "") != EQUAL && strcmp((char *)pSysConfig->ChargeBoxId, "") != EQUAL) { if (system("pidof -s OcppBackend > /dev/null") != 0) { log_error("OcppBackend not running, restart it."); system("/root/OcppBackend &"); } } #endif //0 /*--- 20200908, vern, disable it for DD360 ---*/ /* if (system("pidof -s Module_ProduceUtils > /dev/null") != 0) { log_error("Module_ProduceUtils not running, restart it."); system ("/root/Module_ProduceUtils &"); }*/ } //========================================== // 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; } //DS60-120 remove //log_info("*********Limit = %f ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit); //pDcChargingInfo->ChargingProfileCurrent = ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * 10; //pDcChargingInfo->ChargingProfilePower = ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * pDcChargingInfo->EvBatterytargetVoltage / 100; //pDcChargingInfo->ChargingProfilePower = ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * AC_OUTPUT_VOL; // if ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0) // { // pDcChargingInfo->ChargingProfileCurrent = pDcChargingInfo->ChargingProfilePower / (pDcChargingInfo->EvBatterytargetVoltage * 10); // } } 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); } // // printf("-------------Schedule------------"); // printf("index = %d ", _index); // printf("StartSchedule = %s ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.StartSchedule); // printf("ChargingRateUnit = %s ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingRateUnit); // printf("----------SchedulePeriod---------"); // for (int v = 0; v < 10; v++) // { // printf("StartPeriod = %d ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[v].StartPeriod); // printf("Limit = %f ", ShmOCPP16Data->SmartChargingProfile[_index].ChargingSchedule.ChargingSchedulePeriod[v].Limit); // } // printf("---------------------------------"); } 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_AUTHORIZING && pSysInfo->PageIndex != _LCM_AUTHORIZ_FAIL && pSysInfo->PageIndex != _LCM_AUTHORIZ_COMP && pSysInfo->PageIndex != _LCM_WAIT_FOR_PLUG) { 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; 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; } } } char OldUseId[32] = {0}; static void autoStartCharging(uint8_t gunIndex) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); if ( (pSysInfo->SystemPage >= _LCM_AUTHORIZING && pSysInfo->SystemPage <= _LCM_AUTHORIZ_FAIL) || 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) { #ifdef DD360Audi // LCM show linking pic. & timeout 2 min if( pSysInfo->CurGunSelected == gunIndex ) { systemPageRestoreInit(); pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } StartGunInfoTimeoutDet(gunIndex,Timeout_EVCCID_Link); #endif // Getting EVCCID if( strcmp( (char *)pDcChargingInfo->EVCCID, "" ) != EQUAL ) { log_info("Authorizing EVCCID"); StopSystemTimeoutDet(); strcpy((char *)pSysConfig->UserId, (char *)pDcChargingInfo->EVCCID); pSysInfo->CurGunSelected = gunIndex; ChangeGunSelectByIndex(gunIndex); confirmSelGun(gunIndex); pDcChargingInfo->isEVCCIDVerify = true; ShmDcCommonData->AuthroizeType = IdTokenType_MacAddress; pSysInfo->SystemPage = _LCM_AUTHORIZING; } } else return; } else { strcpy((char *)&pSysConfig->UserId, "AutoStartCharging"); pSysInfo->CurGunSelected = gunIndex; ChangeGunSelectByIndex(gunIndex); confirmSelGun(gunIndex); pSysInfo->SystemPage = _LCM_AUTHORIZING; ShmDcCommonData->AuthroizeType = IdTokenType_NoAuthorization; pDcChargingInfo->StartMethod = _CHARGING_START_AUTOSTART; } if (strcmp( (char *)pSysConfig->UserId , OldUseId ) != EQUAL) { strcpy((char *)OldUseId, (char *)pSysConfig->UserId); log_info("Get User(%d) ID:%s",gunIndex,pSysConfig->UserId); } }else if (pDcChargingInfo->ConnectorPlugIn == NO && pDcChargingInfo->Type == _Type_CCS_2) { strcpy((char *)OldUseId, ""); } } static bool PrecheckIsPass(uint8_t gunIndex) { bool result = true; // relay welding or driving 是反向 result = !ShmDcCommonData->GunRelayWeldingOccur[gunIndex]; return result; } static void ReviewCriticalAlarm(void) { if (//ShmDcCommonData->GunRelayDrivingOccur[0] == YES || //ShmDcCommonData->GunRelayDrivingOccur[1] == YES || //ShmDcCommonData->GunRelayWeldingOccur[0] == YES || //ShmDcCommonData->GunRelayWeldingOccur[1] == YES || pAlarmCode->AlarmEvents.bits.EmergencyStopTrip == YES || pAlarmCode->AlarmEvents.bits.MainPowerBreakerTrip == YES || pAlarmCode->AlarmEvents.bits.DoorOpen == YES || 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 { 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; #if 0 if (pDcChargingInfo->Type == _Type_Chademo) { //ResetChargerAlarmCode(gunIndex, "011012"); //ResetChargerAlarmCode(gunIndex, "011011"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaRelayDrivingFault = NO; } else if (pDcChargingInfo->Type == _Type_CCS_2) { //ResetChargerAlarmCode(gunIndex, "011014"); //ResetChargerAlarmCode(gunIndex, "011013"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSRelayDrivingFault = NO; } else if (pDcChargingInfo->Type == _Type_GB) { //ResetChargerAlarmCode(gunIndex, "011016"); //ResetChargerAlarmCode(gunIndex, "011015"); ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayWeldingFault = NO; ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTRelayDrivingFault = NO; } #endif } } static void isChargingAverageState(void) { if (pSysInfo->MainChargingMode != _MAIN_CHARGING_MODE_AVER) { pSysInfo->ReAssignedFlag = _REASSIGNED_NONE; return; } #if !defined DD360 && !defined DD360Audi && !defined DD360ComBox if (pSysInfo->AcContactorStatus != YES) { pSysInfo->MainChargingMode = _MAIN_CHARGING_MODE_MAX; pSysInfo->ReAssignedFlag = _REASSIGNED_NONE; } #endif //!defined DD360 && !defined DD360Audi // 均充 -> 最大充 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; } } static uint8_t distributionPsuModule(uint8_t *isRessign, uint8_t gunIndex) { #if defined DD360 || defined DD360Audi || defined DD360ComBox return NO; #endif // defined DD360 || defined DD360Audi || defined DD360ComBox uint8_t index = 0; struct ChargingInfoData *pDcChargingInfo = NULL; if (pSysConfig->TotalConnectorCount <= 1 && pSysInfo->IsAlternatvieConf != NO) { return NO; } if (pSysInfo->MainChargingMode == _MAIN_CHARGING_MODE_MAX) { for (index = 0; index < pSysConfig->TotalConnectorCount; index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); // 有其他槍已經分配好 psu 模塊 if (pSysInfo->CurGunSelected != index && pDcChargingInfo->SystemStatus >= S_PREPARNING && pDcChargingInfo->SystemStatus != S_MAINTAIN) { log_info("=============Smart Charging============= Step 1 "); pSysInfo->ReAssignedFlag = _REASSIGNED_PREPARE_M_TO_A; *(isRessign) = YES; break; } } } else if (pSysInfo->MainChargingMode == _MAIN_CHARGING_MODE_AVER && pSysInfo->ReAssignedFlag != _REASSIGNED_NONE) { // 如果在切換最大充的過程中,需等待最大充切換完成後,在走均充流程 if (pSysInfo->BridgeRelayStatus == YES) { 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; return YES; } } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } return YES; } return NO; } 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 ) { while(1) { sleep(3); unsigned char count = GetProcessCount("Module_ChkSysTask"); if( count != 1 ) { system("pkill Module_ChkSysTask"); sleep(10); 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 ((sysStatus == S_ALARM || // sysStatus == S_TERMINATING) && // isEvStopCharging_chademo(gunIndex) == YES) { // /*+++ 20200908, vern, disable it for DD360 +++*/ // if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { // strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); // /*--- 20200908, vern, disable it for DD360 ---*/ // } //} 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; } //else if (sysStatus == S_CHARGING && // ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 && // pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || // (pDcChargingInfo->PresentChargedDuration >= 10 && // pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL) // ) { // // UVP // RecordAlarmCode(gunIndex, "012289"); // ChargingTerminalProcess(gunIndex); //} 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 (isEvStopCharging_chademo(gunIndex) == YES) { // /*+++ 20200908, vern, disable it for DD360 +++*/ // if ((sysStatus == S_ALARM || // sysStatus == S_TERMINATING) && // strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL // ) { // strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); // } // /*--- 20200908, vern, disable it for DD360 ---*/ //} 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; } //else if (sysStatus == S_CHARGING && // isPrechargeStatus_gb(gunIndex) == 10 && // (((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 && // pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || // (pDcChargingInfo->PresentChargedDuration >= 10 && // pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL)) // ) { // // UVP // RecordAlarmCode(gunIndex, "012290"); // ChargingTerminalProcess(gunIndex); //} 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 (isEvStopCharging_chademo(gunIndex) == YES) { // /*+++ 20200908, vern, disable it for DD360 +++*/ // if ((sysStatus == S_ALARM || // sysStatus == S_TERMINATING) && // (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) // ) { // strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); // } // /*--- 20200908, vern, disable it for DD360 ---*/ //} 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; } //else if (sysStatus == S_CHARGING && // ((pDcChargingInfo->EvBatterytargetVoltage * 10) > 0 && // pDcChargingInfo->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || // (pDcChargingInfo->PresentChargedDuration >= 10 && // pDcChargingInfo->PresentChargingVoltage < SYSTEM_MIN_VOL) // ) { // // UVP // RecordAlarmCode(gunIndex, "012288"); // ChargingTerminalProcess(gunIndex); //} 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) { ChargingAlarmProcess(gunIndex); } else if (evBoardStopState == POWER_CABINET_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"); } } ChargingTerminalProcess(gunIndex); } else if (OcppRemoteStop(gunIndex) == YES || WifiScheduleStop(gunIndex)) { // 後臺要求停止 ChargingTerminalProcess(gunIndex); } } void showversion() { uint8_t index = 0; log_info("\t========= Charger info ========= "); log_info("\tSW Version = %s", fwVersion); log_info("\tDebug Version = %s",DebugVersion); log_info("\tModelName = %s", pSysConfig->ModelName); log_info("\tRelay Board FW Rev = %s", pSysInfo->RelayModuleFwRev); log_info("\tFan Board FW Rev = %s", pSysInfo->FanModuleFwRev); log_info("\tPrimary FW Rev = %s", pSysInfo->CsuPrimFwRev); for (index = 0; index < pSysConfig->TotalConnectorCount; index++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index); if (pDcChargingInfo->Type == _Type_Chademo) { log_info("\tCHAdeMO[%d] FW Rev = %s", pDcChargingInfo->type_index, ShmCHAdeMOData->evse[pDcChargingInfo->type_index].version); } else if (pDcChargingInfo->Type == _Type_GB) { log_info("\tGBT[%d] FW Rev = %s", pDcChargingInfo->type_index, ShmGBTData->evse[pDcChargingInfo->type_index].version); } else if (pDcChargingInfo->Type == _Type_CCS_2) { log_info("\tCCS[%d] FW Rev = %s", pDcChargingInfo->type_index, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].version); } } log_info("\t================================ "); } 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; uint8_t Type; 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]); } } } } } } } bool checkGunTempFail(uint8_t gunIndex) { #ifndef DD360 return FALSE; #endif pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); switch (pDcChargingInfo->Type) { case _Type_Chademo: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectTempSensorFail) { if (isCharging(pDcChargingInfo->SystemStatus)) { RecordAlarmCode(gunIndex,"011018"); } else { setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; case _Type_CCS_2: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectTempSensorFail) { if (isCharging(pDcChargingInfo->SystemStatus)) { RecordAlarmCode(gunIndex,"011019"); } else { setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; case _Type_GB: if (ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectTempSensorFail) { if (isCharging(pDcChargingInfo->SystemStatus)) { RecordAlarmCode(gunIndex,"011020"); } else { setChargerMode(gunIndex,S_FAULT); } return TRUE; } break; } return FALSE; } //========================================== // Ocmf //========================================== void ConfigOcmfInfo(uint8_t gun_index) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun_index); strncpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.evseId, (char *)pSysConfig->SerialNumber, ARRAY_SIZE(pSysConfig->SerialNumber)); char trId[32]; sprintf(trId, "%d", ShmSelectGunInfo->PricesInfo[gun_index].TransactionId); memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.transactionId, trId, sizeof(trId)); char clientId[32] = "DC_Charger"; memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.clientId, clientId, sizeof(clientId)); pSysInfo->DcMeterTransactionAction[gun_index].head.tariffId = 0; pSysInfo->DcMeterTransactionAction[gun_index].head.cableId = 2; memcpy((char *)pSysInfo->DcMeterTransactionAction[gun_index].head.userData, (char *)pDcChargingInfo->StartUserId, sizeof(pDcChargingInfo->StartUserId)); } void ConfigOcmfInfo_Record(int _trID, uint8_t gun_index) { strncpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.evseId, (char *)pSysConfig->SerialNumber, ARRAY_SIZE(pSysConfig->SerialNumber)); char trId[32]; sprintf(trId, "%d", _trID); strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.transactionId, trId); strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.clientId, "DC_Charger"); pSysInfo->DcMeterReadTransactionRecord[gun_index].head.tariffId = 0; pSysInfo->DcMeterReadTransactionRecord[gun_index].head.cableId = 2; strcpy((char *)pSysInfo->DcMeterReadTransactionRecord[gun_index].head.userData, "Record"); } void StoreOcmfFile(uint8_t gun_index,int trid,int isRecord) { if (ShmDcCommonData->pGunInfo[gun_index].ConnectorID <= 0 || ShmDcCommonData->pGunInfo[gun_index].ConnectorID > 4) { log_info("Gun%d ConnectorID:%d",gun_index,ShmDcCommonData->pGunInfo[gun_index].ConnectorID); return; } FILE *pfile; char cmd[500]; sprintf((char*)ShmDcCommonData->pGunInfo[gun_index].OcmfFileName,"/mnt/Gun_%d_%d_OCMF", ShmDcCommonData->pGunInfo[gun_index].ConnectorID,trid); log_info("OCMF File:%s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName); pfile = fopen(ShmDcCommonData->pGunInfo[gun_index].OcmfFileName,"w+"); if (isRecord) fprintf(pfile,"%s",pSysInfo->DcMeterReadTransactionRecord[gun_index].transactionOCMF); else fprintf(pfile,"%s",pSysInfo->DcMeterTransactionAction[gun_index].transactionOCMF); fclose(pfile); sprintf(cmd,"ftpput -u root -p y42j/4cj84 192.168.100.1 %s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName); if (system(cmd) != 0 ) { log_info("Put OCMF File to Cabinet Fail"); sprintf(cmd,"rm -f %s",ShmDcCommonData->pGunInfo[gun_index].OcmfFileName); system(cmd); } else { log_info("Put OCMF File to Cabinet OK"); ShmDcCommonData->pGunInfo[gun_index].SendOcmfDataReq = TRUE; } } void ChkOcmfRecord(uint8_t gun_index) { if (pAlarmCode->AlarmEvents.bits.Meter1CommTimeout) { return; } int trid = DB_Get_OcmfTrid(gun_index); if (trid != 0 && trid != ShmDcCommonData->ocmfTridRecord[gun_index] && trid != ShmSelectGunInfo->PricesInfo[gun_index].TransactionId) { ShmDcCommonData->ocmfTridRecord[gun_index] = trid; ConfigOcmfInfo_Record(ShmDcCommonData->ocmfTridRecord[gun_index], gun_index); pSysInfo->DcMeterReadTransactionRecord[gun_index].ActionCmd = _DC_METER_TRANSACTION_ACTION_START; } if (pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady == _OCMF_INFO_READY_YES && ShmDcCommonData->pGunInfo[gun_index].SendOcmfDataReq == FALSE) { log_info("OCMF Record - Reture Pass \n"); pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady = _OCMF_INFO_READY_NO; //ocpp_ocmf_information(gun_index); DB_Update_ocmf_Record(gun_index, ShmDcCommonData->ocmfTridRecord[gun_index], true); StoreOcmfFile(gun_index,trid,TRUE); //ShmDcCommonData->ocmfTridRecord[gun_index] = 0; } else if (pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady == _OCMF_INFO_READY_FAIL) { log_info("OCMF Record - Reture Fail \n"); pSysInfo->DcMeterReadTransactionRecord[gun_index].OcmfInfoReady = _OCMF_INFO_READY_NO; DB_Update_ocmf_Record(gun_index, ShmDcCommonData->ocmfTridRecord[gun_index], false); //ShmDcCommonData->ocmfTridRecord[gun_index] = 0; } } void SetGunMeterCableLoss() { if (pSysConfig->TotalConnectorCount >= 2) { if (pSysConfig->ModelName[7] == 'V' || pSysConfig->ModelName[7] == 'F') { pSysInfo->DcMeterTransactionAction[LEFT_GUN_NUM].head.cableId = 3; } if (pSysConfig->ModelName[9] == 'V' || pSysConfig->ModelName[9] == 'F') { pSysInfo->DcMeterTransactionAction[RIGHT_GUN_NUM].head.cableId = 3; } } else if (pSysConfig->TotalConnectorCount == 1){ if (pSysConfig->ModelName[7] == 'V' || pSysConfig->ModelName[7] == 'F' || pSysConfig->ModelName[9] == 'V' || pSysConfig->ModelName[9] == 'F') { pSysInfo->DcMeterTransactionAction[LEFT_GUN_NUM].head.cableId = 3; } } } int main(void) { bool isModelNameMatch = true; uint8_t isRessign = 0; uint8_t evBoardStopState = 0; uint8_t _ocppProfileChkFlag; uint8_t gunIndex = 0; uint8_t _isStop[2] = {0}; float powerconsumption; uint8_t ConnectID[2]; uint8_t SendOcmfDataReq[2]; if (CreateAllCsuShareMemory() == FAIL) { log_error("create share memory error"); return FAIL; } 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(" ********************************************************"); #if defined DD360 log_info(" ****************** Project:DD360 *********************"); #elif defined DD360Audi log_info(" ****************** Project:DD360Audi *****************"); #elif defined DD360ComBox log_info(" ****************** Project:DD360ComBox ***************"); #endif log_info(" ********************************************************"); if (!InitialSystemDefaultConfig()) { log_error("InitialSystemDefaultConfig NG "); //StopProcessingLoop(); sleep(5); system("reboot -f"); } CheckGunTypeFromHw(); CheckIsAlternatvieByModelName(); InitialShareMemoryInfo(); GetFirmwareVersion(); ChangeLcmByIndex(_LCM_INIT); if (!CheckConnectorTypeStatus()) { isModelNameMatch = false; } Initialization(); SpawnTask(); log_info("Spawned all Task"); if (!isModelNameMatch) { pAlarmCode->AlarmEvents.bits.ModelNameNoneMatchStestFail = YES; ChangeLcmByIndex(_LCM_FIX); // Module Name 與硬體對應不正確 log_error("Module Name & HW info none match. "); sleep(3); KillAllTask(); StopProcessingLoop(); } CreateTimeoutFork(); log_info("Start self test... "); PrimaryLedIndicatorCtrlFork(); ChangeLcmByIndex(_LCM_FIX); 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 //DS60-120 add ) { /* 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"); } } for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { setChargerMode(gunIndex, MODE_ALARM); } //ChangeLcmByIndex(_LCM_FIX); sleep(3); if (pSysWarning->Level == WARN_LV_ER) { //DS60-120 add KillTaskExceptPrimary(); } else { KillTask(); } StopProcessingLoop(); */ for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { setChargerMode(gunIndex, MODE_MAINTAIN); } ChangeLcmByIndex(_LCM_FIX); } 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); if (!DB_Get_PowerConsumption(_index)) { DB_Insert_PowerConsumption(_index, 0); } } DB_Reboot_Record(); } log_info("===== Create DB End ===== "); #if defined DD360Audi ChangeLcmByIndex(_LCM_SELECT_GUN); #else ChangeLcmByIndex(_LCM_IDLE); #endif //defined DD360Audi sleep(1); //***** 須新增的偵測 *****// // 1. Thernal - 控制風扇轉速 // 2. ouput fuse - 控制風扇轉速 CreateRfidFork(); // Main loop showversion(); CheckFwSlotStatusLog(); //AdjustChargerCurrent(); gettimeofday(&_cmdMainPriority_time, NULL); GunIndexInfo *pGunIndexInfo = (GunIndexInfo *)GetGunIndexInfo(); CheckTaskAlive(); CreateWatchdog(); pSysInfo->OTPTemp = GUN_OTP_VALUE; pSysInfo->OTPTempR = GUN_OTP_RECOVERY; time_t ShowEVStatusTimer[2] = { 0 }; SetGunTypeOTPValue(); SetGunMeterCableLoss(); for (;;) { CheckOcppStatus(); ChkPrimaryStatus(); if ((IsConnectorWholeIdle() || (pSysInfo->PageIndex == _LCM_FIX)) && (pSysInfo->SystemTimeoutFlag != Timeout_ReturnToChargingGunDet) ) { CheckFactoryConfigFunction(); //CheckFwUpdateFunction(); } // OCPP 邏輯 OcppRemoteStartChk(); // 讀卡邏輯 ScannerCardProcess(); // 當 AC 沒有搭上時,清除一些錯誤碼 ClearAlarmCodeWhenAcOff(); // 確認是否要回到充電中的槍畫面邏輯判斷 CheckReturnToChargingConn(); //確認Power cabinet PSU Status //powerCabinetPsuAlarmStatus(); if ((GetTimeoutValue(_cmdMainPriority_time) / 1000) > 5000) { //CheckTask(); 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 // OCMF ChkOcmfRecord(gunIndex); } gettimeofday(&_cmdMainPriority_time, NULL); } // 確認當前錯誤 Level = 2 ? ReviewCriticalAlarm(); gEvBoardErr.GunErrMessage = 0; //清除系統執行中的錯誤訊息 gChillerTempErr.TempErrMsg = 0;//清除系統執行中的錯誤訊息 for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { // 重新收集各槍的錯誤狀態 collectError(gunIndex); } for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // convert common status code to alarm event checkEvBoardAlarmState(pDcChargingInfo->Type); } checkChillerAlarmState(); //log_info("MeterCommTimeout:%d",pAlarmCode->AlarmEvents.bits.MeterCommTimeout); for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); autoStartCharging(gunIndex); CheckGpioInStatus(); CheckErrorOccurStatus(gunIndex); // 確認 Relay Welding or Driving Fault CheckRelayWeldingOrDrivingFault(gunIndex); ChkOcppStatus(gunIndex); if (pGunIndexInfo->AcGunIndex > 0 && isDetectPlugin(gunIndex) && !GetIsCardScan() && gunIndex == pSysInfo->CurGunSelected) { // AUDI_LCM_CHANGE pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG; } 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); } checkGunTempFail(gunIndex); if (pSysInfo->SelfTestSeq == _STEST_FAIL ) { setChargerMode(gunIndex, MODE_MAINTAIN); ChangeLcmByIndex(_LCM_FIX); } switch (pDcChargingInfo->SystemStatus) { case S_IDLE: case S_RESERVATION: if (isModeChange(gunIndex)) { if (pDcChargingInfo->SystemStatus == S_IDLE) log_info("============================= S_IDLE(%x) ============================= ", gunIndex); else if (pDcChargingInfo->SystemStatus == S_RESERVATION) { log_info("============================= S_RESERVATION(%x) ============================= ", gunIndex); ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowConf = YES; } pDcChargingInfo->PresentChargedDuration = 0; pDcChargingInfo->RemainChargingDuration = 0; pDcChargingInfo->PresentChargingVoltage = 0;//DS60-120 add pDcChargingInfo->PresentChargingCurrent = 0;//DS60-120 add strcpy((char *)pDcChargingInfo->StartDateTime, ""); strcpy((char *)pDcChargingInfo->StopDateTime, ""); strcpy((char *)pDcChargingInfo->StartUserId, ""); strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, ""); if (pDcChargingInfo->deratingByConnOtp.deratingIndex != 0) { pDcChargingInfo->deratingByConnOtp.deratingIndex = 0; } ShmDcCommonData->ocmfTridRecord[gunIndex] = 0 ; _isStop[gunIndex] = 0; //Jerry add memset(&ShmSelectGunInfo->PricesInfo[gunIndex], 0, sizeof(PricesInfo)); powerconsumption = ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption; ConnectID[gunIndex] = ShmDcCommonData->pGunInfo[gunIndex].ConnectorID; SendOcmfDataReq[gunIndex] = ShmDcCommonData->pGunInfo[gunIndex].SendOcmfDataReq; memset(&ShmDcCommonData->pGunInfo[gunIndex], 0, sizeof(GunInfo)); ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption = powerconsumption; ShmDcCommonData->pGunInfo[gunIndex].ConnectorID = ConnectID[gunIndex]; ShmDcCommonData->pGunInfo[gunIndex].SendOcmfDataReq = SendOcmfDataReq[gunIndex]; ShmSelectGunInfo->PricesInfo[gunIndex].Balance = FAIL_BALANCE_PRICES; destroySelGun(gunIndex); ResetDetAlarmStatus(gunIndex); //recovery OVP status code if (ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] == YES) { ShmSelectGunInfo->AuthorStateFromCabinet[gunIndex] = NO; } //strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].VendorErrorCode, ""); ReleaseAlarmCode(gunIndex); } if (pDcChargingInfo->IsAvailable == NO) { setChargerMode(gunIndex, MODE_MAINTAIN); } case S_FAULT: if (isModeChange(gunIndex)) { log_info("============================= S_FAULT(%x) ============================= ", gunIndex); } if (pSysWarning->Level == WARN_LV_ER) { struct ChargingInfoData *pSelectedDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected); if (gunIndex == pSysInfo->CurGunSelected) { pSysInfo->SystemPage = _LCM_FIX; } else if (pSelectedDcChargingInfo->SystemStatus != S_IDLE && pSelectedDcChargingInfo->SystemStatus != S_RESERVATION && pSelectedDcChargingInfo->SystemStatus != S_MAINTAIN && pSelectedDcChargingInfo->SystemStatus != S_FAULT) { if (pSelectedDcChargingInfo->SystemStatus == S_CHARGING) { pSysInfo->SystemPage = _LCM_COMPLETE; } else { systemPageRestoreInit(); } } ClearDetectPluginFlag(gunIndex); if (pDcChargingInfo->SystemStatus != S_FAULT) { UpdateErrorCodeToOcpp(gunIndex); setChargerMode(gunIndex, MODE_FAULT); } continue; } if (checkGunTempFail(gunIndex)) { continue; } if (pDcChargingInfo->SystemStatus == S_FAULT) { systemPageRestoreInit(); setChargerMode(gunIndex, MODE_IDLE); } isChargingAverageState(); if (PrecheckIsPass(gunIndex) == false) { log_error("Relay welding"); setChargerMode(gunIndex, MODE_FAULT); if (gunIndex == pSysInfo->CurGunSelected) { pSysInfo->SystemPage = _LCM_FIX; } continue; } if (pDcChargingInfo->SystemStatus == S_FAULT) { pSysInfo->SystemPage = _LCM_NONE; setChargerMode(gunIndex, MODE_IDLE); } if (pSysConfig->OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING) { if (pSysInfo->CurGunSelected == gunIndex) { connectorPageRestoreIdle(); } continue; } // Idle 正常程序起點 // 判斷是否有啟用檢查插槍 if (isDetectPlugin(gunIndex)) { StartGunInfoTimeoutDet(gunIndex, Timeout_WaitPlug); // 卡號驗證成功後,等待充電槍插入充電車 if (pDcChargingInfo->RemoteStartFlag == YES) { if (pDcChargingInfo->ConnectorPlugIn == YES && pDcChargingInfo->IsAvailable) { log_info("-----------------1----------------- %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); StopGunInfoTimeoutDet(gunIndex); pDcChargingInfo->StartMethod = _CHARGING_START_REMOTESTART; continue; } } else if (pSysInfo->OrderCharging == NO_DEFINE) { if (pDcChargingInfo->ConnectorPlugIn == YES && pDcChargingInfo->IsAvailable && (pDcChargingInfo->SystemStatus == S_IDLE || pDcChargingInfo->SystemStatus == S_RESERVATION) && //waitSelectGunPlugIt(gunIndex) (waitRightGunPlugIt(gunIndex) == PASS || waitLeftGunPlugIt(gunIndex) == PASS) ) { if (pDcChargingInfo->SystemStatus == S_RESERVATION) { if (strcmp((char*)pSysConfig->UserId, (char*)ShmDcCommonData->pGunInfo[gunIndex].ReservationID) != EQUAL) { //log_info("Not Resercation ID"); continue; } } log_info("-----------------2----------------- "); ChangeGunSelectByIndex(gunIndex); AddPlugInTimes(gunIndex); strcpy((char *)pDcChargingInfo->StartUserId, (char *)pSysConfig->UserId); log_info("index = %d, CardNumber = %s ", gunIndex, pDcChargingInfo->StartUserId); strcpy((char *)pSysConfig->UserId, ""); ShmDcCommonData->AuthroizeType = IdTokenType_Central; // 當前操作的槍號,進入 Preparing setChargerMode(gunIndex, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(LEFT_GUN_NUM); ClearDetectPluginFlag(RIGHT_GUN_NUM); StopGunInfoTimeoutDet(LEFT_GUN_NUM); StopGunInfoTimeoutDet(RIGHT_GUN_NUM); if (pDcChargingInfo->StartMethod != _CHARGING_START_AUTOSTART) pDcChargingInfo->StartMethod = _CHARGING_START_RFID; continue; } } if (isDetectPlugin(gunIndex) && pSysInfo->CurGunSelected == gunIndex) { // LCM => Waiting for plugging // AUDI_LCM_CHANGE pSysInfo->SystemPage = _LCM_WAIT_FOR_PLUG; } } else if (pSysConfig->isAuthrizeByEVCCID && pDcChargingInfo->ConnectorPlugIn && pSysInfo->CurGunSelected == gunIndex && !pDcChargingInfo->isEVCCIDVerify) { systemPageRestoreInit(); pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; continue; } else { if (pSysInfo->CurGunSelected == gunIndex) { connectorPageRestoreIdle(); } } break; case S_REASSIGN_CHECK: { if (isModeChange(gunIndex)) { log_info("============================= S_REASSIGN_CHECK(%x) ============================= ", gunIndex); systemPageRestoreInit(); if (pSysInfo->OrderCharging != NO_DEFINE) { pSysInfo->OrderCharging = NO_DEFINE; } StopSystemTimeoutDet(); gettimeofday(&pDcChargingInfo->PreChargeTimer, NULL); } setChargerMode(gunIndex, S_PREPARNING); if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } #ifdef DD360Audi pDcChargingInfo->Replug_flag = true; #endif } 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 && GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 3000000) { setChargerMode(gunIndex, MODE_PREPARE_FOR_EV); } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); if (pSysInfo->CurGunSelected == gunIndex) { systemPageRestoreInit(); pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARING_FOR_EV: // 等待車端的通訊 (EV 小板),待車端回報後,開始樁端的測試 if (isModeChange(gunIndex)) { log_info("============================= S_PREPARING_FOR_EV(%x) ============================= ", gunIndex); //strcpy((char *)pSysConfig->UserId, ""); StopGunInfoTimeoutDet(gunIndex); StartGunInfoTimeoutDet(gunIndex, Timeout_EvChargingDet); } if (pDcChargingInfo->Type == _Type_Chademo) { // 檢查車端的槍鎖是否為鎖上 if (isEvGunLocked_chademo(gunIndex) == YES) { if (pSysConfig->ModelName[3] == 'P') { ConfigOcmfInfo(gunIndex); DB_Insert_ocmf(gunIndex); //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3; pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START; } setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } else if (pDcChargingInfo->Type == _Type_GB) { // 檢查車端的 charging enable 是否為 1 if (isEvGunLocked_gb(gunIndex) == YES) { if (pSysConfig->ModelName[3] == 'P') { ConfigOcmfInfo(gunIndex); DB_Insert_ocmf(gunIndex); //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3; pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START; } setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } else if (pDcChargingInfo->Type == _Type_CCS_2) { // 檢查車端的 charging enable 是否為 1 if (isEvGunLocked_ccs(gunIndex) == YES) { if (pSysConfig->ModelName[3] == 'P') { ConfigOcmfInfo(gunIndex); DB_Insert_ocmf(gunIndex); //pSysInfo->DcMeterTransactionAction[gunIndex].head.cableId = 3; pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_START; } setChargerMode(gunIndex, MODE_PREPARE_FOR_EVSE); } } checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); // LCM => Pre-charging if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } 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); if (pSysConfig->ModelName[3] == 'P') { ShmDcCommonData->pGunInfo[gunIndex].isMeterStart = TRUE; ShmDcCommonData->ocmfTridRecord[gunIndex] = ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId; } } checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus); checkEvBoardReqStop(pDcChargingInfo->SystemStatus, gunIndex); // LCM => Pre-charging if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } 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); OcppStartTransation(gunIndex); } if (ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionConf) { ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionConf = NO; } ftime(&endChargingTime[gunIndex]); pDcChargingInfo->PresentChargedDuration = DiffTimeb(startChargingTime[gunIndex], endChargingTime[gunIndex]); checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus); 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); } if ((evBoardStopState = isEvBoardStopChargeFlag(gunIndex)) > 0) { // 板端要求停止 (錯誤) if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "EVDisconnected"); } //printf("%d evBoardStopState = %d", gunIndex, evBoardStopState); if (evBoardStopState == EV_BOARD_STOP_CHARGING) { ChargingAlarmProcess(gunIndex); } else if (evBoardStopState == POWER_CABINET_STOP_CHARGING) { ChargingTerminalProcess(gunIndex); } } else if (isEvBoardNormalStopChargeFlag(gunIndex) == YES) { // 板端要求停止 (正常) if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "EVDisconnected"); } ChargingTerminalProcess(gunIndex); } else if (OcppRemoteStop(gunIndex) == YES || WifiScheduleStop(gunIndex) || CheckBackendChargingTimeout(gunIndex) || CheckBackendChargingEnergy(gunIndex) || strcmp((char *)ShmOCPP16Data->StartTransaction[gunIndex].ResponseIdTagInfo.Status, "Invalid") == EQUAL) { // 後臺要求停止 ChargingTerminalProcess(gunIndex); } // LCM => Charging if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_CHARGING; } #ifdef DD360Audi pDcChargingInfo->Replug_flag = false; #endif break; case S_ALARM: case S_TERMINATING: if (isModeChange(gunIndex)) { if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Local"); } if (pDcChargingInfo->SystemStatus == S_ALARM) { log_info("============================= S_ALARM(%x) ============================= ", gunIndex); UpdateErrorCodeToOcpp(gunIndex); if (strcmp((char *)pDcChargingInfo->StartDateTime, "") != EQUAL) { OcppStopTransation(gunIndex); } TheEndCharging(gunIndex); } else { log_info("============================= S_TERMINATING(%x) ============================= ", gunIndex); } //log_info ("terminating......................... %x ", gunIndex); StopGunInfoTimeoutDet(gunIndex); ShmDcCommonData->pGunInfo[gunIndex].RecordEnergyTime = time((time_t*)NULL); if (ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption != 0) DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } //checkPileEndGfdResult(gunIndex, pDcChargingInfo->Type, pDcChargingInfo->SystemStatus); if (ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P' && ShmDcCommonData->pGunInfo[gunIndex].isMeterStart && pDcChargingInfo->RelayK1K2Status == NO && !_isStop[gunIndex]) { pSysInfo->DcMeterTransactionAction[gunIndex].ActionCmd = _DC_METER_TRANSACTION_ACTION_STOP; log_info("Gun%d Stop Dc Meter Transcation",gunIndex); _isStop[gunIndex] = TRUE; } if (pDcChargingInfo->SystemStatus == S_ALARM) { if (pDcChargingInfo->ConnectorPlugIn == NO && GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) { if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) { setChargerMode(gunIndex, MODE_RESERVATION); } else { setChargerMode(gunIndex, MODE_IDLE); } } } else { 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 (ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { if (pDcChargingInfo->SystemStatus == S_ALARM && ShmDcCommonData->pGunInfo[gunIndex].isMeterStop && pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady) { pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady = NO; DB_Update_ocmf(gunIndex); StoreOcmfFile(gunIndex,ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId,FALSE); DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_COMPLETE; } break; case S_COMPLETE: if (isModeChange(gunIndex)) { log_info ("============================= S_COMPLETE(%x) ============================= ", gunIndex); if (strcmp((char *)pDcChargingInfo->StartDateTime, "") != EQUAL) { OcppStopTransation(gunIndex); } TheEndCharging(gunIndex); } if (pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady && ShmDcCommonData->pGunInfo[gunIndex].isMeterStop) { pSysInfo->DcMeterTransactionAction[gunIndex].OcmfInfoReady = NO; DB_Update_ocmf(gunIndex); StoreOcmfFile(gunIndex,ShmSelectGunInfo->PricesInfo[gunIndex].TransactionId,FALSE); DB_Update_PowerConsumption(gunIndex, ShmDcCommonData->pGunInfo[gunIndex].PowerConsumption); } if (pDcChargingInfo->ConnectorPlugIn == NO && GetTimeoutValue(pDcChargingInfo->TimeoutTimer) >= 10000000) { if (ShmDcCommonData->pGunInfo[gunIndex].ReservationStatus) { setChargerMode(gunIndex, MODE_RESERVATION); } else { setChargerMode(gunIndex, MODE_IDLE); } destroySelGun(gunIndex); //Jerry add #if defined DD360 || defined DD3660ComBox //pSysInfo->SystemPage = _LCM_IDLE; connectorPageRestoreIdle(); #endif } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_COMPLETE; } 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) { //log_info("Send precharge ready 1..........%x, status = %d ", // gunIndex, // isPrechargeStatus_ccs(gunIndex)); if (isPrechargeStatus_ccs(gunIndex) == 39) { log_info("Conn %x, Precharge ready, CCS status = PreChargeResponse (%d) ", gunIndex, isPrechargeStatus_ccs(gunIndex)); } else if (isPrechargeStatus_ccs(gunIndex) == 40) { log_info("Conn %x, Precharge ready, CCS status = PowerDeliveryRequest start (%d) ", gunIndex, isPrechargeStatus_ccs(gunIndex)); } 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->ConnectorPage = _LCM_PRE_CHARGE; } 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; setChargerMode(gunIndex, MODE_CHARGING); } if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->ConnectorPage = _LCM_PRE_CHARGE; } break; case S_MAINTAIN: if (isModeChange(gunIndex)) { log_info("============================= S_MAINTAIN(%x) ============================= ", gunIndex); //pSysInfo->SystemPage = _PAGE_MAINTAIN; if (pSysInfo->FirmwareUpdate == YES) { pSysInfo->SystemPage = _PAGE_MAINTAIN; continue; } if (pDcChargingInfo->IsAvailable == NO) { log_info("Gun%d is not availbale"); break; } if (pSysWarning->Level != WARN_LV_ER) { if (!DisplaySelfTestFailReason()) { //DS60-120 add log_info("Soft reboot for retry self-tets. "); sleep(3); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); } } if (pSysWarning->Level == WARN_LV_ER) { //DS60-120 add KillTaskExceptPrimary(); } else { KillTask(); } /* if (pSysInfo->SelfTestSeq == _STEST_FAIL) StopProcessingLoop(); */ } if (pSysInfo->SelfTestSeq == _STEST_FAIL && pSysInfo->SystemTimeoutFlag != Timeout_SelftestChk) { SelfTestRun(); StopSystemTimeoutDet(); sleep(3); break; } if (pDcChargingInfo->IsAvailable && pSysInfo->SelfTestSeq == _STEST_COMPLETE) { if (pSysWarning->Level == WARN_LV_ER) setChargerMode(gunIndex, MODE_FAULT); else setChargerMode(gunIndex, MODE_IDLE); } #ifndef DD360Audi if (pSysInfo->CurGunSelected == gunIndex) { pSysInfo->SystemPage = _PAGE_MAINTAIN; } #endif break; }//switch TryFeedWatchdog(); }//for #if defined DD360Audi if (pSysInfo->SystemPage != _LCM_SELECT_GUN) { #else if (pSysInfo->SystemPage != _LCM_NONE) { #endif //defined DD360Audi ChangeLcmByIndex(pSysInfo->SystemPage); } else { bool dcPageRun = false; if (pGunIndexInfo->AcGunIndex > 0 && pSysInfo->CurGunSelectedByAc != NO_DEFINE) { pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (pAcChargingInfo->SystemStatus == S_IDLE) { ChangeLcmByIndex(_LCM_IDLE); } else if (pAcChargingInfo->SystemStatus == S_PREPARNING) { ChangeLcmByIndex(_LCM_PRE_CHARGE); } else if (pAcChargingInfo->SystemStatus == S_CHARGING) { ChangeLcmByIndex(_LCM_CHARGING); } else if (pAcChargingInfo->SystemStatus == S_TERMINATING || pAcChargingInfo->SystemStatus == S_COMPLETE) { ChangeLcmByIndex(_LCM_COMPLETE); } else { dcPageRun = true; } } else { dcPageRun = true; } if (dcPageRun) { ChangeLcmByIndex(pSysInfo->ConnectorPage); } } //for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) { // pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex); // checkEvBoardAlarmState(pDcChargingInfo->Type); // checkChillerAlarmState(); // //if (checkChillerAlarmState(gunIndex) == ABNORMAL) { // // break; // //} //} TryFeedWatchdog(); usleep(WHILE_LOOP_TIME); } return FAIL; }