12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520 |
- /*
- * Module_SmartBox.c
- *
- * Created on: 2022年5月3日
- * Author: 7564
- */
- #include "Module_SmartBox.h"
- struct SysConfigAndInfo *ShmSysConfigAndInfo;
- struct StatusCodeData *ShmStatusCodeData;
- struct PsuData *ShmPsuData;
- struct DcCommonInformation *ShmDcCommonData;
- struct SmartBoxData *ShmSmartBoxData;
- struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
- byte ConnectorUsingSeq[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY][4] =
- {{0, 2, 3, 1}, {1, 3, 2, 0}};
- struct timespec _log_time;
- #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
- #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
- #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
- int StoreLogMsg(const char *fmt, ...)
- {
- char Buf[4096+256];
- char buffer[4096];
- va_list args;
- struct timeb SeqEndTime;
- struct tm *tm;
- va_start(args, fmt);
- int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
- va_end(args);
- memset(Buf,0,sizeof(Buf));
- ftime(&SeqEndTime);
- SeqEndTime.time = time(NULL);
- tm=localtime(&SeqEndTime.time);
- if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
- {
- sprintf(Buf,"%02d:%02d:%02d:%03d - %s",
- tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm, buffer);
- printf("%s \n", Buf);
- }
- else
- {
- sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s_Log",
- tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
- buffer,
- tm->tm_year+1900,tm->tm_mon+1,
- ShmSysConfigAndInfo->SysConfig.SerialNumber);
- system(Buf);
- }
- return rc;
- }
- void PRINTF_FUNC(char *string, ...)
- {
- va_list args;
- char buffer[4096];
- va_start(args, string);
- vsnprintf(buffer, sizeof(buffer), string, args);
- va_end(args);
- DEBUG_INFO("%s ", buffer);
- }
- //==========================================
- // Init all share memory
- //==========================================
- int InitShareMemory()
- {
- int result = PASS;
- int MeterSMId;
- //creat ShmSysConfigAndInfo
- if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmget ShmSysConfigAndInfoKey NG %d \n");
- #endif
- result = FAIL;
- }
- else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
- #endif
- result = FAIL;
- }
- //creat ShmStatusCodeData
- if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmget ShmStatusCodeKey NG \n");
- #endif
- result = FAIL;
- }
- else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
- #endif
- result = FAIL;
- }
- //creat ShmPsuData
- if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmget ShmPsuKey NG \n");
- #endif
- result = FAIL;
- }
- else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmPsuData NG \n");
- #endif
- result = FAIL;
- }
- if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmget ShmCommonKey NG \n");
- #endif
- result = FAIL;
- }
- else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmDcCommonData NG \n");
- #endif
- result = FAIL;
- }
- if ((MeterSMId = shmget ( ShmSmartBoxKey, sizeof(struct SmartBoxData), IPC_CREAT | 0777 )) < 0)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmSmartBoxKey NG \n");
- #endif
- return FAIL;
- }
- else if ((ShmSmartBoxData = shmat ( MeterSMId, NULL, 0 )) == (void *) - 1)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("shmat ShmSmartBoxData NG \n");
- #endif
- return FAIL;
- }
- return result;
- }
- //==========================================
- // Public Function
- //==========================================
- bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
- {
- for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
- {
- if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
- {
- chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
- return true;
- }
- }
- for (byte index = 0; index < CCS_QUANTITY; index++)
- {
- if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
- {
- chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
- return true;
- }
- }
- for (byte index = 0; index < GB_QUANTITY; index++)
- {
- if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
- {
- chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
- return true;
- }
- }
- return false;
- }
- void Initialization()
- {
- bool isPass = false;
- while(!isPass)
- {
- isPass = true;
- for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
- {
- if (!FindChargingInfoData(_index, &chargingInfo[0]))
- {
- DEBUG_ERROR("SmartBox (main) : FindChargingInfoData false \n");
- isPass = false;
- break;
- }
- }
- sleep(1);
- }
- for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
- {
- ShmSmartBoxData->Dynamic4Fetch[_index].ShareGroup = NONE_GROUP_CAN_SELECTED;
- ShmSmartBoxData->Dynamic4Fetch[_index].TargetRelay = NONE_RELAY_SELECTED;
- ShmSmartBoxData->Dynamic4Fetch[_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_NONE;
- ShmSmartBoxData->Dynamic4Release[_index].ReleaseGroup = NONE_GROUP_CAN_SELECTED;
- ShmSmartBoxData->Dynamic4Release[_index].TargetRelay = NONE_RELAY_SELECTED;
- ShmSmartBoxData->Dynamic4Release[_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
- ShmSmartBoxData->ConnectorUsingGroupCount[_index] = 0;
- }
- }
- void PrintfLog()
- {
- if (ShmPsuData->Work_Step != _WORK_CHARGING)
- {
- PRINTF_FUNC ( "****************************************************************** \n" );
- PRINTF_FUNC ( "SystemPresentPsuQuantity = %d \n", ShmPsuData->SystemPresentPsuQuantity);
- PRINTF_FUNC ( "SystemAvailableCurrent = %d (A) \n", ShmPsuData->SystemAvailableCurrent / 10);
- PRINTF_FUNC ( "SystemAvailablePower = %d (kw) \n", ShmPsuData->SystemAvailablePower / 10);
- PRINTF_FUNC ( "GroupCount = %d \n", ShmPsuData->GroupCount );
- for (int _count = 0; _count < ARRAY_SIZE(ConnectorUsingSeq[0]); _count ++)
- {
- PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
- PRINTF_FUNC ( "Group Index = %d, UsingTarget for Gun-%d \n", _count, ShmPsuData->PsuGroup[_count].UsingTarget);
- PRINTF_FUNC ( "GroupPresentPsuQuantity = %d \n", ShmPsuData->PsuGroup[_count].GroupPresentPsuQuantity );
- PRINTF_FUNC ( "GroupTargetOutputVoltage = %d (V) \n", ShmPsuData->PsuGroup[_count].GroupTargetOutputVoltage / 10);
- PRINTF_FUNC ( "GroupTargetOutputCurrent = %d (A) \n", ShmPsuData->PsuGroup[_count].GroupTargetOutputCurrent / 10);
- PRINTF_FUNC ( "GroupAvailableCurrent = %d (A) \n", ShmPsuData->PsuGroup[_count].GroupAvailableCurrent / 10);
- PRINTF_FUNC ( "GroupAvailablePower = %d (kw) \n", ShmPsuData->PsuGroup[_count].GroupAvailablePower / 10);
- PRINTF_FUNC ( "GroupMaxVoltage = %d (V) \n", ShmPsuData->PsuGroup[_count].GroupMaxVoltage / 10);
- PRINTF_FUNC ( "GroupPresentOutputVoltage = %.1f (V) \n", (double)ShmPsuData->PsuGroup[_count].GroupPresentOutputVoltage / 10);
- PRINTF_FUNC ( "GroupPresentOutputCurrent = %.1f (A) \n", (double)ShmPsuData->PsuGroup[_count].GroupPresentOutputCurrent / 10);
- PRINTF_FUNC ( "GroupPresentOutputPower = %d \n", ShmPsuData->PsuGroup[_count].GroupPresentOutputPower );
- PRINTF_FUNC ( "TotalRatingPower = %f \n", (double)ShmPsuData->PsuGroup[_count].TotalRatingPower);
- PRINTF_FUNC ( "TotalIAvailableCurrent = %f \n", (double)ShmPsuData->PsuGroup[_count].TotalIAvailableCurrent / 10);
- }
- }
- else
- {
- for (byte conn = 0; conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; conn++)
- {
- byte totalUsingGpCount = 0;
- byte totalQuantity = 0;
- unsigned short _targetVol = 0 , _targetCur = 0;
- unsigned short _avaCur = 0 , _avaPow = 0;
- unsigned short _outputVol = 0 , _outputCur = 0;
- unsigned short _ratingPow = 0;
- for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount[conn]; gp++)
- {
- if (ShmPsuData->PsuGroup[ConnectorUsingSeq[conn][gp]].UsingTarget == GUN_LEFT)
- {
- totalUsingGpCount++;
- byte tarGp = ConnectorUsingSeq[conn][gp];
- totalQuantity += ShmPsuData->PsuGroup[tarGp].GroupPresentPsuQuantity;
- _targetVol = ShmPsuData->PsuGroup[tarGp].GroupTargetOutputVoltage / 10;
- _targetCur += ShmPsuData->PsuGroup[tarGp].GroupTargetOutputCurrent / 10;
- _avaCur += ShmPsuData->PsuGroup[tarGp].GroupAvailableCurrent / 10;
- _avaPow += ShmPsuData->PsuGroup[tarGp].GroupAvailablePower / 10;
- _outputVol = (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputVoltage / 10;
- _outputCur = (double)ShmPsuData->PsuGroup[tarGp].GroupPresentOutputCurrent / 10;
- _ratingPow += ShmPsuData->PsuGroup[tarGp].TotalRatingPower;
- }
- }
- if (totalUsingGpCount > 0)
- {
- PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
- PRINTF_FUNC ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount);
- PRINTF_FUNC ( "totalQuantity = %d \n", totalQuantity);
- PRINTF_FUNC ( "_targetVol = %d (V), _targetCur = %d (A) \n", _targetVol, _targetCur);
- PRINTF_FUNC ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow);
- PRINTF_FUNC ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur);
- PRINTF_FUNC ( "_ratingPow = %d \n", _ratingPow);
- }
- for (byte gp = 0; gp < ShmSmartBoxData->ConnectorUsingGroupCount[conn]; gp++)
- {
- if (ShmPsuData->PsuGroup[ConnectorUsingSeq[conn][gp]].UsingTarget == GUN_RIGHT)
- {
- totalUsingGpCount++;
- byte tarGp = ConnectorUsingSeq[conn][gp];
- totalQuantity += ShmPsuData->PsuGroup [tarGp].GroupPresentPsuQuantity;
- _targetVol = ShmPsuData->PsuGroup [tarGp].GroupTargetOutputVoltage / 10;
- _targetCur += ShmPsuData->PsuGroup [tarGp].GroupTargetOutputCurrent / 10;
- _avaCur += ShmPsuData->PsuGroup [tarGp].GroupAvailableCurrent / 10;
- _avaPow += ShmPsuData->PsuGroup [tarGp].GroupAvailablePower / 10;
- _outputVol = (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputVoltage / 10;
- _outputCur = (double) ShmPsuData->PsuGroup [tarGp].GroupPresentOutputCurrent / 10;
- _ratingPow += ShmPsuData->PsuGroup [tarGp].TotalRatingPower;
- }
- }
- if (totalUsingGpCount > 0)
- {
- PRINTF_FUNC ( "----------------------------------------------------------------- \n" );
- PRINTF_FUNC ( "Group Index = %d, totalUsingGpCount = %d \n", conn, totalUsingGpCount);
- PRINTF_FUNC ( "totalQuantity = %d \n", totalQuantity);
- PRINTF_FUNC ( "_targetVol = %d (V), _targetCur = %d (A) \n", _targetVol, _targetCur);
- PRINTF_FUNC ( "_avaCur = %d (A), _avaPow = %d (kw) \n", _avaCur, _avaPow);
- PRINTF_FUNC ( "_outputVol = %d (V), _outputCur = %d (A) \n", _outputVol, _outputCur);
- PRINTF_FUNC ( "_ratingPow = %d \n", _ratingPow);
- }
- }
- }
- }
- void GetSystemMaxVoltage()
- {
- if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
- {
- int _sysVol = 0;
- for (byte group = 0; group < ShmPsuData->GroupCount; group++)
- {
- if (ShmPsuData->PsuGroup[group].GroupMaxVoltage > _sysVol)
- _sysVol = ShmPsuData->PsuGroup[group].GroupMaxVoltage;
- }
- for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
- {
- if (chargingInfo[gun_index]->MaximumChargingVoltage != _sysVol)
- {
- chargingInfo[gun_index]->MaximumChargingVoltage = _sysVol;
- }
- }
- }
- }
- void GetTimespecFunc(struct timespec *time)
- {
- clock_gettime(CLOCK_MONOTONIC, time);
- }
- long int GetTimeoutValue(struct timespec *startTime)
- {
- struct timespec endTime;
- clock_gettime(CLOCK_MONOTONIC, &endTime);
- return 1000 * (endTime.tv_sec - startTime->tv_sec) + (endTime.tv_nsec - startTime->tv_nsec) / 1000000;
- }
- //==========================================
- // Relay Processing
- //==========================================
- void SmartRelayCheck()
- {
- /*
- ---------------------------------------
- G_0 -----------(R1)----------------> Gun - 0
- | -> R3
- G_2 --------|
- | -> R4
- G_3 --------|
- | -> R5
- G_1 -----------(R2)----------------> Gun - 1
- ---------------------------------------
- R3 ON 時機 : G_2 屬於 Gun-0 輸出、G_0屬於 Gun - 1 輸出
- R4 ON 時機 : G_3 屬於 Gun-0 輸出、G_2屬於 Gun - 1 輸出
- R5 ON 時機 : G_3 屬於 Gun-1 輸出、G_1屬於 Gun - 0 輸出
- -------------------------
- 掃描PSU四個群及兩輸出的ShareGroup內的值各屬於哪個輸出
- */
- byte _buff[3] = {0};
- for (byte group = 0; group < ShmPsuData->GroupCount; group++)
- {
- switch(group)
- {
- case _PSU_GROUP_INDEX_0:
- {
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
- {
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- }
- else
- {
- // R3 ON
- _buff[_RELAY_SWITCH_NAME_R3] = 0x01;
- }
- }
- }
- break;
- case _PSU_GROUP_INDEX_2:
- {
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
- {
- // R3 ON
- _buff[_RELAY_SWITCH_NAME_R3] = 0x01;
- }
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
- {
- // R4 ON
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- }
- }
- break;
- case _PSU_GROUP_INDEX_3:
- {
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
- {
- // R4 ON
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- }
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_RIGHT)
- {
- // R5 ON
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- }
- }
- break;
- case _PSU_GROUP_INDEX_1:
- {
- if (ShmPsuData->PsuGroup[group].UsingTarget == GUN_LEFT)
- {
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- }
- else
- {
- // R5 ON
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- }
- }
- }
- break;
- }
- }
- for (byte _Conn = 0; _Conn < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _Conn++)
- {
- if (ShmSmartBoxData->Dynamic4Fetch[_Conn].FetchLoopStep >= _PSU_DYNAMIC_FETCH_STEP_RELAY)
- {
- byte targetGroup = ShmSmartBoxData->Dynamic4Fetch[_Conn].ShareGroup;
- switch(targetGroup)
- {
- case _PSU_GROUP_INDEX_0:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- else
- {
- // R3 ON -- P
- _buff[_RELAY_SWITCH_NAME_R3] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
- }
- }
- }
- break;
- case _PSU_GROUP_INDEX_2:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // R3 ON -- P
- _buff[_RELAY_SWITCH_NAME_R3] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
- }
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // R4 ON -- P
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- }
- break;
- case _PSU_GROUP_INDEX_3:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // R4 ON -- P
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // R5 ON -- P
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
- }
- }
- break;
- case _PSU_GROUP_INDEX_1:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x01;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- else
- {
- // R5 ON -- P
- _buff[_RELAY_SWITCH_NAME_R5] = 0x01;
- ShmSmartBoxData->Dynamic4Fetch[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
- }
- }
- }
- break;
- }
- }
- if (ShmSmartBoxData->Dynamic4Release[_Conn].ReleaseLoopStep >= _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF)
- {
- byte targetGroup = ShmSmartBoxData->Dynamic4Release[_Conn].ReleaseGroup;
- switch(targetGroup)
- {
- case _PSU_GROUP_INDEX_0:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // R3 OFF
- _buff[_RELAY_SWITCH_NAME_R3] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x00;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- }
- }
- break;
- case _PSU_GROUP_INDEX_2:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // R3 OFF
- _buff[_RELAY_SWITCH_NAME_R3] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R3;
- }
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // R5 OFF
- _buff[_RELAY_SWITCH_NAME_R4] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- }
- break;
- case _PSU_GROUP_INDEX_3:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // R4 OFF
- _buff[_RELAY_SWITCH_NAME_R4] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_RIGHT)
- {
- // R5 OFF
- _buff[_RELAY_SWITCH_NAME_R5] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
- }
- }
- break;
- case _PSU_GROUP_INDEX_1:
- {
- if (ShmPsuData->PsuGroup[targetGroup].UsingTarget == GUN_LEFT)
- {
- // 如果是標準品
- if(ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD)
- {
- _buff[_RELAY_SWITCH_NAME_R4] = 0x00;
- _buff[_RELAY_SWITCH_NAME_R5] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R4;
- }
- else
- {
- // R4 OFF
- _buff[_RELAY_SWITCH_NAME_R5] = 0x00;
- ShmSmartBoxData->Dynamic4Release[_Conn].TargetRelay = _RELAY_SWITCH_NAME_R5;
- }
- }
- }
- break;
- }
- }
- }
- memcpy(ShmSmartBoxData->ParallelRelayStatus, _buff, sizeof(_buff));
- }
- //==========================================
- // Sub Processing
- //==========================================
- void Assign2ConnectorProcessing(byte _targetConn)
- {
- // 根據現在該槍拿到的群數量, 依順去設定群的使用目標為左 /右槍
- // 一旦設定該模塊目標為左 /右槍後,AssignedPwr2Connector function 會將該模塊的資訊給對應的左/右槍
- for (byte aGp = 0; aGp < ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]; aGp++)
- {
- if (ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][aGp]].IsUsing == YES)
- {
- ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][aGp]].UsingTarget = _targetConn;
- }
- }
- }
- // 將_group該群的模塊配給_targetConn槍號
- void AddGroup2Connector(byte _targetConn, byte _group)
- {
- ShmPsuData->PsuGroup[_group].IsUsing = YES;
- if ((ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES && _targetConn == GUN_RIGHT) ||
- (ShmDcCommonData->systemType == _SYSTEM_TYPE_STANDARD && ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn] > 0))
- ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn] = 4;
- else
- ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]++;
- // 對應到相對群
- Assign2ConnectorProcessing(_targetConn);
- }
- // 將targetGp該群的模塊從_targetConn槍號移除
- bool ReleaseConnectorProcessing(byte _targetConn, byte targetGp)
- {
- bool result = false;
- if (ShmPsuData->PsuGroup[targetGp].PwSwitchStatus == _PSU_POWER_STATUS_OFF)
- {
- result = true;
- ShmPsuData->PsuGroup[targetGp].UsingTarget = GUN_CHECK;
- ShmPsuData->PsuGroup[targetGp].IsUsing = NO;
- ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn]--;
- }
- return result;
- }
- //==========================================
- // Fetch fork
- //==========================================
- void InitializeDynamicFetch(byte _targetConn)
- {
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup = NONE_GROUP_CAN_SELECTED;
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay = NONE_RELAY_SELECTED;
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent = 0;
- ShmSmartBoxData->SmartChk[_targetConn].IsFetchStart = NO;
- }
- void FetchLoopProcessing(byte _targetConn)
- {
- byte targetGroup = ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup;
- if (targetGroup == NONE_GROUP_CAN_SELECTED &&
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep >= _PSU_DYNAMIC_FETCH_STEP_TG_VOL)
- {
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
- }
- // 用 target vol 比較好還是用當前火線電壓 ? 可以試試看~
- float EvVoltage = chargingInfo[_targetConn]->EvBatterytargetVoltage * 10;
- switch(ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep)
- {
- case _PSU_DYNAMIC_FETCH_STEP_NONE:
- case _PSU_DYNAMIC_FETCH_STEP_WAIT:{ } break;
- case _PSU_DYNAMIC_FETCH_STEP_TG_VOL:
- {
- // 該群升壓
- if (ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage != 0)
- {
- PRINTF_FUNC("EV_ReqVoltage = %f, targetGroup = %d, Group_CurVoltage = %d \n",
- EvVoltage, targetGroup, ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage);
- }
- if (EvVoltage <= PSU_MIN_VOL)
- {
- PRINTF_FUNC("***** FETCH_STEP_ABORT ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
- }
- else if (ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputVoltage >= EvVoltage - PSU_TG_VOL_GAP)
- {
- PRINTF_FUNC("***** FETCH_STEP_RELAY ***** (Gun - %d) \n", _targetConn);
- ShmPsuData->PsuGroup[targetGroup].UsingTarget = _targetConn;
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_RELAY;
- }
- }
- break;
- case _PSU_DYNAMIC_FETCH_STEP_RELAY:
- {
- // 搭上對應的 Relay
- if (ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay < ARRAY_SIZE(ShmSmartBoxData->ParallelRelayStatus))
- {
- if (ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay] == YES)
- {
- if (ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Fetch[_targetConn].TargetRelay] == YES)
- {
- PRINTF_FUNC("***** FETCH_STEP_CUR_SHARE ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_CUR_SHARE;
- }
- }
- }
- }
- break;
- case _PSU_DYNAMIC_FETCH_STEP_CUR_SHARE:
- {
- // 均流 : 目標電流 = 當前電流 / (原本輸出群個數 + share group 個數)
- PRINTF_FUNC("GroupPresent = %d (0.1A), ShareTarget = %d (0.1A), CurrentPresent = %.1f \n",
- ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent,
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent,
- chargingInfo[_targetConn]->PresentChargingCurrent);
- if ((ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent >= ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent - PSU_TG_CUR_GAP &&
- ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent <= ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareTargetCurrent + PSU_TG_CUR_GAP) ||
- chargingInfo[_targetConn]->PresentChargingCurrent <= PSU_MIN_CUR)
- {
- PRINTF_FUNC("***** FETCH_STEP_WATI_FINISH ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_WATI_FINISH;
- }
- }
- break;
- case _PSU_DYNAMIC_FETCH_STEP_WATI_FINISH:
- {
- AddGroup2Connector(_targetConn, targetGroup);
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
- PRINTF_FUNC("***** FETCH_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].ShareGroup = NONE_GROUP_CAN_SELECTED;
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
- }
- break;
- case _PSU_DYNAMIC_FETCH_STEP_FINISH:
- {
- // 完成
- int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
- if (_t >= FETCH_FINISH_WAIT_TIME)
- {
- InitializeDynamicFetch(_targetConn);
- PRINTF_FUNC("***** FETCH_STEP_NONE ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_NONE;
- }
- }
- break;
- case _PSU_DYNAMIC_FETCH_STEP_ABORT:
- {
- // 中斷
- if (ShmPsuData->PsuGroup[targetGroup].IsUsing)
- {
- ShmPsuData->PsuGroup[targetGroup].IsUsing = NO;
- ShmPsuData->PsuGroup[targetGroup].UsingTarget = GUN_CHECK;
- }
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[_targetConn].FetchLoopTime);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
- }
- break;
- }
- }
- byte CheckRemainPwrByConIndex(byte _targetConn)
- {
- byte result = NONE_GROUP_CAN_SELECTED;
- // 該槍已經使用的群數量
- byte usingCount = ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn];
- for (byte Gp = usingCount; Gp < ARRAY_SIZE(ConnectorUsingSeq[_targetConn]); Gp++)
- {
- // 判斷是否有該槍下一個可用群的狀態
- if (ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][Gp]].IsUsing == NO &&
- ShmPsuData->PsuGroup[ConnectorUsingSeq[_targetConn][Gp]].GroupPresentPsuQuantity > 0)
- {
- result = ConnectorUsingSeq[_targetConn][Gp];
- break;
- }
- }
- return result;
- }
- void Chk2StopFetchStep(byte _targetConn)
- {
- // 開始流程後,就讓流程走完吧~
- if (ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep > _PSU_DYNAMIC_FETCH_STEP_NONE &&
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep < _PSU_DYNAMIC_FETCH_STEP_TG_VOL)
- {
- PRINTF_FUNC("***** FETCH_STEP_ABORT ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Fetch[_targetConn].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
- }
- }
- bool GetCanFetchResult(byte gun_index)
- {
- // 如果當前輸出接近實際可提供的能量 (距離 <= CAP_GAP_FETCH <3KW>)
- // 不取 EvBatterytargetVoltage 原因是小板會將該值做不同的處理方式
- float needPower = chargingInfo[gun_index]->PresentChargingVoltage *
- chargingInfo[gun_index]->EvBatterytargetCurrent / 100;
- ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch =
- (needPower > 0 && needPower >= chargingInfo[gun_index]->RealRatingPower - CAP_GAP_FETCH) ? true : false;
- if (!ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch)
- {
- // 考慮每顆模塊最大輸出電流為 100A
- ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = (chargingInfo[gun_index]->EvBatterytargetCurrent >=
- chargingInfo[gun_index]->AvailableChargingCurrent - LIMIT_PWR_MODULE_GAP) ? true : false;
- }
- return ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch;
- }
- void FetchFork()
- {
- pid_t fetchPid;
- fetchPid = fork();
- if(fetchPid > 0)
- {
- bool isPass = false;
- struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
- while(!isPass)
- {
- isPass = true;
- for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
- {
- if (!FindChargingInfoData(_index, &_chargingData[0]))
- {
- DEBUG_ERROR("Smartbox (FetchFork) : FindChargingInfoData false \n");
- isPass = false;
- break;
- }
- }
- sleep(1);
- }
- while(1)
- {
- for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
- {
- if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE ||
- chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION ||
- chargingInfo[gun_index]->SystemStatus == SYS_MODE_MAINTAIN ||
- chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT)
- {
- ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = NO;
- if (ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus != _CONNECTOR_STATUS_NONE)
- ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_NONE;
- }
- // 對充電邏輯來說,充電槍只提需求
- else if (chargingInfo[gun_index]->SystemStatus >= SYS_MODE_MODE_REASSIGN_CHECK &&
- chargingInfo[gun_index]->SystemStatus <= SYS_MODE_REASSIGN)
- {
- // 判斷該群是否被使用中
- if (ShmPsuData->PsuGroup[gun_index].IsUsing)
- {
- // 如果使用中 : 等待把這顆模塊切出
- ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_WAIT;
- }
- else
- {
- // 直接同意該群後輸出
- InitializeDynamicFetch(gun_index);
- ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus = _CONNECTOR_STATUS_USING;
- }
- }
- else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_PREPARING)
- {
- // 這個階段只會拿到屬於該槍的模塊群
- if (ShmDcCommonData->systemType == _SYSTEM_TYPE_SIMPLE)
- {
- // 壁掛 : 強制使用第零群
- AddGroup2Connector(gun_index, _PSU_GROUP_INDEX_0);
- }
- else
- {
- if (!ShmPsuData->PsuGroup[gun_index].IsUsing)
- {
- // 第一個 : Gun index
- // 第二個 : Psu Group index
- AddGroup2Connector(gun_index, gun_index);
- }
- }
- }
- else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_CHARGING)
- {
- // 判斷是否可以及需要提供多餘群輸出
- byte chkRemainGp = NONE_GROUP_CAN_SELECTED;
- if (ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup == NONE_GROUP_CAN_SELECTED)
- chkRemainGp = CheckRemainPwrByConIndex(gun_index);
- else
- chkRemainGp = ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup;
- ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = GetCanFetchResult(gun_index);
- if (ShmDcCommonData->systemType != _SYSTEM_TYPE_SIMPLE &&
- ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_NONE &&
- ((ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch &&
- chkRemainGp != NONE_GROUP_CAN_SELECTED &&
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep <= _PSU_DYNAMIC_FETCH_STEP_WAIT) ||
- ShmDcCommonData->smartFetchRun[gun_index])
- )
- {
- if (!ShmSmartBoxData->SmartChk[gun_index].IsFetchStart)
- {
- // 判斷是否可以及需要提供多餘群輸出
- PRINTF_FUNC("Fetch Target = %d, Target Group = %d \n", gun_index, chkRemainGp);
- // 鎖定目標群,動態分配開始
- // 該群模塊即被鎖定, 預防另外一群也進入相同邏輯,預防搶同一個群的情形
- ShmPsuData->PsuGroup[chkRemainGp].IsUsing = YES;
- ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup = chkRemainGp;
- PRINTF_FUNC("***** FETCH_STEP_WAIT ***** (Gun - %d) \n", gun_index);
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_WAIT;
- // 倒數進入動態分配邏輯 - Fetch loop
- ShmSmartBoxData->SmartChk [gun_index].IsFetchStart = YES;
- // 條件成立, 倒數 FETCH_SMART_CHK_TIME <5s>
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].FetchLoopTime);
- }
- else
- {
- if (ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep == _PSU_DYNAMIC_FETCH_STEP_WAIT)
- {
- int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].FetchLoopTime);
- if (_t >= FETCH_SMART_CHK_TIME)
- {
- PRINTF_FUNC("***** FETCH_STEP_TG_VOL ***** (Gun - %d) \n", gun_index);
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_TG_VOL;
- ShmDcCommonData->smartFetchRun[gun_index] = NO;
- }
- }
- }
- }
- else
- {
- // 動態分配條件中斷
- Chk2StopFetchStep(gun_index);
- }
- }
- FetchLoopProcessing(gun_index);
- }
- usleep(50000);
- }
- }
- }
- //==========================================
- // Release fork
- //==========================================
- void InitializeDynamicRelease(byte _targetConn)
- {
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseGroup = NONE_GROUP_CAN_SELECTED;
- ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay = NONE_RELAY_SELECTED;
- ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCurCap = 0;
- ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap = 0;
- ShmSmartBoxData->Dynamic4Release[_targetConn].LimitCur = 0;
- ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr = 0;
- ShmSmartBoxData->Dynamic4Release[_targetConn].AutoRelease = NO;
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_FETCH_STEP_FINISH;
- }
- byte CheckReleasePwrByConIndex(byte _targetConn)
- {
- byte result = NONE_GROUP_CAN_SELECTED;
- // 該槍已經使用的群數量
- byte usingCount = ShmSmartBoxData->ConnectorUsingGroupCount[_targetConn];
- // 不可把最後一個也拿來釋放
- if (usingCount - 1 > 0)
- result = ConnectorUsingSeq[_targetConn][usingCount - 1];
- return result;
- }
- void ReleaseLoopProcessing(byte _targetConn)
- {
- byte targetGroup = ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseGroup;
- switch(ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep)
- {
- case _PSU_DYNAMIC_RELEASE_STEP_NONE:
- case _PSU_DYNAMIC_RELEASE_STEP_WAIT: {} break;
- case _PSU_DYNAMIC_RELEASE_STEP_LIMIT:
- {
- // 應該要通知可輸出的能量與電流
- // if the current and power limits are below their capacity
- // if (ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr <= ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap ||
- // chargingInfo[_targetConn]->PresentChargingCurrent * 10 <= PSU_LIMIT_CUR)
- if (ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwr <= ShmSmartBoxData->Dynamic4Release[_targetConn].LimitPwrCap)
- {
- PRINTF_FUNC("***** RELEASE_STEP_CUR_SHARE ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_CUR_SHARE;
- }
- }
- break;
- case _PSU_DYNAMIC_RELEASE_STEP_CUR_SHARE:
- {
- PRINTF_FUNC("targetGroup = %d, GroupPresentOutputCurrent = %.1f \n",
- targetGroup,
- ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent);
- // if the output current is below their capacity for 5s
- int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].ReleaseLoopTime);
- if (ShmPsuData->PsuGroup[targetGroup].GroupPresentOutputCurrent <= RELEASE_STEP_CUR_SHARE &&
- _t >= WAIT_FOR_LIMIT_STABLE)
- {
- PRINTF_FUNC("***** RELEASE_STEP_RELAYOFF ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF;
- }
- }
- break;
- case _PSU_DYNAMIC_RELEASE_STEP_RELAYOFF:
- {
- // 釋放對應的 Relay
- PRINTF_FUNC("TargetRelay (%d), targetGroup = %d, ParallelRelayStatus = (%d), RcbParallelStatus = (%d) \n",
- ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay, targetGroup,
- ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay],
- ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay]);
- if (ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay < ARRAY_SIZE(ShmSmartBoxData->ParallelRelayStatus))
- {
- if (ShmSmartBoxData->ParallelRelayStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay] == NO)
- {
- if (ShmSmartBoxData->RcbParallelStatus[ShmSmartBoxData->Dynamic4Release[_targetConn].TargetRelay] == NO)
- {
- PRINTF_FUNC("***** RELEASE_STEP_WATI_FINISH ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH;
- }
- }
- }
- }
- break;
- case _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH:
- {
- if(ReleaseConnectorProcessing(_targetConn, targetGroup))
- {
- GetTimespecFunc ( & ShmSmartBoxData->SmartChk [_targetConn].ReleaseLoopTime );
- PRINTF_FUNC("***** RELEASE_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
- InitializeDynamicRelease(_targetConn);
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_FINISH;
- }
- }
- break;
- case _PSU_DYNAMIC_RELEASE_STEP_FINISH:
- {
- // 完成
- int _t = GetTimeoutValue(&ShmSmartBoxData->SmartChk[_targetConn].ReleaseLoopTime);
- if (_t >= RELEASE_FINISH_WAIT_TIME)
- {
- PRINTF_FUNC("***** RELEASE_STEP_NONE ***** (Gun - %d) \n", _targetConn);
- ShmSmartBoxData->SmartChk[_targetConn].IsReleaseStart = NO;
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
- }
- }
- break;
- case _PSU_DYNAMIC_RELEASE_STEP_ABORT:
- {
- GetTimespecFunc(& ShmSmartBoxData->SmartChk [_targetConn].ReleaseLoopTime);
- PRINTF_FUNC("***** RELEASE_STEP_FINISH ***** (Gun - %d) \n", _targetConn);
- InitializeDynamicRelease(_targetConn);
- ShmSmartBoxData->Dynamic4Release[_targetConn].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_FINISH;
- }
- break;
- }
- }
- void Chk2StopReleaseStep(byte _targetConn)
- {
- // 開始流程後,就讓流程走完吧~
- if (ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup > _PSU_DYNAMIC_RELEASE_STEP_NONE &&
- ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup < _PSU_DYNAMIC_RELEASE_STEP_LIMIT)
- {
- PRINTF_FUNC ( "***** RELEASE_STEP_ABORT ***** (Gun - %d) \n", _targetConn );
- //ShmSmartBoxData->Dynamic4Release [_targetConn].ReleaseGroup = _PSU_DYNAMIC_RELEASE_STEP_ABORT;
- }
- else
- ShmSmartBoxData->SmartChk[_targetConn].IsReleaseStart = NO;
- }
- bool GetCanReleaseResult(byte gun_index, byte releaseGp)
- {
- bool result = false;
- unsigned short releasePwr = ShmPsuData->PsuGroup[releaseGp].TotalRatingPower * 10;
- float needPower = chargingInfo[gun_index]->PresentChargingVoltage *
- chargingInfo[gun_index]->EvBatterytargetCurrent / 100;
- result = (chargingInfo[gun_index]->RealRatingPower > 0 && releasePwr > 0 &&
- needPower < chargingInfo[gun_index]->RealRatingPower - releasePwr - CAP_GAP_RELEASE) ? true : false;
- if (result)
- {
- // afterReleaseMdCur 每個模塊最大 100A : 1A
- float afterReleaseMdCur = chargingInfo[gun_index]->AvailableChargingCurrent -
- ShmPsuData->PsuGroup[releaseGp].GroupAvailableCurrent;
- result = (chargingInfo[gun_index]->EvBatterytargetCurrent >= afterReleaseMdCur - LIMIT_PWR_MODULE_GAP) ? false : true;
- }
- return result;
- }
- void ReleaseFork()
- {
- pid_t releasePid;
- releasePid = fork();
- if(releasePid > 0)
- {
- bool isPass = false;
- struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
- while(!isPass)
- {
- isPass = true;
- for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
- {
- if (!FindChargingInfoData(_index, &_chargingData[0]))
- {
- DEBUG_ERROR("Smartbox (ReleaseFork) : FindChargingInfoData false \n");
- isPass = false;
- break;
- }
- }
- sleep(1);
- }
- while(1)
- {
- for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++)
- {
- if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_CHARGING)
- {
- // 釋出多餘群 : 要判斷所要釋出群所能提供的最大能量 RealRatingPower
- // 先找到是否有下一個要釋出的群
- byte releaseGp = CheckReleasePwrByConIndex(gun_index);
- if (releaseGp != NONE_GROUP_CAN_SELECTED)
- {
- bool canRelease = GetCanReleaseResult(gun_index, releaseGp);
- if (chargingInfo[gun_index]->Type != _Type_Test &&
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep == _PSU_DYNAMIC_FETCH_STEP_NONE &&
- (ShmSmartBoxData->AnotherConnectorStatus[gun_index].ConnectorStaus == _CONNECTOR_STATUS_WAIT ||
- (ShmSmartBoxData->AnotherConnectorStatus[gun_index].NeedToFetch &&
- SMART_MODE && chargingInfo[gun_index]->_TakePsuGpCount > ShmDcCommonData->halfGroupCount) ||
- canRelease ||
- ShmDcCommonData->smartReleaseRun[gun_index])
- )
- {
- //PRINTF_FUNC("RealRatingPower = %d \n", chargingInfo[gun_index]->RealRatingPower);
- //PRINTF_FUNC("releasePwr = %d, needPower = %f \n", releasePwr, needPower);
- if (ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_NONE)
- {
- if (!ShmSmartBoxData->SmartChk[gun_index].IsReleaseStart)
- {
- PRINTF_FUNC("***** Entry release chk (Gun_%d).. ***** \n", gun_index);
- ShmSmartBoxData->SmartChk[gun_index].IsReleaseStart = YES;
- ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable = chargingInfo[gun_index]->PresentChargingPower;
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
- }
- else
- {
- int _delayt = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
- // 每五秒看一次輸出能量是否穩定, 穩定則進入分配
- if (_delayt >= RELEASE_STABLE_CHK_TIME)
- {
- if (chargingInfo[gun_index]->PresentChargingPower >
- ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable + STABLE_CAP_GAP)
- {
- ShmSmartBoxData->Dynamic4Release[gun_index].CheckOutPwrIsStable = chargingInfo[gun_index]->PresentChargingPower;
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
- }
- else
- {
- // 進入穩定
- PRINTF_FUNC("***** RELEASE_STEP_WAIT ***** \n");
- ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_WAIT;
- GetTimespecFunc(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
- }
- }
- }
- }
- else if (ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_WAIT)
- {
- int _delayt = GetTimeoutValue(&ShmSmartBoxData->SmartChk[gun_index].ReleaseLoopTime);
- // 每五秒看一次輸出能量是否穩定, 穩定則進入分配
- if (_delayt >= RELEASE_SMART_CHK_TIME)
- {
- PRINTF_FUNC("***** RELEASE_STEP_LIMIT ***** \n");
- ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseGroup = releaseGp;
- ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_LIMIT;
- ShmDcCommonData->smartReleaseRun[gun_index] = NO;
- }
- }
- }
- else
- {
- // 動態分配條件中斷
- Chk2StopReleaseStep(gun_index);
- }
- }
- }
- else if (chargingInfo[gun_index]->SystemStatus == SYS_MODE_IDLE ||
- chargingInfo[gun_index]->SystemStatus == SYS_MODE_FAULT ||
- chargingInfo[gun_index]->SystemStatus == SYS_MODE_RESERVATION ||
- (chargingInfo[gun_index]->SystemStatus >= SYS_MODE_TERMINATING &&
- chargingInfo[gun_index]->SystemStatus <= SYS_MODE_ALARM))
- {
- if (ShmSmartBoxData->ConnectorStatus[gun_index].ConnectorStaus == _CONNECTOR_STATUS_NONE)
- {
- byte totoalUsingGpCount = ShmSmartBoxData->ConnectorUsingGroupCount[gun_index];
- for (byte _gp = 0; _gp < totoalUsingGpCount; _gp++)
- {
- PRINTF_FUNC("ConnectorUsingSeq[%d][%d] = %d \n", gun_index, _gp, ConnectorUsingSeq[gun_index][_gp]);
- ReleaseConnectorProcessing(gun_index, ConnectorUsingSeq[gun_index][_gp]);
- }
- if (ShmSmartBoxData->Dynamic4Fetch[gun_index].ShareGroup != NONE_GROUP_CAN_SELECTED &&
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep < _PSU_DYNAMIC_FETCH_STEP_FINISH)
- ShmSmartBoxData->Dynamic4Fetch[gun_index].FetchLoopStep = _PSU_DYNAMIC_FETCH_STEP_ABORT;
- ShmSmartBoxData->Dynamic4Release[gun_index].ReleaseLoopStep = _PSU_DYNAMIC_RELEASE_STEP_NONE;
- }
- if (ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch)
- ShmSmartBoxData->ConnectorStatus[gun_index].NeedToFetch = NO;
- }
- ReleaseLoopProcessing(gun_index);
- }
- usleep(50000);
- }
- }
- }
- //==========================================
- // Main Function
- //==========================================
- void TakeAnotherGunStatus(byte target)
- {
- byte another = 0;
- if (target == 0)
- another = 1;
- ShmSmartBoxData->AnotherConnectorStatus[another].ConnectorStaus = ShmSmartBoxData->ConnectorStatus[target].ConnectorStaus;
- ShmSmartBoxData->AnotherConnectorStatus[another].NeedToFetch = ShmSmartBoxData->ConnectorStatus[target].NeedToFetch;
- }
- void AssignedPwr2Connector()
- {
- for(byte _gun = 0; _gun < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _gun++)
- {
- byte usingGroupCount = 0;
- float availablePwr = 0, availableCur = 0, iAvailableCur = 0, totalPsuCount = 0, kwAvailablePwr = 0;
- float outputVol = 0, outputCur = 0;
- float limitCur = 0, limitPwr = 0, remainCur = 0;
- for (byte group = 0; group < ShmPsuData->GroupCount; group++)
- {
- if (ShmPsuData->PsuGroup[group].UsingTarget == _gun)
- {
- usingGroupCount++;
- if (group != ShmSmartBoxData->Dynamic4Fetch[_gun].ShareGroup &&
- (group != ShmSmartBoxData->Dynamic4Release[_gun].ReleaseGroup ||
- ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep <= _PSU_DYNAMIC_RELEASE_STEP_WAIT_FINISH))
- {
- availablePwr += ShmPsuData->PsuGroup[group].GroupAvailablePower;
- availableCur += ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
- iAvailableCur += ShmPsuData->PsuGroup[group].TotalIAvailableCurrent;
- totalPsuCount += ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
- if (ShmPsuData->PsuGroup[group].TotalRatingPower <= 15 ||
- ShmPsuData->PsuGroup[group].TotalRatingPower > 30)
- kwAvailablePwr += (ShmPsuData->PsuGroup[group].GroupAvailablePower) / 10;
- else
- kwAvailablePwr += ShmPsuData->PsuGroup[group].TotalRatingPower;
- }
- // Release Loop 用 : 實際上~ 電流會飄 ....
- // 這段, 只取還要留住的模塊輸出電流與能量就好
- if (group != ShmSmartBoxData->Dynamic4Release[_gun].ReleaseGroup &&
- ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_LIMIT)
- {
- limitCur += ShmPsuData->PsuGroup[group].GroupTargetOutputCurrent;
- remainCur += ShmPsuData->PsuGroup[group].TotalIAvailableCurrent;
- limitPwr += ShmPsuData->PsuGroup[group].TotalRatingPower;
- }
- outputCur += ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
- if (outputVol < ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage ||
- outputVol == 0)
- outputVol = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
- }
- }
- chargingInfo[_gun]->AvailableChargingPower = availablePwr;
- chargingInfo[_gun]->AvailableChargingCurrent = availableCur;
- chargingInfo[_gun]->DeratingChargingCurrent = iAvailableCur;
- chargingInfo[_gun]->_TotalPsuCount = totalPsuCount;
- chargingInfo[_gun]->PresentChargingVoltage = outputVol / 10;
- // 在低於最大 1KW 輸出時~ 讓我們偷雞一下~
- if (chargingInfo[_gun]->SystemStatus == SYS_MODE_CHARGING)
- {
- if (chargingInfo[_gun]->RealMaxPower <= 10 && outputCur < (chargingInfo[_gun]->RealMaxCurrent * 0.9))
- outputCur = (chargingInfo[_gun]->RealMaxCurrent * 0.9);
- }
- chargingInfo[_gun]->PresentChargingCurrent = outputCur / 10;
- chargingInfo[_gun]->RealRatingPower = kwAvailablePwr * 10;
- chargingInfo[_gun]->_TakePsuGpCount = usingGroupCount;
- // 雙槍需要記得另外一把槍的狀態
- if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1)
- TakeAnotherGunStatus(_gun);
- // 取 Release group 的最大電流
- if (ShmSmartBoxData->Dynamic4Release[_gun].ReleaseLoopStep == _PSU_DYNAMIC_RELEASE_STEP_LIMIT &&
- ShmSmartBoxData->Dynamic4Release[_gun].LimitPwrCap == 0)
- {
- // limitCur : 下給剩餘群的需求電流
- //ShmSmartBoxData->Dynamic4Release[_gun].LimitCurCap = limitCur;
- // Release 均流想法(總結) : 如果是抽載不足的自然釋放~ 應該都會跑均流方式
- // 狀況一 : 群1 : 30A,群2 : 30A 共 60A 輸出,且實際上群1 可提供的電流為 75A (400V 輸出)
- // 狀況二 : 群1 : 75A,群2 : 75A 共 150A 輸出,且實際上群1 可提供的電流為 75A (400V 輸出)
- // 狀況三 : 群1 : 70A,群2 : 70A 共 140A 輸出,且實際上群1 可提供的電流為 75A (400V 輸出)
- // ---------------------------------------------
- // 狀況一 : 60A <= 群1可提供的 75A : 均流
- // 狀況一 : 150A > 群1可提供的 75A : 直接切斷
- // 狀況一 : 140A > 群1可提供的 75A : 直接切斷
- if (chargingInfo[_gun]->PresentChargingCurrent <= remainCur)
- {
- PRINTF_FUNC("PresentChargingCurrent = %f, remainCur = %f \n", chargingInfo[_gun]->PresentChargingCurrent, remainCur / 10);
- limitCur = chargingInfo[_gun]->PresentChargingCurrent * 10;
- ShmSmartBoxData->Dynamic4Release[_gun].AutoRelease = YES;
- }
- else
- PRINTF_FUNC("limitCur = %f \n", limitCur);
- ShmSmartBoxData->Dynamic4Release[_gun].LimitCurCap = limitCur;
- ShmSmartBoxData->Dynamic4Release[_gun].LimitPwrCap = limitPwr * 10;
- }
- }
- }
- void CollectGroupInformation(byte group)
- {
- int _groupPower = 0 , _groupCurrent = 0 , _groupMaxVoltage = 0;
- int Iavail = 0, Pavail = 0;
- unsigned short _outputVolBuf = 0, _outputCurBuf = 0;
- for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index ++)
- {
- // Cap
- _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
- _groupPower += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
- if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentMaxOutputVoltage > _groupMaxVoltage)
- _groupMaxVoltage = ShmPsuData->PsuGroup[group].PsuModule[index].PresentMaxOutputVoltage;
- // Iavailable
- Iavail += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
- Pavail += ShmPsuData->PsuGroup[group].PsuModule[index].KwAvailablePower;
- // output
- _outputCurBuf += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
- if (_outputVolBuf == 0 ||
- (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > PSU_MIN_VOL &&
- _outputVolBuf < ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage))
- {
- _outputVolBuf = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
- }
- }
- ShmPsuData->PsuGroup[group].GroupMaxVoltage = _groupMaxVoltage;
- ShmPsuData->PsuGroup[group].GroupAvailableCurrent = _groupCurrent;
- ShmPsuData->PsuGroup[group].GroupAvailablePower = _groupPower;
- ShmPsuData->PsuGroup[group].TotalIAvailableCurrent = Iavail;
- ShmPsuData->PsuGroup[group].TotalRatingPower = Pavail;
- ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = _outputVolBuf;
- ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = _outputCurBuf;
- }
- void CollectPsuInformation()
- {
- int _sysPwr = 0, _sysCur = 0, _sysVol = 0;
- for (byte group = 0; group < ShmPsuData->GroupCount; group++)
- {
- // 取群資訊
- CollectGroupInformation(group);
- // 整理系統資訊
- _sysPwr += ShmPsuData->PsuGroup[group].GroupAvailablePower;
- _sysCur += ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
- if (ShmPsuData->PsuGroup[group].GroupMaxVoltage > _sysVol)
- _sysVol = ShmPsuData->PsuGroup[group].GroupMaxVoltage;
- }
- // 系統,電壓,電流,能量
- ShmPsuData->SystemAvailableCurrent = _sysCur;
- ShmPsuData->SystemAvailablePower = _sysPwr;
- GetSystemMaxVoltage();
- }
- //==========================================
- // Main Loop
- //==========================================
- int main(void)
- {
- if(InitShareMemory() == FAIL)
- {
- #ifdef SystemLogMessage
- DEBUG_ERROR("InitShareMemory NG\n");
- #endif
- if(ShmStatusCodeData != NULL)
- {
- ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
- }
- sleep(5);
- return 0;
- }
- Initialization();
- // 對充電槍操作 : 將模塊切出來與補上剩餘的模塊功率
- FetchFork();
- ReleaseFork();
- GetTimespecFunc(&_log_time);
- while(1)
- {
- if (ShmPsuData->Work_Step >= GET_SYS_CAP)
- {
- // 收集來自 PSU 的資訊
- CollectPsuInformation();
- // 將群資訊分配到對應的使用中充電槍
- AssignedPwr2Connector();
- int time = GetTimeoutValue(&_log_time);
- if (time < 0)
- GetTimespecFunc(&_log_time);
- // 低 Priority 的指令
- if (time > 5000)
- {
- //PrintfLog();
- GetTimespecFunc(&_log_time);
- }
- }
- if (ShmDcCommonData->systemType != _SYSTEM_TYPE_SIMPLE &&
- ShmPsuData->Work_Step == _WORK_CHARGING)
- {
- // 橋接控制
- SmartRelayCheck();
- }
- usleep(50000);
- }
- return -1;
- }
|