/* * Module_AlarmDetect.c * * Created on: 2020年01月15日 * Author: Eason Yang */ #include #include #include #include #include #include #include #include #include #include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include /*Unix 標準函數定義*/ #include /*檔控制定義*/ #include /*PPSIX 終端控制定義*/ #include /*錯誤號定義*/ #include #include #include #include #include "define.h" #include "main.h" #define FILTER_SPEC 2 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define Debug #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL 0 #define ON 1 #define OFF 0 #define SPEC_OV 275 #define SPEC_UV 160 #define SPEC_OC (32*1.1) #define SPEC_OT 85 #define HYSTERETIC_OUV 10 #define HYSTERETIC_OT 10 #define HYSTERETIC_OC 10 struct{ unsigned short int OV[3]; unsigned short int UV[3]; unsigned short int OC; unsigned short int OT_AMB; unsigned short int GMI; unsigned short int Short; unsigned short int Leakage; unsigned short int HandShakingTimeout; unsigned short int EmrgencyBTN; unsigned short int Relay_Welding; unsigned short int Relay_DrivingFault; unsigned short int CP_LevelFail; unsigned short int MCU_SelfTestFail; }Alarm_Counter[2]; void trim(char *s); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct OCPP16Data *ShmOCPP16Data; struct Charger *ShmCharger; int StoreLogMsg(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 if((ShmSysConfigAndInfo->SysConfig.ModelName != NULL) && (ShmSysConfigAndInfo->SysConfig.SerialNumber != NULL) && (strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) >= 14)) { sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]%s_%s_SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); } else { sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1); } #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } 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; } //========================================== // Init all share memory //========================================== int InitShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n"); #endif result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n"); #endif result = FAIL; } else {} //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmStatusCodeData NG\n"); #endif result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmStatusCodeData NG\n"); #endif result = FAIL; } else {} //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0) { DEBUG_ERROR("shmget ShmCharger NG\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCharger NG\n"); result = FAIL; } else {} //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16Data NG\n"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG\n"); result = FAIL; } else {} return result; } //========================================== // Common routine //========================================== void trim(char *s) { int i=0, j, k, l=0; while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n')) i++; j = strlen(s)-1; while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n')) j--; if(i==0 && j==strlen(s)-1) { } else if(i==0) s[j+1] = '\0'; else { for(k=i; k<=j; k++) s[l++] = s[k]; s[l] = '\0'; } } void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } //========================================== // Main process //========================================== int main(void) { if(InitShareMemory() == FAIL) { DEBUG_ERROR("InitShareMemory NG\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1; } sleep(5); return FAIL; } for(;;) { for(int gun_index = 0;gun_indexgun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE) { if(Alarm_Counter[gun_index].OV[0] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].OV[0]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE))) { Alarm_Counter[gun_index].OV[0] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : recover \n"); } } if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE) { if(Alarm_Counter[gun_index].OV[1] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].OV[1]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE))) { Alarm_Counter[gun_index].OV[1] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : recover \n"); } } if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE) { if(Alarm_Counter[gun_index].OV[2] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].OV[2]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_VOLTAGE))) { Alarm_Counter[gun_index].OV[2] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_VOLTAGE; DEBUG_INFO("ALARM_OVER_VOLTAGE : recover \n"); } } } //===================================== // Under voltage detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE) { if(Alarm_Counter[gun_index].UV[0] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].UV[0]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE))) { Alarm_Counter[gun_index].UV[0] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : recover \n"); } } if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE) { if(Alarm_Counter[gun_index].UV[1] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].UV[1]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE))) { Alarm_Counter[gun_index].UV[1] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : recover \n"); } } if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE) { if(Alarm_Counter[gun_index].UV[2] > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : alarm \n"); } } else { Alarm_Counter[gun_index].UV[2]++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_UNDER_VOLTAGE))) { Alarm_Counter[gun_index].UV[2] = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_UNDER_VOLTAGE; DEBUG_INFO("ALARM_UNDER_VOLTAGE : recover \n"); } } } //===================================== // Over current detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : alarm \n"); } } else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT))) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : recover \n"); } } if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3) { if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : alarm \n"); } } else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT))) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : recover \n"); } } if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : alarm \n"); } } else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_CURRENT))) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_CURRENT; DEBUG_INFO("ALARM_OVER_CURRENT : recover \n"); } } } //===================================== // Over temperature detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_TEMPERATURE) { if(Alarm_Counter[gun_index].OT_AMB > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_TEMPERATURE; DEBUG_INFO("ALARM_OVER_TEMPERATURE : alarm \n"); } } else { Alarm_Counter[gun_index].OT_AMB++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_TEMPERATURE))) { Alarm_Counter[gun_index].OT_AMB = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_OVER_TEMPERATURE; DEBUG_INFO("ALARM_OVER_TEMPERATURE : recover \n"); } } //===================================== // Ground fault detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_GROUND_FAIL) { if(Alarm_Counter[gun_index].GMI > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_GROUND_FAIL; DEBUG_INFO("ALARM_GROUND_FAIL : alarm \n"); } } else { Alarm_Counter[gun_index].GMI++; } } else if (!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_GROUND_FAIL)) { Alarm_Counter[gun_index].GMI = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_GROUND_FAIL; DEBUG_INFO("ALARM_GROUND_FAIL : recover \n"); } } //===================================== // CP level fail detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CP_ERROR) { if(Alarm_Counter[gun_index].CP_LevelFail > FILTER_SPEC) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault == OFF) { ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CP_ERROR; DEBUG_INFO("ALARM_CP_ERROR : alarm \n"); } } else { Alarm_Counter[gun_index].CP_LevelFail++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CP_ERROR)) { Alarm_Counter[gun_index].CP_LevelFail= 0; if(ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault == ON) { ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CP_ERROR; DEBUG_INFO("ALARM_CP_ERROR : recover \n"); } } //===================================== // Current AC/DC leak detection //===================================== if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC) || (ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC)) { if(Alarm_Counter[gun_index].Leakage > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = ON; if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC) { ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_AC; ShmCharger->gun_info[gun_index].otherAlarmCode.isACLeakage = ON; DEBUG_INFO("ALARM_CURRENT_LEAK_AC : alarm \n"); } else if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC) { ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_DC; ShmCharger->gun_info[gun_index].otherAlarmCode.isDcLeakage = ON; DEBUG_INFO("ALARM_CURRENT_LEAK_DC : alarm \n"); } } } else { Alarm_Counter[gun_index].Leakage++; } } else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC)) || (!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC))) { Alarm_Counter[gun_index].Leakage = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = OFF; if(ShmCharger->gun_info[gun_index].otherAlarmCode.isACLeakage == ON) { ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_LEAK_AC; ShmCharger->gun_info[gun_index].otherAlarmCode.isACLeakage = OFF; DEBUG_INFO("ALARM_CURRENT_LEAK_AC : recover \n"); } else if(ShmCharger->gun_info[gun_index].otherAlarmCode.isDcLeakage == ON) { ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_LEAK_DC; ShmCharger->gun_info[gun_index].otherAlarmCode.isDcLeakage = OFF; DEBUG_INFO("ALARM_CURRENT_LEAK_DC : recover \n"); } } } //===================================== // MCU self test fail detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_MCU_TESTFAIL) { if(Alarm_Counter[gun_index].MCU_SelfTestFail > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_MCU_TESTFAIL; DEBUG_INFO("ALARM_MCU_TESTFAIL : alarm \n"); } } else { Alarm_Counter[gun_index].MCU_SelfTestFail++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_MCU_TESTFAIL)) { Alarm_Counter[gun_index].MCU_SelfTestFail = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_MCU_TESTFAIL; DEBUG_INFO("ALARM_MCU_TESTFAIL : recover \n"); } } //===================================== // Hand shaking timeout detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_HANDSHAKE_TIMEOUT) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_HANDSHAKE_TIMEOUT; DEBUG_INFO("ALARM_HANDSHAKE_TIMEOUT : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_HANDSHAKE_TIMEOUT)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_HANDSHAKE_TIMEOUT; DEBUG_INFO("ALARM_HANDSHAKE_TIMEOUT : recover \n"); } } //===================================== // Emergency stop detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_EMERGENCY_STOP) { if(Alarm_Counter[gun_index].EmrgencyBTN > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_EMERGENCY_STOP; DEBUG_INFO("ALARM_EMERGENCY_STOP : alarm \n"); } } else { Alarm_Counter[gun_index].EmrgencyBTN++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_EMERGENCY_STOP)) { Alarm_Counter[gun_index].EmrgencyBTN = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_EMERGENCY_STOP; DEBUG_INFO("ALARM_EMERGENCY_STOP : recover \n"); } } //===================================== // Relay welding detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_WELDING) { if(Alarm_Counter[gun_index].Relay_Welding > FILTER_SPEC) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_RELAY_WELDING; DEBUG_INFO("ALARM_RELAY_STATUS : alarm \n"); } } else { Alarm_Counter[gun_index].Relay_Welding++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_WELDING)) { Alarm_Counter[gun_index].Relay_Welding = 0; if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_RELAY_WELDING; DEBUG_INFO("ALARM_RELAY_STATUS : recover \n"); } } //===================================== // Relay driving fault detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_DRIVE_FAULT) { if(Alarm_Counter[gun_index].Relay_DrivingFault > FILTER_SPEC) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_RELAY_DRIVE_FAULT; DEBUG_INFO("ALARM_RELAY_DRIVE_FAULT : alarm \n"); } } else { Alarm_Counter[gun_index].Relay_DrivingFault++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_DRIVE_FAULT)) { Alarm_Counter[gun_index].Relay_DrivingFault = 0; if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_RELAY_DRIVE_FAULT; DEBUG_INFO("ALARM_RELAY_DRIVE_FAULT : recover \n"); } } //===================================== // Current short detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_SHORT) { if(Alarm_Counter[gun_index].Short > FILTER_SPEC) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_SHORT; DEBUG_INFO("ALARM_CIRCUIT_SHORT : alarm \n"); } } else { Alarm_Counter[gun_index].Short++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_SHORT)) { Alarm_Counter[gun_index].Short = 0; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_SHORT; DEBUG_INFO("ALARM_CIRCUIT_SHORT : recover \n"); } } //===================================== // Rotatory switch detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_ROTATORY_SWITCH_FAULT; DEBUG_INFO("ALARM_ROTATORY_SWITCH_FAULT : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_ROTATORY_SWITCH_FAULT; DEBUG_INFO("ALARM_ROTATORY_SWITCH_FAULT : recover \n"); } } //===================================== // Leakage module detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_LEAK_MODULE_FAIL; DEBUG_INFO("ALARM_LEAK_MODULE_FAIL : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL)) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_LEAK_MODULE_FAIL; DEBUG_INFO("ALARM_LEAK_MODULE_FAIL : recover \n"); } } //===================================== // Shutter detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_SHUTTER_FAULT; DEBUG_INFO("ALARM_SHUTTER_FAULT : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT)) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_SHUTTER_FAULT; DEBUG_INFO("ALARM_SHUTTER_FAULT : recover \n"); } } //===================================== // Locker detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail == OFF) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_LOCKER_FAULT; DEBUG_INFO("ALARM_LOCKER_FAULT : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT)) { if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail == ON) { ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_LOCKER_FAULT; DEBUG_INFO("ALARM_LOCKER_FAULT : recover \n"); } } //===================================== // Power drop detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop == OFF) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_POWER_DROP; DEBUG_INFO("ALARM_POWER_DROP : alarm \n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP)) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop == ON) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_POWER_DROP; DEBUG_INFO("ALARM_POWER_DROP : recover \n"); } } //===================================== // OCPP error code message //===================================== if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_VOLTAGE) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverVoltage"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_UNDER_VOLTAGE) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "UnderVoltage"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_CURRENT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OverCurrentFailure"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_OVER_TEMPERATURE) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "HighTemperature"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "GroundFailure"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_ERROR) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "CpError"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_AC) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "ACLeakage"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_LEAK_DC) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "DCLeakage"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_MCU_TESTFAIL) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "McuTestFail"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_HANDSHAKE_TIMEOUT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "HandshakeTimeout"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "EmergencyStop"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_WELDING) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayWelding"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LEAK_MODULE_FAIL) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "LeakageModuleFail"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_SHUTTER_FAULT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "ShutterFault"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_LOCKER_FAULT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "ConnectorLockFailure"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_POWER_DROP) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "PowerDrop"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CURRENT_SHORT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "CircuitShort"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_ROTATORY_SWITCH_FAULT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RotatorySwitchFault"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_RELAY_DRIVE_FAULT) { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError"); sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "RelayDriveFault"); } else { sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError"); memset(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode, 0x00, ARRAY_SIZE(ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode)); } //===================================== // Latch alarm recover in state A //===================================== if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == 1)) { /* TODO: Recover latch alarm here */ } //===================================== // Latch alarm recover in state B1 and B2 //===================================== if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == 2) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == 3)) { /* TODO: Recover latch alarm here */ } //===================================== // Latch alarm recover in state C //===================================== if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == 4)) { /* TODO: Recover latch alarm here */ } } usleep(100000); } return FAIL; }