#include #include #include #include #include #include #include #include #include #include #include "../Config.h" #include "../Log/log.h" #include "../Define/define.h" #include "../ShareMemory/shmMem.h" #include "Ev_Comm.h" #include "Module_EvComm.h" //------------------------------------------------------------------------------ static struct SysConfigData *pSysConfig = NULL; static struct SysInfoData *pSysInfo = NULL; static struct WARNING_CODE_INFO *pSysWarning = NULL; static struct AlarmCodeData *pAlarmCode = NULL; static struct CHAdeMOData *ShmCHAdeMOData = NULL; static struct GBTData *ShmGBTData = NULL; static struct CcsData *ShmCcsData = NULL; static struct FanModuleData *ShmFanModuleData = NULL; static DcCommonInfo *ShmDcCommonData = NULL; #define TempArraySize 10 uint8_t TempArray_1[TempArraySize]={0}; uint8_t TempArray_2[TempArraySize]={0}; uint8_t ptemp_1 = 0; uint8_t ptemp_2 = 0; bool firstcircule = true; float EvTargetVolt[2] = { 0 }; float EvTargetCur[2] = { 0 }; //------------------------------------------------------------------------------ extern bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode); //------------------------------------------------------------------------------ /*static uint8_t getMaxConnectTempAndChiller(uint8_t headTemp1, uint8_t headTemp2, uint8_t chillerTemp1, uint8_t chillerTemp2) { uint8_t i = 0; uint8_t tempSource[4] = {headTemp1, headTemp2, chillerTemp1, chillerTemp2}; uint8_t maxTemp = 0; if (headTemp1 == UNDEFINED_TEMP && headTemp2 == UNDEFINED_TEMP && chillerTemp1 == UNDEFINED_TEMP && chillerTemp2 == UNDEFINED_TEMP) { return UNDEFINED_TEMP; } //先取得第一個非UNDEFINED_TEMP的值 for (i = 0; i < (sizeof(tempSource) / sizeof(uint8_t)); i++) { if (tempSource[i] != UNDEFINED_TEMP) { maxTemp = tempSource[i]; break; } } //找最大的溫度值 for (i = 0; i < (sizeof(tempSource) / sizeof(uint8_t)); i++) { if (tempSource[i] != UNDEFINED_TEMP) { if (maxTemp < tempSource[i]) { maxTemp = tempSource[i]; } } } return maxTemp; } */ static uint8_t getAvageTemp(uint8_t value,uint8_t gun) { uint16_t avagetemp = 0; int i; uint8_t ptr = 0; uint8_t *pArray; if(gun == 0) { pArray = &TempArray_1; ptr = ptemp_1; } else { pArray = &TempArray_2; ptr = ptemp_2; } pArray[ptr] = value; for(i=0;i= TempArraySize){ ptr = 0; firstcircule = false; } if(gun == 0 ) ptemp_1 = ptr; else ptemp_2 = ptr; if(avagetemp > TEMP_BOUNDARY) return UNDEFINED_TEMP; return avagetemp; } static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2) { uint8_t maxTemp = 0; if (headTemp1 > TEMP_BOUNDARY && headTemp2 > TEMP_BOUNDARY) { return UNDEFINED_TEMP; } if (headTemp1 <= TEMP_BOUNDARY) { maxTemp = headTemp1; } if (headTemp2 <= TEMP_BOUNDARY) { if (headTemp2 > maxTemp) { maxTemp = headTemp2; } } return maxTemp; } static float ReadAdcVolt(uint8_t AdcChannel) { //AIN0=CCS GUN Temp 1 //AIN1=CCS GUN Temp 2 //AIN2=CCS_Proximity/2 //AIN3=pilot voltage int fd = -1; uint8_t str[64] = {0}; uint8_t AdcValue[8] = {'\0'}; if (AdcChannel > 7) { return -1; } sprintf((char *)str, "/sys/bus/iio/devices/iio\:device0/in_voltage%d_raw", AdcChannel); fd = open((char *)str, O_RDONLY); read(fd, AdcValue, 4); close(fd); return (1.8 * atoi((char *)&AdcValue[0])) / 4095; //return (1.8 * atoi((char *)&AdcValue)) / 4095; } static void getChillerTemperature(ChillerTemp *chillerTemp) { uint8_t i = 0; float adcVoltage = 0.0; ChillerTemp *pChillerTemp = (ChillerTemp *)chillerTemp; for (i = 0; i < 4; i++) { adcVoltage = 0.0; adcVoltage = ReadAdcVolt(i); ShmDcCommonData->TempVolt[i] = adcVoltage; if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40 pChillerTemp->Temp[i] = ((adcVoltage - 0.908) * 500) + 60; //log_info("1 adcVoltage = %f", (adcVoltage - 0.9) * 500); } else if ((adcVoltage <= 1.07) && (adcVoltage > 0.9)) { pChillerTemp->Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60; //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500); } else { pChillerTemp->Temp[i] = UNDEFINED_TEMP; } /*CcsConnectorTemp1 = ReadAdcVolt(i); if ((CcsConnectorTemp1 <= 0.9) && (CcsConnectorTemp1 >= 0.8)) { //0 ~ -40 CcsConnectorTemp1 = (CcsConnectorTemp1 - 0.9) * 500; } else if ((CcsConnectorTemp1 <= 1.07) && (CcsConnectorTemp1 > 0.9)) { CcsConnectorTemp1 = (CcsConnectorTemp1 - 0.9) * 705.88; } else { CcsConnectorTemp1 = 195; //not available } CcsConnectorTemp |= ((unsigned int)(CcsConnectorTemp1 + 60) & 0xFF) << (i * 8); //0x00(-60)~0xFE(194) */ } } static void AddrAssignment(uint8_t *data) { uint8_t target_number[8]; uint8_t index = 0x00; struct ChargingInfoData *pDcChargingInfo = NULL; memcpy(target_number, data, sizeof(target_number)); index = *(data + 4); if (pSysConfig->TotalConnectorCount == 1) { index = 0x01; } //if (CheckUniqNumber(index)) { pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index - 1); //DS60-120 add if (pDcChargingInfo->Type == _Type_Chademo) { log_info("Set EV board info : (Chademo) TargetAddr = %d ", index); } else if (pDcChargingInfo->Type == _Type_CCS_2) { log_info("Set EV board info : (CCS) TargetAddr = %d ", index); } else if (pDcChargingInfo->Type == _Type_GB) { log_info("Set EV board info : (GB) TargetAddr = %d ", index); } //log_info("EV board id = %x ", index); //DS60-120 remove //log_info("target_number[0] = %x ", target_number[0]); //log_info("target_number[1] = %x ", target_number[1]); //log_info("target_number[2] = %x ", target_number[2]); //log_info("target_number[3] = %x ", target_number[3]); //log_info("target_number[4] = %x ", target_number[4]); log_info("SetTargetAddr = %d, type = %d ", index, pDcChargingInfo->Type); SetTargetAddr(target_number, index); //} } void CheckEvConnect(int gunIndex) { int isDisconnect = FALSE; int gunType = _Type_CCS_2; struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex); struct InfoCodeData* pInfoCode = (struct InfoCodeData*)GetShmInfoCodeData(); struct ChargingInfoData* pDcChargingInfo_0 = (struct ChargingInfoData*)GetDcChargingInfoData(0); struct ChargingInfoData* pDcChargingInfo_1 = NULL; if (pSysConfig->TotalConnectorCount == 1) pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(0); else pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(1); if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) { isDisconnect = ShmDcCommonData->pGunStatus[0].EVLoseFlag | ShmDcCommonData->pGunStatus[1].EVLoseFlag; gunType = pDcChargingInfo_0->Type; } else { isDisconnect = ShmDcCommonData->pGunStatus[gunIndex].EVLoseFlag; gunType = pDcChargingInfo->Type; } //log_info("ShmDcCommonData->EVDisconnectFlag[%d]:%d", gunIndex, ShmDcCommonData->EVDisconnectFlag[gunIndex]); if (isDisconnect) { switch (gunType) { case _Type_Chademo: pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES; break; case _Type_CCS_2: pInfoCode->InfoEvents.bits.CcsEvCommFail = YES; break; case _Type_GB: pInfoCode->InfoEvents.bits.GbEvCommFail = YES; break; } } else { switch (gunType) { case _Type_Chademo: pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO; break; case _Type_CCS_2: pInfoCode->InfoEvents.bits.CcsEvCommFail = NO; break; case _Type_GB: pInfoCode->InfoEvents.bits.GbEvCommFail = NO; break; } } } void CANReceiver(int fd) { pid_t canRecPid; canRecPid = fork(); if (canRecPid < 0) { log_error("Create CAN Bus receive task failed"); return; } if (canRecPid == 0) { int isContinue = 1; int nbytes; int intCmd; uint8_t _index = 0; uint8_t recvID = 0; uint8_t targetGun = 0x00; uint8_t gunTypeIndex = 0; uint8_t ver[16] = {0}; uint8_t printChillerTemp = NO; uint8_t printConnTemp = NO; uint8_t chillerTemp[2] = {0, 0}; uint8_t maxChillerTemp = 0; uint8_t lastChillerTemp[2] = {0}; uint8_t maxConnTemp = 0; uint8_t lastConnTemp[2] = {0, 0}; struct can_frame frame; ChillerTemp chiilerTemp = {0}; struct ChargingInfoData *pDcChargingInfo = NULL; int len = 0; char _info[1024]; int i; unsigned char GunStatus[2]; pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo(); pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData(); ShmCHAdeMOData = (struct CHAdeMOData *)GetShmCHAdeMOData(); ShmGBTData = (struct GBTData *)GetShmGBTData(); ShmCcsData = (struct CcsData *)GetShmCcsData(); ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData(); ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData(); ShmDcCommonData->pGunStatus[0].EVLoseTimer = time((time_t*)NULL); ShmDcCommonData->pGunStatus[1].EVLoseTimer = time((time_t*)NULL); //log_info("Module_EvRXComm Child's PID is %d", getpid()); while (isContinue) { memset(&frame, 0, sizeof(struct can_frame)); for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index); // 檢查是否有收到EV小板訊號 if (pSysInfo->SelfTestSeq == _STEST_COMPLETE) { if ((time((time_t*)NULL) - ShmDcCommonData->pGunStatus[_index].EVLoseTimer > 10) && !ShmDcCommonData->pGunStatus[_index].EVLoseFlag && pSysInfo->SelfTestSeq == _STEST_COMPLETE && pDcChargingInfo->SystemStatus != S_UPDATE && !ShmDcCommonData->debugflag) { ShmDcCommonData->pGunStatus[_index].EVLoseTimer = time((time_t*)NULL); ShmDcCommonData->pGunStatus[_index].EVLoseFlag = TRUE; system("/sbin/ip link set can0 down"); sleep(1); system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100"); system("/sbin/ip link set can0 up"); } } else { ShmDcCommonData->pGunStatus[targetGun].EVLoseTimer = time((time_t*)NULL); ShmDcCommonData->pGunStatus[targetGun].EVLoseFlag = FALSE; } CheckEvConnect(_index); } nbytes = read(fd, &frame, sizeof(struct can_frame)); if (nbytes <= 0) { usleep(10000); continue; } recvID = 0; targetGun = 0x00; intCmd = (int) (frame.can_id & CAN_EFF_MASK); if (intCmd == ADDRESS_REQ) { //ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0; AddrAssignment(frame.data); continue; } intCmd = (int) (frame.can_id & CAN_EFF_MASK & 0xFFFFFF00); recvID = ((uint8_t) (frame.can_id & 0x000000FF)); // 0x01 or 0x02 if (ShmDcCommonData->showCanPackage) { len = 0; len += sprintf(&_info[len], "CAN Dispenser <= EV Rx:\t[0x%X] ", frame.can_id); for (i = 0; i < nbytes; i++) { len += sprintf(&_info[len], "%X ", frame.data[i]); } len += sprintf(&_info[len], "\n"); printf("%s", _info); } for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { // 假設有找到回應的 Index pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index); //if (gun_count == 1 && // _chargingData[_index]->Type == _Type_CCS_2 && // ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0) { // target -= 1; //} if (pDcChargingInfo->Evboard_id == recvID) { targetGun = _index; break; } } if ((targetGun < 0) || (targetGun >= CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)) { log_info("EvComm (CANReceiver) : Target index = %x is < 0 or > QUANTITY ", targetGun); usleep(10000); continue; } //else if (gun_count == 1 && targetGun == 0 && findIndex == 1 && // ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0) { // // 這樣的條件下~ 也是單槍 CCS 舊版本的狀況 : 因為舊版 CCS 不會 timeout, then send request id // ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0; //} if (intCmd == 256) { log_info("EvComm command = 256"); usleep(10000); continue; } // Reset Connect Timer ShmDcCommonData->pGunStatus[targetGun].EVLoseTimer = time((time_t*)NULL); ShmDcCommonData->pGunStatus[targetGun].EVLoseFlag = FALSE; pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun); gunTypeIndex = pDcChargingInfo->type_index; switch (intCmd) { case NOTIFICATION_EV_STATUS: if (pDcChargingInfo->ConnectorPlugIn != frame.data[0]) { if (frame.data[0] == PLUG) { log_info("Conn %d, Plugin. ", targetGun); pDcChargingInfo->isEVCCIDVerify = false; #ifdef DD360Audi if (pSysConfig->isAuthrizeByEVCCID) pSysInfo->CurGunSelected = targetGun; #endif } else if (frame.data[0] == UNPLUG) { if (pDcChargingInfo->Type != _Type_CCS_2) log_info("Conn %d, Unplug. ", targetGun); strcpy( (char *) pDcChargingInfo->EVCCID, ""); } else { log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]); } if(pDcChargingInfo->RemoteStartFlag == YES) { pSysInfo->CurGunSelected = targetGun; } } pDcChargingInfo->PilotVoltage = frame.data[1]; // CCS 小板確認Pilot Voltage != 0 if (pDcChargingInfo->Type == _Type_CCS_2 && pDcChargingInfo->PilotVoltage != 0) { if (frame.data[0] == UNPLUG && pDcChargingInfo->ConnectorPlugIn != frame.data[0]) log_info("Conn %d, Unplug. ", targetGun); pDcChargingInfo->ConnectorPlugIn = frame.data[0]; } else { pDcChargingInfo->ConnectorPlugIn = frame.data[0]; } //log_info("index = %d, ConnectorPlugIn = %x, data[0] = %x ", // targetGun, // pDcChargingInfo->ConnectorPlugIn, // frame.data[0]); //log_info("ConnectorPlugIn = %x ", (-120 + frame.data[1]) / 10); break; case ACK_EV_FW_VERSION: memset(ver, 0, sizeof(ver)); if (pDcChargingInfo->Type == _Type_Chademo) { memcpy(ver, frame.data, frame.can_dlc); memcpy(ShmCHAdeMOData->evse[gunTypeIndex].version, ver, ARRAY_SIZE(ver)); ShmCHAdeMOData->evse[gunTypeIndex].SelfTest_Comp = PASS; log_info("chademo ver. : %s", ShmCHAdeMOData->evse[gunTypeIndex].version); } else if (pDcChargingInfo->Type == _Type_GB) { memcpy(ver, frame.data, frame.can_dlc); memcpy(ShmGBTData->evse[gunTypeIndex].version, ver, ARRAY_SIZE(ver)); ShmGBTData->evse[gunTypeIndex].SelfTest_Comp = PASS; log_info("gbt ver. : %s", ShmGBTData->evse[gunTypeIndex].version); } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { memcpy(ver, frame.data, frame.can_dlc); //DS60-120 add //for (uint8_t _vCount = 0, _vPoint = 0; _vCount < frame.can_dlc; _vCount++) {//DS60-120 remove /*if (_vCount % 2 == 0 && _vCount != 0) { ver[_vCount + _vPoint] = 0x2E; _vPoint++; }*/ //ver[_vCount + _vPoint] = frame.data[_vCount]; //} memcpy(&ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].version, ver, ARRAY_SIZE(ver)); ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].SelfTest_Comp = PASS; log_info("CCS FW = %s ", ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].version); } } if (targetGun == 0) { memset(pSysInfo->Connector1FwRev, 0, sizeof(pSysInfo->Connector1FwRev)); memcpy(pSysInfo->Connector1FwRev, ver, ARRAY_SIZE(ver)); } else if (targetGun == 1) { memset(pSysInfo->Connector2FwRev, 0, sizeof(pSysInfo->Connector2FwRev)); memcpy(pSysInfo->Connector2FwRev, ver, ARRAY_SIZE(ver)); } break; case ACK_EV_HW_VERSION: //log_info("Get EV HW = %s ", frame.data); break; case ACK_GET_OUTPUT_REQ: //DS60-120 add if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EV && pDcChargingInfo->SystemStatus <= S_TERMINATING) || pDcChargingInfo->SystemStatus == S_ALARM || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1) ) { if (pDcChargingInfo->EvBatteryStartSoc <= 0 && pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE) { pDcChargingInfo->EvBatteryStartSoc = frame.data[1]; } // 進入充電時重新更新電池電量 if (GunStatus[targetGun] != pDcChargingInfo->SystemStatus && pDcChargingInfo->SystemStatus == S_CHARGING) { log_info("Reset Gun%d SoC:%d", targetGun, frame.data[1]); pDcChargingInfo->EvBatterySoc = frame.data[1]; GunStatus[targetGun] = pDcChargingInfo->SystemStatus; } if (frame.data[1] > pDcChargingInfo->EvBatterySoc || pDcChargingInfo->SystemStatus == S_CHARGING) { pDcChargingInfo->EvBatterySoc = frame.data[1]; if (frame.data[1] > pDcChargingInfo->EvBatterySoc) log_info("Gun%d SOC:%d", targetGun,pDcChargingInfo->EvBatterySoc); } } //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove //Jerry add set voltage limit pDcChargingInfo->EvBatterytargetVoltage = (float)((frame.data[3] << 8) + frame.data[2]) / 10; if (pDcChargingInfo->EvBatterytargetVoltage > (GetMaxChargingVol(targetGun) * 0.1)) { pDcChargingInfo->EvBatterytargetVoltage = (GetMaxChargingVol(targetGun) * 0.1); } //printf("id = %d, EvBatterytargetVoltage = %.2f", targetGun, pDcChargingInfo->EvBatterytargetVoltage); //Jerry add set currency limit pDcChargingInfo->EvBatterytargetCurrent = (float)((frame.data[5] << 8) + frame.data[4]) / 10; if (pDcChargingInfo->EvBatterytargetCurrent > (GetMaxCharginigCur(targetGun) * 0.1)) { pDcChargingInfo->EvBatterytargetCurrent = (GetMaxCharginigCur(targetGun) * 0.1); } //printf("id = %d, EvBatterytargetCurrent = %.2f", targetGun, pDcChargingInfo->EvBatterytargetCurrent); pDcChargingInfo->RemainChargingDuration = ((short) frame.data[7] << 8) + (short) frame.data[6]; //printf("RemainChargingDuration = %d", pDcChargingInfo->RemainChargingDuration); if (pDcChargingInfo->Type == _Type_Chademo) { if (ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) { log_info("Gun%d CHAdeMO board status = %d ", targetGun, ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus); ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0]; ShmDcCommonData->pGunInfo[targetGun].EVStatus = frame.data[0]; } ShmCHAdeMOData->ev[gunTypeIndex].EvDetection = frame.data[0]; ShmCHAdeMOData->ev[gunTypeIndex].SOC = pDcChargingInfo->EvBatterySoc; ShmCHAdeMOData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10); ShmCHAdeMOData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10); } else if (pDcChargingInfo->Type == _Type_GB) { if (ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) { log_info("Gun%d GB Board status = %d ", targetGun, ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus); ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0]; ShmDcCommonData->pGunInfo[targetGun].EVStatus = frame.data[0]; } ShmGBTData->ev[gunTypeIndex].EvDetection = frame.data[0]; ShmGBTData->ev[gunTypeIndex].SOC = pDcChargingInfo->EvBatterySoc; ShmGBTData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10); ShmGBTData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10); } else if (pDcChargingInfo->Type == _Type_CCS_2) { if (ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus != frame.data[0] && frame.data[0] != 0xFF) { log_info("Gun%d CCS board status = %d ", targetGun, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus); ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus = frame.data[0]; ShmDcCommonData->pGunInfo[targetGun].EVStatus = frame.data[0]; } } if (pDcChargingInfo->EvBatterytargetVoltage > (EvTargetVolt[targetGun] + 5) || pDcChargingInfo->EvBatterytargetVoltage < (EvTargetVolt[targetGun] - 5) || pDcChargingInfo->EvBatterytargetCurrent >(EvTargetCur[targetGun] + 2) || pDcChargingInfo->EvBatterytargetCurrent < (EvTargetCur[targetGun] - 2)) { log_info("Gun%d TargetVoltage = %f , TargetCurrent = %f", targetGun, pDcChargingInfo->EvBatterytargetVoltage, pDcChargingInfo->EvBatterytargetCurrent); EvTargetVolt[targetGun] = pDcChargingInfo->EvBatterytargetVoltage; EvTargetCur[targetGun] = pDcChargingInfo->EvBatterytargetCurrent; } //log_info("EvBatterytargetVoltage = %f ", pDcChargingInfo->EvBatterytargetVoltage); //log_info("EvBatterytargetCurrent = %f ", pDcChargingInfo->EvBatterytargetCurrent); //log_info("BatteryVoltage = %d ", // ShmCHAdeMOData->ev[_chargingData[target]->type_index].TargetBatteryVoltage); //log_info("CurrentRequest = %d ", // ShmCHAdeMOData->ev[_chargingData[target]->type_index].ChargingCurrentRequest); break; case ACK_GET_EV_BATTERY_INFO: //_chargingData[target].EvACorDCcharging = frame.data[0]; //_chargingData[target]->TotalBatteryCap = ((float) frame.data[4] << 8) + (short) frame.data[3]; pDcChargingInfo->EvBatteryMaxVoltage = ((float)(((uint16_t)frame.data[4] << 8) + (uint16_t)frame.data[3])) / 10; //_chargingData[target]->EvBatteryMaxCurrent = ((float) frame.data[4] << 8) + (short) frame.data[3]; //_chargingData[target].MaxiBatteryCurrent = ((short) frame.data[6] << 8) + (short) frame.data[5]; if (pDcChargingInfo->Type == _Type_Chademo) { ShmCHAdeMOData->ev[gunTypeIndex].TotalBatteryCapacity = ((uint16_t)frame.data[2] << 8) + (uint16_t)frame.data[1]; ShmCHAdeMOData->ev[gunTypeIndex].MaxiBatteryVoltage = pDcChargingInfo->EvBatteryMaxVoltage; //log_info("EvBatteryMaxVoltage = %f ", _chargingData[target]->EvBatteryMaxVoltage); //log_info("TotalBatteryCapacity = %d ", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TotalBatteryCapacity); //log_info("MaxiBatteryVoltage = %d ", ShmCHAdeMOData->ev[_chargingData[target]->type_index].MaxiBatteryVoltage); } else if (pDcChargingInfo->Type == _Type_GB) { ShmGBTData->ev[gunTypeIndex].TotalBatteryCapacity = ((uint16_t)frame.data[2] << 8) + (uint16_t)frame.data[1]; ShmGBTData->ev[gunTypeIndex].MaxiBatteryVoltage = pDcChargingInfo->EvBatteryMaxVoltage; } //else if (pDcChargingInfo->Type == _Type_CCS_2) { //} break; case ACK_GET_MISCELLANEOUS_INFO: pDcChargingInfo->GunLocked = frame.data[0]; pDcChargingInfo->PilotVoltage = ((float)(-120 + frame.data[3])) / 10; if (pDcChargingInfo->Type == _Type_Chademo) { ShmCHAdeMOData->evse[gunTypeIndex].ConnectorTemperatureP = frame.data[1]; ShmCHAdeMOData->evse[gunTypeIndex].ConnectorTemperatureN = frame.data[2]; ShmCHAdeMOData->evse[gunTypeIndex].EvboardStatus = frame.data[7]; } else if (pDcChargingInfo->Type == _Type_GB) { ShmGBTData->evse[gunTypeIndex].ConnectorTemperatureP = frame.data[1]; ShmGBTData->evse[gunTypeIndex].ConnectorTemperatureN = frame.data[2]; ShmGBTData->evse[gunTypeIndex].EvboardStatus = frame.data[7]; } /*else if (pDcChargingInfo->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) { //ShmCcsData->V2GMessage_DIN70121[gunTypeIndex]. .ConnectorTemperatureP = frame.data[1]; //ShmCcsData->V2GMessage_DIN70121[gunTypeIndex]. .ConnectorTemperatureN = frame.data[2]; } }*/ ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] = frame.data[1]; ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] = frame.data[2]; if (ShmDcCommonData->TestTemperature == YES) { //ReadCmdline test break; } printChillerTemp = NO; printConnTemp = NO; if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) { getChillerTemperature(&chiilerTemp); memcpy((char *)ShmDcCommonData->SystemTemp, (char *)chiilerTemp.Temp, sizeof(ChillerTemp)); chillerTemp[0] = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]); chillerTemp[1] = getMaxConnectTemp(chiilerTemp.Temp[2], chiilerTemp.Temp[3]); if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) { // 單Chiller maxChillerTemp = getMaxConnectTemp(chillerTemp[0], chillerTemp[1]); } else { // 雙Chiller if (gunTypeIndex == 0) { maxChillerTemp = chillerTemp[0]; } else { maxChillerTemp = chillerTemp[1]; } } //if ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) { // printChillerTemp = YES; //} if(maxChillerTemp > (lastChillerTemp[gunTypeIndex] + 2) || maxChillerTemp < (lastChillerTemp[gunTypeIndex] - 2)) { lastChillerTemp[gunTypeIndex] = maxChillerTemp; printChillerTemp = YES; } pDcChargingInfo->ChillerTemp = maxChillerTemp; } if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) { maxConnTemp = getMaxConnectTemp(frame.data[1], frame.data[2]); //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) { // printConnTemp = YES; //} maxConnTemp = getAvageTemp(maxConnTemp, targetGun); if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2)) { lastConnTemp[targetGun] = maxConnTemp; printConnTemp = YES; } pDcChargingInfo->ConnectorTemp = maxConnTemp; } else { //log_info("Connector%d Tmep is zero:[%d,%d]", gunTypeIndex, ShmDcCommonData->ConnectorTemp[gunTypeIndex][0], // ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]); } //紀錄槍頭和水冷機溫度, 在系統狀態變化或溫度大於150 if ((ShmDcCommonData->SystemModeChange[targetGun] == YES) || (printConnTemp == YES) || (printChillerTemp == YES) //&& //(((pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) && // (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP)) || // ((pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) && // (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP))) ) { ShmDcCommonData->SystemModeChange[targetGun] = NO; log_info("Conn %d max temp = %d, chiller = [%d %d], chiller2 = [%d %d]", targetGun, pDcChargingInfo->ConnectorTemp, chiilerTemp.Temp[0], chiilerTemp.Temp[1], chiilerTemp.Temp[2], chiilerTemp.Temp[3]); } if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) { //沒有水冷槍 break; } if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) { //單一水冷槍,不需要切換水冷機油閥 //ShmFanModuleData-> ? = YES; //尚未定義 break; } //紀錄槍頭溫度 if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) { if (targetGun == 0) { ShmDcCommonData->ChillerValve.LeftTemp = pDcChargingInfo->ConnectorTemp; } else if (targetGun == 1) { ShmDcCommonData->ChillerValve.RightTemp = pDcChargingInfo->ConnectorTemp; } } //有兩把水冷槍,判斷兩把槍頭溫度,將水冷機節流閥導向溫度高的那一把槍 if (ShmDcCommonData->ChillerValve.LeftTemp > ShmDcCommonData->ChillerValve.RightTemp) { //ShmFanModuleData->? = YES; //尚未定義 } else { //ShmFanModuleData->? = NO; //尚未定義 } //log_info("EvboardStatus = %x ", // ShmCHAdeMOData->evse[gunTypeIndex].EvboardStatus); //log_info("ConnectorPlug locked = %x ", // frame.data[0]); //log_info("PilotVoltage = %x ", (-120 + frame.data[3]) / 10); break; case ACK_EVSE_ISOLATION_STATUS: break; case ACK_EVSE_PRECHAGE_INFO: pDcChargingInfo->PrechargeStatus = frame.data[0]; break; case NOTIFICATION_EV_STOP: // 車端要求停止 if ((pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && //DS60-120 add pDcChargingInfo->SystemStatus <= S_TERMINATING) || (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 && pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) { // frame.data[0] : 0x01 => normal stop, 0x02 => ev emergency stop /* log_info("----------------------------- Gun%d NOTIFICATION_EV_STOP err level = %d -----------------------------", targetGun, frame.data[0]); */ if (frame.data[0] == 0x02) { if (AbnormalStopAnalysis(targetGun, frame.data + 1) == true) { pDcChargingInfo->StopChargeFlag = YES; } else { pDcChargingInfo->NormalStopChargeFlag = YES; } } else { AbnormalStopAnalysis(targetGun, frame.data + 1); pDcChargingInfo->NormalStopChargeFlag = YES; } } break; case ACK_EVCCID_REQ: if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL && pDcChargingInfo->Type == _Type_CCS_2) { { memset ( ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID, 0, sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) ); memcpy ( ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID, frame.data, frame.can_dlc ); } sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0], frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] ); pDcChargingInfo->EVCCID [17] = '\0'; log_info( "Gun %d->EVCCID = %s ", targetGun, pDcChargingInfo->EVCCID ); } break; case ACK_DOWNLOAD_FINISH: log_info("Gun %d image download finish",targetGun); break; default: log_info("EV board = %d, Ack none defined. intCmd = %d ", targetGun, intCmd); break; }//switch usleep(10000); }//while } }