#include "define.h" #include "main.h" //#define CDFA_CERTIFICATE // Only enable for CDFA certificate to send receipt by Phihong back end API //========================== // System basic sample constant //========================== #define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define ON 1 #define OFF 0 #define BUFFER_SIZE 128 //========================== // Timeout constant define //========================== #define TIMEOUT_SPEC_HANDSHAKING 180 #define TIMEOUT_SPEC_AUTH 15 #define TIMEOUT_SPEC_HANDSHAKING_LED 185 #define TIMEOUT_SPEC_LOGPPRINTOUT 30 #define TIMEOUT_SPEC_PROFILE_PREPARE 60 #define TIMEOUT_SPEC_BS_HLC_HANDSHAKE 25 #define TIMEOUT_SPEC_EV_READY 30 #define TIMEOUT_SPEC_CCS_HEARTBEAT_COUNT_RESET 10 #define TIMEOUT_SPEC_CCS_HANDSHAKE 120 #define TIMEOUT_SPEC_PWN_CHANGE 5 #define TIMEOUT_SPEC_POWERSAVING_LCD 120 #define TIMEOUT_SPEC_POWERSAVING_RFID 120 #define TIMEOUT_SPEC_POWERSAVING_METER 120 #define TIMEOUT_SPEC_POWERSAVING_LED_STATUS 120 #define TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION 15 #define TIMEOUT_SPEC_RESET_WIFI_MODULE 300 //========================== // GPIO constant define //========================== #define GPIO_OUT_RST_RFID 62 #define GPIO_OUT_RST_4G 114 #define GPIO_OUT_RST_QCA 115 #define GPIO_OUT_RST_ETH 56 #define GPIO_IN_WAKEUP 63 #define GPIO_OUT_RST_4G_WIFI 59 #define MtdBlockSize 0x300000 #define DB_FILE "/Storage/ChargeLog/localCgargingRecord.db" #define DB_FILE_OCPP_LOCAL "/Storage/OCPP/charger.db" //========================== // Declare method //========================== void trim(char *s); int mystrcmp(char *p1,char *p2); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); void split(char **arr, char *str, const char *del); int isReachableInternet(); int isRouteFail(); int InitRfidPort(void); int GetCardSerialNumber(); void setLedMotion(unsigned char gun_index,unsigned char led_mode); void setRequest(unsigned char gun_index,unsigned char isOn); void setSpeaker(unsigned char isOn, unsigned char speaker_mode); void gpio_set_value(unsigned int gpio, unsigned int value); //========================== // Declare RFID module type //========================== #define MODULE_EWT 0 int wtdFd = -1; int rfidFd = -1; char* rfidPortName = "/dev/ttyS2"; RFID rfid; char *valid_Internet[2] = {"8.8.8.8", "180.76.76.76"}; //========================== // Declare share memory //========================== struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; struct CHAdeMOData *ShmCHAdeMOData; struct CcsData *ShmCcsData; struct PrimaryMcuData *ShmPrimaryMcuData; struct FanModuleData *ShmFanModuleData; struct RelayModuleData *ShmRelayModuleData; struct OCPP16Data *ShmOCPP16Data; struct OCPP20Data *ShmOCPP20Data; struct OCPP16Data *ShmOCPP16DataPH; struct Charger *ShmCharger; struct timespec startTime[AC_QUANTITY][TMR_IDX_CNT]; struct timespec startChargingTime[AC_QUANTITY]; struct timespec endChargingTime[AC_QUANTITY]; sqlite3 *localDb; sqlite3 *ocppDb; struct SysConfigData SysConfigOrg; ParsingRatedCur modelnameInfo={0}; struct PreviousData { uint16_t targetCurrent; uint16_t current_limit; uint16_t primaryMcuCp_Pwn_Duty; }previousData[4]; //================================= // Common routine //================================= void trim(char *s) { int i=0, j, k, l=0; while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n')) i++; j = strlen(s)-1; while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n')) j--; if(i==0 && j==strlen(s)-1) { } else if(i==0) s[j+1] = '\0'; else { for(k=i; k<=j; k++) s[l++] = s[k]; s[l] = '\0'; } } int mystrcmp(char *p1,char *p2) { while(*p1==*p2) { if(*p1=='\0' || *p2=='\0') break; p1++; p2++; } if(*p1=='\0' && *p2=='\0') return(PASS); else return(FAIL); } void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } void split(char **arr, char *str, const char *del) { char *s = strtok(str, del); while(s != NULL) { *arr++ = s; s = strtok(NULL, del); } } int StoreLogMsg(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 if((ShmSysConfigAndInfo->SysConfig.ModelName != NULL) && (ShmSysConfigAndInfo->SysConfig.SerialNumber != NULL) && (strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) >= 14)) { sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]%s_%s_SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber); } else { sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1); } #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } void refreshStartTimer(struct timespec *timer) { clock_gettime(CLOCK_MONOTONIC, timer); } int getDiffSecNow(struct timespec timer) { struct timespec timerNow; clock_gettime(CLOCK_MONOTONIC, &timerNow); return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000); } int getDiffSecBetween(struct timespec start, struct timespec end) { return (int)((((unsigned long)(end.tv_sec - start.tv_sec) * 1000) + ((unsigned long)((end.tv_nsec / 1000000) - (start.tv_nsec / 1000000))))/1000); } 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); } long long DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second long long StartTime,StopTime; StartTime=(long long)ST.time; StopTime=(long long)ET.time; return ((StopTime-StartTime)*1000) + (ET.millitm-ST.millitm); } 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 isOvertNow(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 { DEBUG_WARN("Start date parsing error.\n"); } return result; } void getDateTimeString(char* result) { time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm=localtime(&CurrentTime); sprintf(result, "%04d.%02d.%02d %02d:%02d:%02d", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); } int getCurrentYear() { int result = 0; time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm=localtime(&CurrentTime); result = (tm->tm_year + 1900); return result; } unsigned long long getAvailableMemory() { long pages = sysconf(_SC_AVPHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); return pages * page_size; } unsigned int isKernelSupportNAT() { unsigned int result = NO; unsigned int version = 0; FILE *fp; char cmd[256]; char buf[512]; // Get IP address & net mask strcpy(cmd, "uname -v"); fp = popen(cmd, "r"); if(fp != NULL) { if(fgets(buf, sizeof(buf), fp) != NULL) { sscanf(buf, "#%d", &version); //DEBUG_INFO("Kernel version: %d\n", version); if(version >= 30) result = YES; } } pclose(fp); return result; } int getEth0MacAddress() { int result = PASS; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; strcpy(cmd, "ifconfig eth0"); fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, "eth0") > 0) { result = PASS; } if(strstr(buf, "eth0 Link encap:Ethernet HWaddr") > 0) { sscanf(buf, "%*s%*s%*s%*s%s", tmp); strcpy((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, tmp); } } } pclose(fp); return result; } int isUap0up(void) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; strcpy(cmd, "ifconfig uap0");; fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, "uap0") > 0) { result = PASS; } } } pclose(fp); return result; } //====================================================== // OCPP routine //====================================================== void ocpp_process_start() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) system("/root/OcppBackend &"); else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) system("/root/OcppBackend20 &"); } uint8_t ocpp_get_isRemoteStartWait() { uint8_t result = OFF; 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; } uint8_t ocpp_get_connection_status() { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->OcppConnStatus; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->OcppConnStatus; } return result; } uint16_t ocpp_get_connection_timeout() { uint16_t result = TIMEOUT_SPEC_HANDSHAKING; 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; } uint16_t ocpp_get_authorize_timeout() { uint16_t result = TIMEOUT_SPEC_AUTH; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData,"") != 0) { result = atoi((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeTimeout].ItemData); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variableAttribute[0].value,"") != 0) { result = atoi((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_AuthorizeTimeout].variableAttribute[0].value); } } return result; } uint8_t ocpp_get_update_firmware_req() { uint8_t result = NO; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq || ShmOCPP16Data->MsMsg.bits.SignedUpdateFirmwareReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq; } return result; } uint8_t ocpp_get_reset_req() { uint8_t result = NO; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MsMsg.bits.ResetReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char*)ShmOCPP20Data->Reset.type, "Immediate") == 0) { result = ShmOCPP20Data->MsMsg.bits.ResetReq; } else { if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_CHARGING) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_TERMINATING) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_COMPLETE)) && (AC_QUANTITY>1?((ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus != SYS_MODE_CHARGING) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus != SYS_MODE_TERMINATING) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus != SYS_MODE_COMPLETE)):TRUE)) { result = ShmOCPP20Data->MsMsg.bits.ResetReq; } } } return result; } void ocpp_boot_info_sync() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy((char*)ShmOCPP16Data->OcppServerURL, (char*)ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL)); memcpy((char*)ShmOCPP16Data->ChargeBoxId, (char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf((char*)ShmOCPP16Data->BootNotification.CpFwVersion, (char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterSerialNumber, "N/A"); switch(ShmSysConfigAndInfo->SysConfig.ModelName[3]) { case 'M': case 'Z': sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "MID"); break; case 'P': sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "PTB"); break; case 'I': sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "TIC"); break; case 'U': sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "UL"); break; default: sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "N/A"); break; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy((char*)ShmOCPP20Data->OcppServerURL, (char*)ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL)); memcpy((char*)ShmOCPP20Data->ChargeBoxId, (char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf((char*)ShmOCPP20Data->BootNotification.chargingStation.firmwareVersion, (char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); } } void ocpp_set_remotestart(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].RequestStartTransactionReq = status; } } void ocpp_set_remotestop(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq = status; } } uint8_t ocpp_get_remotestart(uint8_t gun_index) { uint8_t result = OFF; 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; } return result; } void ocpp_copy_userid_from_remotestart(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); DEBUG_INFO("==========================================\n"); DEBUG_INFO("Copy IdTag into UserId. \n"); DEBUG_INFO("IdTag : [%s] ---> UserId : [%s] . \n", ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("==========================================\n"); } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("==========================================\n"); DEBUG_INFO("Copy idToken into UserId. \n"); DEBUG_INFO("idToken : [%s] ---> UserId : [%s]. \n", ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("==========================================\n"); } } uint8_t ocpp_get_remotestop(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq; } return result; } void ocpp_set_auth_conf(uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->SpMsg.bits.AuthorizeConf != status) ShmOCPP16Data->SpMsg.bits.AuthorizeConf = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->SpMsg.bits.AuthorizeConf != status) ShmOCPP20Data->SpMsg.bits.AuthorizeConf = status; } } void ocpp_set_auth_req(uint8_t status, ...) { va_list args; if(status == ON) ocpp_set_auth_conf(OFF); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->SpMsg.bits.AuthorizeReq != status) { if(status == ON) memset(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, 0x00, ARRAY_SIZE(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status)); ShmOCPP16Data->SpMsg.bits.AuthorizeReq = status; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->SpMsg.bits.AuthorizeReq != status) { if(status == ON) { memset(&ShmOCPP20Data->Authorize.Response_idTokenInfo, 0x00, sizeof(struct IdTokenInfoType)); va_start(args, status); sprintf((char*)ShmOCPP20Data->Authorize.idToken.type, "%s", va_arg(args, char*)); va_end(args); } ShmOCPP20Data->SpMsg.bits.AuthorizeReq = status; } } } uint8_t ocpp_get_auth_req() { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SpMsg.bits.AuthorizeReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SpMsg.bits.AuthorizeReq; } return result; } uint8_t ocpp_get_auth_conf() { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SpMsg.bits.AuthorizeConf; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SpMsg.bits.AuthorizeConf; } return result; } uint8_t ocpp_compare_reserve_id_with_user(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.UserId, (char*)ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) result = ON; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.UserId, (char*)ShmOCPP20Data->ReserveNow[gun_index].idToken.idToken) == 0) result = ON; } return result; } uint8_t ocpp_compare_reserve_id_with_remote_user(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char*)ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, (char*)ShmOCPP16Data->ReserveNow[gun_index].IdTag) == 0) { result = ON; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->RemoteStartTransaction[gun_index].IdTag)); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, (char*)ShmOCPP20Data->ReserveNow[gun_index].idToken.idToken) == 0) { result = ON; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); } } return result; } uint8_t ocpp_get_auth_result(uint8_t isValidParent, ...) { uint8_t result = OFF; va_list args; uint8_t gun_index; if(isValidParent) { va_start(args, isValidParent); gun_index = va_arg(args, int); va_end(args); switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_AUTHORIZING: if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId == -1) && (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))) { result = PASS; } else if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId != -1) && (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0))) { if(ocpp_compare_reserve_id_with_user(gun_index) || ocpp_compare_reserve_id_with_remote_user(gun_index)) { result = PASS; } else { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->ReserveNow[gun_index].ParentIdTag)==0)) result = PASS; } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId == -1) && ((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) && (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].value) != 0))) || ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId != -1) && ((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) && (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->ReserveNow[gun_index].groupIdToken.idToken)==0)))) result = PASS; } break; case SYS_MODE_CHARGING: case SYS_MODE_TERMINATING: if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) && (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.ParentIdTag)==0) && (strlen((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag) > 0)) result = PASS; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) && ((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken) == 0) || (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].value) == 0))) result = PASS; } break; case SYS_MODE_RESERVATION: if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0) && (strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag, (char*)ShmOCPP16Data->ReserveNow[gun_index].ParentIdTag)==0)) result = PASS; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) && (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->ReserveNow[gun_index].groupIdToken.idToken)==0)) result = PASS; } break; default: break; } } else { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((strcmp((char*)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted")==0)) result = PASS; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "Accepted")==0) && (strcmp((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].value) != 0)) result = PASS; } } //DEBUG_INFO("Authorize result : %s \n", ((result == PASS)?"Pass":"Fail")); return result; } uint8_t ocpp_get_unlocker_req(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor; } return result; } void ocpp_set_unlocker_req(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor != status) ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor != status) ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor = status; } } void ocpp_set_starttransaction_req(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionReq != status) ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionReq = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = status; } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { if(ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionReq != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionReq = status; } } void ocpp_set_starttransaction_conf(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf != status) ShmOCPP16Data->CpMsg.bits[gun_index].StartTransactionConf = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf = status; } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { if(ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionConf != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StartTransactionConf = status; } } void ocpp_set_stoptransaction_req(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq != status) ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq != status) ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = status; } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { if(ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq != status) ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq = status; } } void ocpp_set_stoptransaction_conf(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf != status) { ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionConf = status; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf != status) { ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf = status; } } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { if(ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionConf != status) { ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionConf = status; } } } void ocpp_copy_userid_to_starttransaction(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memcpy((char*)ShmOCPP16Data->StartTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StartTransaction[gun_index].IdTag)); } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { memcpy((char*)ShmOCPP16DataPH->StartTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16DataPH->StartTransaction[gun_index].IdTag)); } } uint8_t ocpp_get_starttransaction_result(uint8_t gun_index) { uint8_t result = PASS; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strstr((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnInvalidId].ItemData, "TRUE")) { if((strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Blocked")==0) || (strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Expired")==0) || (strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Invalid")==0)) result = NO; } } 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[gun_index].Response_idTokenInfo.status, "Blocked")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NoCredit")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAllowedTypeEVSE")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisLocation")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisTime")==0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Unknown")==0)) result = NO; } } return result; } uint8_t ocpp_get_maxcharging_profileId() { uint8_t result = 0; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->MaxChargingProfile.ChargingProfileId; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->MaxChargingProfile.id; } return result; } uint8_t ocpp_get_smartcharging_profileId(uint8_t gun_index) { uint8_t result = 0; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->SmartChargingProfile[gun_index].id; } return result; } void ocpp_reset_smartcharging_profileId(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileId = 0; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { ShmOCPP20Data->SmartChargingProfile[gun_index].id = 0; } } uint8_t ocpp_get_profile_req(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq; } return result; } void ocpp_set_profile_req(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq != status) ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileReq = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq != status) ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq = status; } } uint8_t ocpp_get_profile_conf(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf; } return result; } void ocpp_set_profile_conf(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf != status) ShmOCPP16Data->CSUMsg.bits[gun_index].ChargingProfileConf = status; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf != status) ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileConf = status; } } uint8_t ocpp_get_StopTransactionOnEVSideDisconnect() { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnEVSideDisconnect].ItemData, "TRUE") == 0) result = ON; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char *)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].value, "true") == 0) result = ON; } return result; } uint8_t ocpp_get_cancelreservation_req(uint8_t gun_index) { uint8_t result = OFF; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { result = ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { result = ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq; } return result; } void ocpp_set_cancelreservation_req(uint8_t gun_index, uint8_t status) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq != status) ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq = status; if(ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationReq == OFF) ShmOCPP16Data->CsMsg.bits[gun_index].CancelReservationConf = ON; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq != status) ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq = status; if(ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationReq == OFF) ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationConf = ON; } } uint8_t ocpp_isAuthorizeRemoteStart() { uint8_t result = NO; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strstr((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[AuthorizeRemoteTxRequests].ItemData, "TRUE")) { result = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].value, "true")) { result = YES; } } return result; } uint8_t ocpp_get_freevend_idtag(uint8_t * userId) { uint8_t result = NO; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { strcpy((char*)userId, (char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[FreeVendIdtag].ItemData); result = YES; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { strcpy((char*)userId, (char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].value); result = YES; } return result; } uint8_t ocpp_set_ocmf_data_transfer(uint8_t gun_index) { uint8_t result = NO; memset(ShmOCPP16Data->OcmfData[gun_index].DataString, 0x00, ARRAY_SIZE(ShmOCPP16Data->OcmfData[gun_index].DataString)); memset(ShmOCPP16Data->OcmfData[gun_index].PublicKey, 0x00, ARRAY_SIZE(ShmOCPP16Data->OcmfData[gun_index].PublicKey)); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((strcmp((char*)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessageFormatId, "") != 0) && (strcmp((char*)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessage, "") != 0) && (strcmp((char*)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputSignature, "") != 0) && (strcmp((char*)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKeyHeader, "") != 0) && (strcmp((char*)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKey, "") != 0)) { strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessageFormatId); strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString,"|"); strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessage); strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString, "|{\"SD\":\""); strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputSignature); strcat((char *)ShmOCPP16Data->OcmfData[gun_index].DataString, "\"}"); sprintf((char *)ShmOCPP16Data->OcmfData[gun_index].PublicKey, "%s%s", ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKeyHeader, ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKey); DEBUG_INFO("Set ptb meter message into data transfer success. \n"); result = YES; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { // TO DO OCPP 2.0 } return result; } //====================================================== // 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 CreatShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n"); result = FAIL; } memset(ShmSysConfigAndInfo,0,sizeof(struct SysConfigAndInfo)); //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmStatusCodeData NG\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmStatusCodeData NG\n"); result = FAIL; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmPsuData NG\n"); result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPsuData NG\n"); result = FAIL; } memset(ShmPsuData,0,sizeof(struct PsuData)); //creat ShmCHAdeMOData if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCHAdeMOData NG1\n"); result = FAIL; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCHAdeMOData NG2\n"); result = FAIL; } memset(ShmCHAdeMOData,0,sizeof(struct CHAdeMOData)); //creat ShmCcsData if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCcsData NG\n"); result = FAIL; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCcsData NG\n"); result = FAIL; } memset(ShmCcsData,0,sizeof(struct CcsData)); //creat ShmPrimaryMcuData if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmPrimaryMcuData NG\n"); result = FAIL; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmPrimaryMcuData NG\n"); result = FAIL; } memset(ShmPrimaryMcuData,0,sizeof(struct PrimaryMcuData)); /* //creat ShmFanModuleData if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmFanModuleData NG\n"); result = FAIL; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmFanModuleData NG\n"); result = FAIL; } memset(ShmFanModuleData,0,sizeof(struct FanModuleData)); //creat ShmRelayModuleData if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmRelayModuleData NG\n"); result = FAIL; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmRelayModuleData NG\n"); result = FAIL; } memset(ShmRelayModuleData,0,sizeof(struct RelayModuleData));*/ //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16Data NG\n"); result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16Data NG\n"); result = FAIL; } memset(ShmOCPP16Data,0,sizeof(struct OCPP16Data)); //creat ShmOCPP20Data if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget OCPP20Data NG\n"); result = FAIL; } else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat OCPP20Data NG\n"); result = FAIL; } memset(ShmOCPP20Data,0,sizeof(struct OCPP20Data)); //creat ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), IPC_CREAT | 0777)) < 0) { DEBUG_ERROR("shmget ShmCharger NG\n"); result = FAIL; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmCharger NG\n"); result = FAIL; } memset(ShmCharger,0,sizeof(struct Charger)); //creat ShmOCPP16DataPH if ((MeterSMId = shmget(ShmOcppPHModuleKey, sizeof(struct OCPP16Data), IPC_CREAT|0777)) < 0) { DEBUG_ERROR("shmget ShmOCPP16DataPH NG\n"); result = FAIL; } else if ((ShmOCPP16DataPH = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmOCPP16DataPH NG\n"); result = FAIL; } else {} ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; return result; } //====================================================== // Call WEBAPI to mail receipt (Only for CDFA verify) //====================================================== #ifdef CDFA_CERTIFICATE int sendReceiptMail(char *startDateTime, char *stopDateTime, char *receiptInfo) { int result = FAIL; char reciever[128]; char subject[128]; char content[8192]; char priceDetail[4098]={0}; char cmdBuf[8192]; double totalEnergy; double totalPrice; json_object *detailPrice = json_tokener_parse(receiptInfo); if(!is_error(detailPrice)) { if(json_object_object_get(detailPrice, "totalChargedEnergy") != NULL) totalEnergy = json_object_get_double(json_object_object_get(detailPrice, "totalChargedEnergy")); if(json_object_object_get(detailPrice, "totalPrice") != NULL) totalPrice = json_object_get_double(json_object_object_get(detailPrice, "totalPrice")); if(json_object_object_get(detailPrice, "receiptDetail") != NULL) { for(int idx=0;idx\n", priceDetail , json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "hour")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "chargedEnergy")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "unitPrice")) , json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(detailPrice, "receiptDetail"), idx), "periodPrice"))); } } } json_object_put(detailPrice); // Generate mail content sprintf(reciever, "folus_wen@phihong.com.tw"); sprintf(subject, "Charging Receipt From %s", ShmSysConfigAndInfo->SysConfig.chargePointVendor); sprintf(content, "
\n" "

Receipt of charging on %s


\n" "Location Name: CDFA Lab
\n" "Location Address: xxxxxxxxxxx
\n" "EVSE ID: %s
\n" "Maximum Rate of Energy Transfer: 11.5 KW AC
\n" "Charging start date time: %s
\n" "Charging stop date time: %s
\n" "Energy Delivered: %.4f KWH
\n" "Cost of Charging:
\n" "%s" "***Total charged cost: $ %.2f
\n" "
\n" "
\n" "%s
\n" "47800 Fremont Blvd.
\n" "Fremont, CA 94538, USA
\n", startDateTime , ShmSysConfigAndInfo->SysConfig.ChargeBoxId , startDateTime , stopDateTime , totalEnergy , priceDetail , totalPrice , ShmSysConfigAndInfo->SysConfig.chargePointVendor); json_object *post = json_object_new_object(); json_object_object_add(post, "Receiver", json_object_new_string(reciever)); json_object_object_add(post, "Subject", json_object_new_string(subject)); json_object_object_add(post, "Body", json_object_new_string(content)); json_object_object_add(post, "UseHtml", json_object_new_boolean(1)); // Call WEBAPI sprintf(cmdBuf, "curl -X POST -k -d '%s' -H \"Content-Type: application/json\" https://ocpp.phihong.com.tw:5014/api/Notification/ &", json_object_to_json_string_ext(post, JSON_C_TO_STRING_PLAIN)); system(cmdBuf); //DEBUG_INFO("cmdBuf: %s\n", cmdBuf); json_object_put(post); return result; } #endif /* CDFA_CERTIFICATE */ //====================================================== // SQLite3 related routine //====================================================== int getReceiptInfo(uint8_t gun_index, char *receiptInfo) { int result = PASS; double totalEnergy=0.0; double totalPrice=0.0; json_object *receipt = json_object_new_object(); json_object *receiptAry = json_object_new_array(); for(uint8_t idxHour=0;idxHourSysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod);idxHour++) { json_object *receiptDetail = json_object_new_object(); json_object_object_add(receiptDetail, "hour", json_object_new_int(idxHour)); json_object_object_add(receiptDetail, "chargedEnergy", json_object_new_double(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idxHour])); json_object_object_add(receiptDetail, "unitPrice", json_object_new_double(ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour])); json_object_object_add(receiptDetail, "periodPrice", json_object_new_double(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idxHour]*ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour])); totalEnergy += ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idxHour]; totalPrice += ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idxHour]*ShmSysConfigAndInfo->SysConfig.BillingData.Fee[idxHour]; json_object_array_add(receiptAry, receiptDetail); } json_object_object_add(receipt, "receiptDetail", receiptAry); json_object_object_add(receipt, "totalChargedEnergy", json_object_new_double(totalEnergy)); json_object_object_add(receipt, "totalPrice", json_object_new_double(totalPrice)); json_object_object_add(receipt, "serviceProvider", json_object_new_string((char*)ShmSysConfigAndInfo->SysConfig.chargePointVendor)); json_object_object_add(receipt, "serviceProviderAddress", json_object_new_string("Address")); json_object_object_add(receipt, "serviceProviderTel", json_object_new_string("TEL")); json_object_object_add(receipt, "chargerBoxId", json_object_new_string((char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId)); sprintf(receiptInfo, "%s", json_object_to_json_string_ext(receipt, JSON_C_TO_STRING_PLAIN)); json_object_put(receipt); //DEBUG_INFO("receiptInfo: %s\n", receiptInfo); 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, " "finalCost text" ");"; char* createRecordBufSql="CREATE TABLE IF NOT EXISTS charging_record_buffer(" "reservationId text, " "transactionId text, " "startMethod text, " "userId text, " "dateTimeStart text, " "dateTimeStop text," "socStart text, " "socStop text, " "chargeEnergy text, " "stopReason text, " "finalCost 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* createMeterPermissionRecordSql="CREATE TABLE IF NOT EXISTS `meter_permission_record` ( " "`idx` INTEGER PRIMARY KEY AUTOINCREMENT, " "`item` TEXT NOT NULL, " "`connector` INTEGER NOT NULL, " "`val` TEXT NOT NULL, unique(item,connector) on conflict replace);"; char* createMeterRecordSql="CREATE TABLE IF NOT EXISTS meter_record(" "idx integer primary key AUTOINCREMENT, " "transactionId text, " "ocmfString text, " "publicKey text, " "isUpload text" ");"; //sqlite3_config(SQLITE_CONFIG_URI, 1); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_ERROR( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "Local charging record database open successfully.\n"); if (sqlite3_exec(db, createRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create local charging record table error message: %s\n", errMsg); } else { DEBUG_INFO( "Opened local charging record table successfully\n"); } if (sqlite3_exec(db, createRecordBufSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create local charging record buffer table error message: %s\n", errMsg); } else { DEBUG_INFO( "Opened local charging record buffer table successfully\n"); } if (sqlite3_exec(db, createCfgSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create local config table error message: %s\n", errMsg); } else { DEBUG_INFO( "Opened local config table successfully\n"); } // PTB meter permission status record if (sqlite3_exec(db, createMeterPermissionRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create local meter permission status table error message: %s\n", errMsg); } else { DEBUG_INFO( "Opened local meter permission status table successfully\n"); } // PTB meter data record if (sqlite3_exec(db, createMeterRecordSql, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create local Meter Data table error message: %s\n", errMsg); } else { DEBUG_INFO( "Opened local Meter Data table successfully\n"); } sqlite3_close(db); } return result; } int DB_Open_OCPP20(sqlite3 *db) { int result = PASS; char* errMsg = NULL; char *sqlOcppVariable = "create table if not exists ocpp20_variable (idx integer primary key," "componentName text NOT NULL ," "componentInstance text, " "variableName text NOT NULL, " "variableInstance text, " "variableCharacteristicsDataType integer, " "variableCharacteristicsUnit text, " "variableCharacteristicsMaxLimit real," "variableAttributesType text, " "variableAttributesTypeMutability text, " "variableAttributesTypeValue text, " "variableCharacteristicsMinLimit real," "unique(componentName, componentInstance,variableName, variableInstance) on conflict replace);"; //sqlite3_config(SQLITE_CONFIG_URI, 1); if(sqlite3_open(DB_FILE_OCPP_LOCAL, &db)) { result = FAIL; DEBUG_ERROR( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO( "OCPP local database open successfully.\n"); if(sqlite3_exec(db, sqlOcppVariable, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_ERROR( "Create OCPP 2.0 variable table error message: %s\n", errMsg); } else { DEBUG_INFO( "Create OCPP 2.0 variable table successfully\n"); } sqlite3_close(db); } return result; } int DB_variableClear(sqlite3 *db) { int result = PASS; //char * sqlcleanLocalList = "delete from ocpp20_variable"; char * sqlcleanLocalList = "drop table ocpp20_variable"; char *errMsg = 0; if(sqlite3_open(DB_FILE_OCPP_LOCAL, &db)) { result = FAIL; DEBUG_ERROR( "Can't open database for ocpp 2.0 variable: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { DEBUG_INFO("Command: &s\n", sqlcleanLocalList); if(sqlite3_exec(db, sqlcleanLocalList, 0, 0, &errMsg) != SQLITE_OK) { DEBUG_INFO("%s\n", errMsg); DEBUG_INFO("Drop table failed.\n"); result = FAIL; } DEBUG_INFO("Drop table succeed.\n"); } return result; } int DB_Check_Record_Buf(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char **rs; int rows, cols; if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sqlite3_get_table(db, "select * from charging_record_buffer", &rs, &rows, &cols, &errMsg); if(rows>0) { // Copy record buffer for(int idxRow=1;idxRow<=rows;idxRow++) { if(strcmp(rs[(idxRow*cols)+3], "0") == 0) { result = false; } sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');", rs[(idxRow*cols)+0], rs[(idxRow*cols)+1], rs[(idxRow*cols)+2], rs[(idxRow*cols)+3], rs[(idxRow*cols)+4], rs[(idxRow*cols)+5], rs[(idxRow*cols)+6], rs[(idxRow*cols)+7], rs[(idxRow*cols)+8], rs[(idxRow*cols)+9], rs[(idxRow*cols)+10]); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Copy local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO( "Copy local charging record buffer successfully\n"); } #ifdef CDFA_CERTIFICATE // Only for CDFA certificate sendReceiptMail(rs[(idxRow*cols)+4], rs[(idxRow*cols)+5], rs[(idxRow*cols)+10]); #endif /* CDFA_CERTIFICATE */ } // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Delete local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO( "Delete local charging record buffer successfully\n"); } } else { DEBUG_INFO("There is not any charging record buffer.\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } int DB_Update_Record_Buf(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char receiptInfo[2048]; getReceiptInfo(gun_index, receiptInfo); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(sqlStr, "insert into charging_record_buffer(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, "Power Loss", #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP16Data->Cost.FinalCost[gun_index].description); #endif /* CDFA_CERTIFICATE */ } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf(sqlStr, "insert into charging_record_buffer(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " #ifdef CDFA_CERTIFICATE "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", #else "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');", #endif /* CDFA_CERTIFICATE */ ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, "Power Loss", #ifdef CDFA_CERTIFICATE //receiptInfo);// Only for CDFA certificate #else ShmOCPP20Data->CostUpdated.totalCost); #endif /* CDFA_CERTIFICATE */ } if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Delete local charging record buffer error message: %s\n", errMsg); } else { //DEBUG_INFO( "Delete local charging record buffer successfully\n"); } // Insert record buffer if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Insert local charging record buffer error message: %s\n", errMsg); } else { //DEBUG_INFO( "Insert local charging record buffer successfully\n"); } sqlite3_close(db); } return result; } int DB_Insert_Record(sqlite3 *db, int gun_index) { int result = PASS; char* errMsg = NULL; char sqlStr[4096]; char receiptInfo[2048]; char TmpReadOutputOcmfMessage[2048]; char TmpReadPublicKeyWithHeader[256]; getReceiptInfo(gun_index, receiptInfo); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ShmOCPP16Data->StopTransaction[gun_index].StopReason, #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP16Data->Cost.FinalCost[gun_index].description); #endif /* CDFA_CERTIFICATE */ } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) " #ifdef CDFA_CERTIFICATE "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');", #else "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');", #endif /* CDFA_CERTIFICATE */ ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, #ifdef CDFA_CERTIFICATE receiptInfo);// Only for CDFA certificate #else ShmOCPP20Data->CostUpdated.totalCost); #endif /* CDFA_CERTIFICATE */ } //DEBUG_INFO("sqlStr= %s\n", sqlStr); memset(TmpReadOutputOcmfMessage, 0x00, ARRAY_SIZE(TmpReadOutputOcmfMessage)); memset(TmpReadPublicKeyWithHeader, 0x00, ARRAY_SIZE(TmpReadPublicKeyWithHeader)); if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { strcat((char *)TmpReadOutputOcmfMessage, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessageFormatId); strcat((char *)TmpReadOutputOcmfMessage,"|"); strcat((char *)TmpReadOutputOcmfMessage, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputMessage); strcat((char *)TmpReadOutputOcmfMessage, "|{\"SD\":\""); strcat((char *)TmpReadOutputOcmfMessage, (char *)ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadOutputSignature); strcat((char *)TmpReadOutputOcmfMessage, "\"}"); sprintf((char *)TmpReadPublicKeyWithHeader, "%s%s", ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKeyHeader, ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.ReadPublicKey); sprintf(sqlStr, "insert into meter_record(transactionId, ocmfString, publicKey, isUpload) " "values('%d', '%s', '%s', '%d');", ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId, TmpReadOutputOcmfMessage, TmpReadPublicKeyWithHeader, ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad); DEBUG_INFO("PTB meter message is upload to the backend system: %s \n", ((ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad == YES)?"YES":"NO")); } if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { // Delete buffer if (sqlite3_exec(db, "delete from charging_record_buffer", 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Delete local charging record buffer error message: %s\n", errMsg); } else { DEBUG_INFO( "Delete local charging record buffer successfully\n"); } // Insert charging record if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Insert local charging record error message: %s\n", errMsg); } else { DEBUG_INFO( "Insert local charging record successfully\n"); } sprintf(sqlStr, "delete from charging_record where (idx < (select idx from charging_record order by idx desc limit 1)-2000) and (dateTimeStop < '%04d.01.01 00:00:00');", (getCurrentYear()-3)); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "delete local charging error message: %s\n", errMsg); } else { DEBUG_INFO( "delete local charging record successfully\n"); } // Insert meter data record if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "Insert local meter data error message: %s\n", errMsg); } else { DEBUG_INFO( "Insert local meter data successfully\n"); } // Delet meter data record sprintf(sqlStr, "delete from meter_record where (idx < (select idx from meter_record order by idx desc limit 1)-2000)"); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "delete local meter data error message: %s\n", errMsg); } else { DEBUG_INFO( "delete local meter data record successfully\n"); } sqlite3_close(db); } #ifdef CDFA_CERTIFICATE // Only for CDFA certificate sendReceiptMail((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime, receiptInfo); #endif return result; } int DB_Update_Operactive(sqlite3 *db, uint8_t gun_index, uint8_t isOperactive) { uint8_t result = false; char* errMsg = NULL; char sqlStr[1024]; srand(time(NULL)); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sprintf(sqlStr, "insert or replace into config (item, connector, val) values('isOperactive', %d, %d);", gun_index, isOperactive); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "update config error message: %s\n", errMsg); } else { DEBUG_INFO("update connector-%d config item isOperactive to %d\n", gun_index, isOperactive); } 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='isOperactive' and connector=%d;", gun_index); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { 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; } DEBUG_INFO("Query connector-%d isOperactive: %s\n", gun_index, rs[(idxRow*cols)+3]); } } else { DEBUG_INFO("Query connector-%d fail, default value as operactive.\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } int DB_Update_Meter_Permission(sqlite3 *db, uint8_t gun_index, uint8_t permission_status) { uint8_t result = false; char* errMsg = NULL; char sqlStr[1024]; srand(time(NULL)); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { sprintf(sqlStr, "insert or replace into meter_permission_record (item, connector, val) values('Permission', %d, %d);", gun_index, permission_status); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK) { result = FAIL; DEBUG_INFO( "update meter permission status error message: %s\n", errMsg); } else { DEBUG_INFO("update connector-%d meter permission status item Permission to %d\n", gun_index, permission_status); } sqlite3_close(db); } return result; } int DB_Get_Meter_Permission(sqlite3 *db, uint8_t gun_index) { uint8_t result = PERMISSION_END_CHARGING; char* errMsg = NULL; char sqlStr[1024]; char **rs; int rows, cols; sprintf(sqlStr, "select * from meter_permission_record where item='Permission' and connector=%d;", gun_index); //DEBUG_INFO("sqlStr= %s\n", sqlStr); if(sqlite3_open(DB_FILE, &db)) { result = FAIL; DEBUG_INFO( "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); } else { 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], "1") == 0) { result = PERMISSION_START_CHARGING; } DEBUG_INFO("Query connector-%d meter permission status : %s\n", gun_index, rs[(idxRow*cols)+3]); } } else { DEBUG_INFO("Query connector-%d fail, default value as [ PERMISSION_END_CHARGING ].\n", gun_index); } sqlite3_free_table(rs); sqlite3_close(db); } return result; } //====================================================== // Peripheral initial //====================================================== 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("System watch dog initial fail.\n"); } ioctl(fd, _IOWR('W', 6, int), &timeout); return fd; } void InitGPIO() { /*****************0~3, 4 bank, bank x 32+ num*********************/ /***************************************************************/ /*************** INPUT PIN ***************************************/ /***************************************************************/ /***************************************************************/ /*************** OUTPUT PIN ************************************/ /***************************************************************/ /*MCU request:GPIO3_20 => H:ON; L:OFF*/ system("echo 116 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio116/direction"); system("echo 0 > /sys/class/gpio/gpio116/value"); /*Rfid:GPIO0_19 => Reset_PING H:ON; L:OFF*/ system("echo 19 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio19/direction"); system("echo 1 > /sys/class/gpio/gpio19/value"); /*Speaker:GPIO2_1 => H:ON; L:OFF*/ system("echo 65 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio65/direction"); system("echo 0 > /sys/class/gpio/gpio65/value"); /*Ethernet RST:GPIO1_24 => H:ON; L:OFF*/ system("echo 56 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio56/direction"); system("echo 0 > /sys/class/gpio/gpio56/value"); sleep(3); system("echo 1 > /sys/class/gpio/gpio56/value"); /*4G POWER RST:GPIO3_18 => H:ON; L:OFF*/ system("echo 114 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio114/direction"); system("echo 1 > /sys/class/gpio/gpio114/value"); sleep(3); system("echo 0 > /sys/class/gpio/gpio114/value"); /*4G/WIFI POWER RST:GPIO1_27 => H:OFF L:ON*/ system("echo 59 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio59/direction"); system("echo 1 > /sys/class/gpio/gpio59/value"); sleep(3); system("echo 0 > /sys/class/gpio/gpio59/value"); /*RFID ICC:GPIO0_20 => H:ON; L:OFF*/ system("echo 20 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio20/direction"); /*QCA7000 interrupt:GPIO2_00 => H:ON; L:OFF*/ system("echo 64 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio64/direction"); /*QCA7000 Reset:GPIO3_19 => H:ON; L:OFF*/ system("echo 115 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio115/direction"); system("echo 0 > /sys/class/gpio/gpio115/value"); sleep(3); system("echo 1 > /sys/class/gpio/gpio115/value"); /*RFID RST: GPIO1_30 => H:OFF; L:ON*/ system("echo 62 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio62/direction"); system("echo 0 > /sys/class/gpio/gpio62/value"); /*Wake up button GPIO1_31 => H:OFF; L:ON*/ system("echo 63 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio63/direction"); sleep(1); DEBUG_INFO("Initial GPIO OK\n"); } int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd,wrd; unsigned char *buf; unsigned int ChkSum,ChkSumOrg; if((buf=malloc(MtdBlockSize))==NULL) { DEBUG_ERROR("malloc buffer NG,rebooting..\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("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock10 NG,rebooting..\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=ARRAY_SIZE(ptr->CsuBootLoadFwRev);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("Primary SysConfigData checksum NG, read backup\n"); system("nanddump /dev/mtd11 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock11 (backup) NG,rebooting..\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=ARRAY_SIZE(ptr->CsuBootLoadFwRev);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=ARRAY_SIZE(ptr->CsuBootLoadFwRev);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_WARN("factory default SysConfigData checksum NG, restore factory default\n"); free(buf); system("cd /root;./Module_FactoryConfig -m"); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } } } //load OK memcpy((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)) { memset(ShmSysConfigAndInfo->SysConfig.ModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) { memset(ShmSysConfigAndInfo->SysConfig.SerialNumber, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) { memset(ShmSysConfigAndInfo->SysConfig.SystemId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)); } if(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff) { DEBUG_INFO("Ethernet dhcp config is null.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) == 0x00) { DEBUG_INFO("Model name over length.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) == 0x00) { DEBUG_INFO("Model serial number over length.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) == 0x00) { DEBUG_INFO("SystemId over length.\n"); } system("cd /root;./Module_FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } DEBUG_INFO("Load SysConfigData OK\n"); ShmCharger->isCcsEnable = OFF; for(uint8_t idx=0;idx<3;idx++) { if(ShmSysConfigAndInfo->SysConfig.ModelName[7+idx] == '7') ShmCharger->isCcsEnable = ON; } #ifdef ENABLE_CCS ShmCharger->isCcsEnable = ON; #endif DEBUG_INFO("Is CCS Enable: %s \n",((ShmCharger->isCcsEnable == ON)?"YES":"NO")); RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo); 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;iSysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); DEBUG_INFO("eth0 config as ip: %s, netmask: %s\n", 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 &"); system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &"); //system("/sbin/ethtool -s eth0 speed 10 duplex full autoneg off"); //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 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); // Ethernet MAC address getEth0MacAddress(); //check internet status pid = fork(); if(pid == 0) { for(;;) { if(isRouteFail()) { //DEBUG_ERROR("eth0 not in route, restart eth0.\n"); system("/sbin/ifconfig eth0 down;/sbin/ifconfig eth0 up"); 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); } } if(isReachableInternet() == PASS) { ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet=OFF; cnt_pingDNS_Fail = 0; } else { if(cnt_pingDNS_Fail >= 3) { ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet=ON; if(!ShmSysConfigAndInfo->SysInfo.OcppConnStatus) { 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; } } else { cnt_pingDNS_Fail++; } } // Network status switch(ShmSysConfigAndInfo->SysConfig.ModelName[10]) { case 'E': if((ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) && (ShmOCPP16Data->OcppConnStatus != PASS)) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; } else { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; } break; case 'W': if((ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) && ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) && (ShmOCPP16Data->OcppConnStatus != PASS)) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; } else { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; } break; case 'T': if((ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) && ((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) && (ShmOCPP16Data->OcppConnStatus != PASS)) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; } else { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; } break; case 'D': if((ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) && ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) && ((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == 0) || ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) && (ShmOCPP16Data->OcppConnStatus != PASS)) { ShmSysConfigAndInfo->SysInfo.InternetConn = OFF; } else { ShmSysConfigAndInfo->SysInfo.InternetConn = ON; } break; } //============================================================ // Priority for internet 0 : First / 1 : Second / 2: Third //============================================================ if(!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet) { 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(isKernelSupportNAT() == YES) { if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { if(natInterface != 1) { system("/sbin/iptables -t nat -F"); system("/sbin/iptables -A POSTROUTING -t nat -s 192.168.10.0/24 -o eth0 -j MASQUERADE"); natInterface = 1; } } else { system("/sbin/iptables -t nat -F"); } } } else if(!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi) { 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"); } } else if(!ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi) { 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"); } if(isKernelSupportNAT() == YES) { if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { if(natInterface != 2) { system("/sbin/iptables -t nat -F"); system("/sbin/iptables -A POSTROUTING -t nat -s 192.168.10.0/24 -o ppp0 -j MASQUERADE"); natInterface = 2; } } else { system("/sbin/iptables -t nat -F"); } } } else { if(isKernelSupportNAT() == YES) { if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) { system("/sbin/iptables -t nat -F"); natInterface = 0; } } } // Check is need to reset WIFI/4G module power if(!ShmSysConfigAndInfo->SysInfo.OcppConnStatus && ((system("pidof -s Module_Wifi > /dev/null") != 0) || (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 0) || ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 1) && (ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi == ON)) || ((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) && (ShmStatusCodeData->InfoCode.InfoEvents.bits.ApDisconnectViaWiFi == ON))) && ((system("pidof -s Module_4g > /dev/null") != 0) || (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == 0) || ((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled == 1) && (ShmStatusCodeData->InfoCode.InfoEvents.bits.ApnDisconnectVia4Gi == ON)))) { if(getDiffSecNow(startTime[0][TMR_IDX_RESET_WIFI]) > TIMEOUT_SPEC_RESET_WIFI_MODULE) { if((ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode != 0) || (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled != 0)) { DEBUG_WARN("WIFI/4G module reset.\n"); gpio_set_value(GPIO_OUT_RST_4G_WIFI, ON); sleep(3); gpio_set_value(GPIO_OUT_RST_4G_WIFI, OFF); } refreshStartTimer(&startTime[0][TMR_IDX_RESET_WIFI]); } } else { refreshStartTimer(&startTime[0][TMR_IDX_RESET_WIFI]); } // Bridge ethernet to uap0 to get dynamic ip address if(ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) && (isUap0up() == PASS) && (access("/sys/class/net/br0/address", F_OK) == -1)) { sleep(10); system("/usr/sbin/brctl addbr br0"); system("/usr/sbin/brctl addif br0 eth0"); system("/usr/sbin/brctl addif br0 uap0"); system("/sbin/ifconfig br0 192.168.10.200 up"); system("/bin/sed -i '/interface/d' /etc/udhcpd.conf"); system("/bin/echo 'interface br0' >> /etc/udhcpd.conf"); system("kill udhcpd"); system("/usr/sbin/udhcpd /etc/udhcpd.conf"); DEBUG_INFO("Bridge uap0 & eth0 for local power sharing by ethernet.\n"); } // Change uap0 to low priority if(ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode == 2) && (isUap0up() == PASS)) { system("/sbin/ifmetric uap0 1"); } sleep(5); } } DEBUG_INFO("Initial Ethernet OK\n"); } int SpawnTask(uint8_t gun_index) { if(gun_index == 0) { system ("pkill Module_"); system ("pkill OcppBackend"); if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { system("/root/Module_4g &"); } else if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') { system("/root/Module_Wifi &"); } system ("/root/Module_EventLogging &"); system ("/root/Module_AlarmDetect &"); system ("/root/Module_InternalComm &"); system ("/root/Module_Speaker &"); system ("/root/Module_ProduceUtils &"); system ("/root/Module_LcmControl &"); if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) { ocpp_process_start(); } else { DEBUG_INFO("OCPP URL is empty, need to create a configuration table !!!\n"); ocpp_process_start(); } } return PASS; } int InitQca7000() { int result = PASS; system("/sbin/rmmod qcaspi"); if(isKernelSupportNAT() == YES) system("/sbin/insmod /lib/qcaspi_nat.ko"); else system("/sbin/insmod /lib/qcaspi.ko"); sleep(2); /*+++ vern, for CCS +++*/ //system("/sbin/ifconfig eth1 192.168.253.11 netmask 255.255.255.0 up"); system("/sbin/ifconfig eth1 192.168.0.11 netmask 255.255.255.0 up"); /*--- vern, for CCS ---*/ sleep(1); return result; } int Initialization(uint8_t gun_index) { int result = PASS; if(gun_index == 0) { LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); InitGPIO(); InitEthernet(); if(InitQca7000() != PASS) { DEBUG_ERROR("QCA7000 initial fail.\n"); result = FAIL; } if(DB_Open(localDb) != PASS) { DEBUG_ERROR("Local database initial fail.\n"); result = FAIL; } if(DB_Open_OCPP20(ocppDb) != PASS) { DEBUG_ERROR("OCPP 2.0 configuration variable database initial fail.\n"); result = FAIL; } if((rfidFd = InitRfidPort()) == FAIL) { DEBUG_ERROR("RFID port initial fail.\n"); result = FAIL; } if((wtdFd = InitWatchDog()) == FAIL) { DEBUG_ERROR("Watchdog initial fail.\n"); result = FAIL; } if(result == PASS) DEBUG_INFO("Initialization OK.\n"); else DEBUG_INFO("Initialization Fail.\n"); } ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = DB_Get_Meter_Permission(localDb, gun_index); // Check is ccs Enable/Disable to open ccs power. if(ShmCharger->isCcsEnable == ON) { system("echo 1 > /sys/class/gpio/gpio115/value"); DEBUG_INFO("QCA7000: Power on. \n"); } else { system("echo 0 > /sys/class/gpio/gpio115/value"); DEBUG_INFO("QCA7000: Power off. \n"); } return result; } //===================================================== // Common routine //===================================================== char* getSystemModeName(unsigned char mode) { char* result; switch(mode) { case SYS_MODE_BOOTING: result = "booting"; break; case SYS_MODE_IDLE: result = "idle"; break; case SYS_MODE_AUTHORIZING: result = "authorizing"; break; case SYS_MODE_PREPARING: result = "preparing"; break; case SYS_MODE_CHARGING: result = "charging"; break; case SYS_MODE_TERMINATING: result = "terminating"; break; case SYS_MODE_COMPLETE: result = "complete"; break; case SYS_MODE_ALARM: result = "alarm"; break; case SYS_MODE_FAULT: result = "fault"; break; case SYS_MODE_MAINTAIN: result = "maintain"; break; case SYS_MODE_RESERVATION: result = "reservation"; break; case SYS_MODE_BOOKING: result = "booking"; break; case SYS_MODE_DEBUG: result = "debug"; break; case SYS_MODE_UPDATE: result = "upgrade"; break; default: result = "unknown"; break; } return result; } void setChargerMode(unsigned char gun_index, unsigned char mode) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus = mode; DEBUG_INFO("Gun-[%d] mode switch from %s to %s\n", gun_index, getSystemModeName(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus), getSystemModeName(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)); } unsigned char isMode(unsigned char gun_index, unsigned char mode) { return ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == mode)?YES:NO); } unsigned char isModeChange(unsigned char gun_index) { unsigned char result = NO; if(!isMode(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus)) { result = YES; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus; } return result; } void gpio_set_value(unsigned int gpio, unsigned int value) { int fd; char buf[256]; sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { DEBUG_ERROR("GPIO-%d set %d fail.\n", gpio, value); return; } if (value) write(fd, "1", 2); else write(fd, "0", 2); close(fd); } int gpio_get_value(unsigned int gpio) { int fd; char buf[256]; char ch; int8_t result = FAIL; sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); fd = open(buf, O_RDONLY); if (fd < 0) { DEBUG_ERROR("GPIO-%d get fail\n", gpio); return result; } read(fd, &ch, 1); if (ch != '0') result = 1; else result = 0; close(fd); return result; } int presentChargedEnergyClear(unsigned char gun_index) { int result = FAIL; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = 0; memset(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod)*sizeof(float)); result = PASS; return result; } float presentChargedEnergyTotal(unsigned char gun_index) { float result = 0.0f; for(int idx=0;idxSysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod);idx++) { //result += ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idx]; result += (((int)(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[idx]*10000))/(float)10000); } return result; } int presentChargedEnergyUpdate(unsigned char gun_index) { int result = FAIL; time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm=localtime(&CurrentTime); if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) { // Resolution: 0.0001 kwh ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[tm->tm_hour] += (((float)(ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption - ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start))/10000.0) - presentChargedEnergyTotal(gun_index); } else { // Resolution: 0.0001 kwh ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].presentChargedEnergyPeriod[tm->tm_hour] += ((((float)(ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start))/10000.0) + (((float)(ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start))/10000.0) + (((float)(ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption - ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start))/10000.0)) - presentChargedEnergyTotal(gun_index); } ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy = presentChargedEnergyTotal(gun_index); return result; } //=============================================== // Get firmware version //=============================================== void get_firmware_version(unsigned char gun_index) { FILE *fp; char cmd[512]; char buf[512]; // Get CSU hardware version sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuHwRev, "REV.XXXXXXX"); // Get CSU boot loader version memcpy(ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev)); // Get CSU kernel version 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) { memcpy(ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, buf, strlen(buf)-1); } } // Get MCU firmware version strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW); // Get CSU root file system version //sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.63.00.0000.00"); if((ShmSysConfigAndInfo->SysConfig.ModelName[4] == '1') && (ShmSysConfigAndInfo->SysConfig.ModelName[5] == '1') && (ShmSysConfigAndInfo->SysConfig.ModelName[6] == '1')) { // AX-48 BOM VERSION: A1 sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.64.00.0000.00"); } else if((ShmSysConfigAndInfo->SysConfig.ModelName[4] == '2') && (ShmSysConfigAndInfo->SysConfig.ModelName[5] == '2') && (ShmSysConfigAndInfo->SysConfig.ModelName[6] == '1')) { // AX-32 BOM VERSION: A0 sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.64.00.0000.00"); } else if((ShmSysConfigAndInfo->SysConfig.ModelName[4] == '1') && (ShmSysConfigAndInfo->SysConfig.ModelName[5] == '9') && (ShmSysConfigAndInfo->SysConfig.ModelName[6] == '1')) { // AX-80 BOM VERSION: A0 sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.64.00.0000.00"); } else { // Unknown sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "B0.64.00.0000.00"); } // Get AC connector type from model name for(uint8_t idx=0;idx<3;idx++) { switch(ShmSysConfigAndInfo->SysConfig.ModelName[7+idx]) { case '1': // J1772 Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '4'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '4'; break; case '2': // J1772 Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '1'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '1'; break; case '3': // CE Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '5'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '5'; break; case '4': // CE Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '2'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '2'; break; case '5': // GB Plug ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '6'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '6'; break; case '6': // GB Socket ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[6] = '3'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[6] = '3'; break; } } // Get network option from model name switch(ShmSysConfigAndInfo->SysConfig.ModelName[10]) { case 'B': case 'U': //Blue tooth ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '3'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '3'; break; case 'W': // WIFI ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '1'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '1'; break; case 'T': // 3G/4G ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '2'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '2'; break; case 'D': // WIFI + 4G ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '5'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '5'; break; default: // LAN ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[9] = '0'; ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[9] = '0'; break; } // Get rating power from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[4], 0x03); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[10], &ShmSysConfigAndInfo->SysConfig.ModelName[4], 0x03); // Get vender code from model name memcpy(&ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[12], 0x02); memcpy(&ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev[14], &ShmSysConfigAndInfo->SysConfig.ModelName[12], 0x02); DEBUG_INFO("========================================\n"); DEBUG_INFO("Model: %s\n", ShmSysConfigAndInfo->SysConfig.ModelName); DEBUG_INFO("CSU hardware version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuHwRev); DEBUG_INFO("CSU boot loader version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev); DEBUG_INFO("CSU kernel version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev); DEBUG_INFO("CSU root file system version: %s\n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev); DEBUG_INFO("CSU MCU-%2d firmware version: %s\n", gun_index, ShmCharger->gun_info[gun_index].ver.Version_FW); DEBUG_INFO("========================================\n"); } //=============================================== // Upgrade firmware //=============================================== int upgrade_check() { int result = PASS; int fd; DIR *dir; struct dirent *file; char cmd[512]; long int MaxLen=48*1024*1024, ImageLen=0, wrd; if ((dir = opendir ("/mnt")) != NULL) { /* print all the files and directories within directory */ while ((file = readdir (dir)) != NULL) { if((strlen(file->d_name)>2)) { // Wait for MCU upgrade finish. while(ShmCharger->gun_info[0].mcuFlag.isMcuUpgradeReq || (AC_QUANTITY>1?ShmCharger->gun_info[1].mcuFlag.isMcuUpgradeReq:FALSE))sleep(1); // Wait for LCM upgrade finish. while(ShmCharger->isUpgradeLcmReq)sleep(1); memset(&ShmCharger->fwUpgradeInfo, 0xFF, sizeof(Fw_Upgrade_Info)); DEBUG_INFO("New firmware file: %s\n", file->d_name); sprintf(ShmCharger->fwUpgradeInfo.location, "/mnt/%s", file->d_name); if((fd=open(ShmCharger->fwUpgradeInfo.location, O_RDONLY)) >= 0) { unsigned char *ptr = malloc(MaxLen); //-48 is take out the header memset(ptr, 0xFF, MaxLen); //-48 is take out the header ImageLen = read(fd, ptr, MaxLen); close(fd); ShmCharger->fwUpgradeInfo.fwType = ((ptr[0x13]<<0) | (ptr[0x12]<<8) | (ptr[0x11]<<16) | (ptr[0x10]<<24)); substr(ShmCharger->fwUpgradeInfo.modelName, (char *)ptr, 0, 0x10); DEBUG_INFO("New firmware type: %X\n", ShmCharger->fwUpgradeInfo.fwType); DEBUG_INFO("New firmware model name: %s, %s\n", ShmCharger->fwUpgradeInfo.modelName, ShmSysConfigAndInfo->SysConfig.ModelName); if((ShmCharger->fwUpgradeInfo.modelName[0] == ShmSysConfigAndInfo->SysConfig.ModelName[0]) && (ShmCharger->fwUpgradeInfo.modelName[1] == ShmSysConfigAndInfo->SysConfig.ModelName[1]) && (ShmCharger->fwUpgradeInfo.modelName[7] == ShmSysConfigAndInfo->SysConfig.ModelName[7]) && (ShmCharger->fwUpgradeInfo.modelName[8] == ShmSysConfigAndInfo->SysConfig.ModelName[8]) && (ShmCharger->fwUpgradeInfo.modelName[9] == ShmSysConfigAndInfo->SysConfig.ModelName[9]) && (ShmCharger->fwUpgradeInfo.modelName[11] == ShmSysConfigAndInfo->SysConfig.ModelName[11]) && (ShmCharger->fwUpgradeInfo.modelName[12] == ShmSysConfigAndInfo->SysConfig.ModelName[12]) && (ShmCharger->fwUpgradeInfo.modelName[13] == ShmSysConfigAndInfo->SysConfig.ModelName[13]) && (ShmCharger->fwUpgradeInfo.fwType>0)) { switch(ShmCharger->fwUpgradeInfo.fwType) { case CSU_MLO: case CSU_BOOTLOADER: case CSU_KERNEL_CONFIGURATION: case CSU_KERNEL_IMAGE: case CSU_ROOT_FILE_SYSTEM: case CSU_USER_CONFIGURATION: case CSU_PRIMARY_CONTROLLER: if(Upgrade_Flash(ShmCharger->fwUpgradeInfo.fwType, ShmCharger->fwUpgradeInfo.location, ShmCharger->fwUpgradeInfo.modelName) != PASS) { result = FAIL; } else { if(ShmCharger->fwUpgradeInfo.fwType == CSU_USER_CONFIGURATION) { DEBUG_INFO("Restore model name & serial number.\n"); memcpy(&SysConfigOrg, &ShmSysConfigAndInfo->SysConfig, sizeof(struct SysConfigData)); if(LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-load configuration fail.\n"); result = FAIL; } else { memcpy(&ShmSysConfigAndInfo->SysConfig.ModelName, &SysConfigOrg.ModelName, ARRAY_SIZE(SysConfigOrg.ModelName)); memcpy(&ShmSysConfigAndInfo->SysConfig.SerialNumber, &SysConfigOrg.SerialNumber, ARRAY_SIZE(SysConfigOrg.SerialNumber)); memcpy(&ShmSysConfigAndInfo->SysConfig.SystemId, &SysConfigOrg.SystemId, ARRAY_SIZE(SysConfigOrg.SystemId)); if(StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-write configuration fail.\n"); result = FAIL; } else DEBUG_INFO("Re-write configuration OK.\n"); } } } sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); break; case AC_WALLMOUNT_CONTROLLER: for(int gun_index = 0;gun_indexgun_info[gun_index].mcuFlag.isMcuUpgradeReq = ON; sleep(10); break; case LCM: fd = open("/mnt/lcm.zip", O_RDWR | O_CREAT | O_EXCL); if (fd < 0) { DEBUG_ERROR("Can not create lcm.zip file.\n"); result = FAIL; } else { // Write image to flash DEBUG_INFO("Writing data to lcm.zip file...\n"); wrd=write(fd, ptr+48, ImageLen-48); close(fd); DEBUG_INFO(">> lcm.zip Written length: 0x%x\n", wrd); if(wrd != (ImageLen-48)) { result = FAIL; } else { runShellCmd("mkdir -p /mnt/lcd"); runShellCmd("unzip /mnt/lcm.zip -d /mnt/lcd"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); system("rm -f /mnt/lcm.zip"); result = PASS; } } ShmCharger->isUpgradeLcmReq = ON; sleep(10); break; default: result = FAIL; DEBUG_WARN("Image file is unknown type.\n"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); break; } } else { result = FAIL; DEBUG_ERROR("Model name and Firmware type error.\n"); sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location); system(cmd); } free(ptr); } else { result = FAIL; DEBUG_ERROR("New firmware open error.\n"); } } else { if(strlen(file->d_name) >= 3) { result = FAIL; DEBUG_ERROR("File name error.\n"); } else { DEBUG_ERROR("Searching file.\n"); } } } closedir (dir); } else { result = FAIL; DEBUG_ERROR("/mnt does not valid.\n"); } return result; } //=============================================== // Check RFID is match with start user //=============================================== int isMatchStartUser(unsigned char gun_index) { uint8_t tmpUser[32]; if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)tmpUser, "%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]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*)tmpUser, "%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*)tmpUser, "%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: default: sprintf((char*)tmpUser, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", 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_7BYTE: sprintf((char*)tmpUser, "%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*)tmpUser, "%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: default: sprintf((char*)tmpUser, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } //DEBUG_INFO("==== isMatchStartUser ==== \n"); //DEBUG_INFO("tmpUser : %s \n", tmpUser); //DEBUG_INFO("StartUserId : %s \n", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId); //DEBUG_INFO("========================== \n"); return ((strcmp((char*)tmpUser, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)==0)?YES:NO); } int isMatchPresentUser() { uint8_t tmpUser[32]; if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)tmpUser, "%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]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*)tmpUser, "%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*)tmpUser, "%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: default: sprintf((char*)tmpUser, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)tmpUser, "%02X%02X%02X%02X%02X%02X%02X%02X", 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_7BYTE: sprintf((char*)tmpUser, "%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*)tmpUser, "%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: default: sprintf((char*)tmpUser, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } //DEBUG_INFO("==== isMatchPresentUser ==== \n"); //DEBUG_INFO("tmpUser : %s \n", tmpUser); //DEBUG_INFO("UserId : %s \n", ShmSysConfigAndInfo->SysConfig.UserId); //DEBUG_INFO("============================ \n"); return ((strcmp((char*)tmpUser, (char*)ShmSysConfigAndInfo->SysConfig.UserId)==0)?YES:NO); } //=============================================== // Read RFID Serial Number //=============================================== int GetCardSerialNumber() { int isSuccess = FAIL; int module_type = MODULE_EWT; if(getRequestCardSN(rfidFd,module_type,&rfid)) { if(rfid.cardType == ISO14443A) { if(rfid.snType == RFID_SN_TYPE_4BYTE) { isSuccess = PASS; } else if (rfid.snType == RFID_SN_TYPE_7BYTE) { isSuccess = PASS; } sethaltCard(rfidFd,module_type); } else if(rfid.cardType == IS014443B) { isSuccess = PASS; } else if(rfid.cardType == FELICA) { isSuccess = PASS; } else {} } else {} return isSuccess; } //=============================================== // Set led motion //=============================================== void setLedMotion(unsigned char gun_index,unsigned char led_mode) { switch(led_mode) { case LED_ACTION_INIT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_INIT; break; case LED_ACTION_IDLE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE; break; case LED_ACTION_AUTHED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_AUTHED; break; case LED_ACTION_CONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_CONNECTED; break; case LED_ACTION_CHARGING: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_CHARGING; break; case LED_ACTION_STOP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_STOP; break; case LED_ACTION_ALARM: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_ALARM; break; case LED_ACTION_MAINTAIN: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_MAINTAIN; break; case LED_ACTION_RFID_PASS: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RFID_PASS; break; case LED_ACTION_RFID_FAIL: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RFID_FAIL; break; case LED_ACTION_BLE_CONNECT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_BLE_CONNECT; break; case LED_ACTION_BLE_DISABLE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_BLE_DISABLE; break; case LED_ACTION_DEBUG: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_DEBUG; break; case LED_ACTION_ALL_OFF: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_ALL_OFF; break; case LED_RELAY_ON: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_RELAY_ON; break; case LED_RELAY_OFF: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_RELAY_OFF; break; case LED_ACTION_HANDSHAKE_FAIL: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_HANDSHAKE_FAIL; break; case LED_ACTION_INTERNET_DISCONNECT: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_INTERNET_DISCONNECT; break; case LED_ACTION_RESTORE_SETTING: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RESTORE_SETTING; break; case LED_ACTION_IDLE_BACKEND_CONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_CONNECTED; break; case LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP; break; case LED_ACTION_IDLE_BACKEND_DISCONNECTED: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_DISCONNECTED; break; case LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP; break; case LED_ACTION_RESERVATION_MODE: ShmCharger->gun_info[gun_index].primaryMcuLed.mode = LED_ACTION_RESERVATION_MODE; break; } } //=============================================== // Request on/off set //=============================================== void setRequest(unsigned char gun_index,unsigned char isOn) { if(isOn == ON) { if(ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == OFF) { ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest = ON; DEBUG_INFO("Gun-[%d] permission request: ON \n",gun_index); } } else { if(ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest == ON) { ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest = OFF; DEBUG_INFO("Gun-[%d] permission request: OFF \n",gun_index); } } } //=============================================== // Request on/off get //=============================================== int getRequest(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest; } //=============================================== // Relay on/off set //=============================================== void setRelay(unsigned char gun_index,unsigned char isOn) { if(isOn == ON) { if(ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == OFF) { switch(ShmCharger->gun_info[gun_index].chargingMode) { case CHARGING_MODE_BS: case CHARGING_MODE_HLC: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0x01; if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) DEBUG_INFO("Gun-[%d] Output relay status: ON. [CHARGING_MODE_BS] \n",gun_index); else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) DEBUG_INFO("Gun-[%d] Output relay status: ON. [CHARGING_MODE_HLC] \n",gun_index); break; case CHARGING_MODE_SOCKETE: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] = 0x01; DEBUG_INFO("Gun-[%d] Output relay status: ON. [CHARGING_MODE_SOCKETE] \n",gun_index); break; default: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = ON; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0x01; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0x01; DEBUG_INFO("Gun-[%d] Output relay status: ON. [DEFFAULT] \n",gun_index); break; } } } else { if(ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == ON) { switch(ShmCharger->gun_info[gun_index].chargingMode) { case CHARGING_MODE_BS: case CHARGING_MODE_HLC: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0; if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) DEBUG_INFO("Gun-[%d] Output relay status: OFF. [CHARGING_MODE_BS] \n",gun_index); else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) DEBUG_INFO("Gun-[%d] Output relay status: OFF. [CHARGING_MODE_HLC] \n",gun_index); break; case CHARGING_MODE_SOCKETE: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][3] = 0; DEBUG_INFO("Gun-[%d] Output relay status: OFF. [CHARGING_MODE_SOCKETE] \n",gun_index); break; default: ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn = OFF; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][1] = 0; ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][2] = 0; DEBUG_INFO("Gun-[%d] Output relay status: OFF. [DEFFAULT] \n",gun_index); break; } } } } //=============================================== // Relay on/off get //=============================================== int getRelay(unsigned char gun_index) { return ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn; } //=============================================== // Set speaker on/off request //=============================================== void setSpeaker(unsigned char isOn, unsigned char speaker_mode) { if(isOn == ON) { ShmCharger->isSpeakerOn = ON; ShmCharger->speaker_type = speaker_mode; } } //=============================================== // Initialization RFID communication port //=============================================== int InitRfidPort() { 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; } //=============================================== // Check internet access status //=============================================== int isReachableInternet() { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; char tmp[512]; // Get ip address & net mask 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((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, tmp, strspn(tmp, "addr:"), strlen(tmp)-strspn(tmp, "addr:")); sscanf(buf, "%*s%*s%*s%s", tmp); substr((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress, tmp, strspn(tmp, "Mask:"), strlen(tmp)-strspn(tmp, "Mask:")); } } } pclose(fp); memset(buf, 0x00, sizeof(buf)); // Get gateway fp = popen("ip route", "r"); if(fp == NULL) result = FAIL; else { while(fgets(buf, sizeof(buf), fp) != NULL) { if((strstr(buf, "default") != NULL) && (strstr(buf, "eth0") != NULL)) break; } if(strstr(buf, "default") != NULL) { sscanf(buf, "%*s%*s%s", tmp); substr((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress, tmp, 0, strlen(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; } 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; } //=============================================== // Check reservation date is expired //=============================================== int isReservationExpired(unsigned char gun_index) { int result = NO; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(isOvertNow(ShmOCPP16Data->ReserveNow[gun_index].ExpiryDate)) result = YES; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(isOvertNow(ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime)) result = YES; } return result; } //=============================================== // Check charging profile related date routine //=============================================== int isProfileValid(uint8_t gun_index) { int result = NO; struct tm tmFrom, tmTo; struct timeb tbFrom, tbTo; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidFrom, "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) && (sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ValidTo, "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6)) { tmFrom.tm_year -= 1900; tmFrom.tm_mon -= 1; tbFrom.time = mktime(&tmFrom); tmTo.tm_year -= 1900; tmTo.tm_mon -= 1; tbTo.time = mktime(&tmTo); DEBUG_INFO("Valid from compare Now: %d\n", DiffTimebWithNow(tbFrom)); DEBUG_INFO("Valid to compare Now: %d\n", DiffTimebWithNow(tbTo)); if((DiffTimebWithNow(tbFrom)>=0) && (DiffTimebWithNow(tbTo)<=0)) { result = YES; } } else { DEBUG_WARN("ValidFrom or ValidTo date parsing error.\n"); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((sscanf((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validFrom, "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) && (sscanf((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].validTo, "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6)) { tmFrom.tm_year -= 1900; tmFrom.tm_mon -= 1; tbFrom.time = mktime(&tmFrom); tmTo.tm_year -= 1900; tmTo.tm_mon -= 1; tbTo.time = mktime(&tmTo); DEBUG_INFO("Valid from compare Now: %d\n", DiffTimebWithNow(tbFrom)); DEBUG_INFO("Valid to compare Now: %d\n", DiffTimebWithNow(tbTo)); if((DiffTimebWithNow(tbFrom)>=0) && (DiffTimebWithNow(tbTo)<=0)) { result = YES; } } else { DEBUG_WARN("ValidFrom or ValidTo date parsing error.\n"); } } return result; } int getMaxScheduleStart() { int result = -1; struct tm tmScheduleStart;; struct timeb tbScheduleStart; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((sscanf((char*)ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.StartSchedule, "%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; //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Max schedule start date parsing error.\n"); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((sscanf((char*)ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].startSchedule, "%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; //DEBUG_INFO("Max schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Max schedule start date parsing error.\n"); } } return result; } int getScheduleStart(int gun_index) { int result = -1; struct tm tmScheduleStart;; struct timeb tbScheduleStart; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((sscanf((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.StartSchedule, "%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; //DEBUG_INFO("Schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Schedule start date parsing error.\n"); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((sscanf((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].startSchedule, "%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; //DEBUG_INFO("Schedule start compare Now(seconds): %d\n", result); } else { DEBUG_WARN("Schedule start date parsing error.\n"); } } return result; } int getStartSinceToday() { int result = -1; time_t t; struct tm *tmStartToday; struct timeb tbStartToday; t=time(NULL); tmStartToday=localtime(&t); tmStartToday->tm_hour = 0; tmStartToday->tm_min = 0; tmStartToday->tm_sec = 0; tbStartToday.time = mktime(tmStartToday); result = DiffTimebWithNow(tbStartToday)/1000; //DEBUG_INFO("Start today compare Now(seconds): %d\n", result); return result; } int getStartSinceWeek() { int result = -1; time_t t; struct tm *tmStartWeek; struct timeb tbStartWeek; t=time(NULL); tmStartWeek=localtime(&t); t-=86400*tmStartWeek->tm_wday; tmStartWeek=localtime(&t); tmStartWeek->tm_hour = 0; tmStartWeek->tm_min = 0; tmStartWeek->tm_sec = 0; tbStartWeek.time = mktime(tmStartWeek); result = DiffTimebWithNow(tbStartWeek)/1000; //DEBUG_INFO("Start week compare Now(seconds): %d\n", result); return result; } //=============================================== // Valid from local white list //=============================================== int isValidLocalWhiteCard() { uint8_t result = FAIL; for(uint8_t idx=0;idxSysConfig.LocalWhiteCard);idx++) { if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.UserId, (char*)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[idx]) == 0) { result = PASS; } } return result; } //========================================== // Check routine //========================================== void checkTask() { if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { if(system("pidof -s Module_4g > /dev/null") != 0) { DEBUG_INFO("Module_4g not running, restart it.\n"); system("/root/Module_4g &"); } } if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D')) { if(system("pidof -s Module_Wifi > /dev/null") != 0) { DEBUG_INFO("Module_Wifi not running, restart it.\n"); system("/root/Module_Wifi &"); } } if(system("pidof -s Module_EventLogging > /dev/null") != 0) { DEBUG_INFO("Module_EventLogging not running, restart it.\n"); system("/root/Module_EventLogging &"); } if((strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0)) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if((time((time_t*)NULL) - ShmOCPP16Data->procDogTime) > 180) { DEBUG_WARN("OcppBackend watch dog timeout task restart.\n"); ShmOCPP16Data->procDogTime = time((time_t*)NULL); system("pkill OcppBackend"); sleep(3); ocpp_process_start(); } if(system("pidof -s OcppBackend > /dev/null") != 0) { DEBUG_INFO("OcppBackend not running, restart it.\n"); ocpp_process_start(); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if((time((time_t*)NULL) - ShmOCPP20Data->procDogTime) > 180) { DEBUG_WARN("OcppBackend20 watch dog timeout task restart.\n"); ShmOCPP20Data->procDogTime = time((time_t*)NULL); system("pkill OcppBackend20"); sleep(3); ocpp_process_start(); } if(system("pidof -s OcppBackend20 > /dev/null") != 0) { DEBUG_INFO("OcppBackend20 not running, restart it.\n"); ocpp_process_start(); } } } if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { if(system("pidof -s OcppBackendPH > /dev/null") != 0) { DEBUG_INFO("OcppBackendPH not running, restart it.\n"); system("/root/OcppBackendPH &"); } } if(system("pidof -s Module_AlarmDetect > /dev/null") != 0) { DEBUG_INFO("Module_AlarmDetect not running, restart it.\n"); system("/root/Module_AlarmDetect &"); } if(system("pidof -s Module_InternalComm > /dev/null") != 0) { DEBUG_INFO("Module_InternalComm not running, restart it.\n"); system("/root/Module_InternalComm &"); } if(system("pidof -s Module_Speaker > /dev/null") != 0) { DEBUG_INFO("Module_Speaker not running, restart it.\n"); system("/root/Module_Speaker &"); } if(system("pidof -s Module_ProduceUtils > /dev/null") != 0) { DEBUG_INFO("Module_ProduceUtils not running, restart it.\n"); system ("/root/Module_ProduceUtils &"); } if(system("pidof -s Module_LcmControl > /dev/null") != 0) { DEBUG_INFO("Module_LcmControl not running, restart it.\n"); system ("/root/Module_LcmControl &"); } if((system("pidof -s Module_PowerSharing > /dev/null") != 0) && ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing) { DEBUG_INFO("Module_PowerSharing not running, restart it.\n"); system ("/root/Module_PowerSharing &"); } if((system("pidof -s Module_Firewall > /dev/null") != 0) && ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade) { DEBUG_INFO("Module_Firewall not running, restart it.\n"); system ("/root/Module_Firewall &"); } if(ShmCharger->isCcsEnable == ON) { if((system("pidof -s CsuComm > /dev/null") != 0)) { if(gpio_get_value(GPIO_OUT_RST_QCA) == ON) DEBUG_INFO("CsuComm not running, restart it.\n"); system ("/root/CsuComm &"); } if((system("pidof -s SeccComm > /dev/null") != 0)) { if(gpio_get_value(GPIO_OUT_RST_QCA) == ON) DEBUG_INFO("SeccComm not running, restart it.\n"); sleep(3); system ("/root/SeccComm &"); } } } void checkConnectionTimeout() { if((system("pidof -s OcppBackend > /dev/null") != 0) && (system("pidof -s OcppBackend20 > /dev/null") != 0)) { if(ShmCharger->timeoutSpec.Present_Timeout_Spec != TIMEOUT_SPEC_HANDSHAKING) { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; DEBUG_INFO("[ConnectionTimeOut] Configuration by default: [%d] \n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } else { if(ShmCharger->timeoutSpec.Setting_Timeout_Spec != ocpp_get_connection_timeout()) { ShmCharger->timeoutSpec.Setting_Timeout_Spec = ocpp_get_connection_timeout(); DEBUG_INFO("[ConnectionTimeOut] Receive timeout specification: [%d] \n", ShmCharger->timeoutSpec.Setting_Timeout_Spec); if((ShmCharger->timeoutSpec.Setting_Timeout_Spec >= (TIMEOUT_SPEC_BS_HLC_HANDSHAKE+5)) && (ShmCharger->timeoutSpec.Setting_Timeout_Spec <= 3600)) { DEBUG_INFO("[ConnectionTimeOut] Valid value: [%d] \n", ShmCharger->timeoutSpec.Setting_Timeout_Spec); } else { DEBUG_INFO("[ConnectionTimeOut] Invalid value: [%d] \n", ShmCharger->timeoutSpec.Setting_Timeout_Spec); DEBUG_INFO("[ConnectionTimeOut] Present timeout specification: [%d] \n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } // Connection timeout minimum: 30 seconds / maximum: 3600 seconds if((ShmCharger->timeoutSpec.Setting_Timeout_Spec >= (TIMEOUT_SPEC_BS_HLC_HANDSHAKE+5)) && (ShmCharger->timeoutSpec.Setting_Timeout_Spec <= 3600)) { if(ShmCharger->timeoutSpec.Setting_Timeout_Spec != ShmCharger->timeoutSpec.Present_Timeout_Spec) { ShmCharger->timeoutSpec.Present_Timeout_Spec = ShmCharger->timeoutSpec.Setting_Timeout_Spec; DEBUG_INFO("[ConnectionTimeOut] Configuration by OCPP: [%d] \n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } else { if(ShmCharger->timeoutSpec.Present_Timeout_Spec != TIMEOUT_SPEC_HANDSHAKING) { ShmCharger->timeoutSpec.Present_Timeout_Spec = TIMEOUT_SPEC_HANDSHAKING; DEBUG_INFO("[ConnectionTimeOut] Configuration by default: [%d] \n", ShmCharger->timeoutSpec.Present_Timeout_Spec); } } } } void checkAuthorizeTimeout() { if((system("pidof -s OcppBackend > /dev/null") != 0) && (system("pidof -s OcppBackend20 > /dev/null") != 0)) { if(ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec != TIMEOUT_SPEC_AUTH) { ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec = TIMEOUT_SPEC_AUTH; DEBUG_INFO("[AuthorizeTimeout] Configuration by default: [%d] \n", ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec); } } else { if(ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec != ocpp_get_authorize_timeout()) { ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec = ocpp_get_authorize_timeout(); DEBUG_INFO("[AuthorizeTimeout] Receive timeout specification: [%d] \n", ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec); if((ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec >= 10) && (ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec <= 300)) { DEBUG_INFO("[AuthorizeTimeout] Valid value: [%d] \n", ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec); } else { DEBUG_INFO("[AuthorizeTimeout] Invalid value: [%d] \n", ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec); DEBUG_INFO("[AuthorizeTimeout] Present timeout specification: [%d] \n", ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec); } } // Authorize timeout minimum: 10 seconds / maximum: 300 seconds if((ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec >= 10) && (ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec <= 300)) { if(ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec != ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec) { ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec = ShmCharger->timeoutSpec.Setting_Authorize_Timeout_Spec; DEBUG_INFO("[AuthorizeTimeout] Configuration by OCPP: [%d] \n", ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec); } } else { if(ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec != TIMEOUT_SPEC_AUTH) { ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec = TIMEOUT_SPEC_AUTH; DEBUG_INFO("[AuthorizeTimeout] Configuration by default: [%d] \n", ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec); } } } } void checkReset() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->MsMsg.bits.ResetReq) { if((!isMode(0, SYS_MODE_CHARGING) && !isMode(0, SYS_MODE_TERMINATING) && !isMode(0, SYS_MODE_COMPLETE)) && (AC_QUANTITY>1?(!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING) && !isMode(1, SYS_MODE_COMPLETE)):TRUE)) { ShmOCPP16Data->MsMsg.bits.ResetReq = OFF; sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted"); ShmOCPP16Data->MsMsg.bits.ResetConf = ON; DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP16Data->Reset.Type); for(int gun_index = 0;gun_indexReset.Type, "Hard") == 0) { system("sync"); sleep(10); system("reboot -f"); sleep(10); system("reboot -f"); } else { sleep(10); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->MsMsg.bits.ResetReq) { if((!isMode(0, SYS_MODE_CHARGING) && !isMode(0, SYS_MODE_TERMINATING) && !isMode(0, SYS_MODE_COMPLETE)) && (AC_QUANTITY>1?(!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING) && !isMode(1, SYS_MODE_COMPLETE)):TRUE)) { ShmOCPP20Data->MsMsg.bits.ResetReq = OFF; sprintf((char*)ShmOCPP20Data->Reset.Response_status, "Accepted"); ShmOCPP20Data->MsMsg.bits.ResetConf = ON; DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP20Data->Reset.type); for(int gun_index = 0;gun_indexReset.type, "Immediate") == 0) { system("sync"); sleep(10); system("reboot -f"); sleep(10); system("reboot -f"); } else { sleep(10); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } } } void checkReservation(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq) { ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq = OFF; ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON; if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { sleep(5); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP16Data->ReserveNow[gun_index].ReservationId; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on gun-%d.\n", gun_index); } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq) { ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq = OFF; ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = ON; if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP20Data->ReserveNow[gun_index].id; setChargerMode(gun_index, SYS_MODE_RESERVATION); } DEBUG_INFO("Reservation request on gun-%d.\n", gun_index); } } } void checkUnlocker(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].UnlockConnectorReq == ON) { ShmOCPP16Data->CsMsg.bits[gun_index].UnlockConnectorReq = OFF; if(ShmSysConfigAndInfo->SysConfig.ModelName[9-gun_index] == '4') { sprintf((char*)ShmOCPP16Data->UnlockConnector[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].ResponseStatus, "Unlocked"); ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor = ON; } else { sprintf((char*)ShmOCPP16Data->UnlockConnector[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].ResponseStatus, "NotSupported"); ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor = OFF; } ShmOCPP16Data->CsMsg.bits[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].UnlockConnectorConf = ON; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorReq == ON) { ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorReq = OFF; if(ShmSysConfigAndInfo->SysConfig.ModelName[9-gun_index] == '4') { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_CHARGING) { sprintf((char*)ShmOCPP20Data->UnlockConnector[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].Response_status, "OngoingAuthorizedTransaction"); ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor = OFF; } else { sprintf((char*)ShmOCPP20Data->UnlockConnector[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].Response_status, "Unlocked"); ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor = ON; } } else { sprintf((char*)ShmOCPP20Data->UnlockConnector[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].Response_status, "UnlockFailed"); ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor = OFF; } ShmOCPP20Data->CsMsg.bits[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].UnlockConnectorConf = ON; } } } void checkAvailability(uint8_t gun_index) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq) { if(strcmp((char*)ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Operative") == 0) { DB_Update_Operactive(localDb, gun_index, true); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } else { DB_Update_Operactive(localDb, gun_index, false); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = OFF; } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq) { if(strcmp((char*)ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Operative") == 0) { DB_Update_Operactive(localDb, gun_index, true); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } else { DB_Update_Operactive(localDb, gun_index, false); ShmCharger->gun_info[gun_index].isOperactive = DB_Get_Operactive(localDb, gun_index); } ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = OFF; } } } void checkChargingProfileLimit(uint8_t gun_index, uint8_t system_mode) { uint16_t MaxChargingProfileChargingCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { // Get profile charging profile limit if((ocpp_get_smartcharging_profileId(gun_index) > 0)) { // Checking profile kind if((mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingProfileKind, "Absolute") == PASS)) { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++) { if((getScheduleStart(gun_index) >= ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && ((idx_period == 0) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0)) ) { ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } else { ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; } // Get max charging profile limit if((ocpp_get_maxcharging_profileId() > 0)) { // Absolute profile if((mystrcmp((char*)ShmOCPP16Data->MaxChargingProfile.ChargingProfileKind, "Absolute") == PASS)) { for(uint8_t idx_period=0;idx_periodMaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod);idx_period++) { if((getMaxScheduleStart() >= ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod) && ((idx_period == 0) || (ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0)) ) { MaxChargingProfileChargingCurrent = (mystrcmp((char*)ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->MaxChargingProfile.ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } // Compare target current is over max current for EVSE limit if(gun_index == 0) { if(ShmCharger->gun_info[gun_index].targetCurrent > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = MaxChargingProfileChargingCurrent; } } else { if((ShmCharger->gun_info[gun_index-1].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = (MaxChargingProfileChargingCurrent - ShmCharger->gun_info[gun_index-1].targetCurrent); } } } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { // Get profile charging profile limit if((ocpp_get_smartcharging_profileId(gun_index) > 0)) { // Checking profile kind if((mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfileKind, "Absolute") == PASS)) { // Checking limitation for(uint8_t idx_period=0;idx_periodSmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod);idx_period++) { if((getScheduleStart(gun_index) >= ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) && ((idx_period == 0) || (ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0)) ) { ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } else { ShmCharger->gun_info[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; } // Get max charging profile limit if((ocpp_get_maxcharging_profileId() > 0)) { // Absolute profile if((mystrcmp((char*)ShmOCPP20Data->MaxChargingProfile.chargingProfileKind, "Absolute") == PASS)) { // Checking limitation for(uint8_t idx_period=0;idx_periodMaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod);idx_period++) { if((getMaxScheduleStart() >= ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) && ((idx_period == 0) || (ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0)) ) { MaxChargingProfileChargingCurrent = (mystrcmp((char*)ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->MaxChargingProfile.chargingSchedule[0].chargingSchedulePeriod[idx_period].limit); //DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent); } else break; } } } // Compare target current is over max current for EVSE limit if(gun_index == 0) { if(ShmCharger->gun_info[gun_index].targetCurrent > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = MaxChargingProfileChargingCurrent; } } else { if((ShmCharger->gun_info[gun_index-1].targetCurrent + ShmCharger->gun_info[gun_index].targetCurrent) > MaxChargingProfileChargingCurrent) { ShmCharger->gun_info[gun_index].targetCurrent = (MaxChargingProfileChargingCurrent - ShmCharger->gun_info[gun_index-1].targetCurrent); } } } // Charging session target current check if OCPP disconnect and power sharing server connected if(ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing > 0) { if(ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer) ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent[gun_index]>ShmCharger->gun_info[gun_index].primaryMcuState.rating_current?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent[gun_index]; else { if(ShmCharger->gun_info[gun_index].targetCurrent != 0) DEBUG_WARN("Disconnect from power sharing server, target current set to 0.\n"); ShmCharger->gun_info[gun_index].targetCurrent = 0; } } switch(system_mode) { case SYS_MODE_IDLE: if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->isCcsEnable) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->isCcsEnable) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; } else { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); } } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; break; case SYS_MODE_PREPARING: if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; break; case SYS_MODE_CHARGING: case SYS_MODE_TERMINATING: if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if((ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) || (ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current)) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { if(getDiffSecNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].targetCurrent = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)?6:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float)ShmCharger->gun_info[gun_index].targetCurrent; //ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float)((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); } } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); if((ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) || (ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current)) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { if(getDiffSecNow(startTime[gun_index][TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)? 6:((ShmCharger->gun_info[gun_index].targetCurrent == 0)? 100:ShmCharger->gun_info[gun_index].targetCurrent)); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); } } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].targetCurrent = ((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent <= 5)?6:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float)ShmCharger->gun_info[gun_index].targetCurrent; //ShmCharger->gun_info[gun_index].acCcsInfo.EVSEMaxCurrent = (float)((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); } } } if(previousData[gun_index].primaryMcuCp_Pwn_Duty != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("gun-[%d] primaryMcuCp_Pwn_Duty: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("==================================================\n"); previousData[gun_index].primaryMcuCp_Pwn_Duty = ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current; } if(ShmCharger->gun_info[gun_index].targetCurrent != previousData[gun_index].targetCurrent) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("gun-[%d] targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent); DEBUG_INFO("MaxChargingCurrent: %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); DEBUG_INFO("==================================================\n"); previousData[gun_index].targetCurrent = ShmCharger->gun_info[gun_index].targetCurrent; } if(ShmCharger->gun_info[gun_index].primaryMcuState.current_limit != previousData[gun_index].current_limit) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("gun-[%d] mcu current_limit: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.current_limit); DEBUG_INFO("==================================================\n"); previousData[gun_index].current_limit = ShmCharger->gun_info[gun_index].primaryMcuState.current_limit; } break; } } void checkStopReason(uint8_t gun_index) { sleep(2); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { memset(ShmOCPP16Data->StopTransaction[gun_index].IdTag, 0x00, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); if(!ocpp_get_starttransaction_result(gun_index)) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "DeAuthorized"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EmergencyStop"); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) && (strstr((char*)ShmOCPP16Data->ConfigurationTable.CoreProfile[StopTransactionOnEVSideDisconnect].ItemData, "TRUE") != NULL)) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "EVDisconnected"); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); //memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmOCPP16Data->StartTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else if(ShmOCPP16Data->MsMsg.bits.ResetReq) { if(strcmp((char*)ShmOCPP16Data->Reset.Type, "Hard")==0) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "HardReset"); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "SoftReset"); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } } else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Local"); if(!isMatchStartUser(gun_index)) { memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else { memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } DEBUG_INFO("Gun-[%d] : IdTag [ %s ].\n", gun_index, ShmOCPP16Data->StopTransaction[gun_index].IdTag); } else if(ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStopTransactionReq) { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Remote"); memcpy((char*)ShmOCPP16Data->StopTransaction[gun_index].IdTag, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); } else if(ShmCharger->gun_info[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].isUnlockerConnetor == ON) { sprintf((char*)ShmOCPP16Data->StopTransaction[ShmOCPP16Data->UnlockConnector[gun_index].ConnectorId-1].StopReason, "UnlockCommand"); } else { sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other"); } DEBUG_INFO("Gun-[%d] : StopReason [ %s ].\n",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); presentChargedEnergyUpdate(gun_index); DEBUG_INFO("Gun-[%d] : PresentChargedEnergy [ %.4f ].\n",gun_index ,ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy); ShmOCPP16Data->CpMsg.bits[gun_index].StopTransactionReq = ON; } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { memset(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken)); if(!ocpp_get_starttransaction_result(gun_index)) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "DeAuthorized"); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_EMERGENCY_STOP) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "EmergencyStop"); memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "EVDisconnected"); memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_GROUND_FAIL) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "GroundFault"); } else if((ShmOCPP20Data->MsMsg.bits.ResetReq) && (strcmp((char*)ShmOCPP20Data->Reset.type, "Immediate")==0)) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "ImmediateReset"); memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } else if(ShmCharger->gun_info[gun_index].rfidReq || ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Local"); if(!isMatchStartUser(gun_index)) { memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken)); } else { memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } DEBUG_INFO("Gun-[%d] : idToken [ %s ].\n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken); } else if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L1_OVER_CURRENT) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L2_OVER_CURRENT) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_L3_OVER_CURRENT)) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "OvercurrentFault"); } else if(ShmOCPP20Data->CsMsg.bits[gun_index].RequestStopTransactionReq) { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Remote"); memcpy((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, (char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); } else if(ShmCharger->gun_info[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].isUnlockerConnetor == ON) { sprintf((char*)ShmOCPP20Data->TransactionEvent[ShmOCPP20Data->UnlockConnector[gun_index].connectorId-1].transactionInfo.stoppedReason, "UnlockCommand"); } else { sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Other"); } DEBUG_INFO("Gun-[%d] : StopReason [ %s ].\n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); presentChargedEnergyUpdate(gun_index); DEBUG_INFO("Gun-[%d] : PresentChargedEnergy [ %.4f ].\n",gun_index ,ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy); ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON; } // Maintain server if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) { memcpy(ShmOCPP16DataPH->StopTransaction[gun_index].StopReason, ShmOCPP16Data->StopTransaction[gun_index].StopReason, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].StopReason)); memcpy(ShmOCPP16DataPH->StopTransaction[gun_index].IdTag, ShmOCPP16Data->StopTransaction[gun_index].IdTag, ARRAY_SIZE(ShmOCPP16Data->StopTransaction[gun_index].IdTag)); ShmOCPP16DataPH->CpMsg.bits[gun_index].StopTransactionReq = ON; } } void checkRemoteUpgradeStatus() { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { if(strcmp((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "DownloadFailed")==0) { DEBUG_INFO("Firmware remote upgraded fail...\n"); ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF; ShmCharger->isUpdateSuccess = NO; } else if((strcmp((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded")==0)) { DEBUG_INFO("Firmware remote upgrading...\n"); sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); sleep(1); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF; int result = upgrade_check(); DEBUG_INFO("Remote update Result: %s... \n",((result == PASS)?"Pass": "Fail")); if(result == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success...\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update unsuccess...\n"); } } else if((strcmp((char*)ShmOCPP16Data->SignedFirmwareStatusNotification.status, "SignatureVerified")==0)) { DEBUG_INFO("Signature firmware remote upgrading...\n"); ShmOCPP16Data->SignedFirmwareStatusNotification.requestId = ShmOCPP16Data->SignedUpdateFirmware.requestId; sprintf((char*)ShmOCPP16Data->SignedFirmwareStatusNotification.status, "Installing"); sleep(1); ShmOCPP16Data->SpMsg.bits.SignedFirmwareStatusNotificationReq = ON; ShmOCPP16Data->MsMsg.bits.SignedUpdateFirmwareReq = OFF; if(upgrade_check() == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success.\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update fail.\n"); } } else {} } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { if(strcmp((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "DownloadFailed")==0) { DEBUG_INFO("Firmware remote upgraded fail...\n"); ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = OFF; ShmCharger->isUpdateSuccess = NO; } else if((strcmp((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "Downloaded")==0)) { DEBUG_INFO("Firmware remote upgrading...\n"); sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = OFF; int result = upgrade_check(); DEBUG_INFO("Remote update Result: %s... \n",((result == PASS)?"Pass": "Fail")); if(result == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Remote update success...\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Remote update unsuccess...\n"); } } else {} } } void checkHandshakeCountdown(uint8_t gun_index) { switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_IDLE: if(ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); else ShmCharger->timeoutSpec.Handshake_Timeout = (ShmCharger->timeoutSpec.Present_Timeout_Spec - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); if(!ShmCharger->isAuthrizing) { if(ocpp_get_isRemoteStartWait()) ShmCharger->timeoutSpec.Handshake_Timeout = (ShmCharger->timeoutSpec.Present_Timeout_Spec - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); else refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); } break; case SYS_MODE_PREPARING: if(ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); else ShmCharger->timeoutSpec.Handshake_Timeout = (ShmCharger->timeoutSpec.Present_Timeout_Spec - getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING])); break; case SYS_MODE_RESERVATION: if(ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); else ShmCharger->timeoutSpec.Handshake_Timeout = (ShmCharger->timeoutSpec.Present_Timeout_Spec - (getDiffSecNow(startTime[0][TMR_IDX_GUN_DETECT]))); break; } } void checkRfidAuthrize() { static uint8_t isCheckdResult = FALSE; static uint8_t isReadable = TRUE; static uint8_t lastIdtag[ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)]; uint8_t isStartByWrongReservation = NO; if(!ShmCharger->isAuthrizing) { // Read RFID if(GetCardSerialNumber() != FAIL) { if(isReadable == TRUE) { uint8_t isSnStart = FALSE; uint8_t bufferRFID[ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)]; if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian) { // Big endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)bufferRFID, "%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]); break; case RFID_SN_TYPE_7BYTE: sprintf((char*)bufferRFID, "%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*)bufferRFID, "%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: default: sprintf((char*)bufferRFID, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else { // Little endian switch(rfid.snType) { case RFID_SN_TYPE_8BYTE: sprintf((char*)bufferRFID, "%02X%02X%02X%02X%02X%02X%02X%02X", 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_7BYTE: sprintf((char*)bufferRFID, "%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*)bufferRFID, "%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: default: sprintf((char*)bufferRFID, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } DEBUG_INFO("Authorize request User Id : %s\n", bufferRFID); //DEBUG_INFO("Authorize request User Id : %s\n", ShmSysConfigAndInfo->SysConfig.UserId); for(int gun_index = 0;gun_indexgun_info[gun_index].resultAuthorization = UNKNOW_RFID; // Check SN already start for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING))) { DEBUG_INFO("%s running on connector-%02d.\n", ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, gun_index); isSnStart = TRUE; ShmCharger->gun_info[gun_index].rfidReq = ON; ocpp_set_auth_conf(ON); setLedMotion(gun_index,LED_ACTION_RFID_PASS); setSpeaker(ON, SPEAKER_SHORT); sleep(3); break; } } // Request authorize if isSnStart is false if(!isSnStart) { memcpy(lastIdtag, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); memcpy(ShmSysConfigAndInfo->SysConfig.UserId, bufferRFID, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); refreshStartTimer(&startTime[0][TMR_IDX_AUTH]); ocpp_set_auth_req(ON, "ISO14443"); setLedMotion(0,LED_ACTION_AUTHED); ShmCharger->isAuthrizing = TRUE; ShmCharger->isGetAuthResult = FALSE; isCheckdResult = FALSE; } isReadable = FALSE; } } else { isReadable = TRUE; } } else { // Wait authorize result if(!ocpp_get_auth_conf() && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec)) { // Authorization timeout process. DEBUG_WARN("Authorize timeout !!!\n"); for(int gun_index = 0;gun_indexgun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; setLedMotion(gun_index,LED_ACTION_RFID_FAIL); } setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); sleep(3); ShmCharger->isAuthrizing = FALSE; } else { if(ocpp_get_auth_conf() || (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > 2)) ) { if(ocpp_get_auth_result(NO) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST))) { if(!isCheckdResult) { refreshStartTimer(&startTime[0][TMR_IDX_GUN_DETECT]); ShmCharger->isGetAuthResult = TRUE; isCheckdResult = TRUE; if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0) { ocpp_set_auth_conf(ON); } for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_RESERVATION) && (ocpp_compare_reserve_id_with_user(gun_index) != YES) && (ocpp_get_auth_result(YES, gun_index) != PASS)) { isStartByWrongReservation = YES; ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; DEBUG_INFO("================================================== \n"); DEBUG_INFO("UserId: [ %s ]\n", ShmSysConfigAndInfo->SysConfig.UserId); if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { DEBUG_INFO("Gun-%d IdTag: [ %s ]\n", gun_index, ShmOCPP16Data->ReserveNow[gun_index].IdTag); DEBUG_INFO("Authorize response ParentIdTag: [ %s ]. \n", ShmOCPP16Data->Authorize.ResponseIdTagInfo.ParentIdTag); DEBUG_INFO("Gun-%d Reserve ParentIdTag: [ %s ]. \n", gun_index, ShmOCPP16Data->ReserveNow[gun_index].ParentIdTag); } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { DEBUG_INFO("Gun-%d idToken: [ %s ]\n", gun_index, ShmOCPP20Data->ReserveNow[gun_index].idToken.idToken); DEBUG_INFO("Authorize response groupIdToken idToken: [ %s ]\n", ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken); DEBUG_INFO("Gun-%d Reserve groupIdToken idToken: [ %s]\n", ShmOCPP20Data->ReserveNow[gun_index].groupIdToken.idToken); } DEBUG_INFO("================================================== \n"); DEBUG_INFO("Authorize fail.\n"); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); } else { ShmCharger->gun_info[gun_index].resultAuthorization = VALIDATED_RFID; DEBUG_INFO("Authorize pass.\n"); setSpeaker(ON, SPEAKER_SHORT); } } } // Check handshake timeout for(int gun_index = 0;gun_indextimeoutSpec.Present_Timeout_Spec) && (isStartByWrongReservation != YES)) { if(GetCardSerialNumber() != FAIL) { if(isReadable == TRUE) { if(isMatchPresentUser()) { DEBUG_INFO("Cancel present user.\n"); for(int gun_index = 0;gun_indexgun_info[gun_index].resultAuthorization = DEFAULT_RFID; if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING) ShmCharger->gun_info[gun_index].rfidReq = ON; } setSpeaker(ON, SPEAKER_SHORT); ShmCharger->isAuthrizing = FALSE; } isReadable = FALSE; } } else { for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_RESERVATION)) && (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) || (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) || (modelnameInfo.GetGunCount == 1))) || ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING) && (ShmCharger->gun_selectd == gun_index)) || (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_TERMINATING)) && (ShmCharger->gun_selectd == gun_index)) ) { DEBUG_INFO("Connector-%02d action detect.\n", gun_index); ShmCharger->isAuthrizing = FALSE; ShmCharger->gun_info[gun_index].rfidReq = ON; break; } } isReadable = TRUE; } } else { if(isStartByWrongReservation != YES) DEBUG_INFO("Connector action detect timeout.\n"); else DEBUG_INFO("Start by wrong reservation user. \n"); ShmCharger->isAuthrizing = FALSE; ShmCharger->isGetAuthResult = TRUE; for(int gun_index = 0;gun_indexgun_info[gun_index].resultAuthorization = DEFAULT_RFID; } } } else { DEBUG_INFO("Authorize fail.\n"); ShmCharger->isAuthrizing = FALSE; ShmCharger->isGetAuthResult = TRUE; for(int gun_index = 0;gun_indexgun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; setLedMotion(gun_index,LED_ACTION_RFID_FAIL); } setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); sleep(3); for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING)) setLedMotion(gun_index,LED_ACTION_AUTHED); else setLedMotion(gun_index,LED_ACTION_IDLE); if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING) && (ShmCharger->gun_selectd == gun_index)) { switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod) { case START_METHOD_BACKEND: ocpp_copy_userid_from_remotestart(gun_index); break; default: memcpy(ShmSysConfigAndInfo->SysConfig.UserId, lastIdtag, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("==========================================\n"); DEBUG_INFO("Copy lastIdtag into UserId. \n"); DEBUG_INFO("lastIdtag : [%s] ---> UserId : [%s] . \n", lastIdtag, ShmSysConfigAndInfo->SysConfig.UserId); DEBUG_INFO("==========================================\n"); break; } } } } } } } } void setPtbMeterPermission(uint8_t gun_index, uint8_t permission) { switch(permission) { case PREMISSION_DEFAULT: // Changed permission to [Default] ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = PREMISSION_DEFAULT; DEBUG_INFO("Set PTB meter permission to [ PREMISSION_DEFAULT ] \n"); break; case PERMISSION_START_CHARGING: // Changed permission to [Start Charging] if((ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus != PERMISSION_START_CHARGING) && (ShmCharger->gun_info[gun_index].isSetPtbMeterPermisson != ON)) { ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = PERMISSION_START_CHARGING; ShmCharger->gun_info[gun_index].isSetPtbMeterPermisson = ON; DEBUG_INFO("Set PTB meter permission to [ PERMISSION_START_CHARGING ] \n"); DB_Update_Meter_Permission(localDb, gun_index, PERMISSION_START_CHARGING); } break; case PERMISSION_END_CHARGING: // Changed permission to [End Charging] if((ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus != PERMISSION_END_CHARGING) && (ShmCharger->gun_info[gun_index].isSetPtbMeterPermisson != ON)) { ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = PERMISSION_END_CHARGING; ShmCharger->gun_info[gun_index].isSetPtbMeterPermisson = ON; DEBUG_INFO("Set PTB meter permission to [ PERMISSION_END_CHARGING ] \n"); DB_Update_Meter_Permission(localDb, gun_index, PERMISSION_END_CHARGING); } break; } } void processEndOfChargingForPtbMeter(uint8_t gun_index) { if(getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]) >= 12) { if((ocpp_set_ocmf_data_transfer(gun_index) == YES)) { checkStopReason(gun_index); if(ShmOCPP16Data->OcmfData[gun_index].SendOcmfDataReq != ON) ShmOCPP16Data->OcmfData[gun_index].SendOcmfDataReq = ON; ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad = YES; setChargerMode(gun_index, SYS_MODE_COMPLETE); } else { checkStopReason(gun_index); ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad = NO; setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else { setPtbMeterPermission(gun_index, PERMISSION_END_CHARGING); if((getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]) >= 6) && (getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]) <= 9)) { ShmCharger->gun_info[gun_index].isGetPtbMeterMessage = ON; // After 6 seconds Relay off & PWM off (specifcation) setRelay(gun_index, OFF); setRequest(gun_index, OFF); } } } void checkMissingPtbMeterMessage(uint8_t gun_index) { if((ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus == PERMISSION_START_CHARGING)) { // Trigger get PTB meter message if((getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_SEND]) > 0) && (getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_SEND]) <= 5)) { ShmCharger->gun_info[gun_index].isGetPtbMeterMessage = ON; } // 5 seconds for MCU & PTB communcation + 5 seconds for CSU & MCU get PTB messages. if((getDiffSecNow(startTime[gun_index][TMR_IDX_PTB_METER_SEND]) >= 12)) { if((ShmCharger->gun_info[gun_index].isGetPtbMeterMessage != ON)) { if((ocpp_set_ocmf_data_transfer(gun_index) == YES)) { if(ShmOCPP16Data->OcmfData[gun_index].SendOcmfDataReq != ON) ShmOCPP16Data->OcmfData[gun_index].SendOcmfDataReq = ON; ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad = YES; ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = PERMISSION_END_CHARGING; DB_Update_Meter_Permission(localDb, gun_index, PERMISSION_END_CHARGING); DB_Insert_Record(localDb, gun_index); DEBUG_INFO("Meter data send to the backend system. \n"); } else { ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.isUpLoad = NO; ShmCharger->gun_info[gun_index].Ptb_Meter_Parameters.PtbMeterPermissionStatus = PERMISSION_END_CHARGING; DB_Update_Meter_Permission(localDb, gun_index, PERMISSION_END_CHARGING); DEBUG_INFO("No data to send. \n"); } } else {} } else {} } else { refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_SEND]); } } void checkConnectorStatus(uint8_t gun_index) { if((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC)) { if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)) { if(ShmCharger->gun_info[gun_index].isGunUnpluggedBefore != YES) { ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = YES; switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_CHARGING: DEBUG_INFO("Gun-[%d] is unplugged under: [CHARGING].\n", gun_index); break; case SYS_MODE_TERMINATING: DEBUG_INFO("Gun-[%d] is unplugged under: [TERMINATING].\n", gun_index); break; case SYS_MODE_COMPLETE: DEBUG_INFO("Gun-[%d] is unplugged under: [COMPLETE].\n", gun_index); break; case SYS_MODE_ALARM: DEBUG_INFO("Gun-[%d] is unplugged under: [ALARM].\n", gun_index); break; } } } } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn != ON) { if(ShmCharger->gun_info[gun_index].isGunUnpluggedBefore != YES) { ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = YES; switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_CHARGING: DEBUG_INFO("Socket_e-[%d] is unplugged under: [CHARGING].\n", gun_index); break; case SYS_MODE_TERMINATING: DEBUG_INFO("Socket_e-[%d] is unplugged under: [TERMINATING].\n", gun_index); break; case SYS_MODE_COMPLETE: DEBUG_INFO("Socket_e-[%d] is unplugged under: [COMPLETE].\n", gun_index); break; case SYS_MODE_ALARM: DEBUG_INFO("Socket_e-[%d] is unplugged under: [ALARM].\n", gun_index); break; } } } } else {} } void checkEnable15118() { if(ShmSysConfigAndInfo->SysConfig.isEnable15118 != ShmCharger->isCcsEnable) { if(ShmSysConfigAndInfo->SysConfig.isEnable15118 == ON) { if(ShmCharger->isCcsEnable != ON) { ShmCharger->isCcsEnable = ShmSysConfigAndInfo->SysConfig.isEnable15118; if(gpio_get_value(GPIO_OUT_RST_QCA) != ON) system("echo 1 > /sys/class/gpio/gpio115/value"); } } else { if(ShmCharger->isCcsEnable != OFF) { ShmCharger->isCcsEnable = ShmSysConfigAndInfo->SysConfig.isEnable15118; if(gpio_get_value(GPIO_OUT_RST_QCA) != OFF) system("echo 0 > /sys/class/gpio/gpio115/value"); } } DEBUG_INFO("======================================== \n"); DEBUG_INFO("isCcsEnable status: [%s] \n",(ShmCharger->isCcsEnable == ON? "ON":"OFF")); DEBUG_INFO("isEnable15118 status: [%s] \n", (ShmSysConfigAndInfo->SysConfig.isEnable15118 == ON? "ON":"OFF")); DEBUG_INFO("GPIO_115 status: [%s] \n", (gpio_get_value(GPIO_OUT_RST_QCA) == ON? "ON":"OFF")); DEBUG_INFO("======================================== \n"); } } //====================================================== // Main process //====================================================== int main(void) { //================================================== // Create all share memory //================================================== if(CreatShareMemory()==0) { DEBUG_ERROR("CreatShareMemory NG\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { DEBUG_INFO("CreatShareMemory OK\n"); } for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].PreviousSystemStatus = 0xff; ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch = 0xff; ShmCharger->gun_info[gun_index].mcuResetRequest.isMcuResetRequest = ON; ShmCharger->gun_info[gun_index].isSetBreatheLedTiming = OFF; ShmCharger->gun_info[gun_index].isSetLedBrightness = OFF; } //================================================== // Main loop //================================================== for(;;) { //============================================== // Synchronize share memory from OCPP struct //============================================== ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status(); //============================================== // Period check for 10 seconds //============================================== if((getDiffSecNow(startTime[0][TMR_IDX_CHECK_TASK]) > 10) || (getDiffSecNow(startTime[0][TMR_IDX_CHECK_TASK]) < 0)) { //============================================== // Check task processing //============================================== if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING) { // Check task processing checkTask(); // Check connection timeout specification checkConnectionTimeout(); // Check authorize timeout specification checkAuthorizeTimeout(); // Check is Enable 15118 checkEnable15118(); } refreshStartTimer(&startTime[0][TMR_IDX_CHECK_TASK]); } //============================================== // Something need run in Idle mode //============================================== if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_DEBUG)) && (AC_QUANTITY>1?((ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_DEBUG)):true)) { // Check restore factory setting request if(ShmSysConfigAndInfo->SysInfo.FactoryConfiguration) { // Set led to initial for(int gun_index = 0;gun_indexSysInfo.FirmwareUpdate || ocpp_get_update_firmware_req()) { // If available memory too small, free memory cache first if(getAvailableMemory() < (200*1024*1024)) { DEBUG_INFO("Available memory (%.2f Bytes) less than 200 MBytes, free cache first.\n", getAvailableMemory()/(1024*1024.0)); system("echo 3 > /proc/sys/vm/drop_caches"); } ShmCharger->isUpdateSuccess = NO; for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_UPDATE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE)) { } else { checkRfidAuthrize(); } } //============================================== // Check Local Power Sharing Communication //============================================== if(ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing > 0) { if(ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer) { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LocalPowerSharingCommunicationError == ON) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LocalPowerSharingCommunicationError = OFF; } else { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LocalPowerSharingCommunicationError == OFF) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LocalPowerSharingCommunicationError = ON; } } //============================================== // Connector loop //============================================== for(int gun_index = 0;gun_indexSysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == OFF)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]); } if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_UPDATE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_TERMINATING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_RESERVATION)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]); } else { if((ShmCharger->gun_info[ShmCharger->gun_selectd].isHandshakeTimerRefresh == YES) || (gpio_get_value(GPIO_IN_WAKEUP) == OFF) || (ShmCharger->gun_info[gun_index].GPIO_Input.Button_Mode_Switch == ON) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus != ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) || (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_RESERVATION)) && ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) || (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON)) && (getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]) < 10))) { refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]); if(((gpio_get_value(GPIO_IN_WAKEUP) == OFF) || (ShmCharger->gun_info[gun_index].GPIO_Input.Button_Mode_Switch == ON)) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) && (getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_CHECK_POWER_CONSUMPTION]) > TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION)) { ShmCharger->gun_info[gun_index].isCheckPowerConsumption = YES; refreshStartTimer(&startTime[gun_index][TMR_IDX_LCM_POWER_CONSUMPTION]); } } else { refreshStartTimer(&startTime[gun_index][TMR_IDX_CHECK_POWER_CONSUMPTION]); if((getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_LCM_POWER_CONSUMPTION]) > TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION)) { ShmCharger->gun_info[gun_index].isCheckPowerConsumption = NO; } } } if(getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD]) > TIMEOUT_SPEC_POWERSAVING_LCD) { if(ShmCharger->isLcdOn == ON) { DEBUG_INFO("LCD into power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD])); ShmCharger->isLcdOn = OFF; } } else { if(ShmCharger->isLcdOn == OFF) { DEBUG_INFO("LCD exit power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LCD])); ShmCharger->isLcdOn = ON; } } if(getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_POWERSAVING_RFID]) > TIMEOUT_SPEC_POWERSAVING_RFID) { if(gpio_get_value(GPIO_OUT_RST_RFID) == ON) { DEBUG_INFO("RFID into power saving...%d\n", getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_POWERSAVING_RFID])); gpio_set_value(GPIO_OUT_RST_RFID, OFF); } } else { if(gpio_get_value(GPIO_OUT_RST_RFID) == OFF) { DEBUG_INFO("RFID exit power saving...%d\n", getDiffSecNow(startTime[ShmCharger->gun_selectd][TMR_IDX_POWERSAVING_RFID])); gpio_set_value(GPIO_OUT_RST_RFID, ON); } } if(getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_METER]) > TIMEOUT_SPEC_POWERSAVING_METER) { if(ShmCharger->gun_info[gun_index].isMeterOn) { DEBUG_INFO("Meter into power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_METER])); ShmCharger->gun_info[gun_index].isMeterOn = OFF; } } else { if(!ShmCharger->gun_info[gun_index].isMeterOn) { DEBUG_INFO("Meter exit power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_METER])); ShmCharger->gun_info[gun_index].isMeterOn = ON; } } if(getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]) > TIMEOUT_SPEC_POWERSAVING_LED_STATUS) { if(ShmCharger->gun_info[gun_index].isSleepOn == NO) { DEBUG_INFO("LED status into power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS])); ShmCharger->gun_info[gun_index].isSleepOn = YES; } } else { if(ShmCharger->gun_info[gun_index].isSleepOn == YES) { DEBUG_INFO("LED status exit power saving...%d\n", getDiffSecNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS])); ShmCharger->gun_info[gun_index].isSleepOn = NO; } } //========================================== // Synchronize current rating value from MCU //========================================== ShmSysConfigAndInfo->SysConfig.RatingCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; //========================================== // Assign connector location index for OCPP //========================================== ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].Index = gun_index; //========================================== // Synchronize present charging power //========================================== if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 1) { if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltage*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000; if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower <= 1.0) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0; } else ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0; } else { if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltage*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000) + ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL2*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL2)/1000) + ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingVoltageL3*ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrentL3)/1000)); if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower <= 1.0) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0; } else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0; } } //========================================== // Check initialization "PASS" or "FAIL" //========================================== if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING) { // Alarm event check if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode>0) || (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode>0) || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_ALARM) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_UPDATE) { setChargerMode(gun_index, SYS_MODE_ALARM); } } } } //========================================== // Reservation request check //========================================== checkReservation(gun_index); //========================================== // Change availability check //========================================== checkAvailability(gun_index); if(ShmCharger->gun_info[gun_index].isOperactive) { if(isMode(gun_index, SYS_MODE_MAINTAIN)) { setChargerMode(gun_index, SYS_MODE_IDLE); } } else { if(isMode(gun_index, SYS_MODE_IDLE)) { setChargerMode(gun_index, SYS_MODE_MAINTAIN); } } //========================================== // Unlock Connector signal check //========================================== checkUnlocker(gun_index); //========================================== // Clean EVCCID timeout flag //========================================== if((ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID && (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE)) && (ShmCharger->isCcsEnable) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)) { for(int gun_index = 0;gun_indexgun_info[gun_index].isGetEvCCIDTimeout = OFF; ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = NO; } } //========================================== // Check EVCCID communcation error //========================================== if(ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout == ON) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail = ON; } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail = OFF; } //========================================== // Clean isRemoteStartWait flag //========================================== if(ocpp_get_isRemoteStartWait()) { if(ShmCharger->gun_info[gun_index].isRemoteStartWait == OFF) { ShmCharger->gun_info[gun_index].isRemoteStartWait = ON; DEBUG_INFO("Remote start without connector id... \n"); } refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]); } else { if((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 5)) { if(ShmCharger->gun_info[gun_index].isRemoteStartWait == ON) { ShmCharger->gun_info[gun_index].isRemoteStartWait = OFF; DEBUG_INFO("Clean isRemoteStartWait flag... \n"); } } if((getDiffSecNow(startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]) > 10)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_CLEAN_REMOTE_START_WAIT]); } } //========================================== // QCA7000 close and open timing //========================================== if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus > SYS_MODE_BOOTING) { if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_TERMINATING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_COMPLETE)) && (ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_HLC))) { if((gpio_get_value(GPIO_OUT_RST_QCA) == ON) && (ShmCharger->isCcsEnable)) { gpio_set_value(GPIO_OUT_RST_QCA, OFF); } } else { if((gpio_get_value(GPIO_OUT_RST_QCA) == OFF) && (ShmCharger->isCcsEnable)) { gpio_set_value(GPIO_OUT_RST_QCA, ON); //sleep(3); } } } //========================================== // Synchronized total power consumption //========================================== if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[0] = (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[1] = (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[2] = (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/10000.0); } //========================================== // Connector process //========================================== switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) { case SYS_MODE_BOOTING: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_INIT); //CSU Initialization & task spawn if((Initialization(gun_index) != PASS) || (SpawnTask(gun_index) != PASS)) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = ON; } // Firmware version get_firmware_version(gun_index); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]); refreshStartTimer(&startTime[gun_index][TMR_IDX_LCM_POWER_CONSUMPTION]); } if(ShmCharger->gun_info[gun_index].mcuFlag.isReadFwVerPass && ShmCharger->gun_info[gun_index].mcuFlag.isSetModelNamePass && ShmCharger->gun_info[gun_index].mcuFlag.isSetSerialNumberPass) { ShmCharger->gun_selectd = 0; // Firmware version get_firmware_version(gun_index); // Change availability check checkAvailability(gun_index); // OCPP BootNotification info set DEBUG_INFO("==========================================\n"); DEBUG_INFO("System ID: %s\n",ShmSysConfigAndInfo->SysConfig.SystemId); DEBUG_INFO("==========================================\n"); DEBUG_INFO("=== OCPP BootNotification information ====\n"); ocpp_boot_info_sync(); DEBUG_INFO("OcppServerURL: %s\n",ShmSysConfigAndInfo->SysConfig.OcppServerURL); DEBUG_INFO("ChargeBoxId: %s\n",ShmSysConfigAndInfo->SysConfig.ChargeBoxId); DEBUG_INFO("ChargePointVendor: %s\n",ShmSysConfigAndInfo->SysConfig.chargePointVendor); DEBUG_INFO("==========================================\n"); DEBUG_INFO("========== Set Wifi information ==========\n"); DEBUG_INFO("Wifi mode: %d\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode); DEBUG_INFO("Wifi SSID: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid); DEBUG_INFO("Wifi password: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword); DEBUG_INFO("==========================================\n"); // Set max current to rating current ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; // Default Ethernet / Wifi / 4G to 1:disconnected switch(ShmSysConfigAndInfo->SysConfig.ModelName[10]) { case 'E': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = OFF; break; case 'W': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = OFF; break; case 'T': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = OFF; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON; break; case 'D': ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = ON; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = ON; break; } // Default LCM brightness to 100 ShmCharger->isLcdOn = ON; // Defaule led status to not sleep mode ShmCharger->gun_info[gun_index].isSleepOn = NO; // If Web Server OPCC URL is empty kill Module_OcppBackend if((strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0)) { if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0) DEBUG_INFO("URL is empty kill Module_OcppBackend...\n"); system ("pkill OcppBackend"); } else { system ("pkill OcppBackend"); DEBUG_INFO("Initialization: Kill OcppBackend task. \n"); } // If rotate switch equal zero, the system needs to change Debug mode if(ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch == 0) { setChargerMode(gun_index, SYS_MODE_DEBUG); } else { // Check is operactive if(ShmCharger->gun_info[gun_index].isOperactive) { setChargerMode(gun_index, SYS_MODE_IDLE); } else { setChargerMode(gun_index, SYS_MODE_MAINTAIN); } } // The system identifies 1 phase or 3 phases depending on the model name /* ShmSysConfigAndInfo->SysConfig.AcPhaseCount = ((ShmSysConfigAndInfo->SysConfig.ModelName[2]=='Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='D') || (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='W') ?3:1); */ if((ShmSysConfigAndInfo->SysConfig.ModelName[2]=='Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='D') || (ShmSysConfigAndInfo->SysConfig.ModelName[2]=='W')) { // The dip switch 1: one phase 0: three phases if(ShmCharger->gun_info[gun_index].primaryMcuState.dip_switch == ON) ShmSysConfigAndInfo->SysConfig.AcPhaseCount = 1; else ShmSysConfigAndInfo->SysConfig.AcPhaseCount = 3; DEBUG_INFO("Dip switch: %s \n", (ShmCharger->gun_info[gun_index].primaryMcuState.dip_switch == ON? "ON":"OFF")); } else { ShmSysConfigAndInfo->SysConfig.AcPhaseCount = 1; } DEBUG_INFO("AcPhaseCount: %d \n", ShmSysConfigAndInfo->SysConfig.AcPhaseCount); // Refresh PTB resend timer if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_SEND]); DEBUG_INFO("System memory power consumption: %.4f \n",(ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0)); DEBUG_INFO("Share memory power consumption: %.4f \n",ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption); } break; case SYS_MODE_IDLE: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_IDLE); setRelay(gun_index, OFF); setRequest(gun_index,OFF); ShmCharger->gun_info[gun_index].isGunPlugged = NO; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ShmCharger->gun_info[gun_index].isGetEvCCID = OFF; ocpp_set_remotestart(gun_index, OFF); ocpp_set_remotestop(gun_index, OFF); ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode = 0x00; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = 0; presentChargedEnergyClear(gun_index); ShmCharger->gun_info[gun_index].targetCurrent = 0xFF; ocpp_set_unlocker_req(gun_index, OFF); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = -1; // Response StopTransactionConf ocpp_set_stoptransaction_conf(gun_index, OFF); memset(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId)); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_IDLE; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].isDoEvReadyOnce = OFF; ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; //if(ShmCharger->isCcsEnable)system("pkill Module_CCS"); DB_Check_Record_Buf(localDb, gun_index); ShmCharger->gun_info[gun_index].isEmergencyStopReport = OFF; // Default previousData every time previousData[gun_index].primaryMcuCp_Pwn_Duty = 0; previousData[gun_index].targetCurrent = 0; previousData[gun_index].current_limit = 0; // Refresh PTB resend timer if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_SEND]); } // Check missing PTB meter messages if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') checkMissingPtbMeterMessage(gun_index); // Check handshake timeout checkHandshakeCountdown(gun_index); // LED status in Idle mode if(!ShmCharger->isAuthrizing) { if(ocpp_get_isRemoteStartWait()) { ShmCharger->gun_info[gun_index].isSleepOn = OFF; setLedMotion(gun_index, LED_ACTION_AUTHED); refreshStartTimer(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]); //DEBUG_INFO("Remote Start Transaction without connector Id.\n"); } else { if(ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON) { if(ShmCharger->gun_info[gun_index].rfidReq == OFF) { if(ShmCharger->gun_info[gun_index].isSleepOn == NO) setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED); else setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP); } } else { if(ShmCharger->gun_info[gun_index].rfidReq == OFF) { if(ShmCharger->gun_info[gun_index].isSleepOn == NO) setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED); else setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP); } } } } /* * TODO: * 1. Try to get EVCCID if plug first */ if((ShmSysConfigAndInfo->SysConfig.isAuthrizeByEVCCID && (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE)) && (ShmCharger->isCcsEnable) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) && (ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout == OFF) && (ShmCharger->gun_info[gun_index].isRemoteStartWait != ON) && (ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail != YES)) { switch(ShmCharger->gun_info[gun_index].ccsHandshakeState) { case HANDSHAKE_DUTY_5: if(!getRequest(gun_index)) { setRequest(gun_index, ON); refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); DEBUG_INFO("Try to get EVCCID, Set Request On.\n"); //Let CCS task start to negotiate ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = ON; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_NONE; } // Set CCS 5% PWM duty if(ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_5) //set 5% by SeccComm.c { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK\n"); } break; case HANDSHAKE_DUTY_5_CHECK: if((ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF)) { //2 secs timeout refreshStartTimer(&startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CCS; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS\n"); } break; case HANDSHAKE_CCS: if(getDiffSecNow(startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_BS_HLC_HANDSHAKE) { ShmCharger->gun_info[gun_index].isGetEvCCIDTimeout = ON; ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); DEBUG_INFO("Get EVCCID timeout.\n"); sleep(3); } if((19 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus < 253)) { if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16) { sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%s%02X%02X%02X%02X%02X%02X", ShmOCPP16Data->ConfigurationTable.CoreProfile[EVCCID_PREFIX].ItemData, ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[0], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[1], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[2], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[3], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[4], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[5]); } else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20) { sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[0], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[1], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[2], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[3], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[4], ShmCharger->gun_info[gun_index].acCcsInfo.EVCCID[5]); } //sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "F5902677"); ShmCharger->gun_info[gun_index].isGetEvCCID = ON; DEBUG_INFO("Got EVCCID: %s\n", ShmSysConfigAndInfo->SysConfig.UserId); } break; default: break; } } else { if(getRequest(gun_index)) { setRequest(gun_index, OFF); } ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5; } if(((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B)) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON)) || (ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) || (ocpp_get_remotestart(gun_index) == ON) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart == ON) || (ShmCharger->gun_info[gun_index].isGetEvCCID == ON)) { if((ShmCharger->gun_info[gun_index].rfidReq == ON)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_RFID; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_ISO14443; DEBUG_INFO("Start Method : RFID...\n"); } else if(ocpp_get_remotestart(gun_index)) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_Central; ocpp_copy_userid_from_remotestart(gun_index); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : BACKEND...\n"); } else if(ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart == ON) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BLE; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_Local; memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmCharger->gun_info[gun_index].bleLoginCentralId.id, ARRAY_SIZE(ShmCharger->gun_info[gun_index].bleLoginCentralId.id)); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : BLE...\n"); } else if(ShmCharger->gun_info[gun_index].isGetEvCCID == ON) { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_EVCCID; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_MacAddress; setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : EVCCID...\n"); } else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_FREE; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_NoAuthorization; //memcpy(ShmSysConfigAndInfo->SysConfig.UserId, ShmSysConfigAndInfo->SysConfig.SerialNumber, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); ocpp_get_freevend_idtag(ShmSysConfigAndInfo->SysConfig.UserId); setSpeaker(ON, SPEAKER_SHORT); DEBUG_INFO("Start Method : FREE...\n"); } ShmCharger->gun_info[gun_index].rfidReq = OFF; ocpp_set_remotestart(gun_index, OFF); ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = OFF; ShmCharger->gun_info[gun_index].isGunPlugged = NO; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart = OFF; ShmCharger->gun_info[gun_index].isGetEvCCID = OFF; // Get target current ocpp_set_profile_req(gun_index, ON); sleep(1); checkChargingProfileLimit(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus); setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } else {} break; case SYS_MODE_AUTHORIZING: if(isModeChange(gun_index)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_AUTH]); if(ocpp_isAuthorizeRemoteStart() && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_BACKEND)) { DEBUG_INFO("Remote start request authorize.\n"); ocpp_set_auth_req(ON, "ISO14443"); } else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == START_METHOD_EVCCID)) { DEBUG_INFO("EVCCID request authorize.\n"); ocpp_set_auth_req(ON, "MacAddress"); } } if(getDiffSecNow(startTime[gun_index][TMR_IDX_AUTH]) > ShmCharger->timeoutSpec.Present_Authorize_Timeout_Spec) { // Authorization timeout process. setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); DEBUG_WARN("Authorize timeout !!!\n"); } else { switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod) { case START_METHOD_BACKEND: if(ocpp_isAuthorizeRemoteStart()) { if(ocpp_get_auth_conf()) { if(ocpp_get_auth_result(YES, gun_index)) { memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("[START_METHOD_BACKEND] StartUserId : %s \n",ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId); DEBUG_INFO("Authorize pass.\n"); setSpeaker(ON,SPEAKER_SHORT); setLedMotion(gun_index,LED_ACTION_RFID_PASS); #if 0 if(ShmCharger->isCcsEnable) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; sleep(4); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; //system("/root/Module_CCS &"); } else #endif sleep(4); setChargerMode(gun_index, SYS_MODE_PREPARING); } else { DEBUG_INFO("Authorize fail.\n"); setSpeaker(ON,SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index,LED_ACTION_RFID_FAIL); sleep(3); if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId == -1) setChargerMode(gun_index, SYS_MODE_IDLE); else setChargerMode(gun_index, SYS_MODE_RESERVATION); } ocpp_set_auth_conf(OFF); } } else { if(ShmCharger->isCcsEnable) { //ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; //ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; //sleep(4); //ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; //ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; //system("/root/Module_CCS &"); } memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("[START_METHOD_BACKEND] StartUserId : %s \n",ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId); setChargerMode(gun_index, SYS_MODE_PREPARING); } break; case START_METHOD_EVCCID: ShmCharger->gun_info[gun_index].resultAuthorization = UNKNOW_RFID; if(ocpp_get_auth_conf() || (!ocpp_get_connection_status() && ((ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) || (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_NOCHARGE))) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (getDiffSecNow(startTime[0][TMR_IDX_AUTH]) > 2))) { if(ocpp_get_auth_result(YES, gun_index) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST))) { memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); DEBUG_INFO("[START_METHOD_EVCCID] StartUserId : %s \n",ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId); ShmCharger->gun_info[gun_index].resultAuthorization = VALIDATED_RFID; DEBUG_INFO("Authorize pass [EVCCID].\n"); setSpeaker(ON, SPEAKER_SHORT); setLedMotion(gun_index, LED_ACTION_RFID_PASS); sleep(1); setChargerMode(gun_index, SYS_MODE_PREPARING); ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = NO; } else { ShmCharger->gun_info[gun_index].resultAuthorization = UNVALIDATED_RFID; DEBUG_INFO("Authorize fail [EVCCID].\n"); setSpeaker(ON, SPEAKER_INTERVAL_3COUNT); setLedMotion(gun_index, LED_ACTION_RFID_FAIL); sleep(3); setChargerMode(gun_index, SYS_MODE_IDLE); ShmCharger->gun_info[gun_index].isEvCCIDAuthorizeFail = YES; ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; } ocpp_set_auth_conf(OFF); } break; case START_METHOD_RFID: case START_METHOD_BLE: case START_METHOD_FREE: default: if(ShmCharger->isCcsEnable) { //ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; //ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; //sleep(4); //ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; //ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; //system("/root/Module_CCS &"); } setChargerMode(gun_index, SYS_MODE_PREPARING); break; } } break; case SYS_MODE_PREPARING: if(isModeChange(gun_index)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); setLedMotion(gun_index,LED_ACTION_AUTHED); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; if(ShmCharger->isCcsEnable) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod != START_METHOD_EVCCID) { ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5\n"); } } else { ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; setRequest(gun_index, ON); } } // If control pilot detect Bx, skip watch dog time out. if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_E) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_F)) { ShmCharger->gun_info[gun_index].isGunPlugged = YES; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; switch(ShmCharger->gun_info[gun_index].ccsHandshakeState) { case HANDSHAKE_DUTY_5: if(!getRequest(gun_index)) { setRequest(gun_index, ON); setLedMotion(gun_index,LED_ACTION_CONNECTED); refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); DEBUG_INFO("Set Request On.\n"); //Let CCS task start to negotiate ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = ON; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_NONE; } // Set CCS 5% PWM duty if(ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_5)//set 5% by SeccComm.c { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK\n"); } break; case HANDSHAKE_DUTY_5_CHECK: if((ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF)) { //2 secs timeout refreshStartTimer(&startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CCS; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS\n"); } break; case HANDSHAKE_CCS: //CCS handshake timeout if(getDiffSecNow(startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_BS_HLC_HANDSHAKE) { if(ShmCharger->isCcsEnable) { DEBUG_INFO("TIMEOUT_SPEC_BS_HLC_HANDSHAKE.\n"); ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; break; } else { ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; DEBUG_INFO("BS/HLC %d secs handshake timeout.\n", TIMEOUT_SPEC_BS_HLC_HANDSHAKE); } } if((ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission == OFF) && (ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5)) { DEBUG_INFO("Wait CCS give up negotiagting.\n"); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; } //CCS status check #if 0 if((16 < ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus < 254)) { ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_HLC; DEBUG_INFO("Enter HLC Mode charging.\n"); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_HLC_MODE; refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); } #else if((16 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus < 253)) { //chang PWM duty to BS if((ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF)&&(ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current!=CCS_PWM_DUTY_5)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current =CCS_PWM_DUTY_5; //((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS (set 5% duty)\n"); } //ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_HLC; //ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_HLC_MODE; refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); } if((37 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus < 49)) { //chang PWM duty to BS if((ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF)&&(ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current!=CCS_PWM_DUTY_5)) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current =CCS_PWM_DUTY_5; //((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; } ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_HLC; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_HLC_MODE; //refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); DEBUG_INFO("ccsHandshakeState = HANDSHAKE_HLC_MODE\n"); } else if((54 < ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus <= 255)) { DEBUG_INFO("ccsHandshakeState = CHARGING_MODE_BS, CCS terminated\n"); ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; } #endif break; case HANDSHAKE_CP_STATE_E: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { if(ShmCharger->isCcsEnable) { DEBUG_INFO("Change to CP STATE E for 4 secs.\n"); //CP STATE E for 4 secs sleep(4); } //restore normal CP PWM duty // Determine max charging current to MCU DEBUG_INFO("Determine max charging current to MCU.\n"); ocpp_set_profile_req(gun_index, ON); sleep(1); checkChargingProfileLimit(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus); ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_SET_MAX_CURRENT; refreshStartTimer(&startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]); } break; case HANDSHAKE_SET_MAX_CURRENT: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_BS_MODE; DEBUG_INFO("Enter BS Mode charging.\n"); //for EV READY 30 secs didn't start charging to STATE E refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); } break; case HANDSHAKE_BS_MODE: refreshStartTimer(&startTime[gun_index][TMR_IDX_HANDSHAKING]); checkChargingProfileLimit(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus); if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C) && ((ShmCharger->gun_info[gun_index].targetCurrent != 0))) { setRelay(gun_index,ON); } if((ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON) || (ShmCharger->gun_info[gun_index].targetCurrent == 0)) { ocpp_set_unlocker_req(gun_index, OFF); presentChargedEnergyClear(gun_index); getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime); ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption; if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[0] = (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[1] = (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[2] = (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/10000.0); } memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ocpp_copy_userid_to_starttransaction(gun_index); ocpp_set_starttransaction_req(gun_index, ON); refreshStartTimer(&startChargingTime[gun_index]); // PTB Permission if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') setPtbMeterPermission(gun_index, PERMISSION_START_CHARGING); setChargerMode(gun_index, SYS_MODE_CHARGING); } //EV READY CHECK /* if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_EV_READY) && (ShmCharger->gun_info[gun_index].isEvReady2StateE == OFF)) { if(ShmCharger->gun_info[gun_index].isDoEvReadyOnce == OFF) { DEBUG_INFO("EV READY STATE E 4sec.\n"); ShmCharger->gun_info[gun_index].isEvReady2StateE = ON; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_E; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_STAT_E; } } if(ShmCharger->gun_info[gun_index].isEvReady2StateE == ON) { switch(ShmCharger->gun_info[gun_index].evReadyState) { case EV_READY_STAT_E: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { sleep(4); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_STAT_C; } break; case EV_READY_STAT_C: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { usleep(500000); DEBUG_INFO("EV READY Determine max charging current to MCU.\n"); if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; } } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_SET_MAX_CURRENT; } break; case EV_READY_SET_MAX_CURRENT: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { ShmCharger->gun_info[gun_index].isEvReady2StateE = OFF; ShmCharger->gun_info[gun_index].isDoEvReadyOnce = ON; } break; default: break; } }*/ break; case HANDSHAKE_HLC_MODE: if(ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_START_MODE)//powerDelivery { if(ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn == OFF) { setRelay(gun_index,ON); ShmCharger->gun_info[gun_index].isCCSStartTransation = ON; DEBUG_INFO("HANDSHAKE_HLC_MODE:setRelay ON\n"); } } if((ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON) && (ShmCharger->gun_info[gun_index].isCCSStartTransation == ON)) { DEBUG_INFO("HANDSHAKE_HLC_MODE:Relay ON done\n"); ocpp_set_unlocker_req(gun_index, OFF); presentChargedEnergyClear(gun_index); getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime); ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption; if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[0] = (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[1] = (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[2] = (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/10000.0); } memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ocpp_copy_userid_to_starttransaction(gun_index); ocpp_set_starttransaction_req(gun_index, ON); ShmCharger->gun_info[gun_index].isCCSStartTransation = OFF; // PTB Permission if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') setPtbMeterPermission(gun_index, PERMISSION_START_CHARGING); setChargerMode(gun_index, SYS_MODE_CHARGING); DEBUG_INFO("set SYS_MODE_CHARGING\n"); refreshStartTimer(&startChargingTime[gun_index]); refreshStartTimer(&startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]); } //120 sec timeout if(getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > TIMEOUT_SPEC_CCS_HANDSHAKE) { setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); if(getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > TIMEOUT_SPEC_CCS_HANDSHAKE+5) { DEBUG_INFO("CCS 120 secs handshake timeout, change to BS Mode...\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; //ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; if((ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission == OFF) && (ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5)) { DEBUG_INFO("Wait CCS give up negotiagting.\n"); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_BS; } } } break; default: break; } } else if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEMode) { DEBUG_INFO("Enter Socket-E Mode charging.\n"); presentChargedEnergyClear(gun_index); getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime); ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption; ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption_at_start = ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption; if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[0] = (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[1] = (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[2] = (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/10000.0); } ShmCharger->gun_info[gun_index].chargingMode = CHARGING_MODE_SOCKETE; if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) setRelay(gun_index,ON); memcpy((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId, ShmSysConfigAndInfo->SysConfig.UserId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); ocpp_copy_userid_to_starttransaction(gun_index); ocpp_set_starttransaction_req(gun_index, ON); refreshStartTimer(&startChargingTime[gun_index]); // PTB Permission if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') setPtbMeterPermission(gun_index, PERMISSION_START_CHARGING); setChargerMode(gun_index, SYS_MODE_CHARGING); } else if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) { setRequest(gun_index, ON); ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; } // Unplug charging gun to Idle mode if((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && (ShmCharger->gun_info[gun_index].isGunPlugged == YES)) { DEBUG_INFO("Unplug the connector.\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } // Use RFID card to stop handshaking if((ShmCharger->gun_info[gun_index].rfidReq == ON)) { DEBUG_INFO("Use RFID card to stop handshaking.\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } else { ShmCharger->gun_info[gun_index].rfidReq = OFF; } // Check handshake timeout checkHandshakeCountdown(gun_index); if(getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > ShmCharger->timeoutSpec.Present_Timeout_Spec) { setLedMotion(gun_index, LED_ACTION_HANDSHAKE_FAIL); if(getDiffSecNow(startTime[gun_index][TMR_IDX_HANDSHAKING]) > (ShmCharger->timeoutSpec.Present_Timeout_Spec+5)) { DEBUG_INFO("Handshaking timeout...\n"); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } } if((ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty == ON) && ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = OFF; setChargerMode(gun_index, SYS_MODE_IDLE); } break; case SYS_MODE_CHARGING: if(isModeChange(gun_index)) { ShmCharger->gun_info[gun_index].rfidReq = OFF; //ftime(&startChargingTime[gun_index]); refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); refreshStartTimer(&startTime[gun_index][TMR_IDX_PWN_CHANGE]); ocpp_reset_smartcharging_profileId(gun_index); ocpp_set_profile_req(gun_index, ON); ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; // Refresh timer for getting PTB meter message if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]); } //if time up, clear CCS MSG count if((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (getDiffSecNow(startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]) > TIMEOUT_SPEC_CCS_HEARTBEAT_COUNT_RESET)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]); /*if(ShmCharger->gun_info[gun_index].acCcsInfo.CcsHeartBeat > 0) { ShmCharger->gun_info[gun_index].acCcsInfo.CcsHeartBeat = 0; } else { DEBUG_INFO("CCS could not get MSG from car.\n"); //setChargerMode(gun_index, SYS_MODE_TERMINATING); //setRelay(gun_index, OFF); }*/ } // If unplug the connector during a session, the system must stop charging and stop session. checkConnectorStatus(gun_index); if((ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES) || (ShmCharger->gun_info[gun_index].rfidReq == ON) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || ocpp_get_remotestop(gun_index) || (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) || ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState != CP_STATE_C) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && !ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop == ON) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STOP_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_RENEGOTIATE_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STANDBY_MODE)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && ((49 <= ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus) && (ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus <= 255))) ) { //printf("EVChargeProgress=0x%x, PresentMsgFlowStatus=0x%x\n",ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress,ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus); setChargerMode(gun_index, SYS_MODE_TERMINATING); } else { // Charging session info calculation setLedMotion(gun_index,LED_ACTION_CHARGING); if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1) ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); else { ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[0] = (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[1] = (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/10000.0); //ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption[2] = (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/10000.0); } refreshStartTimer(&endChargingTime[gun_index]); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = getDiffSecBetween(startChargingTime[gun_index], endChargingTime[gun_index]); presentChargedEnergyUpdate(gun_index); // Response StartTransactionConf ocpp_set_starttransaction_conf(gun_index, OFF); // Charging profile preparation if((getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if(!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ocpp_set_profile_conf(gun_index, OFF); } } // Checking profile id > 0 and current time is between charging profile validFrom & validTo checkChargingProfileLimit(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus); // Charging session local limit condition check if(ocpp_get_connection_status()) { // On-line max condition check if((ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else {} setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over max duration(%d) in second.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)); } else if((ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else {} setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over max energy(%.2f) in KWH.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)); } else { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if(ShmCharger->gun_info[gun_index].targetCurrent>0) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C) setRelay(gun_index, ON); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else {} } } else { // Off-line max condition check if((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) || ((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_ENABLE) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE))) { if(((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration*60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)))) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else {} setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging duration(%d) already over off-line max duration(%d) in second.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration, (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)); } else if(((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)))) { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { setRelay(gun_index, OFF); ShmCharger->gun_info[gun_index].isChargerStopByCondition = YES; } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { setRelay(gun_index, OFF); } else {} setChargerMode(gun_index, SYS_MODE_TERMINATING); DEBUG_INFO("Connector-%d charging energy(%.2f) already over off-line max energy(%.2f) in KWH.\n", gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy, ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)); } else { if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].isChargerStopByCondition = NO; if(ShmCharger->gun_info[gun_index].targetCurrent>0) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C) setRelay(gun_index, ON); } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) { if(ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn == ON) setRelay(gun_index, ON); else setRelay(gun_index, OFF); } else {} } } else { if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state > 0) DEBUG_INFO("Connector-%d can not charging in off line\n", gun_index); setRelay(gun_index, OFF); } } // Debug information if((getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) < 0)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime); DB_Update_Record_Buf(localDb, gun_index); } } break; case SYS_MODE_TERMINATING: if(isModeChange(gun_index)) { if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setLedMotion(gun_index, LED_ACTION_STOP); } else {} getDateTimeString((char*)ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; if(ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES) setRelay(gun_index, OFF); // Refresh timer for getting PTB meter message if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]); } refreshStartTimer(&endChargingTime[gun_index]); //if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration != 0) //{ ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = getDiffSecBetween(startChargingTime[gun_index], endChargingTime[gun_index]); //} // If unplug the connector during a session, the system must stop charging and stop session. checkConnectorStatus(gun_index); // End authorize pass if(((ShmCharger->gun_info[gun_index].rfidReq == ON) && isMatchStartUser(gun_index)) || ((ShmCharger->gun_info[gun_index].rfidReq == ON) && ocpp_get_auth_result(YES, gun_index)) || (!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_FREE) && (ShmCharger->gun_info[gun_index].rfidReq == ON)) || (!ocpp_get_connection_status() && (isValidLocalWhiteCard() == PASS) && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == OFF_POLICY_LOCALLIST) && (ShmCharger->gun_info[gun_index].rfidReq == ON)) || (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) || ocpp_get_remotestop(gun_index) || (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) || ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && ((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) && ocpp_get_StopTransactionOnEVSideDisconnect()) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && ((!ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES))) || ocpp_get_reset_req() || ocpp_get_unlocker_req(gun_index) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop == ON) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_STOP_MODE))) { setLedMotion(gun_index, LED_ACTION_STOP); if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { processEndOfChargingForPtbMeter(gun_index); } else { sleep(1); checkStopReason(gun_index); setChargerMode(gun_index, SYS_MODE_COMPLETE); } } else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) { //setChargerMode(gun_index, SYS_MODE_COMPLETE); //Cancel CCS task negotiating ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission = OFF; ShmCharger->gun_info[gun_index].acCcsInfo.EVSENotification = NOTIFICATION_STOP; setRelay(gun_index,OFF); ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = ON; } else { if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { processEndOfChargingForPtbMeter(gun_index); } else { checkStopReason(gun_index); setChargerMode(gun_index, SYS_MODE_COMPLETE); } } } else { // Refresh timer for getting PTB meter message if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') refreshStartTimer(&startTime[gun_index][TMR_IDX_PTB_METER_MESSAGE]); // If the charger stops charging, the led should be stoped blink if(!ShmCharger->gun_info[gun_index].primaryMcuState.relay_state) { setLedMotion(gun_index, LED_ACTION_STOP); } // Charging profile preparation if((getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (getDiffSecNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0)) { if(!ocpp_get_profile_conf(gun_index)) { ocpp_set_profile_req(gun_index, ON); refreshStartTimer(&startTime[gun_index][TMR_IDX_PROFILE_PREPARE]); } else { ocpp_set_profile_conf(gun_index, OFF); } } // Checking profile id > 0 and current time is between charging profile validFrom & validTo checkChargingProfileLimit(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus); setRelay(gun_index, OFF); // Debug information if((getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_LOGPPRINTOUT) || (getDiffSecNow(startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]) < 0)) { refreshStartTimer(&startTime[gun_index][TMR_IDX_REFRESH_CHARGING_INFO]); } if(!ocpp_get_auth_result(YES, gun_index)) ShmCharger->gun_info[gun_index].rfidReq = OFF; if((ShmCharger->gun_info[gun_index].isGunUnpluggedBefore != YES) && (((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_C)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn)) && (ShmCharger->gun_info[gun_index].rfidReq != ON) && (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop != ON) && !ocpp_get_remotestop(gun_index) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop != ON) && !ocpp_get_reset_req() && ocpp_get_starttransaction_result(gun_index) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) && !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration*60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)))) && !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy)))) && (((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress == HLC_START_MODE)) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_BS) || (ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE)) ) { sleep(1); setChargerMode(gun_index, SYS_MODE_CHARGING); } } if((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC) && (ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty == ON) && (ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_100)) { DEBUG_INFO("Set PWM duty 100%% go to SYS_MODE_TERMINATING.\n"); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = OFF; if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'P') { processEndOfChargingForPtbMeter(gun_index); } else { sleep(1); checkStopReason(gun_index); setChargerMode(gun_index, SYS_MODE_COMPLETE); } } break; case SYS_MODE_COMPLETE: if(isModeChange(gun_index)) { setLedMotion(gun_index, LED_ACTION_STOP); refreshStartTimer(&startTime[gun_index][TMR_IDX_RECEIPT_INFORMATION]); } // Check the connector status checkConnectorStatus(gun_index); // Dispay receipt information for 15 seconds if((getDiffSecNow(startTime[gun_index][TMR_IDX_RECEIPT_INFORMATION]) >= 15)) { if(((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A)) || ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && (!ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn)) || ocpp_get_reset_req() || (ShmCharger->gun_info[gun_index].isGunUnpluggedBefore == YES)) { sleep(2); ShmCharger->gun_info[gun_index].rfidReq = OFF; ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF; ocpp_set_remotestop(gun_index, OFF); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop = OFF; ShmCharger->gun_info[gun_index].isGunUnpluggedBefore = NO; DB_Insert_Record(localDb, gun_index); setChargerMode(gun_index, SYS_MODE_IDLE); } } else { // After 6 seconds Relay off & PWM off (specifcation) if((getDiffSecNow(startTime[gun_index][TMR_IDX_RECEIPT_INFORMATION]) >= 6)) { setRelay(gun_index, OFF); setRequest(gun_index, OFF); } } break; case SYS_MODE_ALARM: setLedMotion(gun_index,LED_ACTION_ALARM); setRelay(gun_index, OFF); // Check the connector status checkConnectorStatus(gun_index); /* * TODO: * 1. Customize emergency stop and report stop transaction then return to idle mode if error recover. * 2. Customer: Bambang */ if(((ShmSysConfigAndInfo->SysConfig.ModelName[12] == 'B') && (ShmSysConfigAndInfo->SysConfig.ModelName[13] == 'B')) && (ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == ALARM_EMERGENCY_STOP)) { if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) && !ShmCharger->gun_info[gun_index].isEmergencyStopReport) { checkStopReason(gun_index); ShmCharger->gun_info[gun_index].isEmergencyStopReport = ON; } } if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode == 0) && !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail) { if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus == SYS_MODE_TERMINATING)) && (!ShmCharger->gun_info[gun_index].isEmergencyStopReport)) { setChargerMode(gun_index, ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus); } else { setChargerMode(gun_index, SYS_MODE_IDLE); } } break; case SYS_MODE_FAULT: if(isModeChange(gun_index)) {} break; case SYS_MODE_MAINTAIN: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_MAINTAIN); } break; case SYS_MODE_UPDATE: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_MAINTAIN); } //====================================== // Check local upgrade firmware request //====================================== if(ShmSysConfigAndInfo->SysInfo.FirmwareUpdate) { DEBUG_INFO("Firmware local upgrading...\n"); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = OFF; int value = upgrade_check(); DEBUG_INFO("Local update Value: %s... \n",((value == PASS)?"Pass": "Fail")); if(value == PASS) { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == ON) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = OFF; ShmCharger->isUpdateSuccess = YES; DEBUG_INFO("Local update success...\n"); } else { if(ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail == OFF) ShmStatusCodeData->InfoCode.InfoEvents.bits.CsuFimrwareUpdateFail = ON; ShmCharger->isUpdateSuccess = NO; DEBUG_INFO("Local update unsuccess...\n"); } } else if(ocpp_get_update_firmware_req()) { //====================================== // Check remote upgrade firmware request //====================================== checkRemoteUpgradeStatus(); } else { //====================================== // Upgrade complete reboot system //====================================== if(!ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq && ((AC_QUANTITY>1)?!ShmCharger->gun_info[gun_index^1].mcuFlag.isMcuUpgradeReq:YES) && !ShmCharger->isUpgradeLcmReq) { if(ShmCharger->isUpdateSuccess == YES) { if((strcmp((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing")==0)) { sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; } else if((strcmp((char*)ShmOCPP16Data->SignedFirmwareStatusNotification.status, "Installing")==0)) { ShmOCPP16Data->SignedFirmwareStatusNotification.requestId = ShmOCPP16Data->SignedUpdateFirmware.requestId; sprintf((char*)ShmOCPP16Data->SignedFirmwareStatusNotification.status, "Installed"); ShmOCPP16Data->SpMsg.bits.SignedFirmwareStatusNotificationReq = ON; } sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "Installed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; DEBUG_WARN("Firmware upgrade success.\n"); sleep(5); DEBUG_INFO("Firmware upgraded, reboot...\n"); system("reboot -f"); sleep(5); system("reboot -f"); } else { sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "InstallationFailed"); ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON; DEBUG_WARN("Firmware upgrade fail.\n"); sleep(5); system("rm -rvf /mnt/* "); close(wtdFd); system("/usr/bin/run_evse_restart.sh"); } } } break; case SYS_MODE_RESERVATION: if(isModeChange(gun_index)) {} setLedMotion(gun_index,LED_ACTION_RESERVATION_MODE); if(isReservationExpired(gun_index)) { DEBUG_INFO("Reservation: Time's up...\n"); setChargerMode(gun_index, SYS_MODE_IDLE); } else if(ocpp_get_cancelreservation_req(gun_index)) { DEBUG_INFO("Reservation: Cancel reservation...\n"); setChargerMode(gun_index, SYS_MODE_IDLE); ocpp_set_cancelreservation_req(gun_index, OFF); } else { // Check is there RFID or back end request start if((ShmCharger->gun_info[gun_index].rfidReq == ON) || ocpp_get_remotestart(gun_index)) { if((ShmCharger->gun_info[gun_index].rfidReq == ON)) { if(ocpp_compare_reserve_id_with_user(gun_index) || ocpp_get_auth_result(YES, gun_index)) { DEBUG_INFO("Start Method in reservation : RFID...\n"); DEBUG_INFO("Start request User Id : %s\n", ShmSysConfigAndInfo->SysConfig.UserId); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_RFID; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_ISO14443; setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } else { setLedMotion(gun_index,LED_ACTION_RESERVATION_MODE); ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID; DEBUG_INFO("It's not reserve user id.\n"); } ShmCharger->gun_info[gun_index].rfidReq = OFF; } else if(ocpp_get_remotestart(gun_index)) { if(ocpp_compare_reserve_id_with_remote_user(gun_index) || ocpp_isAuthorizeRemoteStart()) { DEBUG_INFO("Start Method in reservation: BACKEND...\n"); ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod = START_METHOD_BACKEND; ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartIdType = IdTokenType_Central; if(ocpp_isAuthorizeRemoteStart()) ocpp_copy_userid_from_remotestart(gun_index); setChargerMode(gun_index, SYS_MODE_AUTHORIZING); } ocpp_set_remotestart(gun_index, OFF); } } } break; case SYS_MODE_BOOKING: if(isModeChange(gun_index)) {} break; case SYS_MODE_DEBUG: if(isModeChange(gun_index)) { setLedMotion(gun_index,LED_ACTION_DEBUG); } break; } } // System watch dog reset write(wtdFd, "a", 1); usleep(50000); } return FAIL; }