Module_PsuComm.c 62 KB

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