/* * 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 50 #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 Ac_Leak; unsigned short int Dc_Leak; 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; 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); sprintf(Buf,"echo \"[%04d.%02d.%02d %02d:%02d:%02d] - %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, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); #ifdef SystemLogMessage system(Buf); #endif printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer); 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\r\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCharger NG\r\n"); result = FAIL; } else {} //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16Data NG\r\n"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG\r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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.GbGfdTrip == OFF)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_GROUND_FAIL; DEBUG_INFO("ALARM_GROUND_FAIL : alarm \r\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.GbGfdTrip == ON )) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_GROUND_FAIL; DEBUG_INFO("ALARM_GROUND_FAIL : recover \r\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 \r\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 \r\n"); } } //===================================== // Current AC leak detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC) { if(Alarm_Counter[gun_index].Ac_Leak > FILTER_SPEC) { if((ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == OFF)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_AC; DEBUG_INFO("ALARM_CURRENT_LEAK_AC : alarm \r\n"); } } else { Alarm_Counter[gun_index].Ac_Leak++; } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC)) { Alarm_Counter[gun_index].Ac_Leak = 0; if((ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == ON)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_LEAK_AC; DEBUG_INFO("ALARM_CURRENT_LEAK_AC : recover \r\n"); } } //===================================== // Current DC leak detection //===================================== // if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC) // { // if(Alarm_Counter[gun_index].Dc_Leak > FILTER_SPEC) // { // if((ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == OFF)) // { // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = ON; // ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_DC; // DEBUG_INFO("ALARM_CURRENT_LEAK_DC : alarm \r\n"); // } // } // else // { // Alarm_Counter[gun_index].Dc_Leak++; // } // } // else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC)) // { // Alarm_Counter[gun_index].Dc_Leak = 0; // if((ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == ON)) // { // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = OFF; // ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_LEAK_DC; // DEBUG_INFO("ALARM_CURRENT_LEAK_DC : recover \r\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(ShmCharger->gun_info[gun_index].otherAlarmCode.isMcuSelfTest == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isMcuSelfTest = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_MCU_TESTFAIL; DEBUG_INFO("ALARM_MCU_TESTFAIL : alarm \r\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(ShmCharger->gun_info[gun_index].otherAlarmCode.isMcuSelfTest == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isMcuSelfTest = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_MCU_TESTFAIL; DEBUG_INFO("ALARM_MCU_TESTFAIL : recover \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\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 \r\n"); } } //===================================== // Current short detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_SHORT) { if(Alarm_Counter[gun_index].Short > FILTER_SPEC) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isCurrentShort == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isCurrentShort = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_SHORT; DEBUG_INFO("ALARM_CIRCUIT_SHORT : alarm \r\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(ShmCharger->gun_info[gun_index].otherAlarmCode.isCurrentShort == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isCurrentShort = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CURRENT_SHORT; DEBUG_INFO("ALARM_CIRCUIT_SHORT : recover \r\n"); } } //===================================== // Rotatory switch detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isRotatorySwitch == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isRotatorySwitch = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_ROTATORY_SWITCH_FAULT; DEBUG_INFO("ALARM_ROTATORY_SWITCH_FAULT : alarm \r\n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isRotatorySwitch == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isRotatorySwitch = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_ROTATORY_SWITCH_FAULT; DEBUG_INFO("ALARM_ROTATORY_SWITCH_FAULT : recover \r\n"); } } //===================================== // Leakage module detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isLeakageModule == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isLeakageModule = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_LEAK_MODULE_FAIL; DEBUG_INFO("ALARM_LEAK_MODULE_FAIL : alarm \r\n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isLeakageModule == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isLeakageModule = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_LEAK_MODULE_FAIL; DEBUG_INFO("ALARM_LEAK_MODULE_FAIL : recover \r\n"); } } //===================================== // Shutter detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isShutterFail == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isShutterFail = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_SHUTTER_FAULT; DEBUG_INFO("ALARM_SHUTTER_FAULT : alarm \r\n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isShutterFail == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isShutterFail = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_SHUTTER_FAULT; DEBUG_INFO("ALARM_SHUTTER_FAULT : recover \r\n"); } } //===================================== // Locker detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isLockerFault == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isLockerFault = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_LOCKER_FAULT; DEBUG_INFO("ALARM_LOCKER_FAULT : alarm \r\n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isLockerFault== ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isLockerFault = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_LOCKER_FAULT; DEBUG_INFO("ALARM_LOCKER_FAULT : recover \r\n"); } } //===================================== // Power drop detection //===================================== if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isPowerDrop == OFF) { ShmCharger->gun_info[gun_index].otherAlarmCode.isPowerDrop = ON; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_POWER_DROP; DEBUG_INFO("ALARM_POWER_DROP : alarm \r\n"); } } else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP)) { if(ShmCharger->gun_info[gun_index].otherAlarmCode.isPowerDrop == ON) { ShmCharger->gun_info[gun_index].otherAlarmCode.isPowerDrop = OFF; ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_POWER_DROP; DEBUG_INFO("ALARM_POWER_DROP : recover \r\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"); } //===================================== // 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; }