Module_PsuComm.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  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 (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
  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[index]->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. for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
  338. {
  339. chargingInfo[count]->MaximumChargingVoltage = maxVol;
  340. chargingInfo[count]->AvailableChargingCurrent = _current;
  341. chargingInfo[count]->AvailableChargingPower = _power;
  342. }
  343. }
  344. else
  345. {
  346. // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
  347. chargingInfo[group]->AvailableChargingCurrent = _current;
  348. chargingInfo[group]->AvailableChargingPower = _power;
  349. }
  350. }
  351. }
  352. void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer)
  353. {
  354. if (IsOverModuleCount(address))
  355. return;
  356. byte group = FindTargetGroup(address);
  357. sprintf((char *)ShmPsuData->PsuVersion[address].FwPrimaryVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
  358. sprintf((char *)ShmPsuData->PsuVersion[address].FwSecondVersion, "PFC %d.%02d", (pfcSwVer & 0xFF00) >> 8, pfcSwVer & 0xFF);
  359. if (group == 1)
  360. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  361. sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
  362. //DEBUG_INFO("fw Ver. = %s \n", ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion);
  363. }
  364. void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
  365. {
  366. if (IsOverModuleCount(address))
  367. return;
  368. byte group = FindTargetGroup(address);
  369. if (group == 1)
  370. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  371. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL1 = vol1;
  372. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL2 = vol2;
  373. ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL3 = vol3;
  374. }
  375. void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short outCur)
  376. {
  377. unsigned short outputVol = outVol;
  378. unsigned short outputCur = outCur;
  379. // PSU Group - 電壓
  380. ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
  381. // PSU Group - 電流
  382. ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
  383. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  384. {
  385. outputVol = 0;
  386. outputCur = 0;
  387. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  388. {
  389. if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol)
  390. outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage;
  391. outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent;
  392. }
  393. // 黑白機
  394. if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
  395. {
  396. for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
  397. {
  398. float _vol_buf = outputVol;
  399. float _cur_buf = outputCur;
  400. // EVSE - 電壓
  401. _vol_buf /= 10;
  402. chargingInfo[count]->PresentChargingVoltage = _vol_buf;
  403. // EVSE - 電流
  404. _cur_buf /= 10;
  405. chargingInfo[count]->PresentChargingCurrent = _cur_buf;
  406. }
  407. }
  408. if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
  409. (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
  410. {
  411. float _vol_buf = outputVol;
  412. float _cur_buf = outputCur;
  413. // EVSE - 電壓
  414. _vol_buf /= 10;
  415. chargingInfo[group]->PresentChargingVoltage = _vol_buf;
  416. // EVSE - 電流
  417. _cur_buf /= 10;
  418. chargingInfo[group]->PresentChargingCurrent = _cur_buf;
  419. }
  420. }
  421. else
  422. {
  423. float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
  424. float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
  425. // EVSE - 電壓
  426. _vol_buf /= 10;
  427. chargingInfo[group]->PresentChargingVoltage = _vol_buf;
  428. // EVSE - 電流
  429. _cur_buf /= 10;
  430. chargingInfo[group]->PresentChargingCurrent = _cur_buf;
  431. }
  432. // PRINTF_FUNC("Gun_%d, PresentChargingCurrent = %f \n", group,
  433. // chargingInfo[group]->PresentChargingCurrent);
  434. }
  435. void GetFanSpeedCallback(byte address, unsigned int fanSpeed)
  436. {
  437. if (IsOverModuleCount(address))
  438. return;
  439. byte group = FindTargetGroup(address);
  440. if (group == 1)
  441. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  442. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_1 = fanSpeed;
  443. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_2 = fanSpeed;
  444. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_3 = fanSpeed;
  445. ShmPsuData->PsuGroup[group].PsuModule[address].FanSpeed_4 = fanSpeed;
  446. }
  447. void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
  448. {
  449. if (IsOverModuleCount(address))
  450. return;
  451. byte group = FindTargetGroup(address);
  452. if (group == 1)
  453. address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
  454. //PRINTF_FUNC("group = %d, address_%d, Iavail = %d \n", group, address, Iavail);
  455. // PSU Group - 電壓
  456. ShmPsuData->PsuGroup[group].PsuModule[address].IAvailableCurrent = Iavail;
  457. bool isPass = true;
  458. int totalCur = 0;
  459. if (Iavail == 0)
  460. {
  461. for (byte count = 0; count < 2; count++)
  462. {
  463. chargingInfo[group]->SampleChargingCur[count] = Iavail;
  464. }
  465. }
  466. else
  467. {
  468. // 該群的可輸出電流
  469. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  470. {
  471. totalCur += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
  472. }
  473. for (byte count = 0; count < 2; count++)
  474. {
  475. if (chargingInfo[group]->SampleChargingCur[count] == 0)
  476. {
  477. chargingInfo[group]->SampleChargingCur[count] = totalCur;
  478. return;
  479. }
  480. else
  481. {
  482. if (chargingInfo[group]->SampleChargingCur[count] != totalCur)
  483. {
  484. chargingInfo[group]->SampleChargingCur[count] = totalCur;
  485. isPass = false;
  486. continue;
  487. }
  488. }
  489. }
  490. }
  491. if (isPass)
  492. {
  493. chargingInfo[group]->DeratingChargingCurrent = totalCur;
  494. }
  495. }
  496. //==========================================
  497. // Init all share memory
  498. //==========================================
  499. int InitShareMemory()
  500. {
  501. int result = PASS;
  502. int MeterSMId;
  503. //creat ShmSysConfigAndInfo
  504. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  505. {
  506. #ifdef SystemLogMessage
  507. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
  508. #endif
  509. result = FAIL;
  510. }
  511. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  512. {
  513. #ifdef SystemLogMessage
  514. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
  515. #endif
  516. result = FAIL;
  517. }
  518. else
  519. {}
  520. //creat ShmStatusCodeData
  521. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  522. {
  523. #ifdef SystemLogMessage
  524. DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
  525. #endif
  526. result = FAIL;
  527. }
  528. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  529. {
  530. #ifdef SystemLogMessage
  531. DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
  532. #endif
  533. result = FAIL;
  534. }
  535. else
  536. {}
  537. //creat ShmPsuData
  538. if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
  539. {
  540. #ifdef SystemLogMessage
  541. DEBUG_ERROR("shmget ShmPsuData NG \n");
  542. #endif
  543. result = FAIL;
  544. }
  545. else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  546. {
  547. #ifdef SystemLogMessage
  548. DEBUG_ERROR("shmat ShmPsuData NG \n");
  549. #endif
  550. result = FAIL;
  551. }
  552. memset(ShmPsuData,0,sizeof(struct PsuData));
  553. return result;
  554. }
  555. //================================================
  556. // Main process
  557. //================================================
  558. void InitialPsuData()
  559. {
  560. ShmPsuData->SystemPresentPsuQuantity = 0;
  561. for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup); _groupCount++)
  562. {
  563. ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
  564. ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
  565. ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
  566. }
  567. ShmPsuData->Work_Step = _INIT_PSU_STATUS;
  568. }
  569. void Initialization()
  570. {
  571. bool isPass = false;
  572. while(!isPass)
  573. {
  574. isPass = true;
  575. for (byte _index = 0; _index < _gunCount; _index++)
  576. {
  577. if (!FindChargingInfoData(_index, &chargingInfo[0]))
  578. {
  579. DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
  580. isPass = false;
  581. break;
  582. }
  583. }
  584. }
  585. if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
  586. ShmPsuData->GroupCount = 1;
  587. else
  588. ShmPsuData->GroupCount = _gunCount;
  589. }
  590. void CheckSmartChargingStep(bool isWaitingAver, bool isCharging)
  591. {
  592. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
  593. {
  594. if (isWaitingAver)
  595. {
  596. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  597. {
  598. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
  599. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
  600. }
  601. else
  602. {
  603. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
  604. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
  605. }
  606. }
  607. }
  608. else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_A_TO_M)
  609. {
  610. if (isCharging)
  611. {
  612. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  613. {
  614. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_A_TO_M============= Step 12 \n");
  615. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_A_TO_M;
  616. }
  617. else
  618. {
  619. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
  620. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
  621. }
  622. }
  623. }
  624. }
  625. int main(void)
  626. {
  627. if(InitShareMemory() == FAIL)
  628. {
  629. #ifdef SystemLogMessage
  630. DEBUG_ERROR("InitShareMemory NG\n");
  631. #endif
  632. if(ShmStatusCodeData != NULL)
  633. {
  634. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
  635. }
  636. sleep(5);
  637. return 0;
  638. }
  639. PRINTF_FUNC("InitShareMemory OK\n");
  640. // register callback function
  641. RefreshStatus(&GetStatusCallback);
  642. RefreshModuleCount(&GetModuleCountCallback);
  643. RefreshAvailableCap(&GetAvailableCapCallback);
  644. RefreshFwVersion(&GetFwCallback);
  645. RefreshInputVol(&GetInputVoltageCallback);
  646. RefreshGetOutput(&GetPresentOutputCallback);
  647. RefreshFanInfo(&GetFanSpeedCallback);
  648. RefreshIavailable(&GetIavailableCallback);
  649. sleep(2);
  650. _gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
  651. // initial object
  652. InitialPsuData();
  653. Initialization();
  654. libInitialize = InitialCommunication();
  655. byte isInitialComp = NO;
  656. PRINTF_FUNC("ALTERNATIVE_CONG = %d \n", ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf);
  657. //main loop
  658. while (libInitialize)
  659. {
  660. // 斷電狀態
  661. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  662. {
  663. //一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
  664. if (!isInitialComp)
  665. {
  666. InitialPsuData();
  667. ShmPsuData->Work_Step = INITIAL_START;
  668. isInitialComp = YES;
  669. }
  670. sleep(1);
  671. continue;
  672. }
  673. else
  674. isInitialComp = NO;
  675. // 自檢失敗
  676. if (ShmPsuData->Work_Step == _NO_WORKING)
  677. {
  678. PRINTF_FUNC("== PSU == self test fail. \n");
  679. sleep(5);
  680. }
  681. switch(ShmPsuData->Work_Step)
  682. {
  683. case INITIAL_START:
  684. {
  685. PRINTF_FUNC("== PSU == INITIAL_START \n");
  686. gettimeofday(&_cmdSubPriority_time, NULL);
  687. sleep(5);
  688. ShmPsuData->Work_Step = GET_PSU_COUNT;
  689. }
  690. break;
  691. case GET_PSU_COUNT:
  692. {
  693. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  694. byte moduleCount = 0;
  695. if (time > 2000)
  696. {
  697. PRINTF_FUNC("== PSU == %d \n", ShmPsuData->GroupCount);
  698. // if (ShmPsuData->GroupCount == 0)
  699. // ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
  700. // 分別取各群模組數量
  701. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  702. {
  703. // 總和各群模組數量
  704. moduleCount += ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity;
  705. // 取各群模組數量
  706. GetModuleCount(index);
  707. // 取版號
  708. GetModuleVer(index);
  709. }
  710. // 發送取得目前全部模組數量
  711. GetModuleCount(SYSTEM_CMD);
  712. // 判斷系統數量與各群數量一致
  713. if(moduleCount == ShmPsuData->SystemPresentPsuQuantity && moduleCount > 0)
  714. {
  715. PRINTF_FUNC("Psu Count = %d \n", moduleCount);
  716. if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
  717. {
  718. // 電樁在 Booting 的狀態 - 自檢
  719. PRINTF_FUNC("== PSU == GET_SYS_CAP \n");
  720. ShmPsuData->Work_Step = GET_SYS_CAP;
  721. }
  722. else
  723. {
  724. PRINTF_FUNC("== PSU == _WORK_CHARGING \n");
  725. ShmPsuData->Work_Step = _WORK_CHARGING;
  726. //sdlu test
  727. gettimeofday(&_test_time, NULL);
  728. }
  729. }
  730. _getCapDelayCount = 3;
  731. gettimeofday(&_cmdSubPriority_time, NULL);
  732. }
  733. }
  734. break;
  735. case GET_SYS_CAP:
  736. {
  737. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  738. if (time > 1000)
  739. {
  740. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  741. {
  742. // Pooling Status
  743. GetStatus(index);
  744. // 取系統總輸出能力
  745. GetModuleCap(index);
  746. }
  747. _getCapDelayCount--;
  748. gettimeofday(&_cmdSubPriority_time, NULL);
  749. }
  750. // 判斷系統輸出額定功率與電流
  751. if (ShmPsuData->SystemAvailablePower > 0 && ShmPsuData->SystemAvailableCurrent > 0 &&
  752. _getCapDelayCount <= 0)
  753. {
  754. PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
  755. ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
  756. PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
  757. ShmPsuData->Work_Step = BOOTING_COMPLETE;
  758. }
  759. }
  760. break;
  761. case BOOTING_COMPLETE:
  762. {
  763. sleep(1);
  764. }
  765. break;
  766. case _WORK_CHARGING:
  767. {
  768. int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
  769. // sdlu - test
  770. int testtime = GetTimeoutValue(_test_time) / 1000;
  771. // 低 Priority 的指令
  772. if (time > 1500)
  773. {
  774. isCharging = false;
  775. isWaitingAver = false;
  776. for (byte index = 0; index < ShmPsuData->GroupCount; index++)
  777. {
  778. // Pooling Status
  779. GetStatus(index);
  780. // 取系統總輸出能力
  781. GetModuleCap(index);
  782. // 取得模塊輸入電壓
  783. GetModuleInput(index);
  784. // 取得模塊輸出額定電流能力
  785. GetModuleIavailable(index);
  786. if (chargingInfo[index]->SystemStatus == S_CHARGING)
  787. {
  788. isCharging = true;
  789. if ((chargingInfo[index]->PresentChargingCurrent * 10) >=
  790. chargingInfo[index]->EvBatterytargetCurrent - CHK_CUR_RANGE)
  791. {
  792. isWaitingAver = true;
  793. }
  794. }
  795. }
  796. gettimeofday(&_cmdSubPriority_time, NULL);
  797. CheckSmartChargingStep(isWaitingAver, isCharging);
  798. }
  799. for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
  800. {
  801. GetModuleOutput(groupIndex);
  802. // 針對各槍當前狀態,傳送需要回傳的資料指令
  803. if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
  804. (chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING && chargingInfo[groupIndex]->Type == _Type_GB) ||
  805. (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
  806. {
  807. if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 &&
  808. carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
  809. {
  810. carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  811. DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
  812. }
  813. if (chargingInfo[groupIndex]->EvBatterytargetCurrent > 0 &&
  814. carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
  815. {
  816. carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  817. DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
  818. }
  819. if (time > 1500)
  820. {
  821. if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
  822. evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
  823. {
  824. evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
  825. PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", groupIndex,
  826. chargingInfo[groupIndex]->FireChargingVoltage);
  827. }
  828. if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
  829. evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
  830. {
  831. evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
  832. PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
  833. (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
  834. }
  835. }
  836. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  837. {
  838. // PRINTF_FUNC("index = %d, SystemStatus = %d, Ev = %f, curCur = %f \n", groupIndex,
  839. // chargingInfo[groupIndex]->SystemStatus, chargingInfo[groupIndex]->EvBatterytargetCurrent,
  840. // (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
  841. // 智能判斷 Start -----------------------------------------------------------
  842. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
  843. {
  844. if (ShmPsuData->SystemAvailableCurrent != chargingInfo[groupIndex]->AvailableChargingCurrent)
  845. {
  846. // 車端要求電流為該充電槍的額定輸出電流的範圍內
  847. if (chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->AvailableChargingCurrent ||
  848. deratingKeepCount >= DERATING)
  849. {
  850. // 車端降載完成
  851. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_M_TO_A============= Step 3 \n");
  852. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_M_TO_A;
  853. gettimeofday(&_derating_time, NULL);
  854. deratingKeepCount = 0;
  855. }
  856. else
  857. {
  858. deratingKeepCount++;
  859. }
  860. }
  861. }
  862. else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_M_TO_A)
  863. {
  864. bool isChanged = false;
  865. // 需求電流不降低的情況下 -> 依然要切
  866. if (chargingInfo[groupIndex]->AvailableChargingCurrent < chargingInfo[groupIndex]->EvBatterytargetCurrent)
  867. {
  868. PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
  869. (chargingInfo[groupIndex]->PresentChargingCurrent * 10),
  870. chargingInfo[groupIndex]->AvailableChargingCurrent);
  871. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  872. {
  873. if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
  874. {
  875. if ((chargingInfo[subIndex]->PresentChargingCurrent * 10) <= CHK_CUR_RANGE)
  876. isChanged = true;
  877. break;
  878. }
  879. }
  880. // 這狀況下輸出端的電流載滿載衝的狀況下,並不會降電流
  881. // 所以只能拉載到該槍端的最大輸出能力
  882. if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= chargingInfo[groupIndex]->AvailableChargingCurrent - CHK_CUR_RANGE ||
  883. (chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= CHK_CUR_RANGE)
  884. {
  885. isChanged = true;
  886. }
  887. }
  888. else if (((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
  889. ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
  890. {
  891. isChanged = true;
  892. }
  893. if (isChanged)
  894. {
  895. PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, PresentChargingCurrent = %f, GroupPresentOutputCurrent = %d \n", groupIndex,
  896. (chargingInfo[groupIndex]->PresentChargingCurrent * 10),
  897. ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
  898. // 輸出端與車端要求電流接近
  899. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_M_TO_A============= Step 4 \n");
  900. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
  901. }
  902. }
  903. // 智能判斷 End -----------------------------------------------------------
  904. if (testtime > 500 &&
  905. (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
  906. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
  907. {
  908. PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
  909. chargingInfo[groupIndex]->AvailableChargingCurrent,
  910. chargingInfo[groupIndex]->AvailableChargingPower);
  911. PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
  912. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  913. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  914. PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
  915. (chargingInfo[groupIndex]->PresentChargingVoltage * 10),
  916. (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
  917. gettimeofday(&_test_time, NULL);
  918. }
  919. if (ShmPsuData->SystemAvailablePower > 0)
  920. {
  921. // 調整輸出電流 : 漸進調整方式
  922. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A)
  923. {
  924. // 當前充電中的目標電壓
  925. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  926. // 當前充電中的目標電流
  927. float targetCur = 0;
  928. // 準備切出去的模塊電流
  929. float deratingCur = 0;
  930. byte reassignIndex = ELEMENT_NOT_FIND;
  931. // 找到等待分配的槍
  932. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  933. {
  934. if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
  935. {
  936. reassignIndex = subIndex;
  937. }
  938. }
  939. if (reassignIndex != ELEMENT_NOT_FIND)
  940. {
  941. //int derating = GetTimeoutValue(_derating_time) / 1000;
  942. //if (derating > 1000)
  943. {
  944. if (ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent > 0)
  945. {
  946. deratingCur = ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent - DERATING_RANGE;
  947. if (deratingCur <= CHK_CUR_RANGE)
  948. deratingCur = CHK_CUR_RANGE;
  949. PresentOutputVol(reassignIndex, targetVol, deratingCur);
  950. gettimeofday(&_derating_time, NULL);
  951. }
  952. }
  953. // 因為爬的速度沒有降的速度快,所以採兩倍速度爬升
  954. targetCur = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + (DERATING_RANGE * 2);
  955. if (targetCur >= chargingInfo[groupIndex]->EvBatterytargetCurrent)
  956. targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  957. if (targetVol == 0)
  958. {
  959. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  960. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  961. }
  962. else
  963. {
  964. SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
  965. FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
  966. }
  967. }
  968. }
  969. else
  970. {
  971. // 該充電槍的目標電壓與目標電流
  972. PresentOutputVol(SYSTEM_CMD,
  973. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  974. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  975. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  976. {
  977. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  978. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  979. }
  980. else
  981. {
  982. SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
  983. FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
  984. }
  985. }
  986. }
  987. }
  988. else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  989. {
  990. // 智能判斷 Start -----------------------------------------------------------
  991. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
  992. {
  993. bool balanceVol = true;
  994. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  995. {
  996. if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
  997. chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
  998. {
  999. // 各群電壓接近平衡
  1000. if (((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->PresentChargingVoltage * 10) - ZERO_VOLTAGE) ||
  1001. ((chargingInfo[subIndex]->PresentChargingVoltage * 10) < chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE))
  1002. {
  1003. PRINTF_FUNC("** _REASSIGNED_ADJUST_A_TO_M ** Gun_%d, PresentChargingVoltage = %f, PresentChargingVoltage_V = %f, EvBatterytargetVoltage = %f \n", subIndex,
  1004. (chargingInfo[subIndex]->PresentChargingVoltage * 10),
  1005. ((chargingInfo[groupIndex]->PresentChargingVoltage * 10) - ZERO_VOLTAGE),
  1006. (chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE));
  1007. balanceVol = false;
  1008. }
  1009. break;
  1010. }
  1011. }
  1012. if (balanceVol)
  1013. {
  1014. // 閒置端與車端要求電壓接近
  1015. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_A_TO_M============= Step 13 \n");
  1016. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M;
  1017. GetTimeoutValue(_averageComp_time);
  1018. }
  1019. }
  1020. else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING)
  1021. {
  1022. int avrTime = GetTimeoutValue(_averageComp_time) / 1000;
  1023. if (avrTime > 3000)
  1024. {
  1025. // 閒置端與車端要求電壓接近
  1026. PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
  1027. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
  1028. }
  1029. }
  1030. // 智能判斷 End -----------------------------------------------------------
  1031. if (testtime > 500 &&
  1032. (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_A_TO_M && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_WAITING))
  1033. {
  1034. PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
  1035. chargingInfo[groupIndex]->AvailableChargingCurrent,
  1036. chargingInfo[groupIndex]->AvailableChargingPower);
  1037. PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
  1038. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  1039. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  1040. PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
  1041. (chargingInfo[groupIndex]->PresentChargingVoltage * 10),
  1042. (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
  1043. gettimeofday(&_test_time, NULL);
  1044. }
  1045. if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0)
  1046. {
  1047. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
  1048. {
  1049. for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
  1050. {
  1051. if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
  1052. chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
  1053. {
  1054. // 閒置模塊升壓
  1055. PresentOutputVol(subIndex,
  1056. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  1057. ZERO_CURRENT);
  1058. }
  1059. else
  1060. {
  1061. // 充電中的模塊維持輸出
  1062. PresentOutputVol(subIndex,
  1063. chargingInfo[subIndex]->EvBatterytargetVoltage,
  1064. chargingInfo[subIndex]->EvBatterytargetCurrent);
  1065. }
  1066. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  1067. {
  1068. SwitchPower(subIndex, PSU_POWER_OFF);
  1069. FlashLed(subIndex, PSU_FLASH_NORMAL);
  1070. }
  1071. else
  1072. {
  1073. SwitchPower(subIndex, PSU_POWER_ON);
  1074. FlashLed(subIndex, PSU_FLASH_ON);
  1075. }
  1076. }
  1077. }
  1078. else
  1079. {
  1080. PresentOutputVol(groupIndex,
  1081. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  1082. chargingInfo[groupIndex]->EvBatterytargetCurrent);
  1083. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  1084. {
  1085. SwitchPower(groupIndex, PSU_POWER_OFF);
  1086. FlashLed(groupIndex, PSU_FLASH_NORMAL);
  1087. }
  1088. else
  1089. {
  1090. SwitchPower(groupIndex, PSU_POWER_ON);
  1091. FlashLed(groupIndex, PSU_FLASH_ON);
  1092. }
  1093. }
  1094. }
  1095. }
  1096. }
  1097. else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
  1098. chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  1099. {
  1100. if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
  1101. {
  1102. if (!isCharging)
  1103. {
  1104. SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
  1105. FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
  1106. if (chargingInfo[groupIndex]->SystemStatus == S_COMPLETE)
  1107. {
  1108. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
  1109. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
  1110. {
  1111. // 代表在切換的過程中,停止充電了
  1112. if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= STOP_CURRENT)
  1113. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
  1114. }
  1115. }
  1116. }
  1117. else
  1118. {
  1119. // 代表充電的槍依舊在充電,欲進入充電的槍取消充電了
  1120. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
  1121. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
  1122. {
  1123. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
  1124. }
  1125. }
  1126. }
  1127. else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
  1128. {
  1129. SwitchPower(groupIndex, PSU_POWER_OFF);
  1130. FlashLed(groupIndex, PSU_FLASH_NORMAL);
  1131. }
  1132. }
  1133. }
  1134. break;
  1135. }
  1136. }
  1137. usleep(20000);
  1138. }
  1139. return FAIL;
  1140. }