Module_PsuComm.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. #include "Module_PsuComm.h"
  2. #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
  3. #define PASS 1
  4. #define FAIL -1
  5. #define YES 1
  6. #define NO 0
  7. #define DERATING 30
  8. #define ELEMENT_NOT_FIND 255
  9. #define CHK_VOL_RANGE 20
  10. #define CHK_CUR_RANGE 10
  11. #define DERATING_RANGE 100
  12. #define ZERO_CURRENT 0
  13. #define ZERO_VOLTAGE 10
  14. #define STOP_CURRENT 30
  15. #define PSU_MIN_CUR 100
  16. struct SysConfigAndInfo *ShmSysConfigAndInfo;
  17. struct StatusCodeData *ShmStatusCodeData;
  18. struct PsuData *ShmPsuData;
  19. bool libInitialize = false;
  20. byte getAvailableCapOffset = 5;
  21. byte deratingKeepCount = 0;
  22. float carReqVol = 0;
  23. float carReqCur = 0;
  24. float evseOutVol = 0;
  25. float evseOutCur = 0;
  26. void PRINTF_FUNC(char *string, ...);
  27. int StoreLogMsg(const char *fmt, ...);
  28. #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  29. #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  30. #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  31. unsigned long GetTimeoutValue(struct timeval _sour_time);
  32. unsigned long GetTimeoutValue(struct timeval _sour_time)
  33. {
  34. struct timeval _end_time;
  35. gettimeofday(&_end_time, NULL);
  36. return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
  37. }
  38. int StoreLogMsg(const char *fmt, ...)
  39. {
  40. char Buf[4096+256];
  41. char buffer[4096];
  42. time_t CurrentTime;
  43. struct tm *tm;
  44. va_list args;
  45. va_start(args, fmt);
  46. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  47. va_end(args);
  48. memset(Buf,0,sizeof(Buf));
  49. CurrentTime = time(NULL);
  50. tm=localtime(&CurrentTime);
  51. sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
  52. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
  53. buffer,
  54. tm->tm_year+1900,tm->tm_mon+1);
  55. system(Buf);
  56. return rc;
  57. }
  58. void PRINTF_FUNC(char *string, ...)
  59. {
  60. va_list args;
  61. char buffer[4096];
  62. va_start(args, string);
  63. vsnprintf(buffer, sizeof(buffer), string, args);
  64. va_end(args);
  65. if (DEBUG)
  66. printf("%s \n", buffer);
  67. else
  68. DEBUG_INFO("%s \n", buffer);
  69. }
  70. //=================================
  71. // Common routine
  72. //=================================
  73. size_t FindIndex(const int a[], size_t size, int value, byte group)
  74. {
  75. size_t index = 0;
  76. while ( index < size && a[index] != value ) ++index;
  77. return (index == size ? ELEMENT_NOT_FIND : group);
  78. }
  79. byte FindTargetGroup(byte address)
  80. {
  81. byte _group = ELEMENT_NOT_FIND;
  82. if (ShmPsuData->GroupCount == 1)
  83. _group = 0;
  84. else
  85. {
  86. _group = FindIndex(connector_1, ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity, address, 0);
  87. if (_group == ELEMENT_NOT_FIND)
  88. _group = FindIndex(connector_2, ShmPsuData->PsuGroup[1].GroupPresentPsuQuantity, address, 1);
  89. }
  90. return _group;
  91. }
  92. bool IsOverModuleCount(byte count)
  93. {
  94. bool result = false;
  95. if (count >= ShmPsuData->SystemPresentPsuQuantity)
  96. result = true;
  97. return result;
  98. }
  99. //=================================
  100. // Save data to share memory Function
  101. //=================================
  102. bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
  103. {
  104. for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
  105. {
  106. if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
  107. {
  108. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
  109. return true;
  110. }
  111. }
  112. for (byte index = 0; index < CCS_QUANTITY; index++)
  113. {
  114. if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
  115. {
  116. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
  117. return true;
  118. }
  119. }
  120. for (byte index = 0; index < GB_QUANTITY; index++)
  121. {
  122. if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
  123. {
  124. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
  125. return true;
  126. }
  127. }
  128. return false;
  129. }
  130. //=================================
  131. // Alarm code mapping to share memory Function
  132. //=================================
  133. // 檢查 Byte 中某個 Bit 的值
  134. // _byte : 欲改變的 byte
  135. // _bit : 該 byte 的第幾個 bit
  136. unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  137. unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit)
  138. {
  139. return ( _byte & mask_table[_bit] ) != 0x00;
  140. }
  141. void AbnormalStopAnalysis(byte gun_index, int errCode)
  142. {
  143. for (char i = 0; i < 3; i++)
  144. {
  145. unsigned char byteIndex = (errCode >> (8 * i)) & 0xff;
  146. for (char bitIndex = 0; bitIndex < 8; bitIndex++)
  147. {
  148. if(DetectBitValue(byteIndex , bitIndex) == 1)
  149. {
  150. switch(byteIndex)
  151. {
  152. case 0:
  153. {
  154. if (bitIndex == 0)
  155. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
  156. else if (bitIndex == 5)
  157. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
  158. }
  159. break;
  160. case 1:
  161. {
  162. if (bitIndex == 1)
  163. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
  164. else if (bitIndex == 2)
  165. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = YES;
  166. else if (bitIndex == 3)
  167. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
  168. else if (bitIndex == 4)
  169. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
  170. else if (bitIndex == 5)
  171. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
  172. }
  173. break;
  174. case 2:
  175. {
  176. if (bitIndex == 0)
  177. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
  178. else if (bitIndex == 1)
  179. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
  180. else if (bitIndex == 2)
  181. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = YES;
  182. else if (bitIndex == 3)
  183. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
  184. else if (bitIndex == 4)
  185. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
  186. else if (bitIndex == 5)
  187. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = YES;
  188. else if (bitIndex == 6)
  189. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
  190. }
  191. break;
  192. }
  193. }
  194. // else
  195. // {
  196. // switch (byteIndex) {
  197. // case 0: {
  198. // if (bitIndex == 0)
  199. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO;
  200. // else if (bitIndex == 5)
  201. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
  202. // }
  203. // break;
  204. // case 1: {
  205. // if (bitIndex == 1)
  206. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = NO;
  207. // else if (bitIndex == 2)
  208. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO;
  209. // else if (bitIndex == 3)
  210. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO;
  211. // else if (bitIndex == 4)
  212. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
  213. // else if (bitIndex == 5)
  214. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
  215. // }
  216. // break;
  217. // case 2: {
  218. // if (bitIndex == 1)
  219. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO;
  220. // if (bitIndex == 2)
  221. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = NO;
  222. // else if (bitIndex == 3)
  223. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
  224. // else if (bitIndex == 4)
  225. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
  226. // else if (bitIndex == 5)
  227. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
  228. // else if (bitIndex == 6)
  229. // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO;
  230. // }
  231. // break;
  232. // }
  233. // }
  234. }
  235. }
  236. }
  237. //=================================
  238. // Callback Function
  239. //=================================
  240. void GetStatusCallback(byte group, byte address, byte temp, int alarm)
  241. {
  242. if (IsOverModuleCount(address))
  243. return;
  244. byte group1 = FindTargetGroup(address);
  245. if (group1 == 1)
  246. address -= ShmPsuData->PsuGroup[group1 - 1].GroupPresentPsuQuantity;
  247. ShmPsuData->PsuGroup[group1].PsuModule[address].CriticalTemp1 = temp;
  248. ShmPsuData->PsuGroup[group1].PsuModule[address].CriticalTemp2 = temp;
  249. ShmPsuData->PsuGroup[group1].PsuModule[address].CriticalTemp3 = temp;
  250. ShmPsuData->PsuGroup[group1].PsuModule[address].ExletTemp = temp;
  251. ShmPsuData->PsuGroup[group1].PsuModule[address].AlarmCode = alarm;
  252. AbnormalStopAnalysis(group1, alarm);
  253. //printf("alarm = %d \n", alarm);
  254. }
  255. void GetModuleCountCallback(byte group, byte count)
  256. {
  257. if (group == SYSTEM_CMD)
  258. ShmPsuData->SystemPresentPsuQuantity = count;
  259. else
  260. {
  261. ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity = count;
  262. }
  263. }
  264. void GetMaxPowerAndCur(unsigned char mode, int ratingCur, int *pow, int *cur)
  265. {
  266. unsigned short maxCurrent = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10;
  267. unsigned short maxPower = ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10;
  268. if (mode == _MAIN_CHARGING_MODE_AVER)
  269. {
  270. maxCurrent /= 2;
  271. maxPower /= 2;
  272. }
  273. if (maxPower != 0 && maxPower <= *pow)
  274. *pow = maxPower;
  275. if (maxCurrent != 0 && maxCurrent <= *cur)
  276. *cur = maxCurrent;
  277. if (ratingCur != 0 && ratingCur <= *cur)
  278. *cur = ratingCur;
  279. }
  280. void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow)
  281. {
  282. int _groupPower = 0, _groupCurrent = 0;
  283. byte group = FindTargetGroup(address);
  284. if (group == 1)
  285. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  286. if (chargingInfo[group]->DeratingChargingCurrent == 0)
  287. ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = PSU_MIN_CUR;
  288. else
  289. ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
  290. ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
  291. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  292. {
  293. _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
  294. _groupPower += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
  295. }
  296. // 各群得到最大輸出能力 (電流、Power)
  297. ShmPsuData->PsuGroup[group].GroupAvailableCurrent = _groupCurrent;
  298. ShmPsuData->PsuGroup[group].GroupAvailablePower = _groupPower;
  299. chargingInfo[group]->MaximumChargingVoltage = maxVol;
  300. int _power = 0, _current = 0, _ratingcurrent = 0;
  301. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  302. {
  303. _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
  304. _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
  305. _ratingcurrent += chargingInfo[address]->DeratingChargingCurrent;
  306. }
  307. ShmPsuData->SystemAvailableCurrent = _current;
  308. ShmPsuData->SystemAvailablePower = _power;
  309. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER ||
  310. (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
  311. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
  312. {
  313. int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
  314. int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
  315. int ratingCur = chargingInfo[group]->DeratingChargingCurrent;
  316. GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur);
  317. // if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
  318. // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
  319. // {
  320. // chargingInfo[group]->AvailableChargingCurrent = DERATING_RANGE;
  321. // chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
  322. // }
  323. // else
  324. {
  325. // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
  326. // 1. 如不是最大充
  327. // 2. 智能切換成均充過程
  328. chargingInfo[group]->AvailableChargingCurrent = halfCur;
  329. chargingInfo[group]->AvailableChargingPower = halfPow;
  330. }
  331. }
  332. else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  333. {
  334. GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
  335. if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
  336. {
  337. byte _count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
  338. for (byte count = 0; count < _count; count++)
  339. {
  340. chargingInfo[count]->MaximumChargingVoltage = maxVol;
  341. chargingInfo[count]->AvailableChargingCurrent = _current;
  342. chargingInfo[count]->AvailableChargingPower = _power;
  343. }
  344. }
  345. else
  346. {
  347. // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
  348. chargingInfo[group]->AvailableChargingCurrent = _current;
  349. chargingInfo[group]->AvailableChargingPower = _power;
  350. }
  351. }
  352. }
  353. void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer)
  354. {
  355. if (IsOverModuleCount(address))
  356. return;
  357. byte group = FindTargetGroup(address);
  358. if (group == 1)
  359. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  360. sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
  361. //DEBUG_INFO("fw Ver. = %s \n", ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion);
  362. }
  363. void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
  364. {
  365. if (IsOverModuleCount(address))
  366. return;
  367. byte group = FindTargetGroup(address);
  368. if (group == 1)
  369. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  370. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL1 = vol1;
  371. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL2 = vol2;
  372. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL3 = vol3;
  373. }
  374. void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short outCur)
  375. {
  376. unsigned short outputVol = outVol;
  377. unsigned short outputCur = outCur;
  378. // PSU Group - 電壓
  379. ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
  380. // PSU Group - 電流
  381. ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
  382. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  383. {
  384. outputVol = 0;
  385. outputCur = 0;
  386. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  387. {
  388. if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
  389. outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
  390. outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
  391. }
  392. // 黑白機
  393. if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
  394. {
  395. byte _count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
  396. for (byte count = 0; count < _count; count++)
  397. {
  398. // EVSE - 電壓
  399. chargingInfo[count]->PresentChargingVoltage = outputVol;
  400. // EVSE - 電流
  401. chargingInfo[count]->PresentChargingCurrent = outputCur;
  402. }
  403. }
  404. if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_CHARGING) ||
  405. (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
  406. {
  407. // EVSE - 電壓
  408. chargingInfo[group]->PresentChargingVoltage = outputVol;
  409. // EVSE - 電流
  410. chargingInfo[group]->PresentChargingCurrent = outputCur;
  411. }
  412. }
  413. else
  414. {
  415. // EVSE - 電壓
  416. chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
  417. // EVSE - 電流
  418. chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
  419. }
  420. // PRINTF_FUNC("Gun_%d, PresentChargingCurrent = %f \n", group,
  421. // chargingInfo[group]->PresentChargingCurrent);
  422. }
  423. void GetFanSpeedCallback(byte address, unsigned int fanSpeed)
  424. {
  425. if (IsOverModuleCount(address))
  426. return;
  427. byte group = FindTargetGroup(address);
  428. if (group == 1)
  429. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  430. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_1 = fanSpeed;
  431. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_2 = fanSpeed;
  432. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_3 = fanSpeed;
  433. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_4 = fanSpeed;
  434. }
  435. void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
  436. {
  437. //PRINTF_FUNC("GetIavailableCallback address_%d, Vext = %d, Iavail = %d \n", address, Vext, Iavail);
  438. bool isPass = true;
  439. if (Iavail == 0)
  440. {
  441. for (byte count = 0; count < 2; count++)
  442. {
  443. chargingInfo[address]->SampleChargingCur[count] = Iavail;
  444. }
  445. }
  446. else
  447. {
  448. for (byte count = 0; count < 2; count++)
  449. {
  450. if (chargingInfo[address]->SampleChargingCur[count] == 0)
  451. {
  452. chargingInfo[address]->SampleChargingCur[count] = Iavail;
  453. return;
  454. }
  455. else
  456. {
  457. if (chargingInfo[address]->SampleChargingCur[count] != Iavail)
  458. {
  459. chargingInfo[address]->SampleChargingCur[count] = Iavail;
  460. isPass = false;
  461. continue;
  462. }
  463. }
  464. }
  465. }
  466. if (isPass)
  467. {
  468. chargingInfo[address]->DeratingChargingCurrent = Iavail;
  469. }
  470. }
  471. //==========================================
  472. // Init all share memory
  473. //==========================================
  474. int InitShareMemory()
  475. {
  476. int result = PASS;
  477. int MeterSMId;
  478. //creat ShmSysConfigAndInfo
  479. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  480. {
  481. #ifdef SystemLogMessage
  482. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
  483. #endif
  484. result = FAIL;
  485. }
  486. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  487. {
  488. #ifdef SystemLogMessage
  489. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
  490. #endif
  491. result = FAIL;
  492. }
  493. else
  494. {}
  495. //creat ShmStatusCodeData
  496. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  497. {
  498. #ifdef SystemLogMessage
  499. DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
  500. #endif
  501. result = FAIL;
  502. }
  503. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  504. {
  505. #ifdef SystemLogMessage
  506. DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
  507. #endif
  508. result = FAIL;
  509. }
  510. else
  511. {}
  512. //creat ShmPsuData
  513. if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
  514. {
  515. #ifdef SystemLogMessage
  516. DEBUG_ERROR("shmget ShmPsuData NG \n");
  517. #endif
  518. result = FAIL;
  519. }
  520. else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  521. {
  522. #ifdef SystemLogMessage
  523. DEBUG_ERROR("shmat ShmPsuData NG \n");
  524. #endif
  525. result = FAIL;
  526. }
  527. memset(ShmPsuData,0,sizeof(struct PsuData));
  528. return result;
  529. }
  530. //================================================
  531. // Main process
  532. //================================================
  533. void InitialPsuData()
  534. {
  535. ShmPsuData->SystemPresentPsuQuantity = 0;
  536. for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup); _groupCount++)
  537. {
  538. ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
  539. ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
  540. ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
  541. }
  542. ShmPsuData->Work_Step = _INIT_PSU_STATUS;
  543. }
  544. void Initialization()
  545. {
  546. bool isPass = false;
  547. while(!isPass)
  548. {
  549. isPass = true;
  550. for (byte _index = 0; _index < _gunCount; _index++)
  551. {
  552. if (!FindChargingInfoData(_index, &chargingInfo[0]))
  553. {
  554. DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
  555. isPass = false;
  556. break;
  557. }
  558. }
  559. }
  560. if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
  561. ShmPsuData->GroupCount = 1;
  562. else
  563. ShmPsuData->GroupCount = _gunCount;
  564. }
  565. void CheckSmartChargingStep(bool isCharging)
  566. {
  567. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
  568. {
  569. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  570. {
  571. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
  572. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
  573. }
  574. else
  575. {
  576. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
  577. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
  578. }
  579. }
  580. else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_A_TO_M)
  581. {
  582. if (isCharging)
  583. {
  584. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  585. {
  586. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_A_TO_M============= Step 12 \n");
  587. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_A_TO_M;
  588. }
  589. else
  590. {
  591. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
  592. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
  593. }
  594. }
  595. }
  596. }
  597. int main(void)
  598. {
  599. PRINTF_FUNC("Psu Task boot .... \n");
  600. if(InitShareMemory() == FAIL)
  601. {
  602. #ifdef SystemLogMessage
  603. DEBUG_ERROR("InitShareMemory NG\n");
  604. #endif
  605. if(ShmStatusCodeData != NULL)
  606. {
  607. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
  608. }
  609. sleep(5);
  610. return 0;
  611. }
  612. PRINTF_FUNC("InitShareMemory OK\n");
  613. // register callback function
  614. RefreshStatus(&GetStatusCallback);
  615. RefreshModuleCount(&GetModuleCountCallback);
  616. RefreshAvailableCap(&GetAvailableCapCallback);
  617. RefreshFwVersion(&GetFwCallback);
  618. RefreshInputVol(&GetInputVoltageCallback);
  619. RefreshGetOutput(&GetPresentOutputCallback);
  620. RefreshFanInfo(&GetFanSpeedCallback);
  621. RefreshIavailable(&GetIavailableCallback);
  622. _gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
  623. // initial object
  624. InitialPsuData();
  625. Initialization();
  626. libInitialize = InitialCommunication();
  627. byte isInitialComp = NO;
  628. PRINTF_FUNC("ALTERNATIVE_CONG = %d \n", ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf);
  629. //main loop
  630. while (libInitialize)
  631. {
  632. // 斷電狀態
  633. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  634. {
  635. //一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
  636. if (!isInitialComp)
  637. {
  638. InitialPsuData();
  639. ShmPsuData->Work_Step = INITIAL_START;
  640. isInitialComp = YES;
  641. }
  642. sleep(1);
  643. continue;
  644. }
  645. else
  646. isInitialComp = NO;
  647. // 自檢失敗
  648. if (ShmPsuData->Work_Step == _NO_WORKING)
  649. {
  650. PRINTF_FUNC("== PSU == self test fail. \n");
  651. sleep(5);
  652. }
  653. switch(ShmPsuData->Work_Step)
  654. {
  655. case INITIAL_START:
  656. {
  657. PRINTF_FUNC("== PSU == INITIAL_START \n");
  658. gettimeofday(&_cmdSubPriority_time, NULL);
  659. sleep(5);
  660. ShmPsuData->Work_Step = GET_PSU_COUNT;
  661. }
  662. break;
  663. case GET_PSU_COUNT:
  664. {
  665. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  666. byte moduleCount = 0;
  667. if (time > 2000)
  668. {
  669. PRINTF_FUNC("== PSU == GET_PSU_COUNT = %d \n", ShmPsuData->GroupCount);
  670. // if (ShmPsuData->GroupCount == 0)
  671. // ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
  672. // 分別取各群模組數量
  673. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  674. {
  675. // 總和各群模組數量
  676. moduleCount += ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity;
  677. // 取各群模組數量
  678. GetModuleCount(index);
  679. // 取版號
  680. GetModuleVer(index);
  681. }
  682. // 發送取得目前全部模組數量
  683. GetModuleCount(SYSTEM_CMD);
  684. // 判斷系統數量與各群數量一致
  685. if(moduleCount == ShmPsuData->SystemPresentPsuQuantity && moduleCount > 0)
  686. {
  687. PRINTF_FUNC("Psu Count = %d \n", moduleCount);
  688. if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
  689. {
  690. // 電樁在 Booting 的狀態 - 自檢
  691. PRINTF_FUNC("== PSU == GET_SYS_CAP \n");
  692. ShmPsuData->Work_Step = GET_SYS_CAP;
  693. }
  694. else
  695. {
  696. PRINTF_FUNC("== PSU == _WORK_CHARGING \n");
  697. ShmPsuData->Work_Step = _WORK_CHARGING;
  698. //sdlu test
  699. gettimeofday(&_test_time, NULL);
  700. }
  701. }
  702. _getCapDelayCount = 3;
  703. gettimeofday(&_cmdSubPriority_time, NULL);
  704. }
  705. }
  706. break;
  707. case GET_SYS_CAP:
  708. {
  709. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  710. if (time > 1000)
  711. {
  712. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  713. {
  714. // Pooling Status
  715. GetStatus(index);
  716. // 取系統總輸出能力
  717. GetModuleCap(index);
  718. }
  719. _getCapDelayCount--;
  720. gettimeofday(&_cmdSubPriority_time, NULL);
  721. }
  722. // 判斷系統輸出額定功率與電流
  723. if (ShmPsuData->SystemAvailablePower > 0 && ShmPsuData->SystemAvailableCurrent > 0 &&
  724. _getCapDelayCount <= 0)
  725. {
  726. PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
  727. ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
  728. PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
  729. ShmPsuData->Work_Step = BOOTING_COMPLETE;
  730. }
  731. }
  732. break;
  733. case BOOTING_COMPLETE:
  734. {
  735. sleep(1);
  736. }
  737. break;
  738. case _WORK_CHARGING:
  739. {
  740. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  741. // sdlu - test
  742. int testtime = GetTimeoutValue(_test_time) / 1000;
  743. bool isCharging = false;
  744. // 低 Priority 的指令
  745. if (time > 1500)
  746. {
  747. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  748. {
  749. // Pooling Status
  750. GetStatus(index);
  751. // 取系統總輸出能力
  752. GetModuleCap(index);
  753. // 取得模塊輸入電壓
  754. GetModuleInput(index);
  755. // 取得模塊輸出額定電流能力
  756. GetModuleIavailable(index);
  757. if (chargingInfo[index]->SystemStatus == S_CHARGING)
  758. isCharging = true;
  759. }
  760. gettimeofday(&_cmdSubPriority_time, NULL);
  761. }
  762. CheckSmartChargingStep(isCharging);
  763. for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
  764. {
  765. GetModuleOutput(groupIndex);
  766. // 針對各槍當前狀態,傳送需要回傳的資料指令
  767. if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
  768. (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
  769. {
  770. if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 &&
  771. carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
  772. {
  773. carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  774. DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
  775. }
  776. if (chargingInfo[groupIndex]->EvBatterytargetCurrent > 0 &&
  777. carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
  778. {
  779. carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  780. DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
  781. }
  782. if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
  783. evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
  784. {
  785. evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
  786. PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", groupIndex,
  787. chargingInfo[groupIndex]->FireChargingVoltage);
  788. }
  789. if (chargingInfo[groupIndex]->PresentChargingCurrent > 0 &&
  790. evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
  791. {
  792. evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
  793. PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
  794. chargingInfo[groupIndex]->PresentChargingCurrent);
  795. }
  796. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  797. {
  798. // 智能判斷 Start -----------------------------------------------------------
  799. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
  800. {
  801. if (ShmPsuData->SystemAvailableCurrent != chargingInfo[groupIndex]->AvailableChargingCurrent)
  802. {
  803. // 車端要求電流為該充電槍的額定輸出電流的範圍內
  804. if (chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->AvailableChargingCurrent ||
  805. deratingKeepCount >= DERATING)
  806. {
  807. // 車端降載完成
  808. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_M_TO_A============= Step 3 \n");
  809. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_M_TO_A;
  810. gettimeofday(&_derating_time, NULL);
  811. deratingKeepCount = 0;
  812. }
  813. else
  814. {
  815. deratingKeepCount++;
  816. }
  817. }
  818. }
  819. else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_M_TO_A)
  820. {
  821. bool isChanged = false;
  822. // 需求電流不降低的情況下 -> 依然要切
  823. if (chargingInfo[groupIndex]->AvailableChargingCurrent < chargingInfo[groupIndex]->EvBatterytargetCurrent)
  824. {
  825. PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
  826. chargingInfo[groupIndex]->PresentChargingCurrent,
  827. chargingInfo[groupIndex]->AvailableChargingCurrent);
  828. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  829. {
  830. if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
  831. {
  832. if (chargingInfo[subIndex]->PresentChargingCurrent <= CHK_CUR_RANGE)
  833. isChanged = true;
  834. break;
  835. }
  836. }
  837. // 這狀況下輸出端的電流載滿載衝的狀況下,並不會降電流
  838. // 所以只能拉載到該槍端的最大輸出能力
  839. if (chargingInfo[groupIndex]->PresentChargingCurrent >= chargingInfo[groupIndex]->AvailableChargingCurrent - CHK_CUR_RANGE ||
  840. chargingInfo[groupIndex]->PresentChargingCurrent <= CHK_CUR_RANGE)
  841. {
  842. isChanged = true;
  843. }
  844. }
  845. else if ((chargingInfo[groupIndex]->PresentChargingCurrent >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
  846. (chargingInfo[groupIndex]->PresentChargingCurrent <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
  847. {
  848. isChanged = true;
  849. }
  850. if (isChanged)
  851. {
  852. PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, PresentChargingCurrent = %f, GroupPresentOutputCurrent = %d \n", groupIndex,
  853. chargingInfo[groupIndex]->PresentChargingCurrent,
  854. ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
  855. // 輸出端與車端要求電流接近
  856. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_M_TO_A============= Step 4 \n");
  857. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
  858. }
  859. }
  860. // 智能判斷 End -----------------------------------------------------------
  861. if (testtime > 500)
  862. {
  863. PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
  864. chargingInfo[groupIndex]->AvailableChargingCurrent,
  865. chargingInfo[groupIndex]->AvailableChargingPower);
  866. PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
  867. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  868. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  869. PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
  870. chargingInfo[groupIndex]->PresentChargingVoltage,
  871. chargingInfo[groupIndex]->PresentChargingCurrent);
  872. gettimeofday(&_test_time, NULL);
  873. }
  874. if (ShmPsuData->SystemAvailablePower > 0)
  875. {
  876. // 調整輸出電流 : 漸進調整方式
  877. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A)
  878. {
  879. // 當前充電中的目標電壓
  880. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  881. // 當前充電中的目標電流
  882. float targetCur = 0;
  883. // 準備切出去的模塊電流
  884. float deratingCur = 0;
  885. byte reassignIndex = ELEMENT_NOT_FIND;
  886. // 找到等待分配的槍
  887. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  888. {
  889. if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
  890. {
  891. reassignIndex = subIndex;
  892. }
  893. }
  894. if (reassignIndex != ELEMENT_NOT_FIND)
  895. {
  896. //int derating = GetTimeoutValue(_derating_time) / 1000;
  897. //if (derating > 1000)
  898. {
  899. if (ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent > 0)
  900. {
  901. deratingCur = ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent - DERATING_RANGE;
  902. if (deratingCur <= CHK_CUR_RANGE)
  903. deratingCur = CHK_CUR_RANGE;
  904. PresentOutputVol(reassignIndex, targetVol, deratingCur);
  905. gettimeofday(&_derating_time, NULL);
  906. }
  907. }
  908. // 因為爬的速度沒有降的速度快,所以採兩倍速度爬升
  909. targetCur = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + (DERATING_RANGE * 2);
  910. if (targetCur >= chargingInfo[groupIndex]->EvBatterytargetCurrent)
  911. targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  912. if (targetVol == 0)
  913. {
  914. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  915. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  916. }
  917. else
  918. {
  919. SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
  920. FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
  921. }
  922. }
  923. }
  924. else
  925. {
  926. // 該充電槍的目標電壓與目標電流
  927. PresentOutputVol(SYSTEM_CMD,
  928. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  929. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  930. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  931. {
  932. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  933. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  934. }
  935. else
  936. {
  937. SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
  938. FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
  939. }
  940. }
  941. }
  942. }
  943. else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  944. {
  945. // 智能判斷 Start -----------------------------------------------------------
  946. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
  947. {
  948. bool balanceVol = true;
  949. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  950. {
  951. if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
  952. chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
  953. {
  954. // 各群電壓接近平衡
  955. if ((chargingInfo[subIndex]->PresentChargingVoltage < chargingInfo[groupIndex]->PresentChargingVoltage - ZERO_VOLTAGE) ||
  956. (chargingInfo[subIndex]->PresentChargingVoltage < chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE))
  957. {
  958. PRINTF_FUNC("** _REASSIGNED_ADJUST_A_TO_M ** Gun_%d, PresentChargingVoltage = %f, PresentChargingVoltage_V = %f, EvBatterytargetVoltage = %f \n", subIndex,
  959. chargingInfo[subIndex]->PresentChargingVoltage,
  960. (chargingInfo[groupIndex]->PresentChargingVoltage - ZERO_VOLTAGE),
  961. (chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE));
  962. balanceVol = false;
  963. }
  964. break;
  965. }
  966. }
  967. if (balanceVol)
  968. {
  969. // 閒置端與車端要求電壓接近
  970. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_A_TO_M============= Step 13 \n");
  971. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M;
  972. GetTimeoutValue(_averageComp_time);
  973. }
  974. }
  975. else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING)
  976. {
  977. int avrTime = GetTimeoutValue(_averageComp_time) / 1000;
  978. if (avrTime > 3000)
  979. {
  980. // 閒置端與車端要求電壓接近
  981. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
  982. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
  983. }
  984. }
  985. // 智能判斷 End -----------------------------------------------------------
  986. if (testtime > 500)
  987. {
  988. PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
  989. chargingInfo[groupIndex]->AvailableChargingCurrent,
  990. chargingInfo[groupIndex]->AvailableChargingPower);
  991. PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
  992. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  993. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  994. PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
  995. chargingInfo[groupIndex]->PresentChargingVoltage,
  996. chargingInfo[groupIndex]->PresentChargingCurrent);
  997. gettimeofday(&_test_time, NULL);
  998. }
  999. if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0)
  1000. {
  1001. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
  1002. {
  1003. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  1004. {
  1005. if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
  1006. chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
  1007. {
  1008. // 閒置模塊升壓
  1009. PresentOutputVol(subIndex,
  1010. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  1011. ZERO_CURRENT);
  1012. }
  1013. else
  1014. {
  1015. // 充電中的模塊維持輸出
  1016. PresentOutputVol(subIndex,
  1017. chargingInfo[subIndex]->EvBatterytargetVoltage,
  1018. chargingInfo[subIndex]->EvBatterytargetCurrent);
  1019. }
  1020. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  1021. {
  1022. SwitchPower(subIndex, PSU_POWER_OFF);
  1023. FlashLed(subIndex, PSU_FLASH_NORMAL);
  1024. }
  1025. else
  1026. {
  1027. SwitchPower(subIndex, PSU_POWER_ON);
  1028. FlashLed(subIndex, PSU_FLASH_ON);
  1029. }
  1030. }
  1031. }
  1032. else
  1033. {
  1034. PresentOutputVol(groupIndex,
  1035. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  1036. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  1037. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  1038. {
  1039. SwitchPower(groupIndex, PSU_POWER_OFF);
  1040. FlashLed(groupIndex, PSU_FLASH_NORMAL);
  1041. }
  1042. else
  1043. {
  1044. SwitchPower(groupIndex, PSU_POWER_ON);
  1045. FlashLed(groupIndex, PSU_FLASH_ON);
  1046. }
  1047. }
  1048. }
  1049. }
  1050. }
  1051. else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
  1052. chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  1053. {
  1054. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  1055. {
  1056. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  1057. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  1058. if (chargingInfo[groupIndex]->SystemStatus == S_TERMINATING)
  1059. {
  1060. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
  1061. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
  1062. {
  1063. // 代表在切換的過程中,停止充電了
  1064. if (chargingInfo[groupIndex]->PresentChargingCurrent <= STOP_CURRENT)
  1065. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
  1066. }
  1067. }
  1068. }
  1069. else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  1070. {
  1071. SwitchPower(groupIndex, PSU_POWER_OFF);
  1072. FlashLed(groupIndex, PSU_FLASH_NORMAL);
  1073. }
  1074. }
  1075. }
  1076. break;
  1077. }
  1078. }
  1079. usleep(20000);
  1080. }
  1081. return FAIL;
  1082. }