#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 "../../define.h" #include "CheckSystemTask.h" #include "Config.h" #include "timeout.h" #define DEBUG_ALSTON 0 #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define MODELNAME_FAIL 0 #define BUFFER_SIZE 128 #define YES 1 #define NO 0 #define NORMAL 0 #define ABNORMAL 1 #define EQUAL 0 #define BTN_RELEASE 0 #define BTN_PRESS 1 #define MAX_BUF 64 //#define MtdBlockSize 0x600000 #define MtdBlockSize 0x300000 #define SYSFS_GPIO_DIR "/sys/class/gpio" #define UPGRADE_FAN 0x02 #define UPGRADE_RB 0x03 #define UPGRADE_PRI 0x04 #define UPGRADE_AC 0x05 #define UPGRADE_LED 0x06 #define SYSTEM_MIN_VOL 80 #define MIN_OUTPUT_CUR 0 #define AC_OUTPUT_VOL 220 #define NO_DEFINE 255 #define DEFAULT_AC_INDEX 2 #define PSU_MIN_CUR 100 #define DB_FILE "/Storage/ChargeLog/localCgargingRecord.db" #define NETWORK_DB_FILE "/Storage/EventLog/Eventlog.db" #define GUN_OTP_VALUE 150 #define GUN_OTP_RECOVERY 140 #define UNDEFINED_TEMP 255 #define uSEC_VAL 1000000 #define SELFTEST_TIMEOUT 60 #define AUTHORIZE_TIMEOUT 15 #define AUTHORIZE_COMP_TIMEOUT 3 #define AUTHORIZE_FAIL_TIMEOUT 3 #define AUTHORIZE_STOP_TIMEOUT 30 #define RETURN_TO_CHARGING_PAGE 30 #define GUN_PREPARE_TIMEOUT 30 #define GUN_EV_WAIT_TIMEOUT 120 #define GUN_EVSE_WAIT_TIMEOUT 60 #define GUN_COMP_WAIT_TIMEOUT 3 #define GUN_PRECHARGING_TIMEOUT 60 #define TIMEOUT_SPEC_HANDSHAKING 180000 char *valid_Internet[2] = {"8.8.8.8", "180.76.76.76"}; unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; int whileLoopTime = 10000; // 10 ms int wtdFd = -1; byte _authorizeIndex = NO_DEFINE; bool IsAuthorizingMode(); void ClearAuthorizedFlag(); bool isDetectPlugin(); void ClearDetectPluginFlag(); int mystrcmp(unsigned char *p1, unsigned char *p2); void CheckTask(); long long DiffTimebWithNow(struct timeb ST); unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit); void SetBitValue(unsigned char *_byte, unsigned char _bit, unsigned char value); void ChargingTerminalProcess(byte gunIndex); void ChkPrimaryStatus(); void StartSystemTimeoutDet(unsigned char flag); void StopSystemTimeoutDet(); void StartGunInfoTimeoutDet(unsigned char gunIndex, unsigned char flag); void StopGunInfoTimeoutDet(unsigned char gunIndex); int StoreLogMsg_1(const char *fmt, ...); int GetTimeoutValue(struct timespec *startTime); void gpio_set_value(unsigned int gpio, unsigned int value); void PRINTF_FUNC(char *string, ...); void ChangeGunSelectByIndex(byte sel); void ChargingAlarmProcess(byte gunIndex); void CheckSystemErrorFunction(byte index); int opcc_chk_reserve_expired(byte gunIndex); void ocpp_process_start(); void ocpp_auto_response_BootNotification(); void ocpp_auto_response_StartTransationConf(byte gunIndex); bool ocpp_chk_authrization_cmd(); void ocpp_chk_reset_cmd(byte isforce); void ocpp_chk_reserved_cmd(byte gunIndex); void ocpp_chk_availability_cmd(byte gunIndex); void ocpp_chk_unlock_cmd(byte gunIndex); bool ocpp_chk_remoteStop_cmd(byte gunIndex); void ocpp_chk_remoteStart_cmd(); void ocpp_chk_update_cmd(); bool ocpp_chk_invalid_id_cmd(byte gunIndex); void ocpp_set_startTransation_cmd(byte gunIndex); void ocpp_set_stopTransation_cmd(byte gunIndex); void ocpp_set_noErrorCode_cmd(byte gunIndex, char *errString); void ocpp_set_stopReason_by_cmd(byte gunIndex, char *reason); void ocpp_set_authorizeReq_cmd(byte value); void ocpp_set_authorizeConf_cmd(byte value); void ocpp_set_errCode_cmd(byte gunIndex); void ocpp_clear_errorCode_cmd(byte gunIndex); void ocpp_clear_idTag_cmd(byte gun_index); void ocpp_clear_stopReason(byte gun_index); bool ocpp_get_authorize_conf(); unsigned short _ocpp_get_connect_timeout(); void ocpp_chargingProfile_process(byte gun_index); void RecordAlarmCode(byte gunIndex, char *code); void ReleaseSysAlarmCode(byte gunIndex); void ReviewCriticalAlarm(); int DB_Open(sqlite3 *db); int DB_Insert_Record(sqlite3 *db, int gun_index); int DB_Update_Operactive(sqlite3 *db, uint8_t gun_index, uint8_t IsAvailable); int DB_Get_Operactive(sqlite3 *db, uint8_t gun_index); void InitialDHCP(); int GetStartScheduleTime(unsigned char *time); void KillAllTask(); void CheckSystemTaskAlive(); #define DEBUG_INFO_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; struct CHAdeMOData *ShmCHAdeMOData; struct GBTData *ShmGBTData; struct CcsData *ShmCcsData; struct PrimaryMcuData *ShmPrimaryMcuData; struct FanModuleData *ShmFanModuleData; struct RelayModuleData *ShmRelayModuleData; struct LedModuleData *ShmLedModuleData; struct OCPP16Data *ShmOCPP16Data; struct OCPP20Data *ShmOCPP20Data; struct MeterInformation *ShmCsuMeterData; struct DcCommonInformation *ShmDcCommonData; struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY]; struct timeb startChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timeb endChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; int _presentChargingTimeBuf[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timespec _startTransation_time[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; float gunOutputVol [CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; float _ChargingProfilePwBuffer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; float _AcChargingProfileCurBuffer; bool _isSendStartTransaction[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; GunErr errCollect; struct timespec _autoRuntestTime; byte _isTestRun = NO; // for initial index to check EV board type is correct byte _gunIndex = 0; byte _acgunIndex = 0; byte _chademoIndex = 0; byte _ccsIndex = 0; byte _gb_Index = 0; byte _ac_Index = 0; byte bd0_1_status = 0; byte bd0_2_status = 0; byte bd1_1_status = 0; byte bd1_2_status = 0; bool isCardScan = false; bool isModelNameMatch = true; int rfidFd = -1; char* rfidPortName = "/dev/ttyS2"; char* fwVersion = "V2.05.00.0000.00"; sqlite3 *localDb; bool isDb_ready; sqlite3 *networkDb; char MyDefaultPriceString[128]; byte reset4gStep = RESET_4G_STEP_NONE; //================================================ // initial can-bus //================================================ int InitCanBus() { int s0,nbytes; struct timeval tv; struct ifreq ifr0; struct sockaddr_can addr0; system("/sbin/ip link set can0 down"); system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100"); system("/sbin/ip link set can0 up"); s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW); tv.tv_sec = 0; tv.tv_usec = 10000; if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_RCVTIMEO NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_RCVBUF NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_SNDBUF NG"); #endif } strcpy(ifr0.ifr_name, "can0" ); ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */ addr0.can_family = AF_CAN; addr0.can_ifindex = ifr0.ifr_ifindex; bind(s0, (struct sockaddr *)&addr0, sizeof(addr0)); return s0; } //================================================ // initial uart port //================================================ char *_priPortName = "/dev/ttyS1"; char *_485PortName = "/dev/ttyS5"; int InitComPort(byte target) { int fd; struct termios tios; if(target == UPGRADE_PRI) fd = open(_priPortName, O_RDWR); else if (target == UPGRADE_FAN || target == UPGRADE_RB || target == UPGRADE_AC || target == UPGRADE_LED) fd = open(_485PortName, O_RDWR); if(fd<=0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("open 407 Communication port NG \n"); #endif return -1; } ioctl (fd, TCGETS, &tios); tios.c_cflag = B115200| CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN]=0; tios.c_cc[VTIME]=(unsigned char)5; tios.c_lflag=0; tcflush(fd, TCIFLUSH); ioctl (fd, TCSETS, &tios); return fd; } //================================= // Common routine //================================= void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } int InitWatchDog() { int fd; int timeout = 180; system("/usr/bin/fuser -k /dev/watchdog"); sleep(1); system("echo V > /dev/watchdog"); sleep(1); fd = open("/dev/watchdog", O_RDWR); if(fd <= 0) { DEBUG_ERROR_MSG("System watch dog initial fail.\r\n"); } ioctl(fd, _IOWR('W', 6, int), &timeout); return fd; } void CloseWatchDog() { if (wtdFd > 0) { close(wtdFd); sleep(1); system("/usr/bin/fuser -k /dev/watchdog"); sleep(1); system("echo V > /dev/watchdog"); sleep(1); } } int StoreLogMsg_1(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; va_list args; struct timeb SeqEndTime; struct tm *tm; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); ftime(&SeqEndTime); SeqEndTime.time = time(NULL); tm=localtime(&SeqEndTime.time); if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES || DEBUG_ALSTON) { sprintf(Buf,"%02d:%02d:%02d:%03d - %s", tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm, buffer); printf("%s \n", Buf); } else { sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.SerialNumber); system(Buf); } return rc; } //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; //} int GetTimeoutValue(struct timespec *startTime) { struct timespec endTime; clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime); return endTime.tv_sec - startTime->tv_sec; } void GetTimespecFunc(struct timespec *time) { clock_gettime(CLOCK_MONOTONIC_COARSE, time); } int mystrcmp(unsigned char *p1, unsigned char *p2) { while(*p1==*p2) { if(*p1=='\0' || *p2=='\0') break; p1++; p2++; } if(*p1=='\0' && *p2=='\0') return(PASS); else return(FAIL); } 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); } int DiffTimebWithNowSec(struct timeb ST) { //return milli-second struct timeb ET; unsigned int StartTime,StopTime; ftime(&ET); StartTime=(unsigned int)ST.time; StopTime=(unsigned int)ET.time; return (StopTime-StartTime); } int CheckTimeOut(uint8_t *start) { int result = YES; struct ParsingResult { int result; int scanedElement; int year; int month; int mday; int hour; int min; int sec; int tz_hour; int tz_min; float minSec; }parsingResult; struct tm tmStart; struct timeb tbStart; memset(&parsingResult, 0x00, sizeof(struct ParsingResult)); if(strstr((char*)start, ".") != NULL) { // Original data with mini second if(strstr((char*)start, "Z") != NULL) { // Original data with Z parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%fZ", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.minSec); } else { // Original data without Z parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%f%d:%d", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.minSec, &parsingResult.tz_hour, &parsingResult.tz_min); } } else { // Original data without mini second if(strstr((char*)start, "Z") != NULL) { // Original data with Z parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%dZ", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec); } else { // Original data without Z parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d%d:%d", &parsingResult.year, &parsingResult.month, &parsingResult.mday, &parsingResult.hour, &parsingResult.min, &parsingResult.sec, &parsingResult.tz_hour, &parsingResult.tz_min); } } if(parsingResult.scanedElement >= 6) { tmStart.tm_year = parsingResult.year - 1900; tmStart.tm_mon = parsingResult.month - 1; tmStart.tm_mday = parsingResult.mday; tmStart.tm_hour = parsingResult.hour; tmStart.tm_min = parsingResult.min; tmStart.tm_sec = parsingResult.sec; tmStart.tm_gmtoff = 0; tbStart.time = mktime(&tmStart); tbStart.timezone = 0; tbStart.millitm = 0; tbStart.time -= (parsingResult.tz_hour*3600) + (parsingResult.tz_min*60*(parsingResult.tz_hour>=0?1:-1)); if(DiffTimebWithNowSec(tbStart) <= 0) result = NO; else result = YES; } else { PRINTF_FUNC("Start date parsing error.\n"); } return result; } void setChargerMode(byte gun_index, byte mode) { chargingInfo[gun_index]->SystemStatus = mode; } void PRINTF_FUNC(char *string, ...) { va_list args; char buffer[4096]; va_start(args, string); vsnprintf(buffer, sizeof(buffer), string, args); va_end(args); DEBUG_INFO_MSG("%s ", buffer); } 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); } bool CheckBackendChargingTimeout(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) { if (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) { if (chargingInfo[gunIndex]->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)) result = true; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) { // 隨插即充電的要看 offline if (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) { if (chargingInfo[gunIndex]->PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration * 60)) result = true; } } return result; } bool CheckBackendChargingEnergy(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) { if (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) { if (chargingInfo[gunIndex]->PresentChargedEnergy >= ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy) result = true; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) { // 隨插即充電的要看 offline if (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) { if (chargingInfo[gunIndex]->PresentChargedEnergy >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) result = true; } } return result; } bool CheckOcppChargingTimeout(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SessionTarget[gunIndex].targetDuration > 0) { if (chargingInfo[gunIndex]->PresentChargedDuration >= (ShmOCPP16Data->SessionTarget[gunIndex].targetDuration * 60)) { PRINTF_FUNC("CheckOcppChargingTimeout. G_(%d) - (%d) \n", gunIndex, chargingInfo[gunIndex]->PresentChargedDuration); result = true; } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SessionTarget[gunIndex].targetDuration > 0) { if (chargingInfo [gunIndex]->PresentChargedDuration >= (ShmOCPP20Data->SessionTarget[gunIndex].targetDuration * 60)) { PRINTF_FUNC ( "CheckOcppChargingTimeout. G_(%d) - (%d) \n", gunIndex, chargingInfo [gunIndex]->PresentChargedDuration ); result = true; } } } return result; } bool CheckOcppChargingEnergy(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SessionTarget[gunIndex].targetEnergy > 0) { if (chargingInfo[gunIndex]->PresentChargedEnergy >= ShmOCPP16Data->SessionTarget[gunIndex].targetEnergy) { PRINTF_FUNC ( "CheckOcppChargingEnergy. G_(%d) - (%f) \n", gunIndex, chargingInfo[gunIndex]->PresentChargedEnergy ); result = true; } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SessionTarget[gunIndex].targetEnergy > 0) { if (chargingInfo [gunIndex]->PresentChargedEnergy >= ShmOCPP20Data->SessionTarget[gunIndex].targetEnergy) { PRINTF_FUNC ( "CheckOcppChargingEnergy. G_(%d) - (%f) \n", gunIndex, chargingInfo [gunIndex]->PresentChargedEnergy ); result = true; } } } return result; } bool CheckOcppChargingSOC(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SessionTarget[gunIndex].targetSoc > 0) { if (chargingInfo [gunIndex]->EvBatterySoc >= (ShmOCPP16Data->SessionTarget[gunIndex].targetSoc)) { PRINTF_FUNC ( "CheckOcppChargingSOC. G_(%d) - (%d) \n", gunIndex, chargingInfo [gunIndex]->PresentChargedDuration ); result = true; } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SessionTarget[gunIndex].targetSoc > 0) { if (chargingInfo [gunIndex]->EvBatterySoc >= (ShmOCPP20Data->SessionTarget[gunIndex].targetSoc)) { PRINTF_FUNC ( "CheckOcppChargingSOC. G_(%d) - (%d) \n", gunIndex, chargingInfo [gunIndex]->PresentChargedDuration ); result = true; } } } return result; } bool IsGunUsing(byte dcGunIndex) { bool result = false; if((chargingInfo[dcGunIndex]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[dcGunIndex]->SystemStatus <= SYS_MODE_ALARM) || (chargingInfo[dcGunIndex]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[dcGunIndex]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { result = true; } return result; } //========================================== // Log //========================================== void CheckFwSlotStatusLog() { if (bd0_1_status == 0 && bd0_2_status == 1) PRINTF_FUNC("Connector 1 : Chademo"); else if (bd0_1_status == 1 && bd0_2_status == 0) PRINTF_FUNC("Connector 1 : CCS"); else if (bd0_1_status == 1 && bd0_2_status == 1) PRINTF_FUNC("Connector 1 : GB"); if (bd1_1_status == 0 && bd1_2_status == 1) PRINTF_FUNC("Connector 2 : Chademo"); else if (bd1_1_status == 1 && bd1_2_status == 0) PRINTF_FUNC("Connector 2 : CCS"); else if (bd1_1_status == 1 && bd1_2_status == 1) PRINTF_FUNC("Connector 2 : GB"); } void CheckHwSlotStatusLog(byte index) { if (chargingInfo[index]->Type == _Type_Chademo) { PRINTF_FUNC("Hw check : Connector %d, Type : Chademo, Evboard_id = %d \n", index, chargingInfo[index]->Evboard_id); } else if (chargingInfo[index]->Type == _Type_CCS) { PRINTF_FUNC("Hw check : Connector %d, Type : CCS, Evboard_id = %d \n", index, chargingInfo[index]->Evboard_id); } else if (chargingInfo[index]->Type == _Type_GB) { PRINTF_FUNC("Hw check : Connector %d, Type : GB, Evboard_id = %d \n", index, chargingInfo[index]->Evboard_id); } } //========================================== // Check interface status //========================================== int isInterfaceUp(const char *interface) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; strcpy(cmd, "ifconfig"); fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, interface) > 0) { result = PASS; } } } pclose(fp); return result; } //================================= // Create all share memory //================================= int CreateShareMemory() { int MeterSMId; if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmSysConfigAndInfo NG \n"); return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmSysConfigAndInfo NG \n"); return 0; } memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmStatusCodeData NG \n"); return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmStatusCodeData NG \n"); return 0; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmPsuData NG \n"); return 0; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmPsuData NG \n"); return 0; } memset(ShmPsuData, 0, sizeof(struct PsuData)); if(CHAdeMO_QUANTITY > 0) { if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCHAdeMOData NG \n"); return 0; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCHAdeMOData NG \n"); return 0; } memset(ShmCHAdeMOData, 0, sizeof(struct CHAdeMOData)); } if(GB_QUANTITY > 0) { if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmGBTData NG \n"); return 0; } else if ((ShmGBTData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmGBTData NG \n"); return 0; } memset(ShmGBTData, 0, sizeof(struct GBTData)); } //creat ShmCcsData if(CCS_QUANTITY > 0) { if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCcsData NG \n"); return 0; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCcsData NG \n"); return 0; } memset(ShmCcsData, 0, sizeof(struct CcsData)); } //creat ShmPrimaryMcuData if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmPrimaryMcuData NG \n"); return 0; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmPrimaryMcuData NG \n"); return 0; } memset(ShmPrimaryMcuData, 0, sizeof(struct PrimaryMcuData)); //creat ShmFanModuleData if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmFanModuleData NG \n"); return 0; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmFanModuleData NG \n"); return 0; } memset(ShmFanModuleData, 0, sizeof(struct FanModuleData)); //creat ShmRelayModuleData if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmRelayModuleData NG \n"); return 0; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmRelayModuleData NG \n"); return 0; } memset(ShmRelayModuleData, 0, sizeof(struct RelayModuleData)); if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmLedModuleData NG \n"); return 0; } else if ((ShmLedModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmLedModuleData NG \n"); return 0; } memset(ShmLedModuleData, 0, sizeof(struct LedModuleData)); //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmOCPP16Data NG \n"); return 0; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmOCPP16Data NG \n"); return 0; } memset(ShmOCPP16Data,0,sizeof(struct OCPP16Data)); if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget OCPP20Data NG\n"); return 0; } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat OCPP20Data NG\n"); return 0; } memset(ShmOCPP20Data,0,sizeof(struct OCPP20Data)); if ((MeterSMId = shmget(ShmCsuMeterKey, sizeof(struct MeterInformation), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCsuMeterKey NG \n"); return 0; } else if ((ShmCsuMeterData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCsuMeterData NG \n"); return 0; } memset(ShmCsuMeterData, 0, sizeof(struct MeterInformation)); if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCommonKey NG \n"); return 0; } else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCommonKey NG \n"); return 0; } byte buf = 0; if (ShmDcCommonData->rebootCount == 1) buf = ShmDcCommonData->rebootCount; memset(ShmDcCommonData, 0, sizeof(struct DcCommonInformation)); ShmDcCommonData->rebootCount = buf; return 1; } void SetupRebootCount(byte value) { int MeterSMId; if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR_MSG("[main]RecordRebootCount:shmget ShmCommonKey NG \n"); } else { ShmDcCommonData->rebootCount = value; shmctl(MeterSMId, IPC_SET, 0); } } //================================= // LCM Page //================================= void ChangeLcmByIndex(byte page_index) { if (ShmSysConfigAndInfo->SysWarningInfo.Level != _ALARM_LEVEL_CRITICAL || page_index == _LCM_COMPLETE || page_index == _LCM_FIX || page_index == _LCM_EMC) { if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0 && (page_index == _LCM_FIX || page_index == _LCM_EMC)) { bool isUpdate = false; for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if (chargingInfo[_index]->SystemStatus != SYS_MODE_RESERVATION && chargingInfo[_index]->SystemStatus != SYS_MODE_MAINTAIN) { isUpdate = true; } } if (isUpdate && ShmDcCommonData->LcmFwVersion > 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == YES) ShmSysConfigAndInfo->SysInfo.PageIndex = _LCM_EMC; else ShmSysConfigAndInfo->SysInfo.PageIndex = _LCM_FIX; } else ShmSysConfigAndInfo->SysInfo.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"); /* (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"); #ifdef SystemLogMessage DEBUG_INFO_MSG("[main]InitGPIO: Initial GPIO OK \n"); #endif } int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd,wrd; unsigned char *buf; unsigned int ChkSum,ChkSumOrg; if((buf=malloc(MtdBlockSize))==NULL) { DEBUG_ERROR_MSG("malloc buffer NG,rebooting..\r\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.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("/dev/mtdblock10", O_RDWR); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR_MSG("open mtdblock10 NG,rebooting..\r\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd=read(fd, buf, MtdBlockSize); close(fd); if(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; // for(wrd=0;wrdCsuBootLoadFwRev);wrdModelName,buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)),ARRAY_SIZE(ptr->ModelName)); memcpy(&ptr->SerialNumber,buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)+ARRAY_SIZE(ptr->ModelName)+ARRAY_SIZE(ptr->AcModelName)),ARRAY_SIZE(ptr->SerialNumber)); //================================================ // Load configuration from mtdblock11 //================================================ if(ChkSum!=ChkSumOrg) { DEBUG_ERROR_MSG("Primary SysConfigData checksum NG, read backup\r\n"); system("nanddump /dev/mtd11 -f /mnt/EvseConfig.bin"); //fd = open("/dev/mtdblock11", O_RDWR); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR_MSG("open mtdblock11 (backup) NG,rebooting..\r\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.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(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; // for(wrd=0;wrdCsuBootLoadFwRev);wrdAlarmCode.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(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; // for(wrd=0;wrdCsuBootLoadFwRev);wrdCsuBootLoadFwRev)), &ptr->ModelName, ARRAY_SIZE(ptr->ModelName)); memcpy(buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)+ARRAY_SIZE(ptr->ModelName)+ARRAY_SIZE(ptr->AcModelName)), &ptr->SerialNumber, ARRAY_SIZE(ptr->SerialNumber)); if(ChkSum!=ChkSumOrg) { DEBUG_ERROR_MSG("factory default SysConfigData checksum NG, restore factory default\r\n"); free(buf); //system("cd /root;./FactoryConfig -m"); sleep(5); char facBuf[256]; sprintf(facBuf, "cd /root;./FactoryConfig -m %s %s", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); system(facBuf); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } } } //load OK memcpy((struct SysConfigData *)ptr,buf,sizeof(struct SysConfigData)); free(buf); system("rm -f /mnt/EvseConfig.bin"); // SysConfig in flash is empty (0xffffffff) if((strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) || (strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) || (strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) || (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff)) { if(strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) { PRINTF_FUNC("Model name over length.\n"); memset(ShmSysConfigAndInfo->SysConfig.ModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) { PRINTF_FUNC("Model serial number over length.\n"); memset(ShmSysConfigAndInfo->SysConfig.SerialNumber, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) { PRINTF_FUNC("System id over length.\n"); memset(ShmSysConfigAndInfo->SysConfig.SystemId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)); } if(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff) { PRINTF_FUNC("Ethernet dhcp config is null.\n"); } system("cd /root;./Module_FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } PRINTF_FUNC("*********************************************************** \n"); DEBUG_INFO_MSG("Load SysConfigData OK\r\n"); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy((char*)ShmOCPP16Data->ChargeBoxId, (char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy((char*)ShmOCPP20Data->ChargeBoxId, (char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); } return PASS; } int isRouteFail() { int result = YES; FILE *fp; char buf[512]; fp = popen("route -n", "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, "eth0") != NULL) result = NO; } } pclose(fp); return result; } int isReachableInternet() { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; // if (ShmOCPP16Data->OcppConnStatus == PASS) // { // result = PASS; // } // else { strcpy(cmd, "ifconfig eth0"); fp = popen(cmd, "r"); if (fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if (strstr(buf, "inet addr:") > 0) { sscanf(buf, "%*s%s", tmp); substr(tmp, tmp, strspn(tmp, "addr:"), strlen(buf)-strspn(tmp, "addr:")); if (strcmp(tmp, (char *)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress) != EQUAL) { strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, tmp); } sscanf(buf, "%*s%*s%*s%s", tmp); substr(tmp, tmp, strspn(tmp, "Mask:"), strlen(buf)-strspn(tmp, "Mask:")); if (strcmp(tmp, (char *)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress) != 0) { strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress, tmp); } } } } pclose(fp); memset(buf, 0x00, sizeof(buf)); for(int idx=0;idx 0) { //sscanf(buf, "%*s%*s%*s%*s%*s%*s%s", tmp); if(strstr(buf,"100%") != NULL) { } else { result = PASS; } //DEBUG_INFO("%s",buf); //DEBUG_INFO("%s\n",tmp); } } } pclose(fp); } } return result; } void InitEthernet() { system("ifconfig eth0 down");// eth0 down system("ifconfig eth1 down");// eth1 down sleep(2); char tmpbuf[256]; // /sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 down system("echo 1 > /sys/class/gpio/gpio110/value");//reset PHY sleep(2); //Init Eth0 for internet memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf,0,256); sprintf(tmpbuf,"route add default gw %s eth0 ", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); //system("ifconfig lo up"); // /sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up //Init Eth1 for administrator tool memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth1 %s netmask %s up", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress); system(tmpbuf); //Run DHCP client if enabled system("killall udhcpc"); system("rm -rf /etc/resolv.conf"); system("echo nameserver 8.8.8.8 > /etc/resolv.conf"); //Google DNS server system("echo nameserver 180.76.76.76 > /etc/resolv.conf"); //Baidu DNS server //system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up"); if(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0) { sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } //Upgrade system id to /etc/hostname sprintf(tmpbuf, "echo %s > /etc/hostname", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); pid_t pid = fork(); uint8_t cnt_pingDNS_Fail; if(pid == 0) { for(;;) { if (isRouteFail()) { //PRINTF_FUNC("eth0 not in route, restart eht0. \n"); system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up"); if (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0) { InitialDHCP(); } else { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf,0,256); sprintf(tmpbuf,"route add default gw %s eth0 &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); } } if(isReachableInternet() == PASS) { ShmSysConfigAndInfo->SysInfo.ethInternetConn = YES; cnt_pingDNS_Fail = 0; } else { if(++cnt_pingDNS_Fail > 3) { ShmSysConfigAndInfo->SysInfo.ethInternetConn = NO; if((ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient==0)) { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } else { system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf,0,256); sprintf(tmpbuf,"route add default gw %s eth0 &", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); } cnt_pingDNS_Fail = 0; } } bool ethResult = ShmSysConfigAndInfo->SysInfo.ethInternetConn; if(ethResult == YES) { system("/sbin/ifmetric eth0 0"); if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) system("/sbin/ifmetric mlan0 1"); if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) system("/sbin/ifmetric ppp0 2"); } if (!ethResult && ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode != _SYS_WIFI_MODE_DISABLE && (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W' || ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { //ethResult = ShmSysConfigAndInfo->SysConfig.AthInterface.WifiNetworkConn; ethResult = ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi == YES ? NO : YES; if (ethResult) { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric mlan0 0"); } if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) system("/sbin/ifmetric ppp0 2"); } } if (!ethResult && ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == YES && (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T' || ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { //ethResult = ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomNetworkConn; ethResult = ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi == YES ? NO : YES; if (ethResult) { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) system("/sbin/ifmetric mlan0 2"); if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/sbin/ifmetric eth0 1"); system("/sbin/ifmetric ppp0 0"); } } } ShmSysConfigAndInfo->SysInfo.InternetConn = ethResult; sleep(5); } } #ifdef SystemLogMessage DEBUG_INFO_MSG("[main]InitEthernet: Initial Ethernet OK. \n"); #endif } int InitialRfidPort() { int uartO2 = open(rfidPortName, O_RDWR); struct termios tios; if (uartO2 != FAIL) { ioctl (uartO2, TCGETS, &tios); tios.c_cflag = B19200 | CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = (unsigned char) 1; tios.c_lflag = 0; tcflush(uartO2, TCIFLUSH); ioctl(uartO2, TCSETS, &tios); } if (uartO2 < 0) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RfidModuleCommFail = 1; } return uartO2; } void GetMacAddress() { for (byte index = 0; index < 2; index++) { int fd; struct ifreq ifr; char tarEth[5]; char Mac[18]; sprintf(tarEth,"eth%d",index); fd = socket(AF_INET, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name, tarEth, IFNAMSIZ - 1); ioctl(fd, SIOCGIFHWADDR, &ifr); close(fd); sprintf(Mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2], ifr.ifr_hwaddr.sa_data[3], ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]); if (index == 0) strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, Mac); else strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthMacAddress, Mac); } } void GetFirmwareVersion() { // Get CSU root file system version sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, fwVersion); byte count = 0, chademo = 0, ccs = 0, gb = 0; for(uint8_t idx=0;idx<3;idx++) { if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'J' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'K' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'L') { chademo++; count++; } else if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'G') { gb++; count++; } else if (ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'U' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'E' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'T' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'D' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'M' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'N' || ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == 'R' || ShmSysConfigAndInfo->SysConfig.ModelName [7 + idx] == 'V' || ShmSysConfigAndInfo->SysConfig.ModelName [7 + idx] == 'F' || ShmSysConfigAndInfo->SysConfig.ModelName [7 + idx] == 'Y' || ShmSysConfigAndInfo->SysConfig.ModelName [7 + idx] == 'Z' ) { ccs++; count++; } } if (count == 1) { if (chademo > 0) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '1'; else if (ccs > 0) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '2'; else if (gb > 0) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '3'; } else { if (chademo == 1 && ccs == 1) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '4'; else if (chademo == 1 && gb == 1) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '5'; else if (ccs == 1 && gb == 1) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '6'; else if (chademo == 2) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '7'; else if (ccs == 2) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '8'; else if (gb == 2) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[7] = '9'; } // Get network option from model name switch(ShmSysConfigAndInfo->SysConfig.ModelName[10]) { case 'B': case 'U': //Blue tooth ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '3'; break; case 'W': // WIFI ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '1'; break; case 'T': // 3G/4G ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '2'; break; case 'D': ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '5'; break; default: // LAN ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '0'; break; } // Get rating power from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[4], 0x03); // Get IEC or UL char _buf[3] = {0}; memcpy(_buf, &ShmSysConfigAndInfo->SysConfig.ModelName[2], 1); if (strcmp(_buf, "Y") == EQUAL || strcmp(_buf, "Y") == EQUAL) ShmSysConfigAndInfo->SysInfo.ChargerType = _CHARGER_TYPE_IEC; else if (strcmp(_buf, "W") == EQUAL) ShmSysConfigAndInfo->SysInfo.ChargerType = _CHARGER_TYPE_UL; memcpy(_buf, &ShmSysConfigAndInfo->SysConfig.ModelName[12], 2); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[12], 2); if (strcmp(_buf, "PN") == EQUAL || strcmp(_buf, "N7") == EQUAL || strcmp(_buf, "NX") == EQUAL || strcmp(_buf, "OL") == EQUAL || strcmp(_buf, "DE") == EQUAL) ShmDcCommonData->ShowLogoFlag = NO; else ShmDcCommonData->ShowLogoFlag = YES; if (ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'G') ShmDcCommonData->chargerType = CHARGER_TYPE_SIMPLE; else ShmDcCommonData->chargerType = CHARGER_TYPE_STANDARD; } void InitialGunIndexToUnUse() { for (byte index = 0; index < CHAdeMO_QUANTITY; index++) { ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index = NO_DEFINE; } for (byte index = 0; index < CCS_QUANTITY; index++) { ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index = NO_DEFINE; } for (byte index = 0; index < GB_QUANTITY; index++) { ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index = NO_DEFINE; } for (byte index = 0; index < AC_QUANTITY; index++) { ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index = NO_DEFINE; } } void InitialShareMemoryInfo() { FILE *fp; char cmd[512]; char buf[512]; // sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn, "Internet"); // sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, " "); // sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd, " "); ShmSysConfigAndInfo->SysConfig.TotalConnectorCount = 0; ShmSysConfigAndInfo->SysConfig.AcConnectorCount = 0; ShmSysConfigAndInfo->SysInfo.FactoryConfiguration = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageR = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageS = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageT = 0; ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = 0; ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed = 0; ShmSysConfigAndInfo->SysInfo.AuxPower5V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower12V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower24V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower48V = 0; sprintf((char *)ShmSysConfigAndInfo->SysInfo.CsuHwRev, "REV:5.0"); memcpy(ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev)); sprintf(cmd, "/bin/uname -r"); fp = popen(cmd, "r"); if(fp == NULL) sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, "Unknown version"); else { while(fgets(buf, sizeof(buf), fp) != NULL) { strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, buf); } } GetFirmwareVersion(); //sprintf((char *) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, fwVersion); sprintf((char *) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.LcmHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.LcmFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuSecFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.AuxPwrHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.AuxPwrFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, " "); ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = 0; ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp = 0; ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp = 0; ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp = 0; ShmSysConfigAndInfo->SysInfo.InternetConn = NO; ShmSysConfigAndInfo->SysInfo.OcppConnStatus = NO; ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE; strcpy((char *) ShmSysConfigAndInfo->SysConfig.UserId, ""); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcContactStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDipSwitchStestFail = NO; memset(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, 0, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev)); memset(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, 0, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev)); ShmPrimaryMcuData->SelfTest_Comp = NO; ShmRelayModuleData->SelfTest_Comp = NO; ShmFanModuleData->SelfTest_Comp = NO; ShmLedModuleData->SelfTest_Comp = NO; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0; ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE; ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOTTING; ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower = -1; ShmFanModuleData->TestFanSpeed = 0; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ModelNameNoneMatchStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = NO; InitialGunIndexToUnUse(); ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag = NO; ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V015S0; ShmDcCommonData->psuKeepCommunication = NO; ShmDcCommonData->acContactSwitch = NO; ShmDcCommonData->ConnectErrList[0].GunErrMessage = 0; ShmDcCommonData->ConnectErrList[1].GunErrMessage = 0; ShmDcCommonData->LcmFwVersion = 0; ShmDcCommonData->minOutputCur = 0; ShmDcCommonData->evBoardResetFlag = NO; ShmDcCommonData->enObtainAuthorizbyCCID = NO; ShmDcCommonData->_CcidAuthProcessStep = _CCID_NONE; ShmDcCommonData->_isPsuErrorOccur = NO; ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag = NO; } int Initialization() { // 初始化卡號驗證的 Flag ClearAuthorizedFlag(); // 初始化插槍驗證的 Flag ClearDetectPluginFlag(); // UART 2 for Rfid rfidFd = InitialRfidPort(); int pinOut[2] = { 116, 115 }; //D13(Cha)、C13(CCS) for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { chargingInfo[count]->RemoteStartFlag = NO; chargingInfo[count]->ReservedStartFlag = NO; if (chargingInfo[count]->Type == _Type_Chademo) { gpio_set_value(pinOut[count], 0x00); ShmCHAdeMOData->evse[chargingInfo[count]->type_index].SelfTest_Comp = NO; } else if (chargingInfo[count]->Type == _Type_GB) { gpio_set_value(pinOut[count], 0x00); ShmGBTData->evse[chargingInfo[count]->type_index].SelfTest_Comp = NO; } else if (chargingInfo[count]->Type == _Type_CCS) { if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) gpio_set_value(pinOut[1], 0x00); else gpio_set_value(pinOut[count], 0x00); ShmCcsData->V2GMessage_DIN70121[chargingInfo[count]->type_index].SelfTest_Comp = NO; } strcpy((char *)ShmDcCommonData->_reserved_UserId[count], ""); } byte acDirIndex = 0; for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { if (count == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; ocpp_set_noErrorCode_cmd(count + acDirIndex, "NoError"); } byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; count++) { ac_chargingInfo[count]->RemoteStartFlag = NO; if (ac_chargingInfo[count]->Type == _Type_AC) { ac_chargingInfo[count]->SelfTest_Comp = NO; ocpp_set_noErrorCode_cmd(count + hasDc, "NoError"); } } PRINTF_FUNC("Information check done \n"); return PASS; } bool InitialSystemDefaultConfig() { bool result = true; LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); PRINTF_FUNC("ModelName = %s", ShmSysConfigAndInfo->SysConfig.ModelName); 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; } bool DisplaySelfTestFailReason() { bool result = false; // RB、FB、407、EV 小板中有些板子無回應 if (ShmRelayModuleData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail = YES; result = true; } if (ShmFanModuleData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail = YES; result = true; } if (ShmPrimaryMcuData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = YES; result = true; } // if (ShmLedModuleData->SelfTest_Comp == NO) // { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail = YES; } if (ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES) { result = true; } for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->Type == _Type_Chademo) { if (ShmCHAdeMOData->evse[chargingInfo[index]->type_index].SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoboardStestFail = YES; result = true; } } else if (chargingInfo[index]->Type == _Type_GB) { if (ShmGBTData->evse[chargingInfo[index]->type_index].SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbtboardStestFail = YES; result = true; } } else if (chargingInfo[index]->Type == _Type_CCS) { if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { if (ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail = YES; result = true; } } } } for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; index++) { // 先借 GBT 顯示 if (ac_chargingInfo[index]->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcConnectorStestFail = YES; result = true; } } if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO) { // AC Contact 未搭上 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcContactStestFail = YES; result = true; } else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDipSwitchStestFail == YES) { result = true; } else if (ShmPsuData->SystemAvailablePower <= 0 && ShmPsuData->SystemAvailableCurrent <= 0) { // PSU 通訊問題 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = YES; result = true; } return result; } void SelfTestRun() { bool evInitFlag = false; StartSystemTimeoutDet(Timeout_SelftestChk); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_VERSION; while (ShmSysConfigAndInfo->SysInfo.SelfTestSeq != _STEST_COMPLETE || GetTimeoutValue(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) <= 20) { ReviewCriticalAlarm(); ChkPrimaryStatus(); if (ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_CRITICAL || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDipSwitchStestFail == YES) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; return; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) { if (ShmPsuData->Work_Step == _NO_WORKING || ShmSysConfigAndInfo->SysInfo.SelfTestSeq == _STEST_FAIL) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; return; } switch(ShmSysConfigAndInfo->SysInfo.SelfTestSeq) { case _STEST_VERSION: { if (strlen((char *)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev[0] != '\0') { //PRINTF_FUNC("RB pass \n"); ShmRelayModuleData->SelfTest_Comp = YES; } if (strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0') { //PRINTF_FUNC("Fan pass \n"); ShmFanModuleData->SelfTest_Comp = YES; } if (strlen((char *)ShmPrimaryMcuData->version) != 0 || ShmPrimaryMcuData->version[0] != '\0') { //PRINTF_FUNC("407 pass \n"); ShmPrimaryMcuData->SelfTest_Comp = YES; } // EV 小板 if (!evInitFlag) { evInitFlag = YES; for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->Type == _Type_Chademo) { if (strlen((char *)ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version) != 0 || ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version[0] != '\0') { //PRINTF_FUNC("chademo pass \n"); ShmCHAdeMOData->evse[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { //PRINTF_FUNC("chademo fw lose...... %s \n", ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version); evInitFlag = NO; } } else if (chargingInfo[index]->Type == _Type_GB) { if (strlen((char *)ShmGBTData->evse[chargingInfo[index]->type_index].version) != 0 || ShmGBTData->evse[chargingInfo[index]->type_index].version[0] != '\0') { //PRINTF_FUNC("GBT pass \n"); ShmGBTData->evse[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { //PRINTF_FUNC("GBT fw lose...... %s \n", ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version); evInitFlag = NO; } } else if (chargingInfo[index]->Type == _Type_CCS) { if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { if (strlen((char *)ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version) != 0 || ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version[0] != '\0') { //PRINTF_FUNC("ccs fw = %s \n", ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version); ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { //PRINTF_FUNC("ccs fw lose...... %s \n", ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version); evInitFlag = NO; } } } } for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; index++) { if (ac_chargingInfo[index]->Type == _Type_AC) { if (strlen((char *)ac_chargingInfo[index]->version) != 0 || ac_chargingInfo[index]->version[0] != '\0') { ac_chargingInfo[index]->SelfTest_Comp = YES; } else { evInitFlag = NO; } } } } if (ShmFanModuleData->SelfTest_Comp && ShmRelayModuleData->SelfTest_Comp && ShmPrimaryMcuData->SelfTest_Comp && evInitFlag) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_AC_CONTACTOR; } } break; case _STEST_AC_CONTACTOR: { //ShmPsuData->Work_Step = _TEST_COMPLETE; // 因為 30KW 以下沒有 Relay feedback 功能,所以暫時先直接跳過 if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_DETECT; PRINTF_FUNC("Communication board pass. \n"); } } break; case _STEST_PSU_DETECT: { if (ShmPsuData->Work_Step >= GET_SYS_CAP) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_CAP; } } break; case _STEST_PSU_CAP: { // 此測試是要確認當前總輸出能力 // 如果沒有 PSU 模組請 bypass if (ShmPsuData->Work_Step == BOOTING_COMPLETE) { sleep(1); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_COMPLETE; ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE; } } break; } } else break; usleep(100000); } } int SpawnTask() { 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_PsuComm &"); system("/root/Module_ProduceUtils &"); ocpp_process_start(); if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') { system("/root/Module_4g &"); } if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') { system("/root/Module_Wifi &"); } if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D') { system("/root/Module_4g &"); system("/root/Module_Wifi &"); } return PASS; } int StoreUsrConfigData(struct SysConfigData *UsrData) { int result = PASS; int fd,wrd; unsigned int i,Chk; unsigned char *ptr, *BufTmp; Chk=0; ptr=(unsigned char *)UsrData; if((BufTmp = malloc(MtdBlockSize)) != NULL) { memset(BufTmp, 0, MtdBlockSize); memcpy(BufTmp, ptr, sizeof(struct SysConfigData)); for(i=0; i 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) { DEBUG_ERROR_MSG("write /dev/mtdblock11(backup) NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("open /dev/mtdblock11(backup) NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("write /dev/mtdblock10 NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("open /dev/mtdblock10 NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("alloc BlockSize NG\r\n"); result = FAIL; } if(BufTmp != NULL) free(BufTmp); return result; } //=============================================== // Common Detect Chk - Stop Charging ? //=============================================== bool isEvBoardStopChargeFlag(byte gunIndex) { return chargingInfo[gunIndex]->StopChargeFlag; } bool isEvBoardNormalStopChargeFlag(byte gunIndex) { return chargingInfo[gunIndex]->NormalStopChargeFlag; } //=============================================== // 插槍鎖槍狀況 //=============================================== void ClearDetectPluginFlag() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO; for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (chargingInfo[gun_index]->RemoteStartFlag == YES) chargingInfo[gun_index]->RemoteStartFlag = NO; if (chargingInfo[gun_index]->ReservedStartFlag == YES) chargingInfo[gun_index]->ReservedStartFlag = NO; } if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE) ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE; } void DetectPluginStart() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = YES; } bool isDetectPlugin() { if(ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES) return YES; return NO; } bool isEvGunLocked(byte gunIndex) { return chargingInfo[gunIndex]->GunLocked; } //=============================================== // Common Detect Chk - Chademo //=============================================== bool isEvContactorWelding_chademo(byte gunIndex) { return DetectBitValue(ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].EvDetection, 3); } bool isEvStopReq_chademo(byte gunIndex) { return DetectBitValue(ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].EvDetection, 4); } byte isPrechargeStatus_chademo(byte gunIndex) { byte result = 0x00; result = ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].PresentMsgFlowStatus; return result; } //=============================================== // Common Detect Chk - GB //=============================================== byte isPrechargeStatus_gb(byte gunIndex) { byte result = 0x00; result = ShmGBTData->ev[chargingInfo[gunIndex]->type_index].PresentMsgFlowStatus; return result; } //=============================================== // Common Detect Chk - CCS //=============================================== byte isPrechargeStatus_ccs(byte gunIndex) { byte result = 0x00; if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { result = ShmCcsData->V2GMessage_DIN70121[chargingInfo[gunIndex]->type_index].PresentMsgFlowStatus; } return result; } //=============================================== // Callback //=============================================== void DisplayChargingInfo() { PRINTF_FUNC("*********** DisplayChargingInfo *********** \n"); for (byte i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->SystemStatus != SYS_MODE_IDLE && chargingInfo[i]->SystemStatus != SYS_MODE_RESERVATION) { ChangeGunSelectByIndex(i); usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; return; } } if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE && ac_chargingInfo[0]->SystemStatus >= SYS_MODE_PREPARING && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_COMPLETE) { ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX; } usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _AutoReturnTimeout() { PRINTF_FUNC("*********** _AutoReturnTimeout %d*********** \n", ShmSysConfigAndInfo->SysInfo.PageIndex); if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG) { ClearDetectPluginFlag(); } else if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_COMP) { bool needPluginDet = true; if (ShmDcCommonData->enObtainAuthorizbyCCID) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_CHECK) { needPluginDet = false; break; } } } if (needPluginDet) DetectPluginStart(); ShmDcCommonData->_CcidAuthProcessStep = _CCID_AUTHCOMP; } else if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_FAIL) { ShmDcCommonData->_CcidAuthProcessStep = _CCID_AUTHFAIL; } usleep(50000); stopChargingChkByCard = false; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _SelfTestTimeout() { if (ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { ChargingAlarmProcess(gun_index); } } ShmPsuData->Work_Step = _NO_WORKING; ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; PRINTF_FUNC("Self test timeout. \n"); } void _AuthorizedTimeout() { //if(IsAuthorizingMode()) { PRINTF_FUNC("*********** _AuthorizedTimeout *********** \n"); isCardScan = false; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; ShmDcCommonData->_CcidAuthProcessStep = _CCID_AUTHFAIL; //ChangeLcmByIndex(_LCM_AUTHORIZ_FAIL); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ClearAuthorizedFlag(); } } void _DetectPlugInTimeout() { PRINTF_FUNC("*********** _DetectPlugInTimeout (%d)*********** \n", _connectionTimeout); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ClearDetectPluginFlag(); usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _DetectEvChargingEnableTimeout(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) { if(!isEvGunLocked(gunIndex)) { PRINTF_FUNC("*********** _DetectEvChargingEnableTimeout (chademo) ***********\n"); } } else if (chargingInfo[gunIndex]->Type == _Type_GB) { if(!isEvGunLocked(gunIndex)) { PRINTF_FUNC("*********** _DetectEvChargingEnableTimeout (gb) ***********\n"); } } else if (chargingInfo[gunIndex]->Type == _Type_CCS) { if(!isEvGunLocked(gunIndex)) { PRINTF_FUNC("*********** _DetectEvChargingEnableTimeout (ccs) ***********\n"); } } ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(); } void _DetectEvseChargingEnableTimeout(byte gunIndex) { PRINTF_FUNC("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********\n"); //if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS) { setChargerMode(gunIndex, SYS_MODE_IDLE); _AutoReturnTimeout(); } } void _PrepareTimeout(byte gunIndex) { PRINTF_FUNC("*********** _PrepareTimeout ***********\n"); setChargerMode(gunIndex, SYS_MODE_IDLE); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = YES; _AutoReturnTimeout(); } void _CcsPrechargeTimeout(byte gunIndex) { PRINTF_FUNC("*********** _CcsPrechargeTimeout ***********\n"); setChargerMode(gunIndex, SYS_MODE_IDLE); } //=============================================== // 卡號驗證 //=============================================== void AuthorizingStart() { ocpp_set_authorizeReq_cmd(YES); ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = YES; } void ClearAuthorizedFlag() { ocpp_set_authorizeConf_cmd(NO); ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = NO; } bool isAuthorizedComplete() { return ocpp_get_authorize_conf(); } bool IsAuthorizingMode() { if(ShmSysConfigAndInfo->SysInfo.AuthorizeFlag == NO) return false; return true; } //=============================================== // 紀錄 Alarm Code //=============================================== void RecordAlarmCode(byte gunIndex, char *code) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) == EQUAL) memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, code, 6); 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, "012320") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectUCP = YES; else if (strcmp(code, "012321") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectUCP = YES; else if (strcmp(code, "012322") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectUCP = YES; else if (strcmp(code, "011039") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ParallelRelayWeldingFault = YES; else if (strcmp(code, "011040") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ParallelRelayDrivingFault = YES; } void ResetChargerAlarmCode(byte gunIndex, char *code) { 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, "012320") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ChaConnectUCP = NO; else if (strcmp(code, "012321") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.CCSConnectUCP = NO; else if (strcmp(code, "012322") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.GBTConnectUCP = NO; else if (strcmp(code, "011039") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ParallelRelayWeldingFault = NO; else if (strcmp(code, "011040") == EQUAL) ShmDcCommonData->ConnectErrList[gunIndex].GunBits.ParallelRelayDrivingFault = NO; if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) != EQUAL) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012229", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012230", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012231", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011011", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011013", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011015", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011012", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011014", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011016", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011018", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011019", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011020", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012320", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012321", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012322", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011039", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "011040", 6) == EQUAL) { memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6); } } } void ReleaseSysAlarmCode(byte gunIndex) { // 回 idle 後主要清除 GFD Trip、UVP、OVP、GFD Warning,PSU fail if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) != EQUAL) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012251", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012252", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012324", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012325", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012267", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012346", 6) == EQUAL) { memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6); } } if (gunIndex == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AbnormalVoltageOnOutputLine_1 = NO; else if (gunIndex == 1) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AbnormalVoltageOnOutputLine_2 = NO; if (chargingInfo[gunIndex]->Type == _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.ChaConnectUCP = NO; if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) != EQUAL) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012234", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012289", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012217", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012296", 6) == EQUAL) { memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6); } } } else if (chargingInfo[gunIndex]->Type == _Type_CCS) { 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.CCSConnectUCP = NO; if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) != EQUAL) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012235", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012288", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012219", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012297", 6) == EQUAL) { memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6); } } } else if (chargingInfo[gunIndex]->Type == _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.GBTConnectUCP = NO; if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6) != EQUAL) { if (strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012236", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012290", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012221", 6) == EQUAL || strncmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "012298", 6) == EQUAL) { memcpy(chargingInfo[gunIndex]->ConnectorAlarmCode, "", 6); } } } ocpp_clear_errorCode_cmd(gunIndex); } void NormalStop(byte gunIndex) { PRINTF_FUNC("NormalStop (%d) \n", gunIndex); } //=============================================== // EmergencyStop and Charging Stop //=============================================== void ChargingTerminalProcess(byte gunIndex) { setChargerMode(gunIndex, SYS_MODE_TERMINATING); } void ChargingAlarmProcess(byte gunIndex) { CheckSystemErrorFunction(gunIndex); ocpp_set_errCode_cmd(gunIndex); setChargerMode(gunIndex, SYS_MODE_ALARM); } void AcChargingTerminalProcess() { ac_chargingInfo[0]->SystemStatus = SYS_MODE_TERMINATING; } //void StopChargingProcessByString(byte level) //{ // if (level > ShmSysConfigAndInfo->SysWarningInfo.Level) // { // ShmSysConfigAndInfo->SysWarningInfo.Level = level; // } //} //void ReleaseChargingProcessByString(byte level) //{ // if (level >= ShmSysConfigAndInfo->SysWarningInfo.Level) // ShmSysConfigAndInfo->SysWarningInfo.Level = 0; //} // 一般錯誤停止充電處理函式 void BoardErrOccurByString(byte index, char *code) { //byte level = 1; if ((chargingInfo[index]->SystemStatus > SYS_MODE_IDLE && chargingInfo[index]->SystemStatus < SYS_MODE_TERMINATING) || (chargingInfo[index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { PRINTF_FUNC("BoardErrOccurByString (%d) - (%s) \n", index, code); if (strncmp(code, "023730", 6) == EQUAL && ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == NO) { ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop = YES; } ChargingAlarmProcess(index); } //60StopChargingProcessByString(level); } // 急停狀況的停止充電處理函式 void EmcOccurThenStopCharging() { //byte level = 2; // 嚴重的急停有以下幾種 : EMC 按鈕、Mainbreak、Dooropen... // 其錯誤等級為 2 for (byte gun = 0; gun < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun++) { if ((chargingInfo[gun]->SystemStatus > SYS_MODE_IDLE && chargingInfo[gun]->SystemStatus < SYS_MODE_TERMINATING) || (chargingInfo[gun]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[gun]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { ChargingAlarmProcess(gun); } } //StopChargingProcessByString(level); } void ReleaseBoardErrOccurByString(byte index, char *code) { if (strncmp(code, "023730", 6) == 0 && ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == YES) { ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop = NO; } } void ReleaseEmsOccureByString(byte index, char *code) { if (strncmp(code, "012251", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = NO; } else if (strncmp(code, "012252", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = NO; } else if (strncmp(code, "012237", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = NO; } else if (strncmp(code, "012238", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = NO; } } //=============================================== // 確認硬體 (按鈕) 狀態 //=============================================== bool leftBtnPush = false; bool rightBtnPush = false; void ButtonTriggerEvent() { if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS && ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS) ShmSysConfigAndInfo->SysConfig.ShowInformation = YES; else ShmSysConfigAndInfo->SysConfig.ShowInformation = NO; if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS && !leftBtnPush) { if(!leftBtnPush) { leftBtnPush = BTN_PRESS; PRINTF_FUNC("left btn down............................... \n"); if (ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE) { switch(ac_chargingInfo[0]->SystemStatus) { case SYS_MODE_IDLE: case SYS_MODE_MAINTAIN: case SYS_MODE_RESERVATION: { if(isDetectPlugin()) { _DetectPlugInTimeout(); StopSystemTimeoutDet(); } } break; case SYS_MODE_MODE_REASSIGN_CHECK: case SYS_MODE_REASSIGN: case SYS_MODE_PREPARING: case SYS_MODE_PREPARE_FOR_EV: case SYS_MODE_PREPARE_FOR_EVSE: case SYS_MODE_CCS_PRECHARGE_STEP0: case SYS_MODE_CCS_PRECHARGE_STEP1: { // 取消充電 AcChargingTerminalProcess(); } break; case SYS_MODE_CHARGING: { if (ShmSysConfigAndInfo->SysConfig.StopChargingByButton == YES || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE && ac_chargingInfo[0]->isRemoteStart == NO) || ac_chargingInfo[0]->isRemoteStart) { // 停止充電 AcChargingTerminalProcess(); } } break; case SYS_MODE_COMPLETE: {} break; } } else { switch(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus) { case SYS_MODE_IDLE: case SYS_MODE_MAINTAIN: case SYS_MODE_RESERVATION: { if(isDetectPlugin()) { _DetectPlugInTimeout(); StopSystemTimeoutDet(); } } break; case SYS_MODE_MODE_REASSIGN_CHECK: case SYS_MODE_REASSIGN: case SYS_MODE_PREPARING: case SYS_MODE_PREPARE_FOR_EV: case SYS_MODE_PREPARE_FOR_EVSE: case SYS_MODE_CCS_PRECHARGE_STEP0: case SYS_MODE_CCS_PRECHARGE_STEP1: { // 按鈕 - 取消充電 // if (ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE) // AcChargingTerminalProcess(); // else ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } break; case SYS_MODE_CHARGING: { if (ShmSysConfigAndInfo->SysConfig.StopChargingByButton == YES || ShmDcCommonData->_authWithCcidFlag [ShmSysConfigAndInfo->SysInfo.CurGunSelected] == _CCID_AUTHCOMP || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->isRemoteStart == NO) || chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->isRemoteStart) { // 按鈕 - 停止充電 NormalStop(ShmSysConfigAndInfo->SysInfo.CurGunSelected); ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } } break; case SYS_MODE_COMPLETE: { // 回 IDLE //PRINTF_FUNC("right btn down.................SYS_MODE_COMPLETE \n"); //chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = SYS_MODE_IDLE; } break; } } } } else if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_RELEASE) { if(leftBtnPush) { leftBtnPush = BTN_RELEASE; PRINTF_FUNC("left btn up............................... \n"); } } if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS && !rightBtnPush) { if(!rightBtnPush) { rightBtnPush = BTN_PRESS; PRINTF_FUNC("right btn down .................... %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG && ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) return; if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE && ShmSysConfigAndInfo->SysInfo.CurGunSelected + 1 == ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) { ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected + 1 < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO) { ShmSysConfigAndInfo->SysInfo.CurGunSelected++; ChangeGunSelectByIndex(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } else if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if (chargingInfo[_index]->SystemStatus != SYS_MODE_BOOTING && chargingInfo[_index]->SystemStatus != SYS_MODE_IDLE && chargingInfo[_index]->SystemStatus != SYS_MODE_RESERVATION) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = _index; ChangeGunSelectByIndex(ShmSysConfigAndInfo->SysInfo.CurGunSelected); return; } } ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0; ChangeGunSelectByIndex(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } else { ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0; ChangeGunSelectByIndex(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } } } else if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_RELEASE) { if(rightBtnPush) { rightBtnPush = BTN_RELEASE; PRINTF_FUNC("right btn up............................... \n"); } } } void ChkPrimaryStatus() { if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = YES; EmcOccurThenStopCharging(); } else ReleaseEmsOccureByString(0, "012251"); if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = YES; EmcOccurThenStopCharging(); } else ReleaseEmsOccureByString(0, "012238"); if (ShmPrimaryMcuData->InputDet.bits.SpdDetec == ABNORMAL) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = NO; if (ShmPrimaryMcuData->InputDet.bits.DoorOpen == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = YES; EmcOccurThenStopCharging(); } else ReleaseEmsOccureByString(0, "012252"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm) { EmcOccurThenStopCharging(); } else ReleaseEmsOccureByString(0, "012267"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuComminicationErrWithCSU) { EmcOccurThenStopCharging (); } else ReleaseEmsOccureByString (0,"012346"); } //=============================================== // 確認各小板偵測的錯誤狀況 //=============================================== void CheckSystemErrorFunction(byte index) { // System if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip) RecordAlarmCode(index, "012251"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip) RecordAlarmCode(index, "012238"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen) RecordAlarmCode(index, "012252"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm) RecordAlarmCode(index, "012267"); if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuComminicationErrWithCSU) RecordAlarmCode(index, "012346"); if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES) { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_NONE) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_INUVP; } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES) RecordAlarmCode(index, "012203"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES) RecordAlarmCode(index, "012204"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES) RecordAlarmCode(index, "012205"); chargingInfo[index]->StopChargeFlag = YES; } else { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_INUVP) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; } } } else { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_INUVP) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES) { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_NONE) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_INOVP; } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES) RecordAlarmCode(index, "012200"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES) RecordAlarmCode(index, "012201"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES) RecordAlarmCode(index, "012202"); chargingInfo[index]->StopChargeFlag = YES; } else { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_INOVP) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; } } } //=============================================== // 確認 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() { int pinIn[4] = { 22, 23, 44, 45 }; unsigned int gpioValue = 0; for (int i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); { switch (pinIn[i]) { case 22: bd1_1_status = gpioValue; break; case 23: bd1_2_status = gpioValue; break; case 44: bd0_1_status = gpioValue; break; case 45: bd0_2_status = gpioValue; break; } } } } // Bypass useless functions void CheckGpioInStatus() { int pinIn[2] = { 27, 47 }; unsigned int gpioValue = 0; for (int i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); if (gpioValue == 0x01) { switch(pinIn[i]) { // 小板緊急停止 case 47: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { // if (chargingInfo[i]->Type == _Type_Chademo) // BoardErrOccurByString(i, "023730"); // else if (chargingInfo[i]->Type == _Type_CCS) // BoardErrOccurByString(i, "013627"); break; } } } break; case 27: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { // if (chargingInfo[i]->Type == _Type_Chademo) // BoardErrOccurByString(i, "023730"); // else if (chargingInfo[i]->Type == _Type_CCS) // BoardErrOccurByString(i, "013627"); break; } } } break; } } else { switch (pinIn[i]) { // 小板解除緊急停止 case 47: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseBoardErrOccurByString(i, "023730"); // else if (chargingInfo[i]->Type == _Type_CCS) // ReleaseBoardErrOccurByString(i, "013627"); break; } } } break; case 27: { for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseBoardErrOccurByString(i, "023730"); // else if (chargingInfo[i]->Type == _Type_CCS) // ReleaseBoardErrOccurByString(i, "013627"); break; } } } break; } } } } //=============================================== // Main process //=============================================== bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData) { for (byte index = 0; index < CHAdeMO_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index]; return true; } } for (byte index = 0; index < CCS_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index]; return true; } } for (byte index = 0; index < GB_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index]; return true; } } return false; } // 檢查 Byte 中某個 Bit 的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit) { return ( _byte & mask_table[_bit] ) != 0x00; } // 設定 Byte 中某個 Bit的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit // value : 修改的值為 0 or 1 void SetBitValue(unsigned char *_byte, unsigned char _bit, unsigned char value) { if(value == 1) *_byte |= (1 << _bit); else if (value == 0) *_byte ^= (1 << _bit); } void GetCcidAuthPossible(bool *idleReq, byte *idleIndex) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index ++) { if (chargingInfo [gun_index]->SystemStatus == SYS_MODE_PREPARE_FOR_EV && ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_CHECK) { *idleIndex = gun_index; *idleReq = true; break; } } } void UserScanFunction() { bool idleReq = false; unsigned char idleIndex = 255; //unsigned char stopReq = 255; bool hasGunUsing = false; bool isReservedCard = false; // 當前非驗證的狀態 if(!IsAuthorizingMode()) { // 先判斷現在是否可以提供刷卡 // 1. 如果當前沒有槍是閒置狀態,則無提供刷卡功能 // 2. 停止充電 if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_FIX || ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_EMC) { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); return; } if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) > 0) { if (_acgunIndex > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == DEFAULT_AC_INDEX && ac_chargingInfo[0]->SystemStatus != SYS_MODE_ALARM) { // 如果選 AC 槍 if (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && ac_chargingInfo[0]->SystemStatus < SYS_MODE_ALARM) { if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_CHARGING) { char value[32]; PRINTF_FUNC("ac stop charging \n"); PRINTF_FUNC("index = %d, card number = %s, UserId = %s \n", ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc, ac_chargingInfo[0]->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId); memcpy(value, (unsigned char *)ac_chargingInfo[0]->StartUserId, ARRAY_SIZE(ac_chargingInfo[0]->StartUserId)); if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.UserId, value) == EQUAL) { AcChargingTerminalProcess(); } strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } } else if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_IDLE || ac_chargingInfo[0]->SystemStatus == SYS_MODE_RESERVATION) { idleReq = true; } } else { if (IsGunUsing(ShmSysConfigAndInfo->SysInfo.CurGunSelected)) { if (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == SYS_MODE_CHARGING) { char value[32]; PRINTF_FUNC("stop charging \n"); PRINTF_FUNC("index = %d, card number = %s, UserId = %s \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected, chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId); memcpy(value, (unsigned char *)chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId, ARRAY_SIZE(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId)); // 同一張卡直接停掉 if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.UserId, value) == EQUAL) { NormalStop(ShmSysConfigAndInfo->SysInfo.CurGunSelected); ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } else { if (ShmDcCommonData->enObtainAuthorizbyCCID) { GetCcidAuthPossible(&idleReq, &idleIndex); } if (!idleReq) { PRINTF_FUNC ( "_LCM_AUTHORIZ_FAIL \n" ); stopChargingChkByCard = true; strcpy ( (char *) ShmSysConfigAndInfo->SysConfig.UserId, "" ); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; } } } else { if (ShmDcCommonData->enObtainAuthorizbyCCID) { GetCcidAuthPossible(&idleReq, &idleIndex); } } } // else if (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == SYS_MODE_IDLE || // chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == SYS_MODE_RESERVATION) // { // idleIndex = ShmSysConfigAndInfo->SysInfo.CurGunSelected; // idleReq = true; // } else { if (ShmDcCommonData->enObtainAuthorizbyCCID && (ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_AUTHORIZ_COMP || ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_AUTHORIZ_FAIL)) return; for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE) { idleIndex = gun_index; idleReq = true; } else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION) { idleReq = true; } else { hasGunUsing = IsGunUsing(gun_index); } } // 壁掛不給充 - 已經有至少一把槍在充電 if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES && hasGunUsing) { PRINTF_FUNC("DW Serial not support dual charging. \n"); idleReq = false; strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } } } if (idleReq) { // if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && // stopReq != 255 && // ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) // { // idleReq = false; // strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); // } // else { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; gun_index++) { if (ac_chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION) { if (strcmp ( (char *) ShmSysConfigAndInfo->SysConfig.UserId, (char *) ShmDcCommonData->_reserved_ac_UserId [gun_index] ) == EQUAL) { isReservedCard = true; // 驗證通過 ac_chargingInfo[gun_index]->ReservedStartFlag = YES; ShmSysConfigAndInfo->SysInfo.OrderCharging = YES; strcpy ( (char *) ShmSysConfigAndInfo->SysConfig.UserId, "" ); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; break; } } } if (!isReservedCard) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION) { if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.UserId, (char *)ShmDcCommonData->_reserved_UserId[gun_index]) == EQUAL) { isReservedCard = true; // 驗證通過 chargingInfo[gun_index]->ReservedStartFlag = YES; ShmSysConfigAndInfo->SysInfo.OrderCharging = YES; strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; break; } } } } if (!isReservedCard && ((_acgunIndex > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == DEFAULT_AC_INDEX) || (idleIndex != 255 && (chargingInfo[idleIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[idleIndex]->SystemStatus == SYS_MODE_PREPARE_FOR_EV)))) { if (ShmDcCommonData->_CcidAuthProcessStep != _CCID_AUTH) { PRINTF_FUNC("Start Authorizing... \n"); // LCM => Authorizing if (ShmDcCommonData->enObtainAuthorizbyCCID && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != DEFAULT_AC_INDEX) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = idleIndex; } ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZING; ShmDcCommonData->_CcidAuthProcessStep = _CCID_AUTH; // 進入確認卡號狀態 AuthorizingStart(); } } else strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } } else { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } } } } unsigned char isModeChange(unsigned char gun_index) { unsigned char result = NO; if(chargingInfo[gun_index]->SystemStatus != chargingInfo[gun_index]->PreviousSystemStatus) { result = YES; chargingInfo[gun_index]->PreviousSystemStatus = chargingInfo[gun_index]->SystemStatus; } return result; } void ScannerCardProcess() { if (!isDetectPlugin() && !isCardScan && ShmSysConfigAndInfo->SysWarningInfo.Level != _ALARM_LEVEL_CRITICAL && ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) { isCardScan = true; // 處理刷卡及驗證卡號的動作 UserScanFunction(); } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZING) { StartSystemTimeoutDet(Timeout_Authorizing); if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST) { // 白名單驗證 for (int i = 0; i < 10; i++) { if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i], "") != EQUAL) { if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i], (char *)ShmSysConfigAndInfo->SysConfig.UserId) == EQUAL) { PRINTF_FUNC("White Card Pass (%s)... \n", ShmSysConfigAndInfo->SysConfig.UserId); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; ClearAuthorizedFlag(); break; } } } } // 確認驗證卡號完成沒 if (isAuthorizedComplete() || (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == NO && ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING)) { StopSystemTimeoutDet(); // 判斷後台回覆狀態 if(ocpp_chk_authrization_cmd() || (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == NO && ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING)) { // LCM => Authorize complete PRINTF_FUNC("_LCM_AUTHORIZ_COMP \n"); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; } else { // LCM => Authorize fail ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } ClearAuthorizedFlag(); } } else if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_FAIL) { StartSystemTimeoutDet(Timeout_VerifyFail); isCardScan = false; } else if(ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_COMP) { StartSystemTimeoutDet(Timeout_VerifyComp); } else if(ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE && ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG) { StartSystemTimeoutDet(Timeout_WaitPlug); } else { isCardScan = false; } } bool AddGunInfoByConnector(byte typeValue, byte slots) { bool result = true; switch (typeValue) { case '0': // none break; case '1': // IEC 62196-2 Type 1/SAE J1772 Plug break; case '2': // IEC 62196-2 Type 1/SAE J1772 Socket break; case '3': // IEC 62196-2 Type 2 Plug case '4': // IEC 62196-2 Type 2 Socket if (AC_QUANTITY > _ac_Index) { ac_chargingInfo[_acgunIndex] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[_ac_Index]; // AC 固定 index ac_chargingInfo[_acgunIndex]->Index = DEFAULT_AC_INDEX; ac_chargingInfo[_acgunIndex]->ReservationId = -1; ac_chargingInfo[_acgunIndex]->SystemStatus = SYS_MODE_BOOTING; ac_chargingInfo[_acgunIndex]->Type = _Type_AC; ac_chargingInfo[_acgunIndex]->IsAvailable = YES; ac_chargingInfo[_acgunIndex]->schedule.isTriggerStart = NO; ac_chargingInfo[_acgunIndex]->schedule.isTriggerStop = NO; _ac_Index++; _acgunIndex++; } else result = false; break; case '5': // GB/T AC Plug break; case '6': // GB/T AC Socket break; case 'J': // CHAdeMO - 60A case 'K': // CHAdeMO - 200A / 500V case 'L': // CHAdeMO - 80A { if (CHAdeMO_QUANTITY > _chademoIndex) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[_chademoIndex]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->ReservationId = -1; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = SYS_MODE_BOOTING; chargingInfo[_gunIndex]->Type = _Type_Chademo; chargingInfo[_gunIndex]->type_index = _chademoIndex; chargingInfo[_gunIndex]->IsAvailable = YES; chargingInfo[_acgunIndex]->schedule.isTriggerStart = NO; chargingInfo[_acgunIndex]->schedule.isTriggerStop = NO; chargingInfo[_gunIndex]->ModelType = typeValue; _chademoIndex++; _gunIndex++; } else result = false; } break; case 'U': // Natural cooling CCS1 case 'E': // Natural cooling CCS2 case 'T': // Rema CCS1 - 300A case 'D': // Rema CCS2 - 300A case 'M': // CCS2 - 80A case 'N': // CCS1 - 80A case 'R': // CCS2 - 250A case 'V' : // Liquid cooling CCS1 - 500A case 'F' : // Liquid cooling CCS2 - 500A case 'Y' : // CCS1 - 150A case 'Z' : // CCS2 - 150A { if (CCS_QUANTITY > _ccsIndex) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[_ccsIndex]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->ReservationId = -1; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = SYS_MODE_BOOTING; chargingInfo[_gunIndex]->Type = _Type_CCS; chargingInfo[_gunIndex]->type_index = _ccsIndex; chargingInfo[_gunIndex]->IsAvailable = YES; chargingInfo[_acgunIndex]->schedule.isTriggerStart = NO; chargingInfo[_acgunIndex]->schedule.isTriggerStop = NO; chargingInfo[_gunIndex]->ModelType = typeValue; // 現階段預設為走 DIN70121 ShmCcsData->CommProtocol = _CCS_COMM_V2GMessage_DIN70121; if (typeValue == 'U' || typeValue == 'T' || typeValue == 'N' || typeValue == 'V' || typeValue == 'Y') ShmDcCommonData->CcsTypeSaved [_gunIndex] = _CCS_TYPE_CCS1; else if (typeValue == 'E' || typeValue == 'D' || typeValue == 'M' || typeValue == 'R' || typeValue == 'F' || typeValue == 'Z') ShmDcCommonData->CcsTypeSaved [_gunIndex] = _CCS_TYPE_CCS2; _ccsIndex++; _gunIndex++; } else result = false; } break; case 'G': // GBT DC case 'B': { if (GB_QUANTITY > _gb_Index) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[_gb_Index]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->ReservationId = -1; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = SYS_MODE_BOOTING; chargingInfo[_gunIndex]->Type = _Type_GB; chargingInfo[_gunIndex]->type_index = _gb_Index; chargingInfo[_gunIndex]->IsAvailable = YES; chargingInfo[_acgunIndex]->schedule.isTriggerStart = NO; chargingInfo[_acgunIndex]->schedule.isTriggerStop = NO; chargingInfo[_gunIndex]->ModelType = typeValue; _gb_Index++; _gunIndex++; } else result = false; } break; } return result; } bool CheckConnectorTypeStatus() { bool result = true; // 硬體 0 1 => CCS,1 0 => Chademo,1 1 => GB //CheckFwSlotSta.tusLog(); if (strlen((char *) ShmSysConfigAndInfo->SysConfig.ModelName) >= 9) { byte slots = 1; for (byte typeIndex = 7; typeIndex <= 9; typeIndex++) { if(!AddGunInfoByConnector(ShmSysConfigAndInfo->SysConfig.ModelName[typeIndex], slots)) { return false; } slots++; } // AC index 接在 DC 後面 // if (_ac_Index > 0) // ac_chargingInfo[0]->Index += _gunIndex; ShmSysConfigAndInfo->SysConfig.TotalConnectorCount = _gunIndex; ShmSysConfigAndInfo->SysConfig.AcConnectorCount = _acgunIndex; PRINTF_FUNC("Charger Count => DC-Count = %d, AC-Count = %d \n", ShmSysConfigAndInfo->SysConfig.TotalConnectorCount, ShmSysConfigAndInfo->SysConfig.AcConnectorCount); if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 0 && ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 0) result = false; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) { bool isFind = false; if (chargingInfo[0]->Type == _Type_Chademo) { if ((bd0_1_status == 0 && bd0_2_status == 1) || (bd1_1_status == 0 && bd1_2_status == 1)) { isFind = true; } } else if (chargingInfo[0]->Type == _Type_CCS) { if ((bd0_1_status == 1 && bd0_2_status == 0) || (bd1_1_status == 1 && bd1_2_status == 0)) { isFind = true; } } else if (chargingInfo[0]->Type == _Type_GB) { if ((bd0_1_status == 1 && bd0_2_status == 1) || (bd1_1_status == 1 && bd1_2_status == 1)) { isFind = true; } } if (isFind) { chargingInfo[0]->Evboard_id = 0x01; CheckHwSlotStatusLog(0); } else result = false; } else { char type = NO_DEFINE; // 偵測槍屬於哪個 slot : 可知道插在板上的Slot 0 或 1 是 Chademo 還是 CCS for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gunIndex++) { if (gunIndex == 0 && bd0_1_status == 0 && bd0_2_status == 1) { PRINTF_FUNC("HW Conn %d (Chademo) \n", gunIndex); // 與硬體相同 type : Chademo if (chargingInfo[gunIndex]->Type == _Type_Chademo) { chargingInfo[gunIndex]->Evboard_id = 0x01; } } else if (gunIndex == 0 && bd0_1_status == 1 && bd0_2_status == 0) { PRINTF_FUNC("HW Conn %d (CCS) \n", gunIndex); // 與硬體相同 type : CCS if (chargingInfo[gunIndex]->Type == _Type_CCS) { chargingInfo[gunIndex]->Evboard_id = 0x01; } } else if (gunIndex == 0 && bd0_1_status == 1 && bd0_2_status == 1) { PRINTF_FUNC("HW Conn %d (GB) \n", gunIndex); // 與硬體相同 type : GB if (chargingInfo[gunIndex]->Type == _Type_GB) { chargingInfo[gunIndex]->Evboard_id = 0x01; } } else if (gunIndex == 0) { PRINTF_FUNC("HW Conn fail, Gun_%d, Flag1 = %d, Flag2 = %d \n", gunIndex, bd0_1_status, bd0_2_status); } if (gunIndex == 1 && bd1_1_status == 0 && bd1_2_status == 1) { PRINTF_FUNC("HW Conn %d (Chademo) \n", gunIndex); // 與硬體相同 type : Chademo if (chargingInfo[gunIndex]->Type == _Type_Chademo) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } else if (gunIndex == 1 && bd1_1_status == 1 && bd1_2_status == 0) { PRINTF_FUNC("HW Conn %d (CCS) \n", gunIndex); // 與硬體相同 type : CCS if (chargingInfo[gunIndex]->Type == _Type_CCS) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } else if (gunIndex == 1 && bd1_1_status == 1 && bd1_2_status == 1) { PRINTF_FUNC("HW Conn %d (GB) \n", gunIndex); // 與硬體相同 type : GB if (chargingInfo[gunIndex]->Type == _Type_GB) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } else if (gunIndex == 1) { PRINTF_FUNC("HW Conn fail, Gun_%d, Flag1 = %d, Flag2 = %d \n", gunIndex, bd1_1_status, bd1_2_status); } CheckHwSlotStatusLog(gunIndex); if (type == NO_DEFINE) type = chargingInfo[gunIndex]->Type; else { // 雙槍都是同一個 type if (type == chargingInfo[gunIndex]->Type) ShmDcCommonData->SysGunAreSameType = YES; } if (chargingInfo[gunIndex]->Evboard_id == 0x00) result = false; } } } else { // Module Name 不正確 - 告警 result = false; } return result; } void KillTask() { ChangeLcmByIndex(_LCM_FIX); system("killall Module_EventLogging"); system("killall Module_PrimaryComm"); system("killall Module_EvComm"); system("killall Module_InternalComm"); system("killall Module_PsuComm"); system("killall Module_4g &"); system("killall Module_Wifi &"); } void KillTaskExceptDetectTask() { ChangeLcmByIndex(_LCM_FIX); sleep(3); system("killall Module_EvComm"); //system("killall Module_InternalComm"); system("killall Module_PsuComm"); system("killall Module_4g &"); system("killall Module_Wifi &"); } void KillAllTask() { 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_PsuComm"); system("killall OcppBackend &"); system("killall Module_4g &"); system("killall Module_Wifi &"); system("killall Module_DcMeter &"); } void LogUpgradeType(unsigned int type) { switch (type) { case _UPDATE_TYPE_CSU_UBOOT: PRINTF_FUNC("CSU bootloader (uboot) \n"); break; case _UPDATE_TYPE_CSU_DTB: PRINTF_FUNC("CSU kernel configuration (dtb) \n"); break; case _UPDATE_TYPE_CSU_ZIMAGE: PRINTF_FUNC("CSU kernel image (zImage) \n"); break; case _UPDATE_TYPE_CSU_RFILES: PRINTF_FUNC("CSU root file system (ramdisk.gz) \n"); break; case _UPDATE_TYPE_CSU_CONFIG: PRINTF_FUNC("CSU user configuration (bin) \n"); break; case _UPDATE_TYPE_CCS_UBOOT: PRINTF_FUNC("CCS board bootloader (uboot) \n"); break; case _UPDATE_TYPE_CCS_DTB: PRINTF_FUNC("CCS board kernel configuration (dtb) \n"); break; case _UPDATE_TYPE_CCS_ZIMAGE: PRINTF_FUNC("CCS board kernel image (zImage) \n"); break; case _UPDATE_TYPE_CCS_RFILES: PRINTF_FUNC("CCS board file system (ramdisk.gz) \n"); break; case _UPDATE_TYPE_DCM_ST407: PRINTF_FUNC("DCM 407 primary controller \n"); break; case _UPDATE_TYPE_RELAY_CTR: PRINTF_FUNC("Relay control board \n"); break; case _UPDATE_TYPE_FAN_CTR: PRINTF_FUNC("Fan control board \n"); break; case _UPDATE_TYPE_AC_WLMOUNT_CTR: PRINTF_FUNC("AC wall-mount (low-end) controller \n"); break; case _UPDATE_TYPE_LED_CTR: PRINTF_FUNC("LED control board \n"); break; case _UPDATE_TYPE_CHADEMO: PRINTF_FUNC("CAHdeMO board \n"); break; case _UPDATE_TYPE_GBT: PRINTF_FUNC("GBT board \n"); break; } } int CheckUpdateProcess(void) { //bool isPass = true; uint8_t retSucc = 0; uint8_t retFail = 0; byte index = 0; byte target = 0; char new_str[256]; unsigned char *ptr = NULL; int fd = 0; int CanFd = 0; int uartFd = 0; unsigned int Type = 0; long int MaxLen = 48 * 1024 * 1024, ImageLen = 0; DIR *d; struct dirent *dir; byte result = PASS; char Buf[256]; d = opendir("/mnt/"); if (d) { while ((dir = readdir(d)) != NULL) { if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) { continue; } memset(new_str, 0x00, sizeof(new_str)); strcat(new_str, "/mnt/"); strcat(new_str, dir->d_name); PRINTF_FUNC("%s \n", new_str); fd = open(new_str, O_RDONLY); if (fd < 0) { close(fd); result = FAIL; sleep(1); continue; } ptr = malloc(MaxLen); //-48 is take out the header //memset(ptr, 0xFF, MaxLen); //-48 is take out the header //get the image length ImageLen = read(fd, ptr, MaxLen); bool isModelNameFail = false; // DS-----J0E-2PH if((ShmSysConfigAndInfo->SysConfig.ModelName[0] != ptr[0]) || (ShmSysConfigAndInfo->SysConfig.ModelName[1] != ptr[1]) || (ShmSysConfigAndInfo->SysConfig.ModelName[7] != ptr[7]) || (ShmSysConfigAndInfo->SysConfig.ModelName[8] != ptr[8]) || (ShmSysConfigAndInfo->SysConfig.ModelName[9] != ptr[9]) || (ShmSysConfigAndInfo->SysConfig.ModelName[11] != ptr[11]) || (ShmSysConfigAndInfo->SysConfig.ModelName[12] != ptr[12]) || (ShmSysConfigAndInfo->SysConfig.ModelName[13] != ptr[13])) { result = MODELNAME_FAIL; isModelNameFail = true; } if (isModelNameFail) { close(fd); continue; } PRINTF_FUNC("model name check pass. \n"); if (ImageLen > 20) { Type = (((unsigned int)ptr[16]) << 24 | ((unsigned int)ptr[17]) << 16 | ((unsigned int)ptr[18]) << 8 | ((unsigned int)ptr[19])); LogUpgradeType(Type); PRINTF_FUNC("Upgrade Status : PASS : %d, FAIL : %d \n", retSucc, retFail); free(ptr); switch (Type) { case _UPDATE_TYPE_CSU_UBOOT: case _UPDATE_TYPE_CSU_DTB: case _UPDATE_TYPE_CSU_ZIMAGE: case _UPDATE_TYPE_CSU_RFILES: case _UPDATE_TYPE_CSU_CONFIG: system("echo 3 > /proc/sys/vm/drop_caches"); sleep(2); if (Upgrade_Flash(Type, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) retSucc++; else { PRINTF_FUNC("Upgrade CSU Failed (%d) \n", Type); retFail++; } memset(Buf, 0, sizeof(Buf)); sprintf(Buf, "rm -rvf /mnt/%s", new_str); system(Buf); break; case _UPDATE_TYPE_CCS_UBOOT: case _UPDATE_TYPE_CCS_DTB: case _UPDATE_TYPE_CCS_ZIMAGE: case _UPDATE_TYPE_CCS_RFILES: CanFd = InitCanBus(); if (CanFd > 0) { for (index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->Type == _Type_CCS) { byte targetID = chargingInfo[index]->Evboard_id; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1 && ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0) { targetID += 1; } system("echo 3 > /proc/sys/vm/drop_caches"); sleep(2); PRINTF_FUNC("Upgrade CCS Processing..target id = %d \n", targetID); if (Upgrade_CCS(CanFd, Type, targetID, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == FAIL) { PRINTF_FUNC("Upgrade CCS Failed \n"); retFail++; } else retSucc++; } } close(CanFd); } memset(Buf, 0, sizeof(Buf)); sprintf(Buf, "rm -rvf /mnt/%s", new_str); system(Buf); break; case _UPDATE_TYPE_DCM_ST407: case _UPDATE_TYPE_RELAY_CTR: case _UPDATE_TYPE_FAN_CTR: case _UPDATE_TYPE_AC_WLMOUNT_CTR: case _UPDATE_TYPE_LED_CTR: target = 0x00; if (Type == _UPDATE_TYPE_DCM_ST407) { target = UPGRADE_PRI; } else if (Type == _UPDATE_TYPE_RELAY_CTR) { target = UPGRADE_RB; } else if (Type == _UPDATE_TYPE_FAN_CTR) { target = UPGRADE_FAN; } else if (Type == _UPDATE_TYPE_AC_WLMOUNT_CTR) { target = UPGRADE_AC; } else if (Type == _UPDATE_TYPE_LED_CTR) { target = UPGRADE_LED; } uartFd = InitComPort(target); if (Upgrade_UART(uartFd, Type, target, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) { retSucc++; } else { PRINTF_FUNC("Upgrade %x Failed\r\n", Type); retFail++; } if (uartFd > 0) { close(uartFd); } memset(Buf, 0, sizeof(Buf)); sprintf(Buf, "rm -rvf /mnt/%s", new_str); system(Buf); break; case _UPDATE_TYPE_CHADEMO: case _UPDATE_TYPE_GBT: CanFd = InitCanBus(); if (CanFd > 0) { for (index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if ((Type == _UPDATE_TYPE_CHADEMO && chargingInfo[index]->Type == _Type_Chademo) || (Type == _UPDATE_TYPE_GBT && chargingInfo[index]->Type == _Type_GB)) { PRINTF_FUNC("Upgrade GBT / Chademo Processing..target id = %d \n", chargingInfo[index]->Evboard_id); if (Upgrade_CAN(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) retSucc++; else { if (chargingInfo[index]->Type == _Type_Chademo) PRINTF_FUNC("Upgrade Chademo Failed \n"); else PRINTF_FUNC("Upgrade GBT Failed \n"); retFail++; } } } close(CanFd); } memset(Buf, 0, sizeof(Buf)); sprintf(Buf, "rm -rvf /mnt/%s", new_str); system(Buf); break; } } close(fd); } } free(dir); closedir(d); PRINTF_FUNC("Upgrade Result : PASS : %d, FAIL : %d \n", retSucc, retFail); sleep(1); system("rm -rvf /mnt/* "); if (retFail != 0) { result = FAIL; } return result; } void CreateRfidFork() { pid_t rfidRecPid; rfidRecPid = fork(); if (rfidRecPid == 0) { while(true) { // 刷卡判斷 RFID rfid; if (!ShmSysConfigAndInfo->SysConfig.isRFID) {} else if(getRequestCardSN(rfidFd, 0, &rfid)) { //PRINTF_FUNC("Get Card..-%s- \n", ShmSysConfigAndInfo->SysConfig.UserId); if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) == 0) { if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian == RFID_ENDIAN_BIG) { switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5]); break; case RFID_SN_TYPE_7BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6]); break; case RFID_SN_TYPE_10BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7], rfid.currentCard[8], rfid.currentCard[9]); break; case RFID_SN_TYPE_4BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian == RFID_ENDIAN_LITTLE) { switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_7BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_10BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[9], rfid.currentCard[8], rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_4BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } PRINTF_FUNC("RFID : Get card number = %s\n", ShmSysConfigAndInfo->SysConfig.UserId); } } sleep(1); } } } void CreateCheckSystemTaskFork() { pid_t taskPid; taskPid = fork(); if (taskPid == 0) { bool stopToDet = false; while(true) { if (!stopToDet) { for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if (chargingInfo[_index]->SystemStatus == SYS_MODE_UPDATE || chargingInfo[_index]->Type == 0x09) { stopToDet = true; continue; } } if (!stopToDet) CheckSystemTaskAlive(); } sleep(5); } } } void StartSystemTimeoutDet(unsigned char flag) { if (ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag != flag) { GetTimespecFunc(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer); } ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = flag; } void StopSystemTimeoutDet() { GetTimespecFunc(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer); ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = Timeout_None; } void StartGunInfoTimeoutDet(unsigned char gunIndex, unsigned char flag) { if (gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) { if (chargingInfo[gunIndex]->TimeoutFlag != flag) { GetTimespecFunc(&chargingInfo[gunIndex]->ConnectorTimeout); } chargingInfo[gunIndex]->TimeoutFlag = flag; } } void StopGunInfoTimeoutDet(unsigned char gunIndex) { if (gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) { chargingInfo[gunIndex]->TimeoutFlag = Timeout_None; } } void CheckConnectionTimeout() { if(system("pidof -s OcppBackend > /dev/null") != 0) { _connectionTimeout = CONN_PLUG_TIME_OUT; } else { _connectionTimeout = _ocpp_get_connect_timeout(); if(_connectionTimeout <= 0) { _connectionTimeout = CONN_PLUG_TIME_OUT; } } } void CreateTimeoutFork() { pid_t timeoutPid; timeoutPid = fork(); if (timeoutPid > 0) { GetTimespecFunc(&_cmdSubPriority_time); CheckConnectionTimeout(); int _timebuf = 0; while(true) { _timebuf = GetTimeoutValue(&_cmdSubPriority_time); if (_timebuf < 0) { GetTimespecFunc(&_cmdSubPriority_time); } else { if (_timebuf >= 5) { CheckConnectionTimeout(); GetTimespecFunc(&_cmdSubPriority_time); } } //printf("Timeout ***********SystemTimeoutFlag = %d, ********\n", ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag); // 系統 if (ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag != Timeout_None) { _timebuf = GetTimeoutValue(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer); if (_timebuf < 0) { GetTimespecFunc(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer); } else { switch(ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag) { case Timeout_SelftestChk: if (_timebuf >= SELFTEST_TIMEOUT) { _SelfTestTimeout(); StopSystemTimeoutDet(); } break; case Timeout_Authorizing: if (_timebuf >= AUTHORIZE_TIMEOUT) { _AuthorizedTimeout(); StopSystemTimeoutDet(); } break; case Timeout_VerifyFail: if (_timebuf >= AUTHORIZE_FAIL_TIMEOUT) { _AutoReturnTimeout(); StopSystemTimeoutDet(); } break; case Timeout_VerifyComp: if (_timebuf >= AUTHORIZE_COMP_TIMEOUT) { _AutoReturnTimeout(); StopSystemTimeoutDet(); } break; case Timeout_WaitPlug: if (_timebuf >= _connectionTimeout) { _DetectPlugInTimeout(); StopSystemTimeoutDet(); } break; case Timeout_ReturnToChargingGunDet: { if (_timebuf >= RETURN_TO_CHARGING_PAGE) { DisplayChargingInfo(); StopSystemTimeoutDet(); } } break; // case Timeout_AuthorizingForStop: // { // if (_timebuf / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) // { // strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); // ClearAuthorizedFlag(); // StopSystemTimeoutDet(); // } // } // break; } } } // 各槍 for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (chargingInfo[gun_index]->TimeoutFlag != Timeout_None) { _timebuf = GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout); if (_timebuf < 0) { GetTimespecFunc(&chargingInfo[gun_index]->ConnectorTimeout); } else { //printf("Timeout ***********TimeoutFlag = %d, ********\n", chargingInfo[gun_index]->TimeoutFlag); switch(chargingInfo[gun_index]->TimeoutFlag) { case Timeout_Preparing: { if (_timebuf >= GUN_PREPARE_TIMEOUT) { _PrepareTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_EvChargingDet: { if (_timebuf >= GUN_EV_WAIT_TIMEOUT) { _DetectEvChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_EvseChargingDet: { if (chargingInfo[gun_index]->Type == _Type_GB) { if (_timebuf >= GUN_EVSE_WAIT_TIMEOUT * 3) { _DetectEvseChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } else { if (_timebuf >= GUN_EVSE_WAIT_TIMEOUT) { _DetectEvseChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } } break; case Timeout_EvseCompleteDet: { if (_timebuf >= GUN_COMP_WAIT_TIMEOUT) { StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_ForCcsPrechargeDet: { if (_timebuf >= GUN_PRECHARGING_TIMEOUT) { _CcsPrechargeTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; } } } } sleep(1); } } } void GetSystemTime() { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); // byte date[14]; // // // //sprintf(&date, "%d", ); // // date[0] = '0' + ((tmCSU->tm_year + 1900) / 1000 % 10); // date[0] = (tmCSU->tm_year + 1900) / 1000 % 10; // date[1] = (tmCSU->tm_year + 1900) / 100 % 10; // date[2] = (tmCSU->tm_year + 1900) / 10 % 10; // date[3] = (tmCSU->tm_year + 1900) / 1 % 10; // // date[4] = (tmCSU->tm_mon + 1) / 10 % 10; // date[5] = (tmCSU->tm_mon + 1) / 1 % 10; // // date[6] = (tmCSU->tm_mday) / 10 % 10; // date[7] = (tmCSU->tm_mday) / 1 % 10; // // date[8] = (tmCSU->tm_hour) / 10 % 10; // date[9] = (tmCSU->tm_hour) / 1 % 10; // // date[10] = (tmCSU->tm_min) / 10 % 10; // date[11] = (tmCSU->tm_min) / 1 % 10; // // date[12] = (tmCSU->tm_sec) / 10 % 10; // date[13] = (tmCSU->tm_sec) / 1 % 10; // PRINTF_FUNC("%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x \n", date[0], date[1], date[2], date[3], // date[4], date[5], date[6], date[7], // date[8], date[9], date[10], date[11], // date[12], date[13]); } void CheckFactoryConfigFunction() { if(ShmSysConfigAndInfo->SysInfo.FactoryConfiguration) { char Buf[256]; sleep(5); sprintf(Buf, "cd /root;./FactoryConfig -m %s %s", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); system(Buf); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } } void CheckFwUpdateFunction() { //PRINTF_FUNC("ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = %d \n", ShmSysConfigAndInfo->SysInfo.FirmwareUpdate); if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate == YES) { DEBUG_INFO_MSG("ftp : update start. \n"); for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { setChargerMode(gun_index, SYS_MODE_UPDATE); } CloseWatchDog(); sleep(2); KillTask(); byte updateResult = CheckUpdateProcess(); if (updateResult == PASS) DEBUG_INFO_MSG("ftp : update complete. \n"); else if (updateResult == MODELNAME_FAIL) { DEBUG_INFO_MSG("ftp : model name is none match. \n"); KillAllTask(); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = NO; sleep(5); system("/usr/bin/run_evse_restart.sh"); return; } else DEBUG_INFO_MSG("ftp : update fail. \n"); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = NO; sleep(5); system("reboot -f"); } else { ocpp_chk_update_cmd(); } } int TariffParsing(char *StringItem, char *TariffCode) { char *ptrSave, *ptrToken; char strSource[128]; int fee = 0; memcpy(strSource, StringItem, 128); ptrToken = strtok_r(strSource, ";", &ptrSave); while(ptrToken != NULL) { char *strTariff = strstr(ptrToken, TariffCode); if(strTariff != NULL) { char *strFee = strstr(strTariff, "$"); if(strFee != NULL) { strFee++; float fFee = atof(strFee); fee = (int)(fFee * 100); break; } } ptrToken = strtok_r(NULL, ";", &ptrSave); } return fee; } void DefaultPriceHandlerOcpp16(char *StrDefaultPrice) { unsigned int connectionFee = 0, currentRate = 0, occupancyFee = 0; PRINTF_FUNC("DefaultPriceHandler - StrDefaultPrice = %s \n", StrDefaultPrice); connectionFee = TariffParsing(StrDefaultPrice, "Connection Fee"); currentRate = TariffParsing(StrDefaultPrice, "Current Rate"); occupancyFee = TariffParsing(StrDefaultPrice, "Occupancy Fee"); PRINTF_FUNC("*** Connection Fee: %d.%02d ***", (connectionFee / 100), (connectionFee % 100)); PRINTF_FUNC("*** Current Rate: %d.%02d ***", (currentRate / 100), (currentRate % 100)); PRINTF_FUNC("*** Occupancy Fee: %d.%02d ***", (occupancyFee / 100), (occupancyFee % 100)); ShmDcCommonData->balanceInfo.defaultPrice = currentRate; } void UserPriceHandlerOcpp16(char *UserId, char *UserPrice) { unsigned int connectionFee = 0, currentRate = 0, occupancyFee = 0; int accountBalance = 0; byte acGunIndex = 0; for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gunIndex++) { if (gunIndex == 1) acGunIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; else acGunIndex = 0; if((chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_CHARGING) && strcmp((char *)chargingInfo[gunIndex]->StartUserId, UserId) == EQUAL) { connectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Connection Fee"); currentRate = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Current Rate"); occupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Occupancy Fee"); accountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.SetUserPrice.price, "Account Balance"); if (ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].UserPrice != currentRate || ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].AccountBalance != accountBalance) { PRINTF_FUNC("*** Connection Fee: %d.%02d ***", (connectionFee / 100), (connectionFee % 100)); PRINTF_FUNC("*** Current Rate: %d.%02d ***", (currentRate / 100), (currentRate % 100)); PRINTF_FUNC("*** Occupancy Fee: %d.%02d ***", (occupancyFee / 100), (occupancyFee % 100)); PRINTF_FUNC("*** Account Balance: %d.%02d ***", (accountBalance / 100), (accountBalance % 100)); PRINTF_FUNC("*** Connector Id %d User Price %d.%02d, Account Balance %d.%02d ***", (gunIndex), (currentRate / 100), (currentRate % 100), (accountBalance / 100), (accountBalance % 100)); } ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].UserPrice = currentRate; ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].AccountBalance = accountBalance; } } for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; gunIndex++) { acGunIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(strcmp((char *)ac_chargingInfo[gunIndex]->StartUserId, UserId) == EQUAL) { if (ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].UserPrice != currentRate || ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].AccountBalance != accountBalance) { PRINTF_FUNC("*** AC Connector User Price %d.%02d, Account Balance %d.%02d ***", (currentRate / 100), (currentRate % 100), (accountBalance / 100), (accountBalance % 100)); } ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].UserPrice = currentRate; ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].AccountBalance = accountBalance; } } } void RunningFinalCostHandlerOcpp16() { unsigned int connectionFee = 0, sessionFee = 0, occupancyFee = 0, totalCost = 0; int accountBalance = 0; byte acGunIndex = 0; bool isFind = false; for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gunIndex++) { isFind = false; if (gunIndex == 1) acGunIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; else acGunIndex = 0; // PRINTF_FUNC("*** gunIndex = %d, description = %s *** \n", gunIndex + acGunIndex, // ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description); // PRINTF_FUNC("*** gunIndex = %d, f description = %s *** \n", gunIndex + acGunIndex, // ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description); if (chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_ALARM) { if(strlen((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description) > 0) { connectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description, "Connection Fee"); sessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description, "Session Fee"); occupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description, "Occupancy Fee"); totalCost = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description, "Total Cost"); accountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex].description, "Account Balance"); PRINTF_FUNC("*** Connector Id: %d Running Cost *** \n", gunIndex); isFind = true; memset(&ShmOCPP16Data->Cost.RunningCost[gunIndex + acGunIndex], 0x00, sizeof(struct StrcutRunningCost)); } if(strlen((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description) > 0) { connectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description, "Connection Fee"); sessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description, "Session Fee"); occupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description, "Occupancy Fee"); totalCost = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description, "Total Cost"); accountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex].description, "Account Balance"); PRINTF_FUNC("********** Connector Id: %d Final Cost ********** \n", gunIndex); isFind = true; memset(&ShmOCPP16Data->Cost.FinalCost[gunIndex + acGunIndex], 0x00, sizeof(struct StrcutFinalCost)); } if (isFind) { PRINTF_FUNC("*** Connection Fee: %d.%02d *** \n", (connectionFee / 100), (connectionFee % 100)); PRINTF_FUNC("*** Session Fee: %d.%02d *** \n", (sessionFee / 100), (sessionFee % 100)); PRINTF_FUNC("*** Occupancy Fee: %d.%02d *** \n", (occupancyFee / 100), (occupancyFee % 100)); PRINTF_FUNC("*** Total Cost: %d.%02d *** \n", (totalCost / 100), (totalCost % 100)); PRINTF_FUNC("*** Account Balance: %d.%02d *** \n", (accountBalance / 100), (accountBalance % 100)); if (ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].TotalCost != totalCost || ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].AccountBalance != accountBalance) { PRINTF_FUNC("*** Connector Id %d Total Cost %d.%02d, Account Balance %d.%02d *** \n", (gunIndex), (totalCost / 100), (totalCost % 100), (accountBalance / 100), (accountBalance % 100)); } ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].TotalCost = totalCost; ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].AccountBalance = accountBalance; } } } for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; gunIndex++) { isFind = false; acGunIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if (ac_chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_PREPARING && ac_chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_ALARM) { if(strlen((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description) > 0) { connectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description, "Connection Fee"); sessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description, "Session Fee"); occupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description, "Occupancy Fee"); totalCost = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description, "Total Cost"); accountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.RunningCost[acGunIndex].description, "Account Balance"); PRINTF_FUNC("*** AC Connector : Running Cost ***\n"); isFind = true; memset(&ShmOCPP16Data->Cost.RunningCost[acGunIndex], 0x00, sizeof(struct StrcutRunningCost)); } if(strlen((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description) > 0) { connectionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description, "Connection Fee"); sessionFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description, "Session Fee"); occupancyFee = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description, "Occupancy Fee"); totalCost = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description, "Total Cost"); accountBalance = TariffParsing((char *)ShmOCPP16Data->Cost.FinalCost[acGunIndex].description, "Account Balance"); PRINTF_FUNC("*** AC Connector : Final Cost ***\n"); isFind = true; memset(&ShmOCPP16Data->Cost.FinalCost[acGunIndex], 0x00, sizeof(struct StrcutFinalCost)); } if (isFind) { PRINTF_FUNC("*** Connection Fee: %d.%02d ***\n", (connectionFee / 100), (connectionFee % 100)); PRINTF_FUNC("*** Session Fee: %d.%02d ***\n", (sessionFee / 100), (sessionFee % 100)); PRINTF_FUNC("*** Occupancy Fee: %d.%02d ***\n", (occupancyFee / 100), (occupancyFee % 100)); PRINTF_FUNC("*** Total Cost: %d.%02d ***\n", (totalCost / 100), (totalCost % 100)); PRINTF_FUNC("*** Account Balance: %d.%02d ***\n", (accountBalance / 100), (accountBalance % 100)); if (ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].TotalCost != totalCost || ShmDcCommonData->balanceInfo.connectorBalanceInfo[gunIndex + acGunIndex].AccountBalance != accountBalance) { PRINTF_FUNC("*** Connector Id %d Total Cost %d.%02d, Account Balance %d.%02d ***\n", (gunIndex), (totalCost / 100), (totalCost % 100), (accountBalance / 100), (accountBalance % 100)); } ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].TotalCost = totalCost; ShmDcCommonData->balanceInfo.connectorBalanceInfo[acGunIndex].AccountBalance = accountBalance; } } } } //=============================================== // ocpp key //=============================================== bool ocpp_authorizeRemoteTxReqChk_key() { bool result = false; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strstr((char *) ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeRemoteTxRequests].ItemData, "TRUE")) result = true; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { } return result; } //=============================================== // Check reservation date is expired //=============================================== int opcc_chk_reserve_expired(byte gun_index) { int result = NO; byte acDirIndex = 0; if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(chargingInfo[gun_index]->SystemStatus != SYS_MODE_RESERVATION) PRINTF_FUNC("%s \n", ShmOCPP16Data->ReserveNow[gun_index + acDirIndex].ExpiryDate); if (CheckTimeOut(ShmOCPP16Data->ReserveNow[gun_index + acDirIndex].ExpiryDate)) result = YES; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(chargingInfo[gun_index]->SystemStatus != SYS_MODE_RESERVATION) PRINTF_FUNC("%s \n", ShmOCPP20Data->ReserveNow[gun_index + acDirIndex].expiryDateTime); if (CheckTimeOut(ShmOCPP20Data->ReserveNow[gun_index + acDirIndex].expiryDateTime)) result = YES; } return result; } //=============================================== // AC OCPP routine //=============================================== void ocpp_ac_chk_availability_cmd() { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); byte type = 0; // 如果有 DC 槍~ 則 AC 槍在 index = 1 的位置~ 如果沒有 DC 槍則在 index = 0 的位置 if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[hasDc].ChangeAvailabilityReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : AC OcppChangeAvailability******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : AC OcppChangeAvailability******************** \n"); ShmOCPP16Data->CsMsg.bits[hasDc].ChangeAvailabilityReq = NO; if(strcmp((char *)ShmOCPP16Data->ChangeAvailability[hasDc].Type, "Operative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, hasDc, true); type = 1; } else if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[hasDc].Type, "Inoperative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, hasDc, false); type = 2; } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[hasDc].ChangeAvailabilityReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); ShmOCPP20Data->CsMsg.bits[hasDc].ChangeAvailabilityReq = NO; if(strcmp((char *)ShmOCPP20Data->ChangeAvailability[hasDc].operationalStatus, "Operative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, hasDc, true); type = 1; } else if (strcmp((char *)ShmOCPP20Data->ChangeAvailability[hasDc].operationalStatus, "Inoperative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, hasDc, false); type = 2; } } } if (type == 1) { ac_chargingInfo[0]->IsAvailable = YES; } else if (type == 2) { ac_chargingInfo[0]->IsAvailable = NO; } } void ocpp_ac_chk_unlock_cmd() { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); // 如果有 DC 槍~ 則 AC 槍在 index = 1 的位置~ 如果沒有 DC 槍則在 index = 0 的位置 if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[hasDc].UnlockConnectorReq == YES) { ShmOCPP16Data->CsMsg.bits[hasDc].UnlockConnectorReq = NO; if (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CHARGING) { // Unlocked - 充電中,需停止充電 strcpy((char *)ShmOCPP16Data->StopTransaction[hasDc].StopReason, "UnlockCommand"); ac_chargingInfo[0]->StopChargeFlag = YES; } strcpy((char *)ShmOCPP16Data->UnlockConnector[hasDc].ResponseStatus, "Unlocked"); ShmOCPP16Data->CsMsg.bits[hasDc].UnlockConnectorConf = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[hasDc].UnlockConnectorReq == YES) { ShmOCPP20Data->CsMsg.bits[hasDc].UnlockConnectorReq = NO; if (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CHARGING) { // Unlocked - 充電中,需停止充電 strcpy((char *)ShmOCPP20Data->TransactionEvent[hasDc].transactionInfo.stoppedReason, "UnlockCommand"); ac_chargingInfo[0]->StopChargeFlag = YES; } strcpy((char*)ShmOCPP20Data->UnlockConnector[hasDc].Response_status, "Unlocked"); ShmOCPP20Data->CsMsg.bits[hasDc].UnlockConnectorConf = YES; } } } void ocpp_ac_chk_profileConf_cmd() { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[hasDc].ChargingProfileConf == YES) { ShmOCPP16Data->CSUMsg.bits[hasDc].ChargingProfileConf = NO; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[hasDc].ChargingProfileConf == YES) { ShmOCPP20Data->CSUMsg.bits[hasDc].ChargingProfileConf = NO; } } } void ocpp_ac_chargingProfile_process() { int _time = 0; int _startCount = NO_DEFINE; int _maxCount = 0; byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *)ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingProfileKind, "Absolute") == EQUAL && ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingProfileId == YES) { _time = GetStartScheduleTime(ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.StartSchedule); if (_time > -1) { _maxCount = ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod); _startCount = NO_DEFINE; for (byte _count = 0; _count < _maxCount; _count++) { // 預設最小輸出電流 (MIN_OUTPUT_CUR) A if (_time >= ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_count].StartPeriod) { if ((_count == 0 && ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_count].Limit >= MIN_OUTPUT_CUR) || ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_count].Limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } if (_startCount < _maxCount) { //PRINTF_FUNC("AC - Gun_%d, Get Profile - Profile Index = %d \n", hasDc, _startCount); //PRINTF_FUNC("Profile Limit = %.2f \n", ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit); if (ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit >= 1 && ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit <= 5) { ac_chargingInfo[0]->ChargingProfileCurrent = AC_MINIMUM_DUTY; } else if (ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit == 0) { ac_chargingInfo[0]->ChargingProfileCurrent = AC_STOP_DUTY; } else { ac_chargingInfo[0]->ChargingProfileCurrent = ShmOCPP16Data->SmartChargingProfile[hasDc].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char *)ShmOCPP20Data->SmartChargingProfile[hasDc].chargingProfileKind, "Absolute") == EQUAL && ShmOCPP20Data->SmartChargingProfile[hasDc].id == YES) { _time = GetStartScheduleTime(ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].startSchedule); _maxCount = ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod); _startCount = NO_DEFINE; for (byte _count = 0; _count < _maxCount; _count++) { // 預設最小輸出電流 (MIN_OUTPUT_CUR) A if (_time >= ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_count].startPeriod) { if ((_count == 0 && ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_count].limit >= MIN_OUTPUT_CUR) || ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_count].limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } if (_startCount < _maxCount) { //PRINTF_FUNC("Gun_%d, Get Profile - Profile Index = %d \n", 1, _startCount); //PRINTF_FUNC("Profile Limit = %.2f \n", ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit); if (ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit >= 1 && ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit <= 5) { ac_chargingInfo [0]->ChargingProfileCurrent = AC_MINIMUM_DUTY; } else if (ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit == 0) { ac_chargingInfo [0]->ChargingProfileCurrent = AC_STOP_DUTY; } else { ac_chargingInfo [0]->ChargingProfileCurrent = ShmOCPP20Data->SmartChargingProfile[hasDc].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } } else { ac_chargingInfo[0]->ChargingProfilePower = -1; ac_chargingInfo[0]->ChargingProfileCurrent = -1; } if (ac_chargingInfo[0]->ChargingProfileCurrent >= 0 && _AcChargingProfileCurBuffer != ac_chargingInfo[0]->ChargingProfileCurrent) { _AcChargingProfileCurBuffer = ac_chargingInfo[0]->ChargingProfileCurrent; PRINTF_FUNC ( "AC Profile (duty) : ChargingProfileCurrent = %.2f \n", ac_chargingInfo[0]->ChargingProfileCurrent); } } void ocpp_ac_lift_profileReq_cmd(byte gunIndex) { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[hasDc].ChargingProfileConf == NO) { if (ShmOCPP16Data->CSUMsg.bits[hasDc].ChargingProfileReq == NO) ShmOCPP16Data->CSUMsg.bits[hasDc].ChargingProfileReq = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[hasDc].ChargingProfileConf == NO) { if (ShmOCPP20Data->CSUMsg.bits[hasDc].ChargingProfileReq == NO) ShmOCPP20Data->CSUMsg.bits[hasDc].ChargingProfileReq = YES; } } } int opcc_ac_chk_reserve_expired() { int result = NO; byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ac_chargingInfo [0]->SystemStatus != SYS_MODE_RESERVATION) PRINTF_FUNC("%s \n", ShmOCPP16Data->ReserveNow[hasDc].ExpiryDate); if (CheckTimeOut(ShmOCPP16Data->ReserveNow[hasDc].ExpiryDate)) result = YES; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ac_chargingInfo [0]->SystemStatus != SYS_MODE_RESERVATION) PRINTF_FUNC("%s \n", ShmOCPP20Data->ReserveNow[hasDc].expiryDateTime); if (CheckTimeOut(ShmOCPP20Data->ReserveNow[hasDc].expiryDateTime)) result = YES; } return result; } void ocpp_ac_chk_reserved_cmd() { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ac_chargingInfo [0]->SystemStatus == SYS_MODE_IDLE && ShmOCPP16Data->CsMsg.bits [hasDc].ReserveNowReq == YES) { PRINTF_FUNC ( "***************ChkOcppStatus : (AC) OcppReservedStatus******************** \n" ); ShmOCPP16Data->CsMsg.bits [hasDc].ReserveNowReq = NO; if ( ! opcc_ac_chk_reserve_expired ()) { PRINTF_FUNC ( "ReservationId = %d \n", ShmOCPP16Data->ReserveNow [hasDc].ReservationId ); PRINTF_FUNC ( "IdTag = %s \n", ShmOCPP16Data->ReserveNow [hasDc].IdTag ); PRINTF_FUNC ( "*************ChkOcppStatus : (AC) OcppReservedStatus End****************** \n" ); ac_chargingInfo [0]->ReservationId = ShmOCPP16Data->ReserveNow [hasDc].ReservationId; ac_chargingInfo [0]->SystemStatus = SYS_MODE_RESERVATION; strcpy ( (char *) ShmDcCommonData->_reserved_ac_UserId[0], (char *) ShmOCPP16Data->ReserveNow [hasDc].IdTag ); } ShmOCPP16Data->CsMsg.bits [hasDc].ReserveNowConf = YES; } if (ac_chargingInfo [0]->SystemStatus == SYS_MODE_RESERVATION && ShmOCPP16Data->CsMsg.bits [hasDc].CancelReservationReq == YES) { ShmOCPP16Data->CsMsg.bits [hasDc].CancelReservationReq = NO; if (ShmOCPP16Data->ReserveNow [hasDc].ReservationId == ac_chargingInfo [0]->ReservationId) { PRINTF_FUNC ( "***************ChkOcppStatus : (AC) OcppReservedStatus******************** \n" ); PRINTF_FUNC ( "ReservationId = %d \n", ShmOCPP16Data->ReserveNow [hasDc].ReservationId ); PRINTF_FUNC ( "***********ChkOcppStatus : (AC) Cancel OcppReservedStatus End**************** \n" ); ac_chargingInfo [0]->ReservationId = -1; ac_chargingInfo [0]->SystemStatus = SYS_MODE_IDLE; strcpy ( (char *) ShmDcCommonData->_reserved_ac_UserId[0], "" ); ShmOCPP16Data->CsMsg.bits [hasDc].CancelReservationConf = YES; } } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ac_chargingInfo [0]->SystemStatus == SYS_MODE_IDLE && ShmOCPP20Data->CsMsg.bits [hasDc].ReserveNowReq == YES) { PRINTF_FUNC ( "***************ChkOcppStatus : (AC) OcppReservedStatus******************** \n" ); ShmOCPP20Data->CsMsg.bits [hasDc].ReserveNowReq = NO; if ( ! opcc_ac_chk_reserve_expired ()) { PRINTF_FUNC ( "id = %d \n", ShmOCPP20Data->ReserveNow [hasDc].id ); PRINTF_FUNC ( "idToken = %s \n", ShmOCPP20Data->ReserveNow [hasDc].idToken.idToken ); PRINTF_FUNC ( "*************ChkOcppStatus : (AC) OcppReservedStatus End****************** \n" ); ac_chargingInfo [0]->ReservationId = ShmOCPP20Data->ReserveNow [hasDc].id; ac_chargingInfo [0]->SystemStatus = SYS_MODE_RESERVATION; strncpy ( (char *) ShmDcCommonData->_reserved_UserId, (char *) ShmOCPP20Data->ReserveNow [hasDc].idToken.idToken, 30 ); } ShmOCPP20Data->CsMsg.bits [hasDc].ReserveNowConf = YES; } if (ac_chargingInfo [0]->SystemStatus == SYS_MODE_RESERVATION && ShmOCPP20Data->CsMsg.bits [hasDc].CancelReservationReq == YES) { ShmOCPP20Data->CsMsg.bits [hasDc].CancelReservationReq = NO; if (ShmOCPP20Data->ReserveNow [hasDc].id == ac_chargingInfo [0]->ReservationId) { PRINTF_FUNC ( "***************ChkOcppStatus : (AC) OcppReservedStatus******************** \n" ); PRINTF_FUNC ( "ReservationId = %d \n", ShmOCPP20Data->ReserveNow [hasDc].id ); PRINTF_FUNC ( "***********ChkOcppStatus : (AC) Cancel OcppReservedStatus End**************** \n" ); ac_chargingInfo [0]->ReservationId = -1; ac_chargingInfo [0]->SystemStatus = SYS_MODE_IDLE; strcpy ( (char *) ShmDcCommonData->_reserved_UserId, "" ); ShmOCPP20Data->CsMsg.bits [hasDc].CancelReservationConf = YES; } } } } //=============================================== // OCPP routine //=============================================== void ocpp_process_start() { if(strcmp((char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") != EQUAL && strcmp((char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, "") != EQUAL) { if(system("pidof -s OcppBackend > /dev/null") != 0) { DEBUG_ERROR_MSG("OcppBackend not running, restart it.\r\n"); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) system("/root/OcppBackend &"); else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) system("/root/OcppBackend20 &"); } if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((time((time_t*)NULL) - ShmOCPP16Data->procDogTime) > 180) { DEBUG_ERROR_MSG("OcppBackend watch dog timeout task restart.\n"); ShmOCPP16Data->procDogTime = time((time_t*)NULL); system("pkill OcppBackend"); } } if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((time((time_t*)NULL) - ShmOCPP20Data->procDogTime) > 180) { DEBUG_ERROR_MSG("OcppBackend20 watch dog timeout task restart.\n"); ShmOCPP16Data->procDogTime = time((time_t*)NULL); system("pkill OcppBackend20"); } } } if(strcmp((char *)ShmSysConfigAndInfo->SysConfig.MaintainServerURL, "") != EQUAL) { if(system("pidof -s OcppBackendPH > /dev/null") != 0) { DEBUG_ERROR_MSG("OcppBackendPH not running, restart it.\r\n"); system("/root/OcppBackendPH &"); } } } void ocpp_auto_response_BootNotification() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->SpMsg.bits.BootNotificationConf == YES) ShmOCPP16Data->SpMsg.bits.BootNotificationConf = NO; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->SpMsg.bits.BootNotificationConf == YES) ShmOCPP20Data->SpMsg.bits.BootNotificationConf = NO; } } bool ocpp_is_resPass_StartTransactionConf(byte gun_index) { bool result = false; byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CpMsg.bits[gun_index + acDirIndex].StartTransactionConf; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CpMsg.bits[gun_index + acDirIndex].TransactionEventConf; } return result; } void ocpp_auto_response_StartTransationConf(byte gun_index) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CpMsg.bits[gun_index + acDirIndex].StartTransactionConf) ShmOCPP16Data->CpMsg.bits[gun_index + acDirIndex].StartTransactionConf = NO; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CpMsg.bits[gun_index + acDirIndex].TransactionEventConf) ShmOCPP20Data->CpMsg.bits[gun_index + acDirIndex].TransactionEventConf = NO; } } void ocpp_auto_response_ReserveConf(byte gun_index) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) ShmOCPP16Data->CsMsg.bits[gun_index + acDirIndex].ReserveNowConf = YES; else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) ShmOCPP20Data->CsMsg.bits[gun_index + acDirIndex].ReserveNowConf = YES; } bool ocpp_chk_authrization_cmd() { char buf2[16] = ""; memset(buf2, 0, ARRAY_SIZE(buf2)); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) sprintf(buf2, "%s", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status); else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) sprintf(buf2, "%s", ShmOCPP20Data->Authorize.Response_idTokenInfo.status); // 因為無法得知實際的長度,所以只能用搜尋的方式 if(strcmp(buf2, "Accepted") == EQUAL) return true; return false; } bool opcc_sub_get_reset_req() { bool result = false; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) result = ShmOCPP16Data->MsMsg.bits.ResetReq; else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) result = ShmOCPP20Data->MsMsg.bits.ResetReq; return result; } void ocpp_sub_run_reset(bool canReset) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(canReset && strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL) { DEBUG_ERROR_MSG("****** Hard Reboot ****** \n"); sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted"); ShmOCPP16Data->MsMsg.bits.ResetReq = NO; ShmOCPP16Data->MsMsg.bits.ResetConf = YES; sleep(3); system("reboot -f"); } else if (canReset && strcmp((char *)ShmOCPP16Data->Reset.Type, "Soft") == EQUAL) { DEBUG_ERROR_MSG("****** Soft Reboot ****** \n"); sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted"); ShmOCPP16Data->MsMsg.bits.ResetReq = NO; ShmOCPP16Data->MsMsg.bits.ResetConf = YES; sleep(3); KillAllTask(); CloseWatchDog(); system("/usr/bin/run_evse_restart.sh"); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(canReset && strcmp((char *)ShmOCPP20Data->Reset.type, "Immediate") == EQUAL) { DEBUG_ERROR_MSG("****** Hard Reboot ****** \n"); sprintf((char*)ShmOCPP20Data->Reset.Response_status, "Accepted"); ShmOCPP20Data->MsMsg.bits.ResetReq = NO; ShmOCPP20Data->MsMsg.bits.ResetConf = YES; sleep(3); system("reboot -f"); } else if (canReset && strcmp((char *)ShmOCPP20Data->Reset.type, "OnIdle") == EQUAL) { DEBUG_ERROR_MSG("****** Soft Reboot ****** \n"); sprintf((char*)ShmOCPP20Data->Reset.Response_status, "Accepted"); ShmOCPP20Data->MsMsg.bits.ResetReq = NO; ShmOCPP20Data->MsMsg.bits.ResetConf = YES; sleep(3); KillAllTask(); CloseWatchDog(); system("/usr/bin/run_evse_restart.sh"); } } } void ocpp_chk_reset_cmd(byte isforce) { if (opcc_sub_get_reset_req()) { bool canReset = true; if (ShmSysConfigAndInfo->SysWarningInfo.Level != _ALARM_LEVEL_CRITICAL) { for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _index++) { if (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CHARGING) { // Reset - AC 先停止充電 ac_chargingInfo[0]->StopChargeFlag = YES; GetTimespecFunc(&_resetChkTime); } } for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if (chargingInfo[_index]->SystemStatus >= SYS_MODE_REASSIGN && chargingInfo[_index]->SystemStatus <= SYS_MODE_TERMINATING) { canReset = false; // Reset 系統先停止充電 if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL) ocpp_set_stopReason_by_cmd(_index, "HardReset"); else ocpp_set_stopReason_by_cmd(_index, "SoftReset"); } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)ShmOCPP20Data->Reset.type, "Immediate") == EQUAL) ocpp_set_stopReason_by_cmd(_index, "HardReset"); else ocpp_set_stopReason_by_cmd(_index, "SoftReset"); } ChargingTerminalProcess(_index); GetTimespecFunc(&_resetChkTime); } } } if (canReset) { if (GetTimeoutValue(&_resetChkTime) < 0) GetTimespecFunc(&_resetChkTime); if (GetTimeoutValue(&_resetChkTime) >= 5) { ShmDcCommonData->evBoardResetFlag = YES; // Reset -> change status to maintain. for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { setChargerMode(_index, SYS_MODE_MAINTAIN); } ChangeLcmByIndex(_LCM_FIX); } else canReset = false; } else GetTimespecFunc(&_resetChkTime); if (isforce == YES) canReset = true; ocpp_sub_run_reset(canReset); } } void ocpp_chk_reserved_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_IDLE && ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppReservedStatus******************** \n"); ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowReq = NO; if (!opcc_chk_reserve_expired(gunIndex)) { PRINTF_FUNC("ReservationId = %d \n", ShmOCPP16Data->ReserveNow[gunIndex + acDirIndex].ReservationId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP16Data->ReserveNow[gunIndex + acDirIndex].IdTag); PRINTF_FUNC("*************ChkOcppStatus : OcppReservedStatus End****************** \n"); chargingInfo[gunIndex]->ReservationId = ShmOCPP16Data->ReserveNow[gunIndex].ReservationId; chargingInfo[gunIndex]->SystemStatus = SYS_MODE_RESERVATION; strcpy((char *)ShmDcCommonData->_reserved_UserId[gunIndex], (char *)ShmOCPP16Data->ReserveNow[gunIndex + acDirIndex].IdTag); } ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowConf = YES; } if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_RESERVATION && ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationReq = NO; if (ShmOCPP16Data->ReserveNow[gunIndex + acDirIndex].ReservationId == chargingInfo[gunIndex]->ReservationId) { PRINTF_FUNC("***************ChkOcppStatus : OcppReservedStatus******************** \n"); PRINTF_FUNC("ReservationId = %d \n", ShmOCPP16Data->ReserveNow[gunIndex + acDirIndex].ReservationId); PRINTF_FUNC("***********ChkOcppStatus : Cancel OcppReservedStatus End**************** \n"); chargingInfo[gunIndex]->ReservationId = -1; chargingInfo[gunIndex]->SystemStatus = SYS_MODE_IDLE; strcpy((char *)ShmDcCommonData->_reserved_UserId[gunIndex], ""); ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationConf = YES; } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_IDLE && ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppReservedStatus******************** \n"); ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowReq = NO; if (!opcc_chk_reserve_expired(gunIndex)) { PRINTF_FUNC("id = %d \n", ShmOCPP20Data->ReserveNow[gunIndex + acDirIndex].id); PRINTF_FUNC("idToken = %s \n", ShmOCPP20Data->ReserveNow[gunIndex + acDirIndex].idToken.idToken); PRINTF_FUNC("*************ChkOcppStatus : OcppReservedStatus End****************** \n"); chargingInfo[gunIndex]->ReservationId = ShmOCPP20Data->ReserveNow[gunIndex].id; chargingInfo[gunIndex]->SystemStatus = SYS_MODE_RESERVATION; strncpy((char *)ShmDcCommonData->_reserved_UserId[gunIndex], (char *)ShmOCPP20Data->ReserveNow[gunIndex + acDirIndex].idToken.idToken, 30); } ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].ReserveNowConf = YES; } if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_RESERVATION && ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationReq == YES) { ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationReq = NO; if (ShmOCPP20Data->ReserveNow[gunIndex + acDirIndex].id == chargingInfo[gunIndex]->ReservationId) { PRINTF_FUNC("***************ChkOcppStatus : OcppReservedStatus******************** \n"); PRINTF_FUNC("ReservationId = %d \n", ShmOCPP20Data->ReserveNow[gunIndex + acDirIndex].id); PRINTF_FUNC("***********ChkOcppStatus : Cancel OcppReservedStatus End**************** \n"); chargingInfo[gunIndex]->ReservationId = -1; chargingInfo[gunIndex]->SystemStatus = SYS_MODE_IDLE; strcpy((char *)ShmDcCommonData->_reserved_UserId[gunIndex], ""); ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].CancelReservationConf = YES; } } } } void ocpp_chk_availability_cmd(byte gunIndex) { byte type = 0; // 0 : none, 1 : operative, 2 inoperative byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].ChangeAvailabilityReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].ChangeAvailabilityReq = NO; if(strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex + acDirIndex].Type, "Operative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, gunIndex + acDirIndex, true); type = 1; } else if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex + acDirIndex].Type, "Inoperative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, gunIndex + acDirIndex, false); type = 2; } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].ChangeAvailabilityReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].ChangeAvailabilityReq = NO; if(strcmp((char *)ShmOCPP20Data->ChangeAvailability[gunIndex + acDirIndex].operationalStatus, "Operative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, gunIndex + acDirIndex, true); type = 1; } else if (strcmp((char *)ShmOCPP20Data->ChangeAvailability[gunIndex + acDirIndex].operationalStatus, "Inoperative") == EQUAL) { if (isDb_ready) DB_Update_Operactive(localDb, gunIndex + acDirIndex, false); type = 2; } } } if (type == 1) { chargingInfo[gunIndex]->IsAvailable = YES; if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[gunIndex]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[gunIndex]->SystemStatus == SYS_MODE_MAINTAIN) { setChargerMode(gunIndex, SYS_MODE_IDLE); } } else if (type == 2) { chargingInfo[gunIndex]->IsAvailable = NO; if (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[gunIndex]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[gunIndex]->SystemStatus == SYS_MODE_MAINTAIN) { setChargerMode(gunIndex, SYS_MODE_MAINTAIN); } } } void ocpp_chk_unlock_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorReq = NO; if ((chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { // Unlocked - 充電中,需停止充電 strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex + acDirIndex].StopReason, "UnlockCommand"); ChargingTerminalProcess(gunIndex); } if (chargingInfo[gunIndex]->Type == _Type_Chademo || chargingInfo[gunIndex]->Type == _Type_GB) strcpy((char *)ShmOCPP16Data->UnlockConnector[gunIndex + acDirIndex].ResponseStatus, "Unlocked"); else strcpy((char *)ShmOCPP16Data->UnlockConnector[gunIndex + acDirIndex].ResponseStatus, "Unlocked"); ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorConf = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorReq == YES) { ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorReq = NO; if ((chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[gunIndex]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[gunIndex]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { // Unlocked - 充電中,需停止充電 strcpy((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].transactionInfo.stoppedReason, "UnlockCommand"); ChargingTerminalProcess(gunIndex); } if (chargingInfo[gunIndex]->Type == _Type_Chademo || chargingInfo[gunIndex]->Type == _Type_GB) strcpy((char*)ShmOCPP20Data->UnlockConnector[gunIndex + acDirIndex].Response_status, "Unlocked"); else strcpy((char *)ShmOCPP16Data->UnlockConnector[gunIndex + acDirIndex].ResponseStatus, "Unlocked"); ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].UnlockConnectorConf = YES; } } } bool ocpp_chk_remoteStop_cmd(byte gunIndex) { bool result = false; byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) result = ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].RemoteStopTransactionReq; else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) result = ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].RequestStopTransactionReq; if (result) { DEBUG_INFO_MSG("Remote Stop by OCPP (%d) \n", gunIndex + acDirIndex); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex + acDirIndex].StopReason, "Remote"); ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].RemoteStopTransactionReq = NO; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { strcpy((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].transactionInfo.stoppedReason, "Remote"); ShmOCPP20Data->CsMsg.bits[gunIndex + acDirIndex].RequestStopTransactionReq = NO; } } return result; } bool ocpp_sub_get_remote_start_transaction_req(byte gun_index) { bool result = false; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq; } if (result && ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { strcpy((char *)ShmOCPP16Data->StartTransaction[gun_index].IdTag, (char *)ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag); } return result; } void ocpp_sub_set_remote_start_transaction_req(byte gunIndex, bool result) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStartTransactionReq = result; else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) ShmOCPP20Data->CsMsg.bits[gunIndex].RequestStartTransactionReq = result; } void ocpp_chk_remoteStart_cmd() { if(!isDetectPlugin()) { // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 byte acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; for (byte ac_index = 0; ac_index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; ac_index++) { if (ocpp_sub_get_remote_start_transaction_req(acDirIndex)) { if (ac_chargingInfo[ac_index]->SystemStatus == SYS_MODE_IDLE || ac_chargingInfo[ac_index]->SystemStatus == SYS_MODE_RESERVATION) { ac_chargingInfo[ac_index]->RemoteStartFlag = YES; ShmSysConfigAndInfo->SysInfo.OrderCharging = YES; ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX; //ShmSysConfigAndInfo->SysInfo.OrderCharging = DEFAULT_AC_INDEX; //ShmOCPP16Data->CsMsg.bits[ShmSysConfigAndInfo->SysConfig.TotalConnectorCount + ac_index].RemoteStartTransactionReq = NO; DetectPluginStart(); return; } ocpp_sub_set_remote_start_transaction_req(acDirIndex, NO); } } byte threeGunIndex = 0; byte dcIndex = 0; bool isGunUsingStatus = false; byte scheduleIndex = 0; for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { // 如果有 AC 槍,且 DC 槍也有兩把 if (acDirIndex == 1 && _index == 1) threeGunIndex = 1; if (ocpp_sub_get_remote_start_transaction_req(_index + threeGunIndex)) dcIndex = _index; if (chargingInfo[_index]->SystemStatus != SYS_MODE_IDLE) { isGunUsingStatus = true; } if (chargingInfo[_index]->schedule.isTriggerStart) scheduleIndex = _index; } // 如果是雙槍單模,只認閒置狀態的槍,如果有預約~ 則預約也算被使用 if (isGunUsingStatus && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf) { if (dcIndex == 0) threeGunIndex = 0; //ocpp_sub_set_remote_start_transaction_req(dcIndex + threeGunIndex, NO); return; } if (dcIndex == 0) threeGunIndex = 0; if (ocpp_sub_get_remote_start_transaction_req(dcIndex + threeGunIndex)) { if (chargingInfo[dcIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[dcIndex]->SystemStatus == SYS_MODE_RESERVATION) { if (ocpp_authorizeRemoteTxReqChk_key()) { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, (char *)ShmOCPP16Data->RemoteStartTransaction[dcIndex + threeGunIndex].IdTag); } else { chargingInfo[dcIndex]->RemoteStartFlag = YES; ShmSysConfigAndInfo->SysInfo.OrderCharging = YES; ChangeGunSelectByIndex(dcIndex); //ShmSysConfigAndInfo->SysInfo.OrderCharging = gun_index; DetectPluginStart(); } } ocpp_sub_set_remote_start_transaction_req(dcIndex + threeGunIndex, NO); } else if (chargingInfo[scheduleIndex]->schedule.isTriggerStart) { if (chargingInfo[scheduleIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[scheduleIndex]->SystemStatus == SYS_MODE_RESERVATION) { chargingInfo[scheduleIndex]->RemoteStartFlag = YES; ShmSysConfigAndInfo->SysInfo.OrderCharging = YES; DetectPluginStart(); } chargingInfo[scheduleIndex]->schedule.isTriggerStart = NO; } } } bool ocpp_remote_start_wait_cmd() { bool result = false; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.isRemoteStartWaitReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq; } return result; } void ocpp_chk_update_cmd() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq == YES) { ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = NO; if (strcmp((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded") == EQUAL) { DEBUG_INFO_MSG("Backend : update start. \n"); sleep(2); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, ""); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { setChargerMode(_index, SYS_MODE_UPDATE); } for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _index++) { ac_chargingInfo[_index]->SystemStatus = SYS_MODE_UPDATE; } CloseWatchDog(); sleep(2); KillTask(); byte updateResult = CheckUpdateProcess(); if (updateResult == PASS) { DEBUG_INFO_MSG("Backend : update complete. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed"); } else if (updateResult == MODELNAME_FAIL) { DEBUG_INFO_MSG("Backend : model name is none match. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; sleep(5); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); return; } else { DEBUG_INFO_MSG("Backend : update fail. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); } strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; sleep(5); system("reboot -f"); } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq == YES) { ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = NO; if (strcmp((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "Downloaded") == EQUAL) { DEBUG_INFO_MSG("Backend : update start. \n"); sleep(2); strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, ""); strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "Installing"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { setChargerMode(_index, SYS_MODE_UPDATE); } for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _index++) { ac_chargingInfo[_index]->SystemStatus = SYS_MODE_UPDATE; } CloseWatchDog(); sleep(2); KillTask(); byte updateResult = CheckUpdateProcess(); if (updateResult == PASS) { DEBUG_INFO_MSG("Backend : update complete. \n"); strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "Installed"); } else if (updateResult == MODELNAME_FAIL) { DEBUG_INFO_MSG("Backend : model name is none match. \n"); strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; sleep(5); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); return; } else { DEBUG_INFO_MSG("Backend : update fail. \n"); strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed"); } strcpy((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "Installed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; sleep(5); system("reboot -f"); } } } } bool ocpp_chk_invalid_id_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strstr((char *) ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnInvalidId].ItemData, "TRUE")) { if (strcmp((char *)ShmOCPP16Data->StartTransaction[gunIndex + acDirIndex].ResponseIdTagInfo.Status, "Blocked") == EQUAL || strcmp((char *)ShmOCPP16Data->StartTransaction[gunIndex + acDirIndex].ResponseIdTagInfo.Status, "Expired") == EQUAL || strcmp((char *)ShmOCPP16Data->StartTransaction[gunIndex + acDirIndex].ResponseIdTagInfo.Status, "Invalid") == EQUAL) return true; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strstr((char *) ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "TRUE")) { if (strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "Blocked") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "Expired") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "Invalid") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "NoCredit") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "NotAllowedTypeEVSE") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "NotAtThisLocation") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "NotAtThisTime") == EQUAL || strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].Response_idTokenInfo.status, "Unknown") == EQUAL) return true; } } return false; } bool ocpp_chk_profileConf_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf == YES) { ShmOCPP16Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf = NO; return true; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf == YES) { ShmOCPP20Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf = NO; return true; } } return false; } void ocpp_chk_notificationMessage_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].TriggerMessageReq == YES) { if (chargingInfo[gunIndex]->Type == _Type_Chademo && (chargingInfo[gunIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[gunIndex]->SystemStatus ==SYS_MODE_RESERVATION || chargingInfo[gunIndex]->SystemStatus ==SYS_MODE_MAINTAIN)) { if (ShmDcCommonData->_cha_try_communication[gunIndex].try2CommunicationFlag == NO) { PRINTF_FUNC("Trigger msg (StatusNotification) = %d (chademo) \n", gunIndex); ShmDcCommonData->_cha_try_communication[gunIndex].elapsedTime = 0; GetTimespecFunc(&ShmDcCommonData->_cha_try_communication[gunIndex].detectTimer); ShmDcCommonData->_cha_try_communication[gunIndex].try2CommunicationFlag = YES; } } else if (chargingInfo[gunIndex]->Type == _Type_CCS || chargingInfo[gunIndex]->Type == _Type_GB || chargingInfo[gunIndex]->Type == _Type_AC) { PRINTF_FUNC("Trigger msg (StatusNotification) = %d (ccs) \n", gunIndex); } ShmOCPP16Data->CsMsg.bits[gunIndex + acDirIndex].TriggerMessageReq = NO; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { } if (ShmDcCommonData->_cha_try_communication[gunIndex].try2CommunicationFlag) { int _timeBuf = GetTimeoutValue(&ShmDcCommonData->_cha_try_communication[gunIndex].detectTimer); if (_timeBuf < 0) { ShmDcCommonData->_cha_try_communication[gunIndex].elapsedTime = 0; GetTimespecFunc(&ShmDcCommonData->_cha_try_communication[gunIndex].detectTimer); } if (_timeBuf > 30 || (_timeBuf > 2 && chargingInfo[gunIndex]->ConnectorPlugIn)) { PRINTF_FUNC("Trigger msg - timeout or Plugin. \n"); ShmDcCommonData->_cha_try_communication[gunIndex].try2CommunicationFlag = NO; } else ShmDcCommonData->_cha_try_communication[gunIndex].elapsedTime = (_timeBuf / uSEC_VAL); } } void ocpp_lift_profileReq_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (ShmOCPP16Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf == NO) { if (ShmOCPP16Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileReq == NO) ShmOCPP16Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileReq = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (ShmOCPP20Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileConf == NO) { if (ShmOCPP20Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileReq == NO) ShmOCPP20Data->CSUMsg.bits[gunIndex + acDirIndex].ChargingProfileReq = YES; } } } void ocpp_set_startTransation_cmd(byte gunIndex) { byte _OcppGunIndex = gunIndex; // 如果有 AC 槍,而現在是 DC 第二把槍進入充電 if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 1 && gunIndex == 1) _OcppGunIndex = 2; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)chargingInfo[gunIndex]->StartUserId, (char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag); else strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, (char *)chargingInfo[gunIndex]->StartUserId); if (strcmp((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, "") == EQUAL) strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", chargingInfo[gunIndex]->StartUserId); ShmOCPP16Data->CpMsg.bits[_OcppGunIndex].StartTransactionReq = YES; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken, (char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken); else strcpy((char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken); ShmOCPP20Data->CpMsg.bits[_OcppGunIndex].TransactionEventReq = YES; } } void ocpp_set_stopTransation_cmd(byte gunIndex) { byte _OcppGunIndex = gunIndex; // 如果有 AC 槍,而現在是 DC 第二把槍進入充電 if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 1 && gunIndex == 1) _OcppGunIndex = 2; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag); else strcpy((char *)ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP16Data->StopTransaction[_OcppGunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[_OcppGunIndex].StopTransactionReq = YES; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken, (char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken); else strcpy((char *)ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP20Data->TransactionEvent[_OcppGunIndex].idToken.idToken); ShmOCPP20Data->CpMsg.bits[_OcppGunIndex].TransactionEventReq = YES; } } void ocpp_set_noErrorCode_cmd(byte gunIndex, char *errString) { // 參數 gunIndex 已包含 AC 槍 if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex].ErrorCode, errString); else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { } } void ocpp_set_stopReason_by_cmd(byte gunIndex, char *reason) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *)ShmOCPP16Data->StopTransaction[gunIndex + acDirIndex].StopReason, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex + acDirIndex].StopReason, reason); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].transactionInfo.stoppedReason, "") == EQUAL) { strcpy((char *)ShmOCPP20Data->TransactionEvent[gunIndex + acDirIndex].transactionInfo.stoppedReason, reason); } } } void ocpp_set_authorizeReq_cmd(byte value) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) ShmOCPP16Data->SpMsg.bits.AuthorizeReq = value; else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) ShmOCPP20Data->SpMsg.bits.AuthorizeReq = value; } void ocpp_set_authorizeConf_cmd(byte value) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) ShmOCPP16Data->SpMsg.bits.AuthorizeConf = value; else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) ShmOCPP20Data->SpMsg.bits.AuthorizeConf = value; } void ocpp_set_errCode_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *)chargingInfo[gunIndex]->ConnectorAlarmCode, "") != EQUAL) { strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].ErrorCode, "InternalError"); strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].VendorErrorCode, (char *)chargingInfo[gunIndex]->ConnectorAlarmCode); } else if (strcmp((char *)chargingInfo[gunIndex]->EvConnAlarmCode, "") != EQUAL) { strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].ErrorCode, "OtherError"); strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].VendorErrorCode, (char *)chargingInfo[gunIndex]->EvConnAlarmCode); } else { strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].ErrorCode, "NoError"); strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].VendorErrorCode, ""); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { } } void ocpp_clear_errorCode_cmd(byte gunIndex) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].ErrorCode, "NoError") != EQUAL) strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].ErrorCode, "NoError"); if (strcmp((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].VendorErrorCode, "") != EQUAL) strcpy((char *)ShmOCPP16Data->StatusNotification[gunIndex + acDirIndex].VendorErrorCode, ""); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { } } void ocpp_clear_idTag_cmd(byte gun_index) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) strcpy((char *)ShmOCPP16Data->StartTransaction[gun_index + acDirIndex].ResponseIdTagInfo.Status, ""); else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) strcpy((char *)ShmOCPP20Data->TransactionEvent[gun_index + acDirIndex].Response_idTokenInfo.status, ""); } void ocpp_clear_stopReason(byte gun_index) { byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gun_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) strcpy((char *)ShmOCPP16Data->StopTransaction[gun_index + acDirIndex].StopReason, ""); else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) strcpy((char *)ShmOCPP20Data->TransactionEvent[gun_index + acDirIndex].transactionInfo.stoppedReason, ""); } unsigned short _ocpp_get_connect_timeout() { uint16_t result = (TIMEOUT_SPEC_HANDSHAKING / 1000); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData,"") != 0) result = atoi((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[ConnectionTimeOut].ItemData); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value,"") != 0) result = atoi((char *)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value); } return result; } bool ocpp_get_authorize_conf() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) return ShmOCPP16Data->SpMsg.bits.AuthorizeConf; else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) return ShmOCPP20Data->SpMsg.bits.AuthorizeConf; return false; } bool ocpp_get_startTransation_req(byte gunIndex) { bool result = false; byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (gunIndex == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; // 如果有 AC 槍,而現在是 DC 第二把槍進入充電 if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CpMsg.bits[gunIndex + acDirIndex].StartTransactionReq; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CpMsg.bits[gunIndex + acDirIndex].TransactionEventReq; } return result; } void ocpp_get_freeVendor(byte gunIndex) { byte _OcppGunIndex = gunIndex; // 如果有 AC 槍,而現在是 DC 第二把槍進入充電 if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 1 && gunIndex == 1) _OcppGunIndex = 2; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, ""); if (strlen((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[FreeVendIdtag].ItemData) > 0) { strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[FreeVendIdtag].ItemData); } else { strcpy((char *)ShmOCPP16Data->StartTransaction[_OcppGunIndex].IdTag, (char *)ShmSysConfigAndInfo->SysConfig.SerialNumber); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strlen((char *)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].value) > 0) { } else { } } } void ocpp_parsing_DT_defaultPrice_cmd() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp(MyDefaultPriceString, (char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData) != EQUAL) { DefaultPriceHandlerOcpp16((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData); memcpy(MyDefaultPriceString, ShmOCPP16Data->ConfigurationTable.CoreProfile[DefaultPrice].ItemData, 128); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { //ShmOCPP20Data->CostUpdated } } void ocpp_parsing_DT_userPrice_cmd() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strlen((char *)ShmOCPP16Data->Cost.SetUserPrice.idToken) > 0 && strlen((char *)ShmOCPP16Data->Cost.SetUserPrice.price) > 0) { UserPriceHandlerOcpp16((char *)ShmOCPP16Data->Cost.SetUserPrice.idToken, (char *)ShmOCPP16Data->Cost.SetUserPrice.price); //memset(&ShmOCPP16Data->Cost.SetUserPrice, 0x00, sizeof(struct StrcutSetUserPrice)); } } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { //ShmOCPP20Data->CostUpdated } } void ocpp_parsing_DT_running_final_cmd() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { RunningFinalCostHandlerOcpp16(); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { //ShmOCPP20Data->CostUpdated } } void ocpp_chargingProfile_process(byte _index) { int _time = 0; int _startCount = NO_DEFINE; int _maxCount = 0; byte acDirIndex = 0; // 如果有 AC 槍,則固定是第 2 把槍,所以索引固定為 1 (只會影響右槍所以考慮右槍狀況) if (_index == 1) acDirIndex = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if (strcmp((char *)ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingProfileKind, "Absolute") == EQUAL && ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingProfileId == YES) { _time = GetStartScheduleTime(ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.StartSchedule); if (_time > -1) { _maxCount = ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod); _startCount = NO_DEFINE; for (byte _count = 0; _count < _maxCount; _count++) { // 預設最小輸出電流 (MIN_OUTPUT_CUR) A if (_time >= ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod[_count].StartPeriod) { if ((_count == 0 && ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod[_count].Limit >= MIN_OUTPUT_CUR) || ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod[_count].Limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } if (_startCount < _maxCount) { //PRINTF_FUNC("Gun_%d, Get Profile - Profile Index = %d \n", _index + acDirIndex, _startCount); chargingInfo[_index]->ChargingProfilePower = ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * AC_OUTPUT_VOL * ShmOCPP16Data->SmartChargingProfile[_index + acDirIndex].ChargingSchedule.ChargingSchedulePeriod[_startCount].NumberPhases; if (chargingInfo[_index]->EvBatterytargetVoltage > 0 && chargingInfo[_index]->PresentChargingVoltage > 0) chargingInfo[_index]->ChargingProfileCurrent = (chargingInfo[_index]->ChargingProfilePower / chargingInfo[_index]->PresentChargingVoltage) * 10; else chargingInfo[_index]->ChargingProfileCurrent = 0; } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } if (strcmp((char *)ShmOCPP16Data->MaxChargingProfile.ChargingProfileKind, "Absolute") == EQUAL && ShmOCPP16Data->MaxChargingProfile.ChargingProfileId == YES) { _time = GetStartScheduleTime(ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.StartSchedule); if (_time > -1) { _maxCount = ARRAY_SIZE(ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod); _startCount = NO_DEFINE; for (byte _count = 0; _count < _maxCount; _count++) { if (_time >= ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_count].StartPeriod) { if ((_count == 0 && ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_count].Limit >= MIN_OUTPUT_CUR) || ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_count].Limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } //PRINTF_FUNC("_startCount = %d, Max Profile Limit = %f \n", _startCount, ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit); if (_startCount < _maxCount) { float maxChargingProfilePow = ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_startCount].Limit * AC_OUTPUT_VOL * ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[_startCount].NumberPhases; if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) maxChargingProfilePow /= 2; ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower = maxChargingProfilePow; } else ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower = -1; } } else ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower = -1; } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if (strcmp((char *)ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingProfileKind, "Absolute") == EQUAL && ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].id == YES) { _time = GetStartScheduleTime(ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].startSchedule); _maxCount = ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod); _startCount = NO_DEFINE; for (byte _count = 0; _count < _maxCount; _count++) { // 預設最小輸出電流 (MIN_OUTPUT_CUR) A if (_time >= ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod[_count].startPeriod) { if ((_count == 0 && ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod[_count].limit >= MIN_OUTPUT_CUR) || ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod[_count].limit > MIN_OUTPUT_CUR) { _startCount = _count; } } } if (_startCount < _maxCount) { //PRINTF_FUNC("Gun_%d, Get Profile - Profile Index = %d \n", _index + acDirIndex, _startCount); //PRINTF_FUNC("Profile Limit = %f \n", ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit); chargingInfo[_index]->ChargingProfilePower = ShmOCPP20Data->SmartChargingProfile[_index + acDirIndex].chargingSchedule[0].chargingSchedulePeriod[_startCount].limit * AC_OUTPUT_VOL; if (chargingInfo[_index]->EvBatterytargetVoltage > 0 && chargingInfo[_index]->PresentChargingVoltage > 0) chargingInfo[_index]->ChargingProfileCurrent = (chargingInfo[_index]->ChargingProfilePower / chargingInfo[_index]->PresentChargingVoltage) * 10; else chargingInfo[_index]->ChargingProfileCurrent = 0; } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } } else { chargingInfo[_index]->ChargingProfilePower = -1; chargingInfo[_index]->ChargingProfileCurrent = -1; } if (chargingInfo[_index]->ChargingProfilePower >= 0 && _ChargingProfilePwBuffer[_index] != chargingInfo[_index]->ChargingProfilePower) { _ChargingProfilePwBuffer[_index] = chargingInfo[_index]->ChargingProfilePower; PRINTF_FUNC("Profile : ChargingProfilePower = %.2f \n", chargingInfo[_index]->ChargingProfilePower); PRINTF_FUNC("Profile : ChargingProfileCurrent = %.2f \n", chargingInfo[_index]->ChargingProfileCurrent); } } void CheckOcppProfileConfirm(byte gun_index) { if ((chargingInfo [gun_index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo [gun_index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo [gun_index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo [gun_index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { if (chargingInfo [gun_index]->SystemStatus == SYS_MODE_CHARGING) { // 進充電後,如果輸出電壓落差大於 10V 則直接繼續看 ChargingProfile if (chargingInfo [gun_index]->PresentChargingVoltage >= gunOutputVol [gun_index] + 10 || chargingInfo [gun_index]->PresentChargingVoltage <= gunOutputVol [gun_index] - 10) { gunOutputVol [gun_index] = chargingInfo [gun_index]->PresentChargingVoltage; } } ocpp_chk_profileConf_cmd ( gun_index ); } } void CheckAcOcppProfileConfirm() { if (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_PREPARING && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CHARGING) { ocpp_ac_chk_profileConf_cmd(); } } //=============================================== // wifi schedule //=============================================== bool WifiScheduleStop(byte gunIndex) { bool result = false; result = chargingInfo[gunIndex]->schedule.isTriggerStop; chargingInfo[gunIndex]->schedule.isTriggerStop = NO; return result; } //=============================================== // SQLite3 related routine //=============================================== int NetworkDB_Open(sqlite3 *db) { int result = PASS; char* errMsg = NULL; char* createNerRecordSql="CREATE TABLE IF NOT EXISTS network_record(" "idx integer primary key AUTOINCREMENT, " "occurDatetime text NOT NULL, " "isInternet text NOT NULL, " "isOcppConnected text NOT NULL, " "isEth0Internet text NOT NULL, " "isMlan0Internet text NOT NULL, " "isPpp0Internet text NOT NULL, " "rssiMlan0 text NOT NULL, " "rssiPpp0 text NOT NULL" ");"; //sqlite3_config(SQLITE_CONFIG_URI, 1); if(sqlite3_open(NETWORK_DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database (Net) : %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local network status record database open successfully.\n"); if (sqlite3_exec(db, createNerRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create local network status record table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened local network status record table successfully\n"); } sqlite3_close(db); } return result; } int DB_Open(sqlite3 *db) { int result = PASS; char* errMsg = NULL; char* createRecordSql="CREATE TABLE IF NOT EXISTS charging_record(" "idx integer primary key AUTOINCREMENT, " "reservationId text, " "transactionId text, " "startMethod text, " "userId text, " "dateTimeStart text, " "dateTimeStop text," "socStart text, " "socStop text, " "chargeEnergy text, " "stopReason text," "vincode text" ");"; char* createCfgSql="CREATE TABLE IF NOT EXISTS `config` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`item` TEXT NOT NULL, " "`connector` INTEGER NOT NULL, " "`val` TEXT NOT NULL, unique(item,connector) on conflict replace);"; char* creatererrecordSql="CREATE TABLE IF NOT EXISTS `event_record` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`occurDatetime` TEXT NOT NULL, " "`statusCode` TEXT NOT NULL, unique(occurDatetime,statusCode) on conflict replace);"; char* createrebootSql="CREATE TABLE IF NOT EXISTS `reboot_record` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`rebootDatetime` TEXT NOT NULL, unique(rebootDatetime) on conflict replace);"; char * createconsumptionSql = "CREATE TABLE IF NOT EXISTS `power_consumption` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`connector` INTEGER NOT NULL, " "`val` TEXT NOT NULL, unique(connector) on conflict replace);"; // char * createTestSql = "CREATE TABLE IF NOT EXISTS `for_test` ( " // "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " // "`connector` INTEGER NOT NULL, " // "`testID` TEXT, " // "`checkStatus` INTEGER NOT NULL " // ");"; if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local charging record database open successfully.\r\n"); if (sqlite3_exec(db, createRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create local charging record table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened local charging record table successfully\n"); } if (sqlite3_exec(db, createCfgSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create local config table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened local config table successfully\n"); } if (sqlite3_exec(db, creatererrecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create local record table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened local record table successfully\n"); } if (sqlite3_exec(db, createrebootSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create reboot record table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened reboot record table successfully\n"); } if (sqlite3_exec(db, createconsumptionSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Create power consumption record table error message: %s\n", errMsg); } else { PRINTF_FUNC( "Opened power consumption record table successfully\n"); } // if (sqlite3_exec(db, createTestSql, 0, 0, &errMsg) != SQLITE_OK) // { // result = FAIL; // printf( "Create test table error message: %s\n", errMsg); // } // else // { // printf( "Opened test table successfully\n"); // } sqlite3_close(db); } return result; } int DB_Insert_Record(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char insertSql[1024]; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(insertSql, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, vincode) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", chargingInfo[gun_index]->ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, chargingInfo[gun_index]->StartMethod, chargingInfo[gun_index]->StartUserId, chargingInfo[gun_index]->StartDateTime, chargingInfo[gun_index]->StopDateTime, chargingInfo[gun_index]->EvBatteryStartSoc, chargingInfo[gun_index]->EvBatterySoc, chargingInfo[gun_index]->PresentChargedEnergy, ShmOCPP16Data->StopTransaction[gun_index].StopReason, chargingInfo[gun_index]->EVCCID); } else if (ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf(insertSql, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason) " "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s');", chargingInfo[gun_index]->ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, chargingInfo[gun_index]->StartMethod, chargingInfo[gun_index]->StartUserId, chargingInfo[gun_index]->StartDateTime, chargingInfo[gun_index]->StopDateTime, chargingInfo[gun_index]->EvBatteryStartSoc, chargingInfo[gun_index]->EvBatterySoc, chargingInfo[gun_index]->PresentChargedEnergy, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason); } if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local charging record database open successfully.\n"); if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Insert local charging record error message: %s\n", errMsg); } else { PRINTF_FUNC( "Insert local charging record successfully\n"); } sprintf(insertSql, "delete from charging_record where idx < (select idx from charging_record order by idx desc limit 1)-2000;"); if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "delete local charging error message: %s\n", errMsg); } else { PRINTF_FUNC( "delete local charging record successfully\n"); } sqlite3_close(db); } return result; } int DB_Update_Operactive(sqlite3 *db, uint8_t gun_index, uint8_t IsAvailable) { uint8_t result = false; char* errMsg = NULL; char sqlStr[1024]; srand(time(NULL)); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local charging record database open successfully (%d).\r\n", IsAvailable); sprintf(sqlStr, "insert or replace into config (item, connector, val) values('IsAvailable', %d, %d);", gun_index, IsAvailable); PRINTF_FUNC("sqlStr= %s\r\n", sqlStr); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "update config error message: %s\n", errMsg); } else { PRINTF_FUNC("update connector-%d config item isOperactive to %d\r\n", gun_index, IsAvailable); } sqlite3_close(db); } return result; } int DB_Get_Operactive(sqlite3 *db, uint8_t gun_index) { uint8_t result = true; char* errMsg = NULL; char sqlStr[1024]; char **rs; int rows, cols; sprintf(sqlStr, "select * from config where item='IsAvailable' and connector=%d;", gun_index); //DEBUG_INFO("sqlStr= %s\r\n", sqlStr); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local config query database open successfully.\r\n"); sqlite3_get_table(db, sqlStr, &rs, &rows, &cols, &errMsg); if(rows>0) { for(int idxRow=1;idxRow<=rows;idxRow++) { if(strcmp(rs[(idxRow*cols)+3], "0") == 0) { result = false; } PRINTF_FUNC("Query connector-%d isOperactive: %s\r\n", gun_index, rs[(idxRow*cols)+3]); } } else { PRINTF_FUNC("Query connector-%d fail, set default value to operactive.\r\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } void DB_Update_PowerConsumption(sqlite3 *db, uint8_t gun_index, float value) { char* errMsg = NULL; char sqlStr[1024]; srand(time(NULL)); if(sqlite3_open(DB_FILE, &db)) { PRINTF_FUNC( "Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sprintf(sqlStr, "insert or replace into power_consumption (connector, val) values(%d, %f);", gun_index, value); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { PRINTF_FUNC( "update power_consumption error message: %s\n", errMsg); } else { //PRINTF_FUNC("update connector-%d power_consumption item consumption to %f \r\n", gun_index, value); } sqlite3_close(db); } } float DB_Get_PowerConsumption(sqlite3 *db, uint8_t gun_index) { float result = 0; char* errMsg = NULL; char sqlStr[1024]; char **rs; int rows, cols; sprintf(sqlStr, "select * from power_consumption where connector=%d;", gun_index); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC("Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC("Local config query database open successfully.\r\n"); sqlite3_get_table(db, sqlStr, &rs, &rows, &cols, &errMsg); if (rows > 0) { for (int idxRow = 1; idxRow <= rows; idxRow++) { result = atof(rs[(idxRow * cols) + 2]); } } else { PRINTF_FUNC( "Query connector-%d fail, set default value to consumption.\r\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } int DB_Reboot_Record(sqlite3 *db) { int result = PASS; char* errMsg = NULL; char insertSql[256]; sprintf(insertSql, "insert into reboot_record(rebootDatetime) values(CURRENT_TIMESTAMP);"); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC( "Local charging record database open successfully.\n"); if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Insert reboot record error message: %s\n", errMsg); } else { PRINTF_FUNC( "Insert reboot record successfully\n"); } sprintf(insertSql, "delete from reboot_record where idx < (select idx from charging_record order by idx desc limit 1)-2000;"); if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "delete reboot record error message: %s\n", errMsg); } else { PRINTF_FUNC( "delete reboot record successfully\n"); } sqlite3_close(db); } return result; } int DB_Insert_test_Record(sqlite3 *db, uint8_t gun_index, char *textID) { int result = PASS; char* errMsg = NULL; char insertSql[1024]; sprintf(insertSql, "insert into for_test (connector, testID, checkStatus) values(%d, %s, 0);", gun_index, textID); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Insert sdlu test error message : %s\n", errMsg); } else { PRINTF_FUNC( "Insert sdlu test successfully\n"); } sqlite3_close(db); } return result; } int DB_delete_test_Record(sqlite3 *db, uint8_t gun_index, char *textID) { int result = PASS; char* errMsg = NULL; char insertSql[1024]; sprintf(insertSql, "delete from for_test where testID = %s", textID); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC("Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { if (sqlite3_exec(db, insertSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; PRINTF_FUNC( "Test message 2: %s\n", errMsg); } else { PRINTF_FUNC( "Test message 2 successfully\n"); } sqlite3_close(db); } return result; } int DB_sql_test(sqlite3 *db, uint8_t gun_index) { int result = PASS; char* errMsg = NULL; char insertSql[1024]; char valueStr[128]; char **rs; int rows, cols; sprintf(insertSql, "select testID from for_test where checkStatus=0;"); if (sqlite3_open(DB_FILE, &db)) { result = FAIL; PRINTF_FUNC("Can't open database: %s\r\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { PRINTF_FUNC("Local for_test query database open successfully.\r\n"); sqlite3_get_table(db, insertSql, &rs, &rows, &cols, &errMsg); if (rows > 0) { for (int idxRow = 1; idxRow <= rows; idxRow++) { strcpy(valueStr, rs[(idxRow * cols)]); printf("valueStr = %s \n", valueStr); } } else { PRINTF_FUNC("select testID from for_test fail \r\n"); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } //=============================================== // Config process //=============================================== void AddPlugInTimes(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) ShmSysConfigAndInfo->SysConfig.ChademoPlugInTimes += 1; else if(chargingInfo[gunIndex]->Type == _Type_CCS) ShmSysConfigAndInfo->SysConfig.Ccs2PlugInTimes += 1; else if(chargingInfo[gunIndex]->Type == _Type_GB) ShmSysConfigAndInfo->SysConfig.GbPlugInTimes += 1; } void ChangeStartOrStopDateTime(byte isStart, byte gunIndex) { char cmdBuf[32]; struct timeb csuTime; struct tm *tmCSU; 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 *)chargingInfo[gunIndex]->StartDateTime, cmdBuf); else { if (strcmp((char *)chargingInfo[gunIndex]->StartDateTime, "00:00:00") != EQUAL) strcpy((char *)chargingInfo[gunIndex]->StopDateTime, cmdBuf); } } void zipLogFiles() { const char* logPath = "/Storage/SystemLog"; // 獲取目錄 DIR* pDir = opendir(logPath); if (pDir != NULL) { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); // PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, // tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, // tmCSU->tm_sec); // Read items inside the folder struct dirent* pEntry = NULL; while ((pEntry = readdir(pDir)) != NULL) { if (strcmp(pEntry->d_name, ".") != 0 && strcmp(pEntry->d_name, "..") != 0 && strncmp(pEntry->d_name, "[", 1) == 0 && strstr(pEntry->d_name, "tar") < 0) { char yearC[5]; unsigned short year = 0; char monthC[3]; unsigned short month = 0; yearC[4] = '\0'; strncpy(yearC, pEntry->d_name + 1, 4); monthC[2] = '\0'; strncpy(monthC, pEntry->d_name + 6, 2); year = atoi(yearC); month = atoi(monthC); if (year != 0) { if (year < tmCSU->tm_year + 1900 || (year >= tmCSU->tm_year + 1900 && month < tmCSU->tm_mon + 1)) { DEBUG_INFO_MSG("tar file name : %s \n", pEntry->d_name); char file[256]; memset(file, 0x00, sizeof(file)); strcat(file, "tar zcvf "); strcat(file, logPath); strncat(file, "/", 1); strcat(file, pEntry->d_name); strcat(file, ".tar"); strncat(file, " ", 1); strcat(file, logPath); strncat(file, "/", 1); strcat(file, pEntry->d_name); PRINTF_FUNC("zip = %s \n", file); system(file); } } } } } // Close folder closedir(pDir); } void ChangeGunSelectByIndex(byte sel) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = sel; ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE; } void CheckIsAlternatvieByModelName() { if(ShmSysConfigAndInfo->SysConfig.ModelName[1] == 'W') { // 壁掛 ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf = YES; } else ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf = NO; } void StopProcessingLoop() { ocpp_process_start(); for (;;) { CheckTask(); CheckFactoryConfigFunction(); CheckFwUpdateFunction(); ocpp_chk_reset_cmd(YES); if (ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_CRITICAL) { // 經過底下的 function 後,ShmSysConfigAndInfo->SysWarningInfo.Level 會再被更新一次 ChkPrimaryStatus(); ButtonTriggerEvent(); ReviewCriticalAlarm(); if (ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_NORMAL && ShmDcCommonData->rebootCount < 1) { PRINTF_FUNC("Soft reboot for retry self-test (Primary). \n"); SetupRebootCount(1); KillAllTask(); sleep(3); system("/usr/bin/run_evse_restart.sh"); return; } } sleep(1); } } void CreateWatchdog() { if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO) { wtdFd = InitWatchDog(); if (wtdFd < 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } } bool IsConnectorWholeIdle() { bool result = true; for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { if (chargingInfo[count]->SystemStatus != SYS_MODE_IDLE && chargingInfo[count]->SystemStatus != SYS_MODE_RESERVATION) { result = false; break; } } for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; count++) { if (ac_chargingInfo[count]->SystemStatus != SYS_MODE_IDLE && ac_chargingInfo[count]->IsErrorOccur == NO) { result = false; break; } } return result; } void ClearAlarmCodeWhenAcOff() { if (!ShmSysConfigAndInfo->SysInfo.AcContactorStatus) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = NO; } } //========================================== // Check task processing //========================================== void CheckTask() { if(reset4gStep == RESET_4G_STEP_NONE && (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T' || ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { if(system("pidof -s Module_4g > /dev/null") != 0) { DEBUG_ERROR_MSG("Module_4g not running, restart it.\r\n"); system("/root/Module_4g &"); } } if(reset4gStep == RESET_4G_STEP_NONE && (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W' || ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { if(system("pidof -s Module_Wifi > /dev/null") != 0) { DEBUG_ERROR_MSG("Module_Wifi not running, restart it.\r\n"); system("/root/Module_Wifi &"); } } if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { if(system("pidof -s Module_DcMeter > /dev/null") != 0) { DEBUG_ERROR_MSG("Module_DcMeter not running, restart it.\r\n"); system("/root/Module_DcMeter &"); } } ocpp_process_start(); if(system("pidof -s Module_ProduceUtils > /dev/null") != 0) { DEBUG_ERROR_MSG("Module_ProduceUtils not running, restart it.\r\n"); system ("/root/Module_ProduceUtils &"); } } void Check267Alarm() { bool canRun = true; for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if((chargingInfo[_index]->SystemStatus > SYS_MODE_IDLE && chargingInfo[_index]->SystemStatus < SYS_MODE_TERMINATING) || (chargingInfo[_index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[_index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { canRun = false; break; } } if (canRun) { if ( ! ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES; } } } void CheckSystemTaskAlive() { unsigned char lostId = CheckSystemTask(ShmSysConfigAndInfo->SysInfo.SystemPage); if (lostId != 0) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost == NO) { EmcOccurThenStopCharging(); sleep(2); if (lostId == _SYSTEM_TASK_LOST_ITEM_MAIN) PRINTF_FUNC ( "System task lost (CSU). \n" ); else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVCOMM) { PRINTF_FUNC ( "System task lost (EVComm). \n" ); for (byte gun = 0; gun < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun ++) { chargingInfo [gun]->ConnectorPlugIn = NO; } } else if (lostId == _SYSTEM_TASK_LOST_ITEM_PSUCOMM) PRINTF_FUNC ( "System task lost (PSU Task). \n" ); else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVENTLOG) PRINTF_FUNC ( "System task lost (Event log). \n" ); else if (lostId == _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM) PRINTF_FUNC ( "System task lost (Primary). \n" ); else if (lostId == _SYSTEM_TASK_LOST_ITEM_LCMCONTROL) PRINTF_FUNC ( "System task lost (LCM Comm). \n" ); else if (lostId == _SYSTEM_TASK_LOST_ITEM_INTERCOMM) PRINTF_FUNC("System task lost (Internal Comm). \n"); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = YES; } } else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = NO; } void InitialDHCP() { char tmpbuf[256]; memset(tmpbuf,0,256); system("pgrep -f \"udhcpc -i eth0\" | xargs kill"); sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId); system(tmpbuf); } void Run4gResetProc() { if (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == _SYS_4G_MODE_ENABLE || ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == _SYS_WIFI_MODE_STATION) { if (!ShmSysConfigAndInfo->SysInfo.OcppConnStatus && !ShmSysConfigAndInfo->SysInfo.InternetConn) { if (reset4gStep == RESET_4G_STEP_NONE) { if ((ShmStatusCodeData->FaultCode.FaultEvents.bits.Telecom4GModuleBroken == YES && _4gResetChkFlag >= 12) || _4gResetChkFlag >= 60) { PRINTF_FUNC("Reset 4G/Wifi module. \n"); reset4gStep = RESET_4G_STEP_DELETE_TASK; } else _4gResetChkFlag++; } } else _4gResetChkFlag = 0; switch(reset4gStep) { case RESET_4G_STEP_DELETE_TASK: { PRINTF_FUNC("Killall 4G / Wifi task. \n"); system("killall Module_4g &"); system("killall Module_Wifi &"); reset4gStep = RESET_4G_STEP_GPIO_HIGH; } break; case RESET_4G_STEP_GPIO_HIGH: { PRINTF_FUNC("Disable 4G/Wifi. GPIO-104 -> High. \n"); system("echo 1 > /sys/class/gpio/gpio104/value"); reset4gStep = RESET_4G_STEP_GPIO_LOW_COMP; } break; case RESET_4G_STEP_GPIO_LOW_COMP: { PRINTF_FUNC("Enable 4G/Wifi. GPIO-104 -> Low. \n"); system("echo 0 > /sys/class/gpio/gpio104/value"); reset4gStep = RESET_4G_STEP_NONE; _4gResetChkFlag = 0; } break; } } else { if (reset4gStep != RESET_4G_STEP_NONE) system("echo 0 > /sys/class/gpio/gpio104/value"); reset4gStep = RESET_4G_STEP_NONE; _4gResetChkFlag = 0; } } //========================================== // Check Smart Charging Profile //========================================== int GetStartScheduleTime(unsigned char *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; } //========================================== // sub function //========================================== void CheckReturnToChargingConn() { if ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount + ShmSysConfigAndInfo->SysConfig.AcConnectorCount) > 1 && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZ_FAIL && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZ_COMP && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_WAIT_FOR_PLUG) { bool isReturnTimeout = false; for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { // 如果選的 DC 槍在充電~ 則 DC 槍不改變 if (count == ShmSysConfigAndInfo->SysInfo.CurGunSelected) { if ((chargingInfo[count]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[count]->SystemStatus <= SYS_MODE_COMPLETE) || (chargingInfo[count]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[count]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { isReturnTimeout = false; break; } } else if (count != ShmSysConfigAndInfo->SysInfo.CurGunSelected) { if ((chargingInfo[count]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[count]->SystemStatus <= SYS_MODE_COMPLETE) || (chargingInfo[count]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[count]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } } // AC 槍 if (!isReturnTimeout && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { // 沒有選中 AC,且 AC 在充電中 if (ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE && (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_PREPARING && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_COMPLETE)) { // 當前 DC 充電槍在 idle 狀態 if (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == SYS_MODE_IDLE || chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == SYS_MODE_RESERVATION) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == DEFAULT_AC_INDEX && ((chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus <= SYS_MODE_COMPLETE) || (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1))) { // 當前 DC 充電槍在 idle 狀態 if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_IDLE || ac_chargingInfo[0]->SystemStatus == SYS_MODE_RESERVATION) { isReturnTimeout = true; StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } } } if (!isReturnTimeout) StopSystemTimeoutDet(); } } bool GetStartChargingByAlterMode(byte _gun) { bool result = true; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 2 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { for (byte _select = 0; _select < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _select++) { if (_select != _gun) { if (chargingInfo[_select]->SystemStatus != SYS_MODE_IDLE && chargingInfo[_select]->SystemStatus != SYS_MODE_RESERVATION) { result = false; break; } } } } return result; } void TheEndCharging(byte gun_index) { chargingInfo[gun_index]->isRemoteStart = NO; StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvseCompleteDet); ChangeStartOrStopDateTime(NO, gun_index); DB_Insert_Record(localDb, gun_index); } void AdjustChargerCurrent() { ShmSysConfigAndInfo->SysConfig.RatingCurrent = ShmPsuData->SystemAvailableCurrent / 10; // 設定的電流~ 如超過可輸出的電流,則 bypass if (ShmSysConfigAndInfo->SysConfig.RatingCurrent < ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent || ShmSysConfigAndInfo->SysConfig.RatingCurrent == 0) { ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent = 0; } PRINTF_FUNC ("PSU : MaxChargingPower = %d, MaxChargingCurrent = %d", ShmPsuData->SystemAvailablePower / 10, ShmPsuData->SystemAvailableCurrent / 10 ); PRINTF_FUNC ("Config : ChargingPower = %d, ChargingCurrent = %d", ShmSysConfigAndInfo->SysConfig.MaxChargingPower, ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent ); } void CheckStatusOfMeter() { // 橋接如果搭上~ 則兩個電表都是使用狀態 // 如橋接沒有搭上~ 則視該火線 relay 狀態為電表使用狀態 if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES) { for (byte mIndex = 0; mIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; mIndex++) ShmCsuMeterData->_meter[mIndex].isCalculation = YES; } else { for (byte mIndex = 0; mIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; mIndex++) { if (chargingInfo[mIndex]->RelayKPK2Status == YES || chargingInfo[mIndex]->RelayK1K2Status) ShmCsuMeterData->_meter[mIndex].isCalculation = YES; else ShmCsuMeterData->_meter[mIndex].isCalculation = NO; } } } void ReviewCriticalAlarm() { if (ShmDcCommonData->GunRelayDrivingOccur[0] == YES || ShmDcCommonData->GunRelayDrivingOccur[1] == YES || ShmDcCommonData->GunRelayWeldingOccur[0] == YES || ShmDcCommonData->GunRelayWeldingOccur[1] == YES || ShmDcCommonData->ParaRelayWeldingOccur == YES || ShmDcCommonData->ParaRelayDrivingOccur == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen || ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess != _EXTRA_ERR_PROCESS_NONE || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuComminicationErrWithCSU || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost) { ShmSysConfigAndInfo->SysWarningInfo.Level = _ALARM_LEVEL_CRITICAL; } else ShmSysConfigAndInfo->SysWarningInfo.Level = _ALARM_LEVEL_NORMAL; } void CheckRelayWeldingOrDrivingFault(byte gun_index) { // relay welding fault then stop the charging process. byte faultCode = RELAY_STATUS_ERROR_NONE; if (gun_index == 0) { if (ShmDcCommonData->RelayCheckStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->RelayCheckStatus[RELAY_SMR1_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_WELDING; } else if (ShmDcCommonData->RelayCheckStatus[RELAY_SMR1_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->RelayCheckStatus[RELAY_SMR1_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_DRIVING; } } else if (gun_index == 1) { if (ShmDcCommonData->RelayCheckStatus[RELAY_SMR2_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->RelayCheckStatus[RELAY_SMR2_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_WELDING; } else if (ShmDcCommonData->RelayCheckStatus[RELAY_SMR2_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->RelayCheckStatus[RELAY_SMR2_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_DRIVING; } } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount >= 2 && !ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf) { // 橋接 if (ShmDcCommonData->RelayCheckStatus[RELAY_PARA_P_STATUS] == RELAY_STATUS_ERROR_WELDING || ShmDcCommonData->RelayCheckStatus[RELAY_PARA_N_STATUS] == RELAY_STATUS_ERROR_WELDING) { faultCode = RELAY_STATUS_ERROR_PARA_WELDING; } else if (ShmDcCommonData->RelayCheckStatus[RELAY_PARA_P_STATUS] == RELAY_STATUS_ERROR_DRIVING || ShmDcCommonData->RelayCheckStatus[RELAY_PARA_N_STATUS] == RELAY_STATUS_ERROR_DRIVING) { faultCode = RELAY_STATUS_ERROR_PARA_DRIVING; } } if (faultCode == RELAY_STATUS_ERROR_WELDING) { // welding if (chargingInfo[gun_index]->Type == _Type_Chademo) RecordAlarmCode(gun_index, "011011"); else if (chargingInfo[gun_index]->Type == _Type_GB) RecordAlarmCode(gun_index, "011015"); else if (chargingInfo[gun_index]->Type == _Type_CCS) RecordAlarmCode(gun_index, "011013"); ShmDcCommonData->GunRelayWeldingOccur[gun_index] = YES; EmcOccurThenStopCharging(); } else if (faultCode == RELAY_STATUS_ERROR_DRIVING) { // driving if (chargingInfo[gun_index]->Type == _Type_Chademo) RecordAlarmCode(gun_index, "011012"); else if (chargingInfo[gun_index]->Type == _Type_GB) RecordAlarmCode(gun_index, "011016"); else if (chargingInfo[gun_index]->Type == _Type_CCS) RecordAlarmCode(gun_index, "011014"); ShmDcCommonData->GunRelayDrivingOccur[gun_index] = YES; EmcOccurThenStopCharging(); } else { if (chargingInfo[gun_index]->SystemStatus <= SYS_MODE_TERMINATING || chargingInfo[gun_index]->SystemStatus >= SYS_MODE_ALARM) { ShmDcCommonData->GunRelayWeldingOccur[gun_index] = NO; ShmDcCommonData->GunRelayDrivingOccur[gun_index] = NO; if (chargingInfo[gun_index]->Type == _Type_Chademo) { ResetChargerAlarmCode(gun_index, "011012"); ResetChargerAlarmCode(gun_index, "011011"); } else if (chargingInfo[gun_index]->Type == _Type_CCS) { ResetChargerAlarmCode(gun_index, "011014"); ResetChargerAlarmCode(gun_index, "011013"); } else if (chargingInfo[gun_index]->Type == _Type_GB) { ResetChargerAlarmCode(gun_index, "011016"); ResetChargerAlarmCode(gun_index, "011015"); } } } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 2) { if ((chargingInfo[0]->SystemStatus <= SYS_MODE_TERMINATING || chargingInfo[0]->SystemStatus >= SYS_MODE_ALARM) && (chargingInfo[1]->SystemStatus <= SYS_MODE_TERMINATING || chargingInfo[1]->SystemStatus >= SYS_MODE_ALARM)) { if (faultCode == RELAY_STATUS_ERROR_PARA_WELDING) { // parallel welding RecordAlarmCode ( gun_index, "011039" ); ShmDcCommonData->ParaRelayWeldingOccur = YES; EmcOccurThenStopCharging (); } else if (faultCode == RELAY_STATUS_ERROR_PARA_DRIVING) { // parallel driving RecordAlarmCode ( gun_index, "011040" ); ShmDcCommonData->ParaRelayDrivingOccur = YES; EmcOccurThenStopCharging (); } else { ShmDcCommonData->ParaRelayWeldingOccur = NO; ShmDcCommonData->ParaRelayDrivingOccur = NO; ResetChargerAlarmCode ( gun_index, "011039" ); ResetChargerAlarmCode ( gun_index, "011040" ); } } } } bool PrecheckIsPass(byte gun_index) { bool result = true; // relay welding or driving 是反向 if (result) result = !ShmDcCommonData->GunRelayWeldingOccur[gun_index]; if (result) result = !ShmDcCommonData->ParaRelayWeldingOccur; return result; } void CollectError(byte gun_index) { errCollect.GunErrMessage |= ShmDcCommonData->ConnectErrList[gun_index].GunErrMessage; } void AlarmCheck(byte type) { // type : Cha = 0、CCS = 1、GBT = 2 if (type == _Type_Chademo) { // GFD Trip if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 0)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip = NO; // UVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 1)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoOutputUVPFail = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoOutputUVPFail = NO; // OTP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 2)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoConnectorOTP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoConnectorOTP = NO; // OVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 3)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = NO; // GFD Warning if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 4)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGroundWarning = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGroundWarning = NO; // Relay Welding if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 5)) ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = NO; // Relay Driving if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 6)) ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault = NO; // Connect temp Sensor broken if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 7)) ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoConnectorTempSensorBroken = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoConnectorTempSensorBroken = NO; // Output UCP if (DetectBitValue(errCollect.GunErrMessage >> (8 * 3), 0)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputUCP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputUCP = NO; } else if (type == _Type_CCS) { // GFD Trip if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 0)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip = NO; // UVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 1)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsOutputUVPFail = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsOutputUVPFail = NO; // OTP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 2)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsConnectorOTP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsConnectorOTP = NO; // OVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 3)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = NO; // GFD Warning if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 4)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGroundfaultWarning = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGroundfaultWarning = NO; // Relay Welding if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 5)) ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = NO; // Relay Driving if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 6)) ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault = NO; // Connect temp Sensor broken if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 7)) ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsConnectorTempSensorBroken = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsConnectorTempSensorBroken = NO; // Output UCP if (DetectBitValue(errCollect.GunErrMessage >> (8 * 3), 1)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCCSOutputUCP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCCSOutputUCP = NO; } else if (type == _Type_GB) { // GFD Trip if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 0)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGfdTrip = NO; // UVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 1)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbtOutputUVPFail = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbtOutputUVPFail = NO; // OTP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 2)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbConnectorOTP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbConnectorOTP = NO; // OVP if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 3)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = NO; // GFD Warning if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 4)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGroundfaultWarning = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.GbGroundfaultWarning = NO; // Relay Welding if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 5)) ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = NO; // Relay Driving if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 6)) ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayDrivingFault = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayDrivingFault = NO; // Connect temp Sensor broken if (DetectBitValue(errCollect.GunErrMessage >> (8 * type), 7)) ShmStatusCodeData->FaultCode.FaultEvents.bits.GbConnectorTempSensorBroken = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.GbConnectorTempSensorBroken = NO; // Output UCP if (DetectBitValue(errCollect.GunErrMessage >> (8 * 3), 2)) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGBTOutputUCP = YES; else ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGBTOutputUCP = NO; } } void SystemAlarmCheck() { byte system = 3; // Parallel Welding if (DetectBitValue(errCollect.GunErrMessage >> (8 * system), 3)) ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayWelding = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayWelding = NO; // Parallel Driving if (DetectBitValue(errCollect.GunErrMessage >> (8 * system), 4)) ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayDriving = YES; else ShmStatusCodeData->FaultCode.FaultEvents.bits.ParallelRelayDriving = NO; } void SavePresentChargedDuration(byte gun_index) { int _diffTime = 0; ftime(&endChargingTime[gun_index]); _diffTime = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index]); // below 0 or over 5 sec is abnormal if (_diffTime < 0 || _diffTime > chargingInfo[gun_index]->PresentChargedDuration + 5) { _presentChargingTimeBuf[gun_index] = chargingInfo[gun_index]->PresentChargedDuration; ftime(&startChargingTime[gun_index]); PRINTF_FUNC("TimeZone changed (%d) \n", gun_index); } else chargingInfo[gun_index]->PresentChargedDuration = _presentChargingTimeBuf[gun_index] + _diffTime; } void ClearEnergyTimePeriod(byte gun_index) { for (int i = 0; i < 24; i++) { ShmDcCommonData->energy_time_period[gun_index][i] = 0; } } void ChangeToMaxChargingMode() { if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER && ShmPsuData->PsuStopChargeFlag == NO) { if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES) { // 均充 -> 最大充 if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE) { // 切換最大充起始位置 PRINTF_FUNC("======= Aver -> Max : Preparing. (Step 11) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_PREPARE_A_TO_M; } } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_COMP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_WAITING) { PRINTF_FUNC("======= Aver -> Max : Current Balancing. (Step 14) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_WAITING; } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_COMP) { PRINTF_FUNC("======= Aver -> Max : Charging mode = MAX ======= \n"); ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } else { ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } else { // 需考量如果再切換均充過程 ? (預計要進入充電的臨時取消充電) ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } void CheckOcppCostAndPrice() { if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling && strcmp((char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") != EQUAL && strcmp((char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, "") != EQUAL) { ocpp_parsing_DT_defaultPrice_cmd(); ocpp_parsing_DT_userPrice_cmd(); ocpp_parsing_DT_running_final_cmd(); } } void CheckAuthrizeByEvccid() { if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE && ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID) ShmDcCommonData->enObtainAuthorizbyCCID = YES; else ShmDcCommonData->enObtainAuthorizbyCCID = NO; } void CheckConnectorOTP(byte _index) { if (chargingInfo[_index]->Type == _Type_Chademo) { // if (chargingInfo[_index]->ConnectorTemp != UNDEFINED_TEMP) // { // ResetChargerAlarmCode(_index, "011018"); // if (chargingInfo[_index]->ConnectorTemp >= GUN_OTP_VALUE) // RecordAlarmCode(_index, "012229"); // else if (chargingInfo[_index]->ConnectorTemp != 0 && // chargingInfo[_index]->ConnectorTemp < GUN_OTP_RECOVERY) // ResetChargerAlarmCode(_index, "012229"); // } // else // { // // 沒接上 Sensor or 異常 // //RecordAlarmCode(_index, "011018"); // ResetChargerAlarmCode(_index, "012229"); // } } else if (chargingInfo[_index]->Type == _Type_CCS) { // CCS 不管甚麼輸出都會有槍溫偵測!!~ if (chargingInfo[_index]->ConnectorTemp != UNDEFINED_TEMP) { ResetChargerAlarmCode(_index, "011019"); if(chargingInfo[_index]->ConnectorTemp >= GUN_OTP_VALUE) RecordAlarmCode(_index, "012230"); else if (chargingInfo[_index]->ConnectorTemp != 0 && chargingInfo[_index]->ConnectorTemp < GUN_OTP_RECOVERY) ResetChargerAlarmCode(_index, "012230"); } else { // 沒接上 Sensor or 異常 RecordAlarmCode(_index, "011019"); ResetChargerAlarmCode(_index, "012230"); } } else if (chargingInfo[_index]->Type == _Type_GB && chargingInfo[_index]->ModelType == 'B') { if (chargingInfo[_index]->ConnectorTemp != UNDEFINED_TEMP) { ResetChargerAlarmCode(_index, "011020"); if(chargingInfo[_index]->ConnectorTemp >= GUN_OTP_VALUE) RecordAlarmCode(_index, "012231"); else if (chargingInfo[_index]->ConnectorTemp != 0 && chargingInfo[_index]->ConnectorTemp < GUN_OTP_RECOVERY) ResetChargerAlarmCode(_index, "012231"); } else { // 沒接上 Sensor or 異常 RecordAlarmCode(_index, "011020"); ResetChargerAlarmCode(_index, "012231"); } } } void ChkConnectorBoardStop(byte index) { if (isEvBoardStopChargeFlag(index) == YES) { // 板端要求停止 (錯誤) ocpp_set_stopReason_by_cmd(index, "EVDisconnected"); ChargingAlarmProcess(index); } else if (isEvBoardNormalStopChargeFlag(index) == YES) { // 板端要求停止 (正常) ocpp_set_stopReason_by_cmd(index, "EVDisconnected"); ChargingTerminalProcess(index); } } void ChkPsuErrorStop(byte index) { if (ShmPsuData->PsuGroup[index].GroupErrorFlag.bits.PsuFailure == YES || (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf && ShmPsuData->PsuGroup[0].GroupErrorFlag.bits.PsuFailure)) { if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if (chargingInfo[gun_index]->PresentChargingCurrent <= 5 && ((chargingInfo[gun_index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[gun_index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[gun_index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[gun_index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1))) { ocpp_set_stopReason_by_cmd(gun_index, "Local"); ChargingAlarmProcess(gun_index); } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { if (chargingInfo[index]->PresentChargingCurrent <= 5) { ocpp_set_stopReason_by_cmd(index, "Local"); ChargingAlarmProcess(index); } } } } void ChkBackendStop(byte index) { if (ocpp_chk_invalid_id_cmd(index)) { // Start Transaction Stop ocpp_set_stopReason_by_cmd(index, "DeAuthorized"); ChargingTerminalProcess(index); } else if (ocpp_chk_remoteStop_cmd(index) == YES || WifiScheduleStop(index)) { // 後臺要求停止 ChargingTerminalProcess(index); } } void ChkConfigurationStop(byte index) { if (CheckBackendChargingTimeout(index) || CheckBackendChargingEnergy(index)) { // 網頁設定 PRINTF_FUNC("CheckBackendCharging stop charging (%d) \n", index); ChargingTerminalProcess(index); return; } if (CheckOcppChargingTimeout(index) || CheckOcppChargingEnergy(index) || CheckOcppChargingSOC(index)) { // OCPP 設定 PRINTF_FUNC("CheckOcppCharging stop charging (%d) \n", index); ChargingTerminalProcess(index); } } void RecordGfdResult(byte index) { if (chargingInfo[index]->Type == _Type_Chademo) { if (chargingInfo[index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(index, "012234"); } else if (chargingInfo[index]->GroundFaultStatus == GFD_WARNING) { // GFD 警告 RecordAlarmCode(index, "012296"); } } else if (chargingInfo[index]->Type == _Type_GB) { if (chargingInfo[index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(index, "012236"); } else if (chargingInfo[index]->GroundFaultStatus == GFD_WARNING) { // GFD 警告 RecordAlarmCode(index, "012298"); } } else if (chargingInfo[index]->Type == _Type_CCS) { if (chargingInfo[index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode(index, "012235"); } else if (chargingInfo[index]->GroundFaultStatus == GFD_WARNING) { // GFD 警告 RecordAlarmCode(index, "012297"); } } } void CcidAuthorizationProcessing(byte gun_index) { if (chargingInfo [gun_index]->Type == _Type_CCS && chargingInfo [gun_index]->IsAvailable && ShmDcCommonData->enObtainAuthorizbyCCID && chargingInfo[gun_index]->ConnectorPlugIn && strcmp ((char *)ShmSysConfigAndInfo->SysConfig.UserId, "") == EQUAL) { AddPlugInTimes(gun_index); PRINTF_FUNC("CcidAuthorizationProcessing. \n"); ChangeGunSelectByIndex(gun_index); setChargerMode(gun_index, SYS_MODE_MODE_REASSIGN_CHECK); } } void CheckCcidAuthorizationFunction(byte gun_index) { if (chargingInfo [gun_index]->Type == _Type_CCS && ShmDcCommonData->enObtainAuthorizbyCCID) { if (ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_GET && ShmDcCommonData->_CcidAuthProcessStep == _CCID_NONE && strcmp ( (char *) ShmSysConfigAndInfo->SysConfig.UserId, "" ) == EQUAL) { PRINTF_FUNC ( "index = %d, Get for CCID (main). \n", gun_index ); ShmDcCommonData->_authWithCcidFlag [gun_index] = _CCID_CHECK; ShmDcCommonData->_CcidAuthProcessStep = _CCID_CHECK; memcpy ( ShmSysConfigAndInfo->SysConfig.UserId, chargingInfo [gun_index]->EVCCID, sizeof(chargingInfo [gun_index]->EVCCID) ); } else if (ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_CHECK) { if (ShmDcCommonData->_CcidAuthProcessStep == _CCID_AUTHFAIL) { PRINTF_FUNC ( "index = %d, _CCID_AUTHFAIL. \n", gun_index ); ShmDcCommonData->_authWithCcidFlag [gun_index] = ShmDcCommonData->_CcidAuthProcessStep; ShmDcCommonData->_CcidAuthProcessStep = _CCID_NONE; } else if (ShmDcCommonData->_CcidAuthProcessStep == _CCID_AUTHCOMP) { PRINTF_FUNC ( "index = %d, _CCID_AUTHCOMP. \n", gun_index ); ShmDcCommonData->_authWithCcidFlag [gun_index] = ShmDcCommonData->_CcidAuthProcessStep; strcpy((char *)chargingInfo[gun_index]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ShmDcCommonData->_CcidAuthProcessStep = _CCID_NONE; } } } } bool isCcidEnterToCharging(byte gun_index) { bool result = false; if (ShmDcCommonData->enObtainAuthorizbyCCID) { if (ShmDcCommonData->_CcidAuthProcessStep == _CCID_AUTHCOMP) { for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if (chargingInfo [_index]->Type == _Type_CCS && chargingInfo [_index]->IsAvailable && ShmDcCommonData->_authWithCcidFlag [_index] == _CCID_CHECK) { if (_index != gun_index) result = true; break; } } if (!result) ShmDcCommonData->_CcidAuthProcessStep = _CCID_NONE; } } return result; } bool IsNoneSelectAcModule() { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 0 || (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE)) { result = true; } return result; } bool IsSelectAcModule() { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount == 0) return result; else if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == DEFAULT_AC_INDEX) { result = true; } return result; } void DisplayPageChkByAcModule() { if (IsSelectAcModule()) { if (ac_chargingInfo [0]->ConnectorPlugIn == AC_SYS_A) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } } int main(void) { if(CreateShareMemory() == 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("CreatShareMemory NG \n"); #endif if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PRINTF_FUNC("===== Boot and Initialization start ===== \n"); if (!InitialSystemDefaultConfig()) { DEBUG_ERROR_MSG("InitialSystemDefaultConfig NG \n"); StopProcessingLoop(); } PRINTF_FUNC("CheckConnectorTypeStatus and CheckIsAlternatvie \n"); CheckGunTypeFromHw(); CheckIsAlternatvieByModelName(); InitialShareMemoryInfo(); PRINTF_FUNC("InitialShareMemoryInfo OK. \n"); if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC) PRINTF_FUNC("ChargerType (IEC or UL) = IEC \n"); else PRINTF_FUNC("ChargerType (IEC or UL) = UL \n"); ChangeLcmByIndex(_LCM_INIT); if (!CheckConnectorTypeStatus()) isModelNameMatch = false; Initialization(); PRINTF_FUNC("===== Initial Complete ===== \n"); PRINTF_FUNC("===== Spawn all Task and self test start ===== \n"); SpawnTask(); if (!isModelNameMatch) { // Module Name 與硬體對應不正確 PRINTF_FUNC("*** Module Name & HW info none match : Please check if the Model name and HW are matched. ***\n"); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ModelNameNoneMatchStestFail = YES; ChangeLcmByIndex(_LCM_FIX); sleep(3); KillTask(); StopProcessingLoop(); } PRINTF_FUNC("Module Name & HW info correct. \n"); CreateTimeoutFork(); if (!DEBUG_ALSTON) { PRINTF_FUNC("Self test run..\n"); SelfTestRun(); } else { sleep(3); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_COMPLETE; } StopSystemTimeoutDet(); if (!DEBUG_ALSTON && (ShmSysConfigAndInfo->SysInfo.SelfTestSeq == _STEST_FAIL || ShmPsuData->Work_Step == _NO_WORKING || ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsSeccTimeoutQCA7000Comm == YES || strcmp((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, " ") == EQUAL)) { if (ShmSysConfigAndInfo->SysWarningInfo.Level != _ALARM_LEVEL_CRITICAL) { if (!DisplaySelfTestFailReason() && ShmDcCommonData->rebootCount < 1) { PRINTF_FUNC("=======Soft reboot for retry self-test======= \n"); SetupRebootCount(1); sleep(3); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); } else if (ShmDcCommonData->rebootCount < 1) { PRINTF_FUNC("=======Soft reboot for retry self-test (Normal)======= \n"); SetupRebootCount(1); sleep(3); KillAllTask(); system("/usr/bin/run_evse_restart.sh"); } else SetupRebootCount(0); } for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { ChargingAlarmProcess(gun_index); } //ChangeLcmByIndex(_LCM_FIX); sleep(3); //if (ShmSysConfigAndInfo->SysWarningInfo.Level == 2) //{ KillTaskExceptDetectTask(); //} //else // KillTask(); StopProcessingLoop(); } else { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { setChargerMode(gun_index, SYS_MODE_IDLE); } SetupRebootCount(0); } PRINTF_FUNC("===== Self Test Complete ===== \n"); PRINTF_FUNC("===== Finally Create DB ===== \n"); // Local DB if(DB_Open(localDb) != PASS) { PRINTF_FUNC("DB_Open fail. \n"); isDb_ready = false; } else { isDb_ready = true; for (int _acIndex = 0; _acIndex < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _acIndex++) { byte hasDc = ((ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) ? 1 : 0); ac_chargingInfo[0]->IsAvailable = DB_Get_Operactive(localDb, _acIndex + hasDc); } for(int _index=0; _index< ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;_index++) { chargingInfo[_index]->IsAvailable = DB_Get_Operactive(localDb, _index); chargingInfo[_index]->PowerConsumption = DB_Get_PowerConsumption(localDb, _index); } DB_Reboot_Record(localDb); } if (NetworkDB_Open(networkDb) != PASS) { PRINTF_FUNC("NetworkDB_Open fail. \n"); } ChangeLcmByIndex(_LCM_IDLE); sleep(1); CreateRfidFork(); sleep(1); if (!DEBUG_ALSTON) { PRINTF_FUNC("===== Create chk system Task ===== \n"); CreateCheckSystemTaskFork(); } PRINTF_FUNC("===== Create DB End ===== \n"); PRINTF_FUNC("===== Charger info ===== "); PRINTF_FUNC("SW Version = %s", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); PRINTF_FUNC("ModelName = %s", ShmSysConfigAndInfo->SysConfig.ModelName); CheckFwSlotStatusLog(); AdjustChargerCurrent(); GetTimespecFunc(&_cmdMainPriority_time); _ocppProfileChkFlag_1 = 0; _ocppProfileChkFlag_2 = 0; if(strcmp((char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") == EQUAL) { DEBUG_ERROR_MSG("URL is empty kill Module_OcppBackend...\n"); system ("pkill OcppBackend"); } int _mainTimebuf = 0; for (;;) { if (ShmDcCommonData->_isAutoRunTest != _isTestRun) { if (ShmDcCommonData->_isAutoRunTest == YES) { GetTimespecFunc(&_autoRuntestTime); } _isTestRun = ShmDcCommonData->_isAutoRunTest; } if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { ocpp_ac_chk_availability_cmd(); ocpp_ac_chk_unlock_cmd(); } ocpp_auto_response_BootNotification(); ocpp_chk_reset_cmd(NO); ButtonTriggerEvent(); if (!DEBUG_ALSTON) ChkPrimaryStatus(); if ((IsConnectorWholeIdle() || ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_FIX)) { CheckFactoryConfigFunction(); CheckFwUpdateFunction(); } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 0) { sleep(1); continue; } // OCPP 邏輯 ocpp_chk_remoteStart_cmd(); // 讀卡邏輯 ScannerCardProcess(); // 當 AC 沒有搭上時,清除一些錯誤碼 ClearAlarmCodeWhenAcOff(); // 確認是否要回到充電中的槍畫面邏輯判斷 CheckReturnToChargingConn(); if ((_acgunIndex > 0 && isDetectPlugin() && !isCardScan)) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } _mainTimebuf = GetTimeoutValue(&_cmdMainPriority_time); if (_mainTimebuf < 0) GetTimespecFunc(&_cmdMainPriority_time); if (GetTimeoutValue(&_cmdMainPriority_time) >= 5) { if (ShmPsuData->PsuStopChargeFlag) Check267Alarm(); CheckTask(); Run4gResetProc(); for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) { if ((chargingInfo[_index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[_index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[_index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[_index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { ocpp_chargingProfile_process(_index); if (chargingInfo[_index]->SystemStatus == SYS_MODE_CHARGING && ((_index == 0 && _ocppProfileChkFlag_1 >= 12) || (_index == 1 && _ocppProfileChkFlag_2 >= 12))) { ocpp_lift_profileReq_cmd(_index); gunOutputVol[_index] = chargingInfo[_index]->PresentChargingVoltage; if (_index == 0) _ocppProfileChkFlag_1 = 0; else if (_index == 1) _ocppProfileChkFlag_2 = 0; } else if (chargingInfo[_index]->SystemStatus != SYS_MODE_CHARGING) { ocpp_lift_profileReq_cmd(_index); if (_index == 0) _ocppProfileChkFlag_1 = 0; else if (_index == 1) _ocppProfileChkFlag_2 = 0; } else { if (_index == 0) _ocppProfileChkFlag_1++; else if (_index == 1) _ocppProfileChkFlag_2++; } if (chargingInfo[_index]->SystemStatus >= SYS_MODE_CHARGING && chargingInfo[_index]->SystemStatus <= SYS_MODE_ALARM) { DB_Update_PowerConsumption(localDb, _index, chargingInfo[_index]->PowerConsumption); } } if (chargingInfo[_index]->SystemStatus == SYS_MODE_RESERVATION) { if (opcc_chk_reserve_expired(_index)) { chargingInfo[_index]->SystemStatus = SYS_MODE_IDLE; } } // OTP CheckConnectorOTP(_index); } for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _index++) { if ((ac_chargingInfo[0]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CHARGING) || (ac_chargingInfo[0]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && ac_chargingInfo[0]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { ocpp_ac_chargingProfile_process(); } if ((ac_chargingInfo[_index]->SystemStatus >= SYS_MODE_PREPARING && ac_chargingInfo[_index]->SystemStatus <= SYS_MODE_CHARGING)) { if (ac_chargingInfo[_index]->SystemStatus == SYS_MODE_CHARGING && _ac_ocppProfileChkFlag == 12) { ocpp_ac_lift_profileReq_cmd(_index); _ac_ocppProfileChkFlag = 0; } else if (ac_chargingInfo[_index]->SystemStatus != SYS_MODE_CHARGING) { ocpp_ac_lift_profileReq_cmd(_index); _ac_ocppProfileChkFlag = 0; } else _ac_ocppProfileChkFlag++; } } CheckOcppCostAndPrice(); CheckAuthrizeByEvccid(); GetTimespecFunc(&_cmdMainPriority_time); if (!DEBUG_ALSTON && wtdFd == -1) { PRINTF_FUNC("===== Create crazy dog ===== \n"); CreateWatchdog(); } } if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'M' || ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'L') CheckStatusOfMeter(); // 確認當前錯誤 Level = 2 ? ReviewCriticalAlarm(); errCollect.GunErrMessage = 0; if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { CheckAcOcppProfileConfirm(); ocpp_ac_chk_reserved_cmd(); } for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { //CheckGpioInStatus(); // 確認系統的錯誤狀態 CheckSystemErrorFunction(gun_index); // 確認 Relay Welding or Driving Fault CheckRelayWeldingOrDrivingFault(gun_index); // 收集各槍的錯誤狀態 CollectError(gun_index); ocpp_chk_reserved_cmd(gun_index); ocpp_chk_availability_cmd(gun_index); ocpp_chk_unlock_cmd(gun_index); // check charging profile confirm flag CheckOcppProfileConfirm(gun_index); //PRINTF_FUNC("index = %d, ErrorCode = %s \n", gun_index, ShmOCPP16Data->StatusNotification[gun_index].ErrorCode); switch(chargingInfo[gun_index]->SystemStatus) { case SYS_MODE_IDLE: case SYS_MODE_RESERVATION: case SYS_MODE_MAINTAIN: case SYS_MODE_FAULT: { if ((chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE || chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION) && isModeChange(gun_index)) { if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE) { PRINTF_FUNC("================= SYS_MODE_IDLE (%x) ================ \n", gun_index); chargingInfo[gun_index]->ReservationId = -1; } else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION) { PRINTF_FUNC("================= SYS_MODE_RESERVATION (%x) ================ \n", gun_index); PRINTF_FUNC("================= Id : %s ================ \n", ShmDcCommonData->_reserved_UserId[gun_index]); } chargingInfo[gun_index]->PresentChargedDuration = 0; chargingInfo[gun_index]->RemainChargingDuration = 0; chargingInfo[gun_index]->PresentChargingVoltage = 0; chargingInfo[gun_index]->PresentChargingCurrent = 0; strcpy((char *)chargingInfo[gun_index]->StartDateTime, "00:00:00"); strcpy((char *)chargingInfo[gun_index]->StopDateTime, "00:00:00"); strcpy((char *)chargingInfo[gun_index]->StartUserId, ""); strcpy((char *)chargingInfo[gun_index]->EVCCID, ""); _isSendStartTransaction[gun_index] = false; ClearEnergyTimePeriod(gun_index); gunOutputVol[gun_index] = 0.0; ocpp_clear_stopReason(gun_index); ocpp_auto_response_StartTransationConf(gun_index); ShmDcCommonData->startTransactionFlag[gun_index] = START_TRANSATION_STATUS_WAIT; ShmDcCommonData->_authWithCcidFlag[gun_index] = _CCID_NONE; } if (chargingInfo[gun_index]->IsAvailable == NO) { setChargerMode(gun_index, SYS_MODE_MAINTAIN); } if (ShmSysConfigAndInfo->SysWarningInfo.Level == _ALARM_LEVEL_CRITICAL) { if (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected) ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_FIX; else if (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus != SYS_MODE_IDLE && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus != SYS_MODE_RESERVATION && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus != SYS_MODE_MAINTAIN && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus != SYS_MODE_FAULT) ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; ClearDetectPluginFlag(); ocpp_set_errCode_cmd(gun_index); setChargerMode(gun_index, SYS_MODE_FAULT); } else { ChangeToMaxChargingMode(); if (PrecheckIsPass(gun_index)) { if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; setChargerMode(gun_index, SYS_MODE_IDLE); } CcidAuthorizationProcessing(gun_index); // { // Idle 正常程序起點 // 判斷是否有啟用檢查插槍 if(isDetectPlugin()) { // 卡號驗證成功後,等待充電槍插入充電車 if (chargingInfo[gun_index]->RemoteStartFlag == YES) { if (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable) { PRINTF_FUNC("Conn %d Start Charging : Remote \n", gun_index); chargingInfo[gun_index]->RemoteStartFlag = NO; chargingInfo[gun_index]->isRemoteStart = YES; ChangeGunSelectByIndex(gun_index); AddPlugInTimes(gun_index); setChargerMode(gun_index, SYS_MODE_MODE_REASSIGN_CHECK); strcpy((char *)chargingInfo[gun_index]->StartUserId, ""); ClearDetectPluginFlag(); continue; } } else if (chargingInfo[gun_index]->ReservedStartFlag == YES) { if (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable) { chargingInfo[gun_index]->ReservedStartFlag = NO; ChangeGunSelectByIndex(gun_index); AddPlugInTimes(gun_index); strcpy((char *)chargingInfo[gun_index]->StartUserId, (char *)ShmDcCommonData->_reserved_UserId[gun_index]); PRINTF_FUNC("Conn %d Start Charging : Reserved CardNumber = %s \n", gun_index, chargingInfo[gun_index]->StartUserId); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); strcpy((char *)ShmDcCommonData->_reserved_UserId[gun_index], ""); // 當前操作的槍號,進入 Preparing setChargerMode(gun_index, SYS_MODE_MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); continue; } } else if (ShmSysConfigAndInfo->SysInfo.OrderCharging == NO_DEFINE) { if (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable && chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE) { ChangeGunSelectByIndex(gun_index); AddPlugInTimes(gun_index); strcpy((char *)chargingInfo[gun_index]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId); PRINTF_FUNC("Conn %d Start Charging : RFID CardNumber = %s \n", gun_index, chargingInfo[gun_index]->StartUserId); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); // 當前操作的槍號,進入 Preparing setChargerMode(gun_index, SYS_MODE_MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); continue; } } if (!isCardScan && (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected || (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE))) { // LCM => Waiting for plugging ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE && (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable)) { PRINTF_FUNC("Conn %d Start Charging : Plug and charing \n", gun_index); bool isCanStartChargingFlag = GetStartChargingByAlterMode(gun_index); if (isCanStartChargingFlag) { ChangeGunSelectByIndex(gun_index); AddPlugInTimes(gun_index); setChargerMode(gun_index, SYS_MODE_MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); ocpp_get_freeVendor(gun_index); continue; } } else { if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd())) { if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == DEFAULT_AC_INDEX) { if (ac_chargingInfo[0]->ConnectorPlugIn == AC_SYS_A) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE && ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_WAIT_FOR_PLUG) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } // else if (ChkAcModuleStatusIsNone() && // (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL)) // { // ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; // } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_IDLE; } } } // Idle 正常程序終點 } else { setChargerMode(gun_index, SYS_MODE_FAULT); if (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected) ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_FIX; } ReleaseSysAlarmCode(gun_index); } } break; case SYS_MODE_MODE_REASSIGN_CHECK: { if (isModeChange(gun_index)) { PRINTF_FUNC("================= SYS_MODE_MODE_REASSIGN_CHECK (%x) ================ \n", gun_index); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE) ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE; StopSystemTimeoutDet(); } ocpp_clear_errorCode_cmd(gun_index); bool isRessign = false; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO) { if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->SystemStatus != SYS_MODE_MODE_REASSIGN_CHECK) { if (((chargingInfo[index]->SystemStatus >= SYS_MODE_PREPARING && chargingInfo[index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) && chargingInfo[index]->SystemStatus != SYS_MODE_MAINTAIN && chargingInfo[index]->SystemStatus != SYS_MODE_RESERVATION) { // A 槍在充電過程中 - 進行分配動作 PRINTF_FUNC("======= Max -> Aver : Preparing. (Step 1) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_PREPARE_M_TO_A; isRessign = true; break; } else { // A 槍已結束充電 - 直接回 B 槍最大充 PRINTF_FUNC("======= Max -> Aver : Charging mode = MAX (Keep) ======= \n"); //ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER; break; } } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { // 如果在切換最大充的過程中,需等待最大充切換完成後,再走均充流程 if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_COMP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_WAITING) { PRINTF_FUNC("======= Aver -> Max : Aver -> Max : Current Balancing. (Step 14) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_WAITING; } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_COMP) { PRINTF_FUNC("======= Aver -> Max : Charging mode = MAX ======= \n"); ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; continue; } } else { setChargerMode(gun_index, SYS_MODE_PREPARING); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; continue; } } if (isRessign) setChargerMode(gun_index, SYS_MODE_REASSIGN); else setChargerMode(gun_index, SYS_MODE_PREPARING); if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_REASSIGN: { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_REASSIGN (%x) ================ \n", gun_index); } ocpp_clear_errorCode_cmd(gun_index); // 重新分配,此階段主要是讓已經在充電或者準備進入充電前的緩衝 // 此狀態下~ 控制權在於 PSU 及 EV小板 Process if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_RELAY_M_TO_A && ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { PRINTF_FUNC("======= Max -> Aver : Charging mode = AVER ======= \n"); ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE) { if ((ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO && ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) || (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES && ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)) { setChargerMode(gun_index, SYS_MODE_PREPARING); } } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_PREPARING: { if (isModeChange(gun_index)) { PRINTF_FUNC("=================== SYS_MODE_PREPARING (%x) =============== \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_Preparing); } ocpp_clear_errorCode_cmd(gun_index); if (ShmPsuData->SystemPresentPsuQuantity > 0 && ShmPsuData->SystemAvailablePower > 10 && ShmPsuData->Work_Step == _WORK_CHARGING && GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout) >= 5) { setChargerMode(gun_index, SYS_MODE_PREPARE_FOR_EV); } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount >= 2) { bool oughtAver = true; for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { // 共同進入充電邏輯 if (chargingInfo[index]->SystemStatus != SYS_MODE_PREPARING) { oughtAver = false; break; } } if (oughtAver) { PRINTF_FUNC("********* Smart Charging : _REASSIGNED_NONE (AVER) ********** \n"); ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_PREPARE_FOR_EV: // 等待車端的通訊 (EV 小板),待車端回報後,開始樁端的測試 { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_PREPARE_FOR_EV (%x) ================ \n", gun_index); _presentChargingTimeBuf[gun_index] = 0; //strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvChargingDet); ShmDcCommonData->startTransactionFlag[gun_index] = START_TRANSATION_STATUS_WAIT; // Start Transation printf("StartUserId = %s \n", chargingInfo[gun_index]->StartUserId); if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || strcmp((char *)chargingInfo[gun_index]->StartUserId, "") != EQUAL || chargingInfo[gun_index]->isRemoteStart == YES) { _isSendStartTransaction[gun_index] = true; ocpp_set_startTransation_cmd(gun_index); GetTimespecFunc(&_startTransation_time[gun_index]); } ShmDcCommonData->_CcidAuthProcessStep = _CCID_NONE; } ocpp_clear_errorCode_cmd(gun_index); CheckCcidAuthorizationFunction(gun_index); if (!_isSendStartTransaction[gun_index] && chargingInfo [gun_index]->Type == _Type_CCS && ShmDcCommonData->enObtainAuthorizbyCCID) { if (ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_AUTHCOMP) { PRINTF_FUNC("_CCID_AUTHCOMP \n"); _isSendStartTransaction[gun_index] = true; ocpp_set_startTransation_cmd(gun_index); GetTimespecFunc(&_startTransation_time[gun_index]); } else if (ShmDcCommonData->_authWithCcidFlag [gun_index] == _CCID_AUTHFAIL) { PRINTF_FUNC("_CCID_AUTHFAIL \n"); ChargingTerminalProcess(gun_index); } } // if (isCcidEnterToCharging(gun_index)) // { // // } ShmDcCommonData->startTransactionFlag[gun_index] = ocpp_is_resPass_StartTransactionConf(gun_index); if (ShmDcCommonData->startTransactionFlag[gun_index] == START_TRANSATION_STATUS_PASS) { if (ocpp_chk_invalid_id_cmd(gun_index)) ShmDcCommonData->startTransactionFlag[gun_index] = START_TRANSATION_STATUS_FAIL; } else { if (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == NO) { if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING || ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || !ocpp_get_startTransation_req(gun_index) || strcmp((char *)chargingInfo[gun_index]->StartUserId, "") != EQUAL || _isTestRun) { ShmDcCommonData->startTransactionFlag[gun_index] = START_TRANSATION_STATUS_PASS; } } } // 小板停止 ChkConnectorBoardStop(gun_index); // psu 停止 ChkPsuErrorStop(gun_index); if (ocpp_chk_remoteStop_cmd(gun_index) == YES || WifiScheduleStop(gun_index) || (_isSendStartTransaction[gun_index] && ShmDcCommonData->startTransactionFlag[gun_index] == START_TRANSATION_STATUS_FAIL) || (_isSendStartTransaction[gun_index] && ShmDcCommonData->startTransactionFlag[gun_index] == START_TRANSATION_STATUS_WAIT && GetTimeoutValue(&_startTransation_time[gun_index]) > 45)) { // 後臺要求停止 ChargingTerminalProcess(gun_index); if (ShmDcCommonData->startTransactionFlag[gun_index] == START_TRANSATION_STATUS_FAIL) PRINTF_FUNC("StartTransaction req fail. (%d) \n", gun_index); else if (ShmDcCommonData->startTransactionFlag[gun_index] == START_TRANSATION_STATUS_WAIT) PRINTF_FUNC("StartTransaction req timeout. (%d) \n", gun_index); } // 檢查車端的槍鎖是否為鎖上 if (isEvGunLocked(gun_index) == YES) { setChargerMode(gun_index, SYS_MODE_PREPARE_FOR_EVSE); } // LCM => Pre-charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { // if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || // ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) // { // ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; // } if (ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZ_FAIL) { } else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } if (ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_NONE) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { if (ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZ_FAIL) {} else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } } break; case SYS_MODE_PREPARE_FOR_EVSE: // 等待 RB 通訊及測試,並將狀態回報, CSU 確認 Pass 後,開始進入充電 { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_PREPARE_FOR_EVSE (%x) ================ \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvseChargingDet); } ocpp_clear_errorCode_cmd(gun_index); if (chargingInfo[gun_index]->Type == _Type_Chademo) { // 檢查樁端的 GFD 結果 if (isPrechargeStatus_chademo(gun_index) >= 6) { // 當前操作的槍號,進入 Charging setChargerMode(gun_index, SYS_MODE_CHARGING); } } else if (chargingInfo[gun_index]->Type == _Type_GB) { // 檢查樁端的 GFD 結果 if (isPrechargeStatus_gb(gun_index) >= 6) { setChargerMode(gun_index, SYS_MODE_CHARGING); } } else if (chargingInfo[gun_index]->Type == _Type_CCS) { // 檢查樁端的 GFD 結果 if ((chargingInfo[gun_index]->GroundFaultStatus == GFD_PASS || chargingInfo[gun_index]->GroundFaultStatus == GFD_WARNING)) { setChargerMode(gun_index, SYS_MODE_CCS_PRECHARGE_STEP0); } } RecordGfdResult(gun_index); // 小板停止 ChkConnectorBoardStop(gun_index); // psu 停止 ChkPsuErrorStop(gun_index); // 後台要求停止 ChkBackendStop(gun_index); // LCM => Pre-charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_CHARGING: // 剛進入充電狀態,等待 EV 小板要求的輸出電流後開始輸出 { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_CHARGING (%x) ================ \n", gun_index); StopGunInfoTimeoutDet(gun_index); ftime(&startChargingTime[gun_index]); ocpp_clear_idTag_cmd(gun_index); ChangeStartOrStopDateTime(YES, gun_index); if (_isTestRun == YES) { GetTimespecFunc(&_autoRuntestTime); } } ocpp_clear_errorCode_cmd(gun_index); if (_isTestRun == YES) { if (GetTimeoutValue(&_autoRuntestTime) > 60) { ChargingTerminalProcess(gun_index); } } SavePresentChargedDuration(gun_index); if (chargingInfo[gun_index]->Type == _Type_Chademo) { if (ShmDcCommonData->minOutputCur != 0 && chargingInfo[gun_index]->PresentChargedDuration >= 10 && chargingInfo[gun_index]->PresentChargingCurrent < ShmDcCommonData->minOutputCur) { // UCP RecordAlarmCode(gun_index, "012320"); ChargingTerminalProcess(gun_index); } } else if (chargingInfo[gun_index]->Type == _Type_GB) { if (ShmDcCommonData->minOutputCur != 0 && chargingInfo[gun_index]->PresentChargedDuration >= 10 && chargingInfo[gun_index]->PresentChargingCurrent < ShmDcCommonData->minOutputCur) { // UCP RecordAlarmCode(gun_index, "012322"); ChargingTerminalProcess(gun_index); } } else if (chargingInfo[gun_index]->Type == _Type_CCS) { if (ShmDcCommonData->minOutputCur != 0 && chargingInfo[gun_index]->PresentChargedDuration >= 10 && chargingInfo[gun_index]->PresentChargingCurrent < ShmDcCommonData->minOutputCur) { // UCP RecordAlarmCode(gun_index, "012321"); ChargingTerminalProcess(gun_index); } } RecordGfdResult(gun_index); // 小板停止 ChkConnectorBoardStop(gun_index); // psu 停止 ChkPsuErrorStop(gun_index); // 後台要求停止 ChkBackendStop(gun_index); // 設定停止 ChkConfigurationStop(gun_index); // LCM => Charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule() || !stopChargingChkByCard) { // if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || // ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) // { // ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; // } if (ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZ_FAIL) { } else { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_CHARGING; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_CHARGING; if (!stopChargingChkByCard) ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_ALARM: case SYS_MODE_TERMINATING: { if (isModeChange(gun_index)) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen) ocpp_set_stopReason_by_cmd(gun_index, "EmergencyStop"); else ocpp_set_stopReason_by_cmd(gun_index, "Local"); if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_ALARM) { PRINTF_FUNC("================== SYS_MODE_ALARM (%x) ================ \n", gun_index); if (strcmp((char *)chargingInfo[gun_index]->StartDateTime, "") != EQUAL) { ocpp_auto_response_StartTransationConf(gun_index); ocpp_set_stopTransation_cmd(gun_index); } TheEndCharging(gun_index); } else { PRINTF_FUNC("================== SYS_MODE_TERMINATING (%x) ================ \n", gun_index); } ShmDcCommonData->_returnIdleHoldFlag[gun_index] = NO; StopGunInfoTimeoutDet(gun_index); } if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_ALARM) { ChangeToMaxChargingMode(); ocpp_set_errCode_cmd(gun_index); } if (chargingInfo[gun_index]->Type == _Type_Chademo) { } else if (chargingInfo[gun_index]->Type == _Type_GB) { } else if (chargingInfo[gun_index]->Type == _Type_CCS) { } if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_ALARM) { if (chargingInfo [gun_index]->ConnectorPlugIn == NO) { if (ShmDcCommonData->_returnIdleHoldFlag [gun_index] == NO && GetTimeoutValue ( & chargingInfo [gun_index]->ConnectorTimeout ) >= 10) { ShmDcCommonData->_returnIdleHoldFlag [gun_index] = YES; StopGunInfoTimeoutDet ( gun_index ); StartGunInfoTimeoutDet ( gun_index, Timeout_EvseCompleteDet ); } else if (ShmDcCommonData->_returnIdleHoldFlag [gun_index] == YES && GetTimeoutValue ( & chargingInfo [gun_index]->ConnectorTimeout ) >= 2) { setChargerMode ( gun_index, SYS_MODE_IDLE ); } } else if (_isTestRun == YES && GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout) >= 10) { setChargerMode(gun_index, SYS_MODE_IDLE); } } else { if (chargingInfo[gun_index]->Type == _Type_Chademo) { if (isEvGunLocked(gun_index) == NO || isPrechargeStatus_chademo(gun_index) <= 0) { setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else if (chargingInfo[gun_index]->Type == _Type_GB) { if (isEvGunLocked(gun_index) == NO || isPrechargeStatus_gb(gun_index) <= 0) { setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else if (chargingInfo[gun_index]->Type == _Type_CCS) { if (isEvGunLocked(gun_index) == NO && (isPrechargeStatus_ccs(gun_index) >= 53 || isPrechargeStatus_ccs(gun_index) == 0 || isPrechargeStatus_ccs(gun_index) == 13 || isPrechargeStatus_ccs(gun_index) == 14)) { setChargerMode(gun_index, SYS_MODE_COMPLETE); } } } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_COMPLETE: { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_COMPLETE (%x) ================ \n", gun_index); if (strcmp((char *)chargingInfo[gun_index]->StartDateTime, "") != EQUAL) { ocpp_set_errCode_cmd(gun_index); ocpp_auto_response_StartTransationConf(gun_index); ocpp_set_stopTransation_cmd(gun_index); } TheEndCharging(gun_index); ShmDcCommonData->_returnIdleHoldFlag[gun_index] = NO; } ocpp_clear_errorCode_cmd(gun_index); ChangeToMaxChargingMode(); if (chargingInfo[gun_index]->ConnectorPlugIn == NO) { if (ShmDcCommonData->_returnIdleHoldFlag[gun_index] == NO && GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout) >= 10) { ShmDcCommonData->_returnIdleHoldFlag[gun_index] = YES; StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvseCompleteDet); } else if (ShmDcCommonData->_returnIdleHoldFlag[gun_index] == YES && GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout) >= 2) { setChargerMode(gun_index, SYS_MODE_IDLE); } } else if (_isTestRun == YES && GetTimeoutValue(&chargingInfo[gun_index]->ConnectorTimeout) >= 10) { setChargerMode(gun_index, SYS_MODE_IDLE); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } break; case SYS_MODE_CCS_PRECHARGE_STEP0: { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_CCS_PRECHARGE_STEP0 (%x) ================ \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_ForCcsPrechargeDet); } ocpp_clear_errorCode_cmd(gun_index); RecordGfdResult(gun_index); // 小板停止 ChkConnectorBoardStop(gun_index); // psu 停止 ChkPsuErrorStop(gun_index); // 後台要求停止 ChkBackendStop(gun_index); // 等待 EV 小板 (CCS) 通知可以開始 Precharge // 切換 D+ Relay to Precharge Relay if (isPrechargeStatus_ccs(gun_index) == 39 || isPrechargeStatus_ccs(gun_index) == 40) { if (chargingInfo[gun_index]->RelayKPK2Status == YES && chargingInfo[gun_index]->PrechargeStatus != PRECHARGE_READY) //if (chargingInfo[gun_index]->PrechargeStatus != PRECHARGE_PRERELAY_PASS) { if (isPrechargeStatus_ccs(gun_index) == 39) PRINTF_FUNC("Conn %x, Precharge ready, CCS status = PreChargeResponse (%d) \n", gun_index, isPrechargeStatus_ccs(gun_index)); else if (isPrechargeStatus_ccs(gun_index) == 40) PRINTF_FUNC("Conn %x, Precharge ready, CCS status = PowerDeliveryRequest start (%d) \n", gun_index, isPrechargeStatus_ccs(gun_index)); chargingInfo[gun_index]->PrechargeStatus = PRECHARGE_READY; } } else if (isPrechargeStatus_ccs(gun_index) == 45 || isPrechargeStatus_ccs(gun_index) == 46) { setChargerMode(gun_index, SYS_MODE_CCS_PRECHARGE_STEP1); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } break; } case SYS_MODE_CCS_PRECHARGE_STEP1: { if (isModeChange(gun_index)) { PRINTF_FUNC("================== SYS_MODE_CCS_PRECHARGE_STEP1 (%x) ================ \n", gun_index); } ocpp_clear_errorCode_cmd(gun_index); RecordGfdResult(gun_index); // 小板停止 ChkConnectorBoardStop(gun_index); // psu 停止 ChkPsuErrorStop(gun_index); // 後台要求停止 ChkBackendStop(gun_index); // 等待小板通知進入充電 // 切換 D+ Relay to Precharge Relay if (chargingInfo[gun_index]->RelayK1K2Status == YES) { chargingInfo[gun_index]->PrechargeStatus = PRECHARGE_READY; setChargerMode(gun_index, SYS_MODE_CHARGING); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index && ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0) { if (IsNoneSelectAcModule()) { if (ShmSysConfigAndInfo->SysInfo.SystemPage <= _LCM_AUTHORIZING || ShmSysConfigAndInfo->SysInfo.SystemPage >= _LCM_AUTHORIZ_FAIL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } } else { if ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE || ocpp_remote_start_wait_cmd ())) { DisplayPageChkByAcModule(); } } ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } else if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) { ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } break; } } if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE || chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[gun_index]->SystemStatus == SYS_MODE_MAINTAIN || chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT) { ocpp_chk_notificationMessage_cmd(gun_index); } } if (ShmSysConfigAndInfo->SysInfo.SystemPage != _LCM_NONE) { ChangeLcmByIndex(ShmSysConfigAndInfo->SysInfo.SystemPage); } else { bool dcPageRun = false; if (_acgunIndex > 0 && ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE) { if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_IDLE) ChangeLcmByIndex(_LCM_IDLE); else if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_PREPARING) ChangeLcmByIndex(_LCM_PRE_CHARGE); else if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_CHARGING) ChangeLcmByIndex(_LCM_CHARGING); else if (ac_chargingInfo[0]->SystemStatus == SYS_MODE_TERMINATING || ac_chargingInfo[0]->SystemStatus == SYS_MODE_COMPLETE) ChangeLcmByIndex(_LCM_COMPLETE); else dcPageRun = true; } else dcPageRun = true; if (dcPageRun) ChangeLcmByIndex(ShmSysConfigAndInfo->SysInfo.ConnectorPage); } bool isCharging = false; SystemAlarmCheck(); for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { AlarmCheck(chargingInfo[gun_index]->Type); if (_isTestRun == YES) { if (IsGunUsing(gun_index)) { isCharging = true; if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[gun_index]->SystemStatus == SYS_MODE_ALARM) { GetTimespecFunc(&_autoRuntestTime); } } } } if (_isTestRun == YES) { if (!isCharging) { if (GetTimeoutValue(&_autoRuntestTime) >= 60) { DetectPluginStart(); GetTimespecFunc(&_autoRuntestTime); } } else { ClearDetectPluginFlag(); } } write(wtdFd, "a", 1); usleep(whileLoopTime); } return FAIL; }