#include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include #include #include #include #include #include #include "../Define/define.h" #include "../ShareMemory/shmMem.h" #include "../Config.h" #include "../Log/log.h" #include "Module_InternalComm.h" #include "internalComm.h" //------------------------------------------------------------------------------ static struct SysConfigData *pSysConfig = NULL; static struct SysInfoData *pSysInfo = NULL; static struct AlarmCodeData *pAlarmCode = NULL; static struct InfoCodeData *pInfoCode = NULL; static struct FaultCodeData *pFaultCode = NULL; static struct OCPP16Data *ShmOCPP16Data = NULL; static int Uart5Fd = 0; static struct timespec _ac_charging_comp; static struct timespec _ac_preparing; static struct timeb _ac_startChargingTime; static struct timeb _ac_endChargingTime; static Ac_Status acStatus; static Ac_Led_Status ledStatus; static Ac_Alarm_code acAlarmCode; static Ac_Charging_energy acChargingEnergy; static Ac_Charging_current acChargingCurrent; static int _alarm_code[] = { AC_OVP, AC_UVP, AC_OCP, AC_OTP, AC_GMI_FAULT, AC_CP_ERROR, AC_AC_LEAKAGE, AC_DC_LEAKAGE, AC_SYSTEM_SELFTEST_FAULT, AC_HANDSHAKE_TIMEOUT, AC_EMC_STOP, AC_RELAY_WELDING, AC_GF_MODULE_FAULT, AC_SHUTTER_FAULT, AC_LOCKER_FAULT, AC_POWER_DROP, AC_CIRCUIT_SHORT, AC_ROTARY_SWITCH_FAULT, AC_RELAY_DRIVE_FAULT }; //------------------------------------------------------------------------------ static void OcppStopTransation(uint8_t gunIndex) { struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (strcmp((char *)pAcChargingInfo->StartUserId, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)pAcChargingInfo->StartUserId); } log_info("AC IdTag = %s \n", ShmOCPP16Data->StopTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StopTransactionReq = YES; } static void SetCpDuty(uint8_t _value) { Config_Ac_Duty(Uart5Fd, ADDR_AC_PLUG, _value); } static uint8_t GetChargingCurrent(void) { return Query_Charging_Current(Uart5Fd, ADDR_AC_PLUG, &acChargingCurrent); } static uint8_t GetChargingEnergy(void) { return Query_Charging_Energy(Uart5Fd, ADDR_AC_PLUG, &acChargingEnergy); } static void ChangeStartOrStopDateTime(uint8_t isStart) { char cmdBuf[32]; struct timeb csuTime; struct tm *tmCSU; struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); ftime(&csuTime); tmCSU = localtime(&csuTime.time); sprintf(cmdBuf, "%04d-%02d-%02d %02d:%02d:%02d", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); if (isStart) { strcpy((char *)pAcChargingInfo->StartDateTime, cmdBuf); } else { strcpy((char *)pAcChargingInfo->StopDateTime, cmdBuf); } } static void OcppStartTransation(uint8_t gunIndex) { struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (strcmp((char *)pAcChargingInfo->StartUserId, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)pAcChargingInfo->StartUserId); } log_info("AC IdTag = %s \n", ShmOCPP16Data->StartTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionReq = YES; } static void SetLegacyReq(uint8_t _switch) { Config_Legacy_Req(Uart5Fd, ADDR_AC_PLUG, _switch); } static void ChangeLedStatus(void) { struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (pAcChargingInfo->SystemStatus == S_IDLE) { ledStatus.ActionMode = 1; } else if (pAcChargingInfo->SystemStatus == S_PREPARNING) { ledStatus.ActionMode = 3; } else if (pAcChargingInfo->SystemStatus == S_CHARGING) { ledStatus.ActionMode = 4; } Config_LED_Status(Uart5Fd, ADDR_AC_PLUG, &ledStatus); } static uint8_t isModeChange(void) { uint8_t result = NO; struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (pAcChargingInfo->SystemStatus != pAcChargingInfo->PreviousSystemStatus) { result = YES; pAcChargingInfo->PreviousSystemStatus = pAcChargingInfo->SystemStatus; } return result; } static bool OcppRemoteStop(uint8_t gunIndex) { bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq; if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Remote"); ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO; } return result; } static void CheckAlarmOccur(void) { bool isErr = false; uint8_t count = 0; struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); for (count = 0; count < sizeof(_alarm_code) / sizeof(_alarm_code[0]); count++) { if (acAlarmCode.AcAlarmCode & _alarm_code[count]) { isErr = true; switch (_alarm_code[count]) { case AC_OVP: pAlarmCode->AlarmEvents.bits.AcSystemInputOVP = YES; break; case AC_UVP: pAlarmCode->AlarmEvents.bits.AcSystemInputUVP = YES; break; case AC_OCP: pAlarmCode->AlarmEvents.bits.SystemAcOutputOCP = YES; break; case AC_OTP: pAlarmCode->AlarmEvents.bits.SystemAmbientOTP = YES; break; case AC_GMI_FAULT: pAlarmCode->AlarmEvents.bits.AcGroundfaultFail = YES; break; case AC_CP_ERROR: pInfoCode->InfoEvents.bits.PilotFault = YES; break; case AC_AC_LEAKAGE: pAlarmCode->AlarmEvents.bits.RcdTrip = YES; break; case AC_DC_LEAKAGE: pAlarmCode->AlarmEvents.bits.RcdTrip = YES; break; case AC_SYSTEM_SELFTEST_FAULT: pAlarmCode->AlarmEvents.bits.McuSelftestFail = YES; break; case AC_HANDSHAKE_TIMEOUT: break; //case AC_EMC_STOP: pAlarmCode->AlarmEvents.bits.EmergencyStopTrip = YES; break; case AC_RELAY_WELDING: pFaultCode->FaultEvents.bits.AcOutputRelayWelding = YES; break; case AC_GF_MODULE_FAULT: pFaultCode->FaultEvents.bits.RcdSelfTestFail = YES; break; case AC_SHUTTER_FAULT: break; case AC_LOCKER_FAULT: pFaultCode->FaultEvents.bits.AcConnectorLockFail = YES; break; case AC_POWER_DROP: pAlarmCode->AlarmEvents.bits.SystemL1InputDrop = YES; break; case AC_CIRCUIT_SHORT: pAlarmCode->AlarmEvents.bits.CircuitShort = YES; break; case AC_ROTARY_SWITCH_FAULT: break; case AC_RELAY_DRIVE_FAULT: pFaultCode->FaultEvents.bits.AcOutputRelayDrivingFault = YES; break; } } else { switch (_alarm_code[count]) { case AC_OVP: pAlarmCode->AlarmEvents.bits.AcSystemInputOVP = NO; break; case AC_UVP: pAlarmCode->AlarmEvents.bits.AcSystemInputUVP = NO; break; case AC_OCP: pAlarmCode->AlarmEvents.bits.SystemAcOutputOCP = NO; break; case AC_OTP: pAlarmCode->AlarmEvents.bits.SystemAmbientOTP = NO; break; case AC_GMI_FAULT: pAlarmCode->AlarmEvents.bits.AcGroundfaultFail = NO; break; case AC_CP_ERROR: pInfoCode->InfoEvents.bits.PilotFault = NO; break; case AC_AC_LEAKAGE: pAlarmCode->AlarmEvents.bits.RcdTrip = NO; break; case AC_DC_LEAKAGE: pAlarmCode->AlarmEvents.bits.RcdTrip = NO; break; case AC_SYSTEM_SELFTEST_FAULT: pAlarmCode->AlarmEvents.bits.McuSelftestFail = NO; break; case AC_HANDSHAKE_TIMEOUT: break; //case AC_EMC_STOP: pAlarmCode->AlarmEvents.bits.EmergencyStopTrip = NO; break; case AC_RELAY_WELDING: pFaultCode->FaultEvents.bits.AcOutputRelayWelding = NO; break; case AC_GF_MODULE_FAULT: pFaultCode->FaultEvents.bits.RcdSelfTestFail = NO; break; case AC_SHUTTER_FAULT: break; case AC_LOCKER_FAULT: pFaultCode->FaultEvents.bits.AcConnectorLockFail = NO; break; case AC_POWER_DROP: pAlarmCode->AlarmEvents.bits.SystemL1InputDrop = NO; break; case AC_CIRCUIT_SHORT: pAlarmCode->AlarmEvents.bits.CircuitShort = NO; break; case AC_ROTARY_SWITCH_FAULT: break; case AC_RELAY_DRIVE_FAULT: pFaultCode->FaultEvents.bits.AcOutputRelayDrivingFault = NO; break; } } } pAcChargingInfo->IsErrorOccur = isErr; } static void GetAcAlarmCode(void) { if (Query_AC_Alarm_Code(Uart5Fd, ADDR_AC_PLUG, &acAlarmCode) == PASS) { CheckAlarmOccur(); } } static void GetAcStatus(void) { struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (Query_AC_Status(Uart5Fd, ADDR_AC_PLUG, &acStatus) == PASS) { pSysConfig->AcRatingCurrent = acStatus.MaxCurrent; if (pSysConfig->AcMaxChargingCurrent == 0) { pSysConfig->AcMaxChargingCurrent = pSysConfig->AcRatingCurrent; } pAcChargingInfo->ConnectorPlugIn = acStatus.CpStatus; // log_info("CpStatus = %d \n", acStatus.CpStatus); // printf("CurLimit = %d \n", acStatus.CurLimit); // printf("PilotVol_P = %d \n", acStatus.PilotVol_P); // printf("PilotVol_N = %d \n", acStatus.PilotVol_N); // printf("LockStatus = %d \n", acStatus.LockStatus); // printf("RelayStatus = %d \n", acStatus.RelayStatus); // printf("ShutterStatus = %d \n", acStatus.ShutterStatus); // printf("MeterStatus = %d \n", acStatus.MeterStatus); // printf("PpStatus = %d \n", acStatus.PpStatus); // printf("MaxCurrent = %d \n", acStatus.MaxCurrent); // printf("RotateSwitchStatus = %d \n", acStatus.RelayStatus); // printf("============================== \n"); // // pAcChargingInfo->SystemStatus = acStatus.CpStatus; } // else // log_info("GetAcStatus return fail. \n"); } static void ChangeToCsuMode(void) { struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); pAcChargingInfo->IsModeChagned = Config_CSU_Mode(Uart5Fd, ADDR_AC_PLUG); // if (pAcChargingInfo->IsModeChagned == PASS) // { // Config_Reset_MCU(Uart5Fd, ADDR_AC_PLUG); // } } static void GetAcModelName(void) { memset(pSysConfig->AcModelName, 0, sizeof(pSysConfig->AcModelName)); if (Query_Model_Name(Uart5Fd, ADDR_AC_PLUG, pSysConfig->AcModelName) == PASS) { log_info("ac model name = %s \n", pSysConfig->AcModelName); } } static void GetFwVersion_AC(void) { Ver ver = {0}; struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); if (Query_FW_Ver(Uart5Fd, ADDR_AC_PLUG, &ver) == PASS) { pAcChargingInfo->SelfTest_Comp = YES; strcpy((char *)pAcChargingInfo->version, ver.Version_FW); } } void AcPlugTask(int uartFD) { static float _beforeChargingTotalEnergy = 0.0; if (pSysConfig->AcConnectorCount <= 0) { return; } //share memory mapping pSysConfig = (struct SysConfigData *)GetShmSysConfigData(); pSysInfo = (struct SysInfoData *)GetShmSysInfoData(); pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData(); pInfoCode = (struct InfoCodeData *)GetShmInfoCodeData(); pFaultCode = (struct FaultCodeData *)GetShmFaultCodeData(); ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data(); struct ChargingInfoData *pAcChargingInfo = (struct ChargingInfoData *)GetAcChargingInfoData(0); Uart5Fd = uartFD; //pAcChargingInfo->SelfTest_Comp = YES; //pAcChargingInfo->IsModeChagned = PASS; //--------------------------------------------- if (pAcChargingInfo->SelfTest_Comp == NO) { pAcChargingInfo->IsModeChagned = NO; GetFwVersion_AC(); GetAcModelName(); } else if (pAcChargingInfo->SelfTest_Comp == YES) { if (pAcChargingInfo->IsModeChagned != PASS) { ChangeToCsuMode(); return; } GetAcStatus(); GetAcAlarmCode(); uint8_t _status = S_NONE; if (pAcChargingInfo->SystemStatus == S_IDLE && pAcChargingInfo->IsErrorOccur) { _status = S_ALARM; } else if (acStatus.CpStatus == AC_SYS_A || pAcChargingInfo->IsErrorOccur) { if (pAcChargingInfo->SystemStatus == S_CHARGING) { _status = S_TERMINATING; } else if (pAcChargingInfo->SystemStatus >= S_TERMINATING) { if (GetClockTimeoutValue(_ac_charging_comp) >= 10000000 && acStatus.CpStatus == AC_SYS_A) { _status = S_IDLE; } } else { _status = S_IDLE; } } else if (pAcChargingInfo->SystemStatus >= S_PREPARNING && pAcChargingInfo->SystemStatus < S_CHARGING) { if (acStatus.CpStatus == AC_SYS_C && acStatus.RelayStatus == YES) { _status = S_CHARGING; } else if (GetClockTimeoutValue(_ac_preparing) >= 30000000) { _status = S_IDLE; } } else if ((acStatus.CpStatus == AC_SYS_B || pAcChargingInfo->ConnectorPlugIn == AC_SYS_B) && pAcChargingInfo->IsAvailable && !pAcChargingInfo->IsErrorOccur && (pSysInfo->WaitForPlugit == YES || pSysConfig->AuthorisationMode == AUTH_MODE_DISABLE)) { if (pAcChargingInfo->RemoteStartFlag == YES) { log_info("** AC Remote \n"); pAcChargingInfo->RemoteStartFlag = NO; strcpy((char *)pAcChargingInfo->StartUserId, ""); pSysInfo->WaitForPlugit = NO; _status = S_PREPARNING; } else if (pSysInfo->OrderCharging == NO_DEFINE) { log_info("** UserId = %s \n", pSysConfig->UserId); strcpy((char *)pAcChargingInfo->StartUserId, (char *)pSysConfig->UserId); log_info("** CardNumber = %s \n", pAcChargingInfo->StartUserId); strcpy((char *)pSysConfig->UserId, ""); pSysInfo->WaitForPlugit = NO; _status = S_PREPARNING; } } else if (pAcChargingInfo->SystemStatus == S_CHARGING) { if (OcppRemoteStop(1)) { _status = S_TERMINATING; } } //printf("_status = %d \n", _status); if (_status != S_NONE && pAcChargingInfo->SystemStatus != _status) { pAcChargingInfo->SystemStatus = _status; } // 設定限制最大充電電流 >= 6 ~ <= 32 switch (pAcChargingInfo->SystemStatus) { case S_IDLE: case S_ALARM: { if (isModeChange()) { pAcChargingInfo->PresentChargedEnergy = 0.0; pAcChargingInfo->PresentChargingVoltage = 0; pAcChargingInfo->ChargingFee = 0.0; strcpy((char *)pAcChargingInfo->StartDateTime, ""); strcpy((char *)pAcChargingInfo->StopDateTime, ""); _beforeChargingTotalEnergy = 0.0; } ChangeLedStatus(); } break; case S_PREPARNING: { if (isModeChange()) { pSysInfo->SystemPage = _PAGE_PRECHARGE; pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX; if (pSysInfo->OrderCharging != NO_DEFINE) { pSysInfo->OrderCharging = NO_DEFINE; } GetClockTime(&_ac_preparing, NULL); } if (GetChargingEnergy() == PASS) { //pAcChargingInfo->PresentChargedEnergy = acChargingEnergy.Energy / 100; _beforeChargingTotalEnergy = acChargingEnergy.Energy; } SetLegacyReq(YES); ChangeLedStatus(); } break; case S_CHARGING: { if (isModeChange()) { ftime(&_ac_startChargingTime); OcppStartTransation(1); ChangeStartOrStopDateTime(YES); pSysInfo->CurGunSelectedByAc = DEFAULT_AC_INDEX; } if (GetChargingEnergy() == PASS) { if ((acChargingEnergy.Energy - _beforeChargingTotalEnergy) > 0) { pAcChargingInfo->PresentChargedEnergy += (acChargingEnergy.Energy - _beforeChargingTotalEnergy) / 100; if (pSysConfig->BillingData.isBilling) { pAcChargingInfo->ChargingFee += pAcChargingInfo->PresentChargedEnergy * pSysConfig->BillingData.Cur_fee; } } _beforeChargingTotalEnergy = acChargingEnergy.Energy; } if (GetChargingCurrent() == PASS) { pAcChargingInfo->PresentChargingPower = (((float)(AC_DEFAULT_VOL * acChargingCurrent.OuputCurrentL1) / 10) / 1000); } ftime(&_ac_endChargingTime); pAcChargingInfo->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime); pAcChargingInfo->PresentChargingVoltage = AC_DEFAULT_VOL; pAcChargingInfo->PresentChargingCurrent = ((float)acChargingCurrent.OuputCurrentL1 / 10); // 用以判斷是否有在輸出 pAcChargingInfo->IsCharging = acStatus.RelayStatus; SetCpDuty(pSysConfig->AcMaxChargingCurrent); ChangeLedStatus(); } break; case S_TERMINATING: { if (isModeChange()) { ChangeStartOrStopDateTime(NO); GetClockTime(&_ac_charging_comp, NULL); } SetLegacyReq(NO); if (acStatus.RelayStatus == NO) { pAcChargingInfo->SystemStatus = S_COMPLETE; } } break; case S_COMPLETE: { if (isModeChange()) { GetClockTime(&_ac_charging_comp, NULL); ftime(&_ac_endChargingTime); if (strcmp((char *)pAcChargingInfo->StartDateTime, "") != EQUAL) { // AC 固定為第2把槍 OcppStopTransation(1); } ChangeStartOrStopDateTime(NO); pAcChargingInfo->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime); } } break; } } }