Module_PsuComm.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. #include "Module_PsuComm.h"
  2. #define Debug
  3. #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
  4. #define PASS 1
  5. #define FAIL -1
  6. #define YES 1
  7. #define NO 0
  8. #define SELF_TEST 0
  9. struct SysConfigAndInfo *ShmSysConfigAndInfo;
  10. struct StatusCodeData *ShmStatusCodeData;
  11. struct PsuData *ShmPsuData;
  12. void trim(char *s);
  13. int mystrcmp(char *p1,char *p2);
  14. void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
  15. void split(char **arr, char *str, const char *del);
  16. bool libInitialize = false;
  17. byte gun_count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
  18. byte getAvailableCapOffset = 5;
  19. float carReqVol = 0;
  20. float carReqCur = 0;
  21. float evseOutVol = 0;
  22. float evseOutCur = 0;
  23. int cmdDelayTime = 30000;
  24. //用來判斷目前英飛源韌體版本 (1.9 版的 目前輸出電壓 及 可輸出電流 看的位置會不一樣)
  25. //byte InfyPwrModelVerIs109 = 0;
  26. int StoreLogMsg(const char *fmt, ...);
  27. #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  28. #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  29. #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  30. unsigned long GetTimeoutValue(struct timeval _sour_time);
  31. unsigned long GetTimeoutValue(struct timeval _sour_time)
  32. {
  33. struct timeval _end_time;
  34. gettimeofday(&_end_time, NULL);
  35. return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
  36. }
  37. int StoreLogMsg(const char *fmt, ...)
  38. {
  39. char Buf[4096+256];
  40. char buffer[4096];
  41. time_t CurrentTime;
  42. struct tm *tm;
  43. va_list args;
  44. va_start(args, fmt);
  45. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  46. va_end(args);
  47. memset(Buf,0,sizeof(Buf));
  48. CurrentTime = time(NULL);
  49. tm=localtime(&CurrentTime);
  50. sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
  51. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
  52. buffer,
  53. tm->tm_year+1900,tm->tm_mon+1);
  54. system(Buf);
  55. return rc;
  56. }
  57. int DiffTimeb(struct timeb ST, struct timeb ET)
  58. {
  59. //return milli-second
  60. unsigned int StartTime,StopTime;
  61. StartTime=(unsigned int)ST.time;
  62. StopTime=(unsigned int)ET.time;
  63. return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
  64. }
  65. //=================================
  66. // Common routine
  67. //=================================
  68. char* getTimeString(void)
  69. {
  70. char *result=malloc(21);
  71. time_t timep;
  72. struct tm *p;
  73. time(&timep);
  74. p=gmtime(&timep);
  75. sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec);
  76. return result;
  77. }
  78. void trim(char *s)
  79. {
  80. int i=0, j, k, l=0;
  81. while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
  82. i++;
  83. j = strlen(s)-1;
  84. while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
  85. j--;
  86. if(i==0 && j==strlen(s)-1) { }
  87. else if(i==0) s[j+1] = '\0';
  88. else {
  89. for(k=i; k<=j; k++) s[l++] = s[k];
  90. s[l] = '\0';
  91. }
  92. }
  93. int mystrcmp(char *p1,char *p2)
  94. {
  95. while(*p1==*p2)
  96. {
  97. if(*p1=='\0' || *p2=='\0')
  98. break;
  99. p1++;
  100. p2++;
  101. }
  102. if(*p1=='\0' && *p2=='\0')
  103. return(PASS);
  104. else
  105. return(FAIL);
  106. }
  107. void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
  108. {
  109. strncpy(dest, src + start, cnt);
  110. dest[cnt] = 0;
  111. }
  112. void split(char **arr, char *str, const char *del)
  113. {
  114. char *s = strtok(str, del);
  115. while(s != NULL)
  116. {
  117. *arr++ = s;
  118. s = strtok(NULL, del);
  119. }
  120. }
  121. //=================================
  122. // Save data to share memory Function
  123. //=================================
  124. bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
  125. {
  126. for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
  127. {
  128. if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
  129. {
  130. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
  131. return true;
  132. }
  133. }
  134. for (byte index = 0; index < CCS_QUANTITY; index++)
  135. {
  136. if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
  137. {
  138. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
  139. return true;
  140. }
  141. }
  142. for (byte index = 0; index < GB_QUANTITY; index++)
  143. {
  144. if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
  145. {
  146. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
  147. return true;
  148. }
  149. }
  150. return false;
  151. }
  152. void GetPsuRequestCallback(byte phy_id, char *serial_number)
  153. {
  154. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  155. return;
  156. //printf("++++++++++++++++++++phy_id = %d \n", phy_id);
  157. // ********************** 每次送電後,需判斷要把所有的模塊分配到哪個 Group **********************
  158. byte group = 0;
  159. if(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || gun_count == 1)
  160. {
  161. // 初始化狀態,則直接先分配到同個群
  162. group = 0;
  163. }
  164. else
  165. {
  166. group = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
  167. }
  168. bool isNewPsu = true;
  169. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  170. {
  171. if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == phy_id &&
  172. strncmp((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber, serial_number, 7) == 0)
  173. {
  174. isNewPsu = false;
  175. }
  176. }
  177. if (isNewPsu)
  178. {
  179. ShmPsuData->SystemPresentPsuQuantity++;
  180. printf("get psu********Membar = %d, group = %d \n", ShmPsuData->SystemPresentPsuQuantity, group);
  181. if (ShmPsuData->Work_Step >= _TEST_LINE_STEP && ShmPsuData->Work_Step <= _TEST_COMPLETE)
  182. {
  183. // 已經進入火線上的驗證動作
  184. ShmPsuData->NeedBackTest = YES;
  185. }
  186. else if (ShmPsuData->Work_Step == _WORK_CHARGING)
  187. {
  188. // 一旦進入火線,分配一個不會用到的給該模塊
  189. group++;
  190. }
  191. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address = ShmPsuData->SystemPresentPsuQuantity;
  192. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID = phy_id;
  193. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].AssignID = (group >> 6) + ShmPsuData->SystemPresentPsuQuantity;
  194. strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber, serial_number);
  195. ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
  196. //PsuAddressAssignment(phy_id, serial_number, ShmPsuData->SystemPresentPsuQuantity, group);
  197. PsuAddressAssignment(phy_id, group);
  198. if (ShmPsuData->Work_Step != _WORK_CHARGING)
  199. {
  200. ShmPsuData->GroupCount = group + 1;
  201. }
  202. }
  203. }
  204. void SaveStatusCallback(byte group, byte address, char cri_temp1, int alarm)
  205. {
  206. //EVSE
  207. //for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  208. //{
  209. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  210. {
  211. if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == address)
  212. {
  213. ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp1 = cri_temp1;
  214. //ShmPsuData->PsuGroup[group].PsuModule[index].INFYPWR_Alarm.AlarmCode = alarm;
  215. break;
  216. }
  217. }
  218. //printf ("psu alarm = %08x \n", alarm);
  219. //}
  220. }
  221. //模組三向輸入電壓
  222. void SavePresentInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
  223. {
  224. //EVSE
  225. //search group
  226. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  227. {
  228. for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  229. {
  230. //search id
  231. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  232. {
  233. //update module msg
  234. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL1 = vol1;
  235. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL2 = vol2;
  236. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL3 = vol3;
  237. break;
  238. }
  239. }
  240. }
  241. }
  242. // 模塊輸出的電壓電流
  243. void SavePresentOutputCallback(byte address, unsigned short out_vol, unsigned short out_cur)
  244. {
  245. unsigned short outputVol = 0;
  246. unsigned short outputCur = 0;
  247. unsigned short group = 0;
  248. bool isChange = false;
  249. // PSU
  250. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  251. {
  252. for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  253. {
  254. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  255. {
  256. //如果英飛源模組不是 ver1.09 版使用模組輸出電壓
  257. /*
  258. if(InfyPwrModelVerIs109 == 0)
  259. {
  260. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol;
  261. }
  262. */
  263. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol;
  264. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent = out_cur;
  265. for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++)
  266. {
  267. //update voltage
  268. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage > outputVol)
  269. {
  270. outputVol = ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage;
  271. }
  272. //update total current
  273. outputCur += ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent;
  274. group = groupIndex;
  275. isChange = true;
  276. }
  277. }
  278. /*
  279. if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > outputVol)
  280. outputVol = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
  281. outputCur += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
  282. */
  283. }
  284. }
  285. if (isChange)
  286. {
  287. // PSU Group
  288. // 電壓
  289. ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
  290. // 電流
  291. ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
  292. //EVSE - 槍端的輸出電壓
  293. chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
  294. //EVSE - 槍端的輸出電流
  295. chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
  296. }
  297. //printf("GroupPresentOutputVoltage = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage);
  298. //printf("GroupPresentOutputCurrent = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent);
  299. }
  300. //PSU able_power = KW (單位 0.1) exp. 300 = 30kw
  301. //PSU able_cur = A (單位 0.1) exp. 400 = 40A
  302. void SaveAvailableCapCallback(byte address, unsigned short maxv,unsigned short minv, unsigned short able_cur, unsigned short able_power)
  303. {
  304. unsigned int power = 0;
  305. unsigned int current = 0;
  306. unsigned int group = 0;
  307. bool isChange = false;
  308. //bool sameGroup = false;
  309. //search group
  310. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  311. {
  312. for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  313. {
  314. //search group-id
  315. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  316. {
  317. //先更新該模組資訊
  318. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailablePower = able_power;
  319. //電壓在 150V 時使用額定電流
  320. if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage < 1500 )
  321. {
  322. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur;
  323. }
  324. //如果英飛源模組不是 ver1.09 版 或 (如果英飛源模組是 ver1.09 版但回應可輸出電流有誤則使用額定報文可輸出電流)
  325. /*
  326. if(InfyPwrModelVerIs109 == 0 ||
  327. (InfyPwrModelVerIs109 == 1 && ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent == 0))
  328. {
  329. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur;
  330. }
  331. */
  332. //該對應的模組群重新計算總合
  333. for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++)
  334. {
  335. power += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailablePower;
  336. current += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailableCurrent;
  337. group = groupIndex;
  338. isChange = true;
  339. }
  340. /*
  341. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == YES)
  342. {
  343. for (int index = 0; index < ShmPsuData->SystemPresentPsuQuantity; index++)
  344. {
  345. if (recordPsuData[index]._phy_addr == ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID)
  346. {
  347. if (recordPsuData[index]._fire_index == group)
  348. {
  349. sameGroup = true;
  350. }
  351. break;
  352. }
  353. }
  354. }
  355. else
  356. sameGroup = true;
  357. if(sameGroup)
  358. {
  359. ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower = able_power;
  360. ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent = able_cur;
  361. isChange = true;
  362. }
  363. */
  364. }
  365. /*
  366. if(sameGroup)
  367. {
  368. power += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
  369. current += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
  370. }
  371. */
  372. }
  373. }
  374. if (isChange)
  375. {
  376. // PSU Group
  377. // Available Power
  378. ShmPsuData->PsuGroup[group].GroupAvailablePower = power;
  379. // Available Current
  380. ShmPsuData->PsuGroup[group].GroupAvailableCurrent = current;
  381. //EVSE
  382. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == NO)
  383. {
  384. if (ShmPsuData->PsuGroup[group].GroupAvailablePower < chargingInfo[group]->AvailableChargingPower)
  385. {
  386. printf("Power derating old = %f, new = %d ***************************************************************** \n",
  387. chargingInfo[group]->AvailableChargingPower,
  388. ShmPsuData->PsuGroup[group].GroupAvailablePower);
  389. }
  390. }
  391. chargingInfo[group]->MaximumChargingVoltage = maxv;
  392. chargingInfo[group]->AvailableChargingCurrent = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
  393. chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
  394. }
  395. //printf("GetAvb:%d maxV= %d, minV = %d, mixA =%d pwr =%d\n", address, maxv, minv, able_cur, able_power);
  396. }
  397. void GetBarCodeCallback(byte address, char *serial_number , unsigned short module_ver)
  398. {
  399. //EVSE
  400. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  401. {
  402. for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  403. {
  404. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  405. {
  406. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[0] = (module_ver >> 8) & 0xFF;
  407. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[1] = (module_ver) & 0xFF;
  408. //strcpy((char *)ShmPsuData->PsuGroup[groupIndex].PsuModule[ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity].SerialNumber, serial_number);
  409. }
  410. }
  411. }
  412. }
  413. void GetMiscInfoCallback(byte address, unsigned short CmdType , unsigned int value)
  414. {
  415. //EVSE
  416. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  417. {
  418. for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  419. {
  420. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  421. {
  422. if(CmdType == MISC_REQCMD_DC_BOARD_TMP){
  423. //數值未處理
  424. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp2 = (byte)value;
  425. }else if(CmdType == MISC_REQCMD_PFC_BOARD_TMP){
  426. //數值未處理
  427. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp3 = (byte)value;
  428. }else if(CmdType == MISC_REQCMD_FAN_SPEED){
  429. //數值未處理
  430. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FanSpeed_1 = (unsigned short)value;
  431. }
  432. }
  433. }
  434. }
  435. //暫定如果有回 misc 就認定英飛源為 1.9 版
  436. //InfyPwrModelVerIs109 = 1;
  437. //printf("Get Misc : %d \n",InfyPwrModelVerIs109);
  438. }
  439. void SaveHardwareVersion(byte group, byte address, int hw_ver)
  440. {
  441. //EVSE
  442. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  443. {
  444. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  445. {
  446. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[0] = (hw_ver >> 24) & 0xFF;
  447. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[1] = (hw_ver >> 16) & 0xFF;
  448. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[2] = (hw_ver >> 8) & 0xFF;
  449. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[3] = hw_ver & 0xFF;
  450. break;
  451. }
  452. }
  453. }
  454. //Vext 模組二極體後電壓
  455. //Iavail 模組目前因環境因素的真實能輸出電流
  456. void SavePresentModeleVextIavailCallback(byte address, unsigned short Vext, unsigned short Iavail)
  457. {
  458. //EVSE
  459. //search group
  460. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  461. {
  462. for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  463. {
  464. //search id
  465. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  466. {
  467. //update module msg
  468. //ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = Vext;
  469. //
  470. if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage >= 1500)
  471. {
  472. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = Iavail;
  473. }
  474. //printf("Vext = %d I = %d \n", Vext,Iavail);
  475. break;
  476. }
  477. }
  478. }
  479. }
  480. void GetOutputPowerSwitchStatusCallback(byte address, unsigned char value)
  481. {
  482. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  483. {
  484. for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
  485. {
  486. if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
  487. {
  488. //printf("PowerSwitch = %d, group = %d, address = %d \n", value, group, address);
  489. if(value){
  490. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x00;
  491. }else{
  492. ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x01;
  493. }
  494. break;
  495. }
  496. }
  497. }
  498. }
  499. //==========================================
  500. // Init all share memory
  501. //==========================================
  502. int InitShareMemory()
  503. {
  504. int result = PASS;
  505. int MeterSMId;
  506. //creat ShmSysConfigAndInfo
  507. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  508. {
  509. #ifdef SystemLogMessage
  510. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
  511. #endif
  512. result = FAIL;
  513. }
  514. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  515. {
  516. #ifdef SystemLogMessage
  517. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
  518. #endif
  519. result = FAIL;
  520. }
  521. else
  522. {}
  523. //creat ShmStatusCodeData
  524. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  525. {
  526. #ifdef SystemLogMessage
  527. DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
  528. #endif
  529. result = FAIL;
  530. }
  531. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  532. {
  533. #ifdef SystemLogMessage
  534. DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
  535. #endif
  536. result = FAIL;
  537. }
  538. else
  539. {}
  540. //creat ShmPsuData
  541. if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
  542. {
  543. #ifdef SystemLogMessage
  544. DEBUG_ERROR("shmget ShmPsuData NG \n");
  545. #endif
  546. result = FAIL;
  547. }
  548. else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  549. {
  550. #ifdef SystemLogMessage
  551. DEBUG_ERROR("shmat ShmPsuData NG \n");
  552. #endif
  553. result = FAIL;
  554. }
  555. memset(ShmPsuData,0,sizeof(struct PsuData));
  556. return result;
  557. }
  558. //================================================
  559. // Main process
  560. //================================================
  561. void InitialPsuData()
  562. {
  563. ShmPsuData->SystemPresentPsuQuantity = 0;
  564. for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup); _groupCount++)
  565. {
  566. ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
  567. ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
  568. ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
  569. }
  570. ShmPsuData->Work_Step = 0xff;
  571. }
  572. void Initialization()
  573. {
  574. bool isPass = false;
  575. while(!isPass)
  576. {
  577. isPass = true;
  578. for (byte _index = 0; _index < _gunCount; _index++)
  579. {
  580. if (!FindChargingInfoData(_index, &chargingInfo[0]))
  581. {
  582. DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
  583. isPass = false;
  584. break;
  585. }
  586. }
  587. }
  588. }
  589. int main(void)
  590. {
  591. printf("Psu Task boot .... \n");
  592. if(InitShareMemory() == FAIL)
  593. {
  594. #ifdef SystemLogMessage
  595. DEBUG_ERROR("InitShareMemory NG\n");
  596. #endif
  597. if(ShmStatusCodeData != NULL)
  598. {
  599. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
  600. }
  601. sleep(5);
  602. return 0;
  603. }
  604. printf("InitShareMemory OK\n");
  605. // register callback function
  606. GetPsuAddressReq(&GetPsuRequestCallback);
  607. RefreshSerialNumber(&GetBarCodeCallback);
  608. RefreshVextAndIavail(&SavePresentModeleVextIavailCallback);
  609. RefreshMiscInfo(&GetMiscInfoCallback);
  610. RefreshStatus(&SaveStatusCallback);
  611. RefreshInputVol(&SavePresentInputVoltageCallback);
  612. RefreshGetOutput(&SavePresentOutputCallback);
  613. RefreshAvailableCap(&SaveAvailableCapCallback);
  614. RefreshOutputPowerSwitch(&GetOutputPowerSwitchStatusCallback);
  615. // initial object
  616. InitialPsuData();
  617. Initialization();
  618. libInitialize = InitialCommunication();
  619. byte priorityLow = 1;
  620. //main loop
  621. while (libInitialize)
  622. {
  623. // 斷電狀態
  624. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  625. {
  626. //一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
  627. InitialPsuData();
  628. sleep(1);
  629. ShmPsuData->Work_Step = ASSIGN_START;
  630. continue;
  631. }
  632. // update psu fw req
  633. // if(psu update req ?)
  634. // {
  635. //
  636. // continue;
  637. // }
  638. // 自檢失敗
  639. if (ShmPsuData->Work_Step == _NO_WORKING)
  640. {
  641. DEBUG_ERROR("== PSU == self test fail. \n");
  642. printf("== PSU == self test fail. \n");
  643. sleep(5);
  644. }
  645. switch(ShmPsuData->Work_Step)
  646. {
  647. case ASSIGN_START:
  648. {
  649. printf("== PSU == ASSIGN_COMP \n");
  650. gettimeofday(&_id_assign_time, NULL);
  651. ShmPsuData->Work_Step = ASSIGN_COMP;
  652. //發送使用 ID DIP MODE
  653. //InfyPwrModelVerIs109 = 0;
  654. EnableDipAddrMode();
  655. }
  656. break;
  657. case ASSIGN_COMP:
  658. {
  659. if (priorityLow == 1)
  660. {
  661. //如果還未取得模組數量
  662. if(ShmPsuData->SystemPresentPsuQuantity == 0)
  663. {
  664. //發送取得目前全部模組數量 (英飛源開機須等待讓模組互相通訊)
  665. RequestModuleTotalMumbert();
  666. usleep(cmdDelayTime);
  667. }
  668. //己取得模組數量 (目前還未分配群組所以都使用預設 0)
  669. else
  670. {
  671. for (byte psuIndex = 0; psuIndex < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; psuIndex++)
  672. {
  673. if (ShmPsuData->PsuGroup[0].PsuModule[psuIndex].Address == NONE_CARE_ADDRESS)
  674. continue;
  675. //get status
  676. GetStatus(SET_GROUP_CMD, 0);
  677. usleep(cmdDelayTime);
  678. //get barcode & ver
  679. GetSerialNumber(SET_GROUP_CMD, 0);
  680. usleep(cmdDelayTime);
  681. //GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_DC_BOARD_TMP);
  682. //usleep(cmdDelayTime);
  683. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_DC_BOARD_TMP);
  684. usleep(cmdDelayTime);
  685. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
  686. usleep(cmdDelayTime);
  687. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
  688. usleep(cmdDelayTime);
  689. }
  690. }
  691. //printf("Get Misc2 : %d \n",InfyPwrModelVerIs109);
  692. }
  693. priorityLow >= 20 ? priorityLow = 1 : priorityLow++;
  694. // 等待十秒
  695. if (GetTimeoutValue(_id_assign_time) >= 15000000)
  696. {
  697. ShmPsuData->Work_Step = ENABLE_POW;
  698. printf("INFYPWR Num = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  699. printf("== PSU == ENABLE_POW \n");
  700. }
  701. }
  702. break;
  703. case ENABLE_POW:
  704. {
  705. if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
  706. {
  707. // 電樁在 Booting 的狀態 - 自檢
  708. printf("== PSU == _TEST_LINE_STEP \n");
  709. ShmPsuData->Work_Step = _TEST_LINE_STEP;
  710. }
  711. else
  712. {
  713. printf("== PSU == _WORK_CHARGING \n");
  714. ShmPsuData->Work_Step = _WORK_CHARGING;
  715. gettimeofday(&_workModePriority_time, NULL);
  716. }
  717. }
  718. break;
  719. case _TEST_LINE_STEP:
  720. {
  721. printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  722. if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0)
  723. {
  724. sleep(1);
  725. continue;
  726. }
  727. #if (SELF_TEST)
  728. // 對整個 Group 保持通訊
  729. bool isFind = false;
  730. while(ShmPsuData->Work_Step != _NO_WORKING &&
  731. _curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  732. {
  733. GetStatus(SET_GROUP_CMD, 0);
  734. usleep(cmdDelayTime);
  735. GetAvailableCap(SET_GROUP_CMD, 0, 0);
  736. usleep(cmdDelayTime);
  737. //如果在開機自我測試中又加入新的模組就全部重做自我測試
  738. if (ShmPsuData->NeedBackTest == YES)
  739. {
  740. ShmPsuData->NeedBackTest = NO;
  741. _curCheckPsuIndexForFireLine = 0x00;
  742. }
  743. if (isFind)
  744. {
  745. GetPresentOutput(SET_MODULE_CMD, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID);
  746. usleep(cmdDelayTime);
  747. //printf("isFind ****** \n");
  748. //printf("stop vor = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  749. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage <= 200)
  750. {
  751. // 檢查下一個
  752. _curCheckPsuIndexForFireLine++;
  753. isFind = false;
  754. }
  755. //英飛源無法設定 v = 0
  756. //程序放在此
  757. //1.前一個模組會被關閉
  758. //2.++後的新的模組也會先被先關閉 1 次
  759. SetPresentOutput(SET_MODULE_CMD, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID,
  760. ZERO_VOL, ZERO_CUR, chargingInfo[0]->AvailableChargingCurrent);
  761. usleep(cmdDelayTime);
  762. EnableOutputPower(SET_MODULE_CMD ,ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID , SWITCH_OFF);
  763. usleep(cmdDelayTime);
  764. EnableGreenLedFlash(SET_MODULE_CMD ,ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID , SWITCH_OFF);
  765. usleep(cmdDelayTime);
  766. }
  767. else
  768. {
  769. printf("AvailableCurrent[%d] = %d \n",_curCheckPsuIndexForFireLine, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent);
  770. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent > 0)
  771. {
  772. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage == 0)
  773. {
  774. //printf("set output vol = %d, cur = %d \n", SELF_TEST_VOL, SELF_TEST_CUR);
  775. SetPresentOutput(SET_MODULE_CMD, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID,
  776. SELF_TEST_VOL, SELF_TEST_CUR, chargingInfo[0]->AvailableChargingCurrent);
  777. usleep(cmdDelayTime);
  778. EnableOutputPower(SET_MODULE_CMD ,ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID , SWITCH_ON);
  779. usleep(cmdDelayTime);
  780. EnableGreenLedFlash(SET_MODULE_CMD ,ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID , SWITCH_ON);
  781. usleep(cmdDelayTime);
  782. }
  783. if(!isCheckOutputTimeStart)
  784. {
  785. gettimeofday(&_chk_output_time, NULL);
  786. isCheckOutputTimeStart = true;
  787. }
  788. else
  789. {
  790. // 如果五秒內火線上都沒有偵測到電壓,則代表異常
  791. if (GetTimeoutValue(_chk_output_time) >= 20000000)
  792. {
  793. // 自檢失敗
  794. printf("self test timeout \n");
  795. EnableOutputPower(SET_GROUP_CMD, 0, SWITCH_OFF);
  796. usleep(cmdDelayTime);
  797. EnableGreenLedFlash(SET_MODULE_CMD, 0, SWITCH_OFF);
  798. usleep(cmdDelayTime);
  799. ShmPsuData->Work_Step = _NO_WORKING;
  800. continue;
  801. }
  802. }
  803. for (byte gunIndex = 0; gunIndex < _gunCount; gunIndex ++)
  804. {
  805. GetPresentOutput(SET_MODULE_CMD, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID);
  806. usleep(cmdDelayTime);
  807. printf("Cur psu[%d] output voltage = %d \n",_curCheckPsuIndexForFireLine, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  808. printf("Fire[%d] voltage = %f \n", gunIndex, chargingInfo[gunIndex]->FuseChargingVoltage);
  809. // 該模組的輸出電壓與火線上的電壓一致
  810. if (chargingInfo[gunIndex]->FuseChargingVoltage >= 1500 &&
  811. ((chargingInfo[gunIndex]->FuseChargingVoltage >= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage - 300) &&
  812. (chargingInfo[gunIndex]->FuseChargingVoltage <= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage + 300)))
  813. {
  814. printf("Cur psu output voltage2 = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  815. // 找到火線上的電壓了,這邊紀錄火線是紀錄屬於哪一把槍的火線
  816. if (_curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  817. {
  818. // 紀錄當前 PSU 是哪個火線上的
  819. recordPsuData[_curCheckPsuIndexForFireLine]._fire_index = gunIndex;
  820. recordPsuData[_curCheckPsuIndexForFireLine]._phy_addr = ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID;
  821. strcpy(recordPsuData[_curCheckPsuIndexForFireLine]._serial_num, (char *)ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].SerialNumber);
  822. printf("Find Fire Line Number end~~~~~~~~~~~~~~~ = %d \n", gunIndex);
  823. usleep(300000);
  824. isCheckOutputTimeStart = false;
  825. isFind = true;
  826. break;
  827. }
  828. }
  829. }
  830. }
  831. }
  832. usleep(100000);
  833. }
  834. if (ShmPsuData->Work_Step != _NO_WORKING)
  835. {
  836. printf("== PSU == TEST_POWER_STEP \n");
  837. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  838. }
  839. EnableOutputPower(SET_GROUP_CMD, 0, SWITCH_OFF);
  840. usleep(cmdDelayTime);
  841. EnableGreenLedFlash(SET_MODULE_CMD, 0, SWITCH_OFF);
  842. usleep(cmdDelayTime);
  843. #else
  844. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  845. #endif
  846. }
  847. break;
  848. case _TEST_POWER_STEP:
  849. {
  850. if(!_chkTotalCapStart)
  851. {
  852. _chkTotalCapStart = true;
  853. gettimeofday(&_chk_cap_time, NULL);
  854. }
  855. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  856. {
  857. GetStatus(SET_GROUP_CMD, groupIndex);
  858. usleep(cmdDelayTime);
  859. //infypwr v1.9 (如果沒回也沒差)
  860. GetVextAndIavail(SET_MODULE_CMD, 0);
  861. usleep(cmdDelayTime);
  862. GetAvailableCap(SET_GROUP_CMD, groupIndex, 0);
  863. usleep(cmdDelayTime);
  864. }
  865. if (GetTimeoutValue(_chk_cap_time) >= 2000000)
  866. {
  867. printf("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n",
  868. chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower);
  869. for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++)
  870. {
  871. printf("index = %d, fire index = %d, phy addr = %d \n",
  872. index, recordPsuData[index]._fire_index, recordPsuData[index]._phy_addr);
  873. }
  874. printf("== PSU == TEST_COMPLETE \n");
  875. ShmPsuData->Work_Step = _TEST_COMPLETE;
  876. }
  877. }
  878. break;
  879. case _TEST_COMPLETE:
  880. {
  881. priorityLow = 1;
  882. sleep(1);
  883. }
  884. break;
  885. case _WORK_CHARGING:
  886. {
  887. int time = GetTimeoutValue(_workModePriority_time) / 1000;
  888. //printf("GroupCount = %d \n", ShmPsuData->GroupCount);
  889. //printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  890. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  891. {
  892. if (time > 1000)
  893. {
  894. GetStatus(SET_GROUP_CMD, groupIndex);
  895. usleep(cmdDelayTime);
  896. GetAvailableCap(SET_GROUP_CMD, groupIndex, 0);
  897. usleep(cmdDelayTime);
  898. /*
  899. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_DC_BOARD_TMP);
  900. usleep(cmdDelayTime);
  901. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
  902. usleep(cmdDelayTime);
  903. GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
  904. usleep(cmdDelayTime);
  905. */
  906. gettimeofday(&_workModePriority_time, NULL);
  907. }
  908. GetPresentOutput(SET_GROUP_CMD, groupIndex);
  909. GetVextAndIavail(SET_MODULE_CMD, 0);
  910. if (carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
  911. {
  912. carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  913. DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
  914. }
  915. if (carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
  916. {
  917. carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  918. DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
  919. }
  920. if (evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
  921. {
  922. evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
  923. printf("evse output vol = %f \n", chargingInfo[groupIndex]->FireChargingVoltage);
  924. }
  925. if (evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
  926. {
  927. evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
  928. printf("evse output cur = %f \n", chargingInfo[groupIndex]->PresentChargingCurrent);
  929. }
  930. // 針對各槍當前狀態,傳送需要回傳的資料指令
  931. if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
  932. (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
  933. {
  934. if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0)
  935. {
  936. // 該充電槍的目標電壓與目標電流
  937. SetPresentOutput(SET_GROUP_CMD, groupIndex,
  938. chargingInfo[groupIndex]->EvBatterytargetVoltage,
  939. chargingInfo[groupIndex]->EvBatterytargetCurrent,
  940. chargingInfo[groupIndex]->AvailableChargingCurrent);
  941. usleep(cmdDelayTime);
  942. }
  943. if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
  944. {
  945. EnableOutputPower(SET_GROUP_CMD, groupIndex, SWITCH_OFF);
  946. usleep(cmdDelayTime);
  947. EnableGreenLedFlash(SET_GROUP_CMD , groupIndex , SWITCH_OFF);
  948. usleep(cmdDelayTime);
  949. }
  950. else
  951. {
  952. EnableOutputPower(SET_GROUP_CMD, groupIndex, SWITCH_ON);
  953. usleep(cmdDelayTime);
  954. EnableGreenLedFlash(SET_GROUP_CMD , groupIndex, SWITCH_ON);
  955. usleep(cmdDelayTime);
  956. }
  957. }
  958. else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
  959. chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  960. {
  961. SetPresentOutput(SET_GROUP_CMD, groupIndex, ZERO_VOL, ZERO_CUR, chargingInfo[groupIndex]->AvailableChargingCurrent);
  962. usleep(cmdDelayTime);
  963. EnableGreenLedFlash(SET_GROUP_CMD , groupIndex , SWITCH_OFF);
  964. usleep(cmdDelayTime);
  965. EnableOutputPower(SET_GROUP_CMD, groupIndex, SWITCH_OFF);
  966. usleep(cmdDelayTime);
  967. }
  968. }
  969. priorityLow >= 200 ? priorityLow = 1 : priorityLow++;
  970. break;
  971. }
  972. }
  973. usleep(45000);
  974. }
  975. return FAIL;
  976. }