Module_PsuComm.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  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 DERATING 10
  9. #define SELF_TEST 0
  10. float maxChargingVol = 5000; // 限制最大充電電壓,如依照模塊則填上 0
  11. struct SysConfigAndInfo *ShmSysConfigAndInfo;
  12. struct StatusCodeData *ShmStatusCodeData;
  13. struct PsuData *ShmPsuData;
  14. void trim(char *s);
  15. int mystrcmp(char *p1,char *p2);
  16. void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
  17. void split(char **arr, char *str, const char *del);
  18. bool libInitialize = false;
  19. byte getAvailableCapOffset = 5;
  20. byte deratingKeepCount = 0;
  21. float carReqVol = 0;
  22. float carReqCur = 0;
  23. float evseOutVol = 0;
  24. float evseOutCur = 0;
  25. int cmdDelayTime = 60000;
  26. int StoreLogMsg(const char *fmt, ...);
  27. unsigned long GetTimeoutValue(struct timeval _sour_time);
  28. #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  29. #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  30. #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
  31. unsigned long GetTimeoutValue(struct timeval _sour_time)
  32. {
  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. // Alarm code mapping to share memory Function
  123. //=================================
  124. void AbnormalStopAnalysis(byte gun_index, byte *errCode)
  125. {
  126. char string[7];
  127. sprintf(string, "%d%d%d%d%d%d", *(errCode + 5), *(errCode + 4), *(errCode + 3), *(errCode + 2), *(errCode + 1), *(errCode + 0));
  128. // if (gun_index < _gunCount)
  129. // {
  130. // if (strlen((char *)ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index]) <= 0)
  131. // {
  132. // memcpy(&ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index][0], string, 7);
  133. // ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level = 0x00;
  134. // }
  135. // }
  136. printf("PSU Alarm code = %s \n", errCode);
  137. }
  138. //=================================
  139. // ReAssigned PSU Function
  140. //=================================
  141. void ReAssignedResource()
  142. {
  143. int index = 0;
  144. struct PsuModuleData PsuModule[ShmPsuData->SystemPresentPsuQuantity];
  145. for (byte i = 0; i < 4; i++)
  146. {
  147. for(byte psuCount = 0; psuCount < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; psuCount++)
  148. {
  149. memcpy(&PsuModule[index], &ShmPsuData->PsuGroup[i].PsuModule[psuCount], sizeof(struct PsuModuleData));
  150. index++;
  151. }
  152. ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity = 0;
  153. }
  154. for(int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
  155. {
  156. byte group = PsuModule[i].FireWireIndex;
  157. memcpy(&ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity],
  158. &PsuModule[i], sizeof(struct PsuModuleData));
  159. printf("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n",
  160. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
  161. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
  162. group);
  163. PsuAddressAssignment(ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
  164. (char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber,
  165. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
  166. group);
  167. ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
  168. }
  169. }
  170. //=================================
  171. // Save data to share memory Function
  172. //=================================
  173. bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
  174. {
  175. for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
  176. {
  177. if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
  178. {
  179. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
  180. return true;
  181. }
  182. }
  183. for (byte index = 0; index < CCS_QUANTITY; index++)
  184. {
  185. if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
  186. {
  187. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
  188. return true;
  189. }
  190. }
  191. for (byte index = 0; index < GB_QUANTITY; index++)
  192. {
  193. if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
  194. {
  195. chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
  196. return true;
  197. }
  198. }
  199. return false;
  200. }
  201. void GetPsuRequestCallback(byte phy_id, char *serial_number)
  202. {
  203. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  204. return;
  205. // ********************** 每次送電後,需判斷要把所有的模塊分配到哪個 Group **********************
  206. byte group = 0;
  207. if(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || _gunCount == 1)
  208. {
  209. // 初始化狀態,則直接先分配到同個群
  210. group = 0;
  211. }
  212. else
  213. {
  214. group = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
  215. }
  216. bool isNewPsu = true;
  217. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  218. {
  219. if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == phy_id &&
  220. strncmp((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber, serial_number, 7) == 0)
  221. {
  222. isNewPsu = false;
  223. }
  224. }
  225. if (isNewPsu)
  226. {
  227. ShmPsuData->SystemPresentPsuQuantity++;
  228. printf("get psu********id = %d, group = %d \n", ShmPsuData->SystemPresentPsuQuantity, group);
  229. if (ShmPsuData->Work_Step >= _TEST_LINE_STEP && ShmPsuData->Work_Step <= _TEST_COMPLETE)
  230. {
  231. // 已經進入火線上的驗證動作
  232. ShmPsuData->NeedBackTest = YES;
  233. }
  234. else if (ShmPsuData->Work_Step == _WORK_CHARGING)
  235. {
  236. // 一旦進入火線,分配一個不會用到的給該模塊
  237. group = 0x03;
  238. }
  239. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address = ShmPsuData->SystemPresentPsuQuantity;
  240. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID = phy_id;
  241. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].AssignID = (group >> 6) + ShmPsuData->SystemPresentPsuQuantity;
  242. strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber, serial_number);
  243. byte isFind = false;
  244. for (byte index = 0; index < conn_1_count; index++)
  245. {
  246. printf("connector_1[%d] = %d, phy_id = %d \n", index, connector_1[index], phy_id);
  247. if (connector_1[index] == phy_id)
  248. {
  249. isFind = true;
  250. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 0;
  251. break;
  252. }
  253. }
  254. if (!isFind)
  255. {
  256. for (byte index = 0; index < conn_2_count; index++)
  257. {
  258. printf("connector_2[%d] = %d, phy_id = %d \n", index, connector_2[index], phy_id);
  259. if (connector_2[index] == phy_id)
  260. {
  261. isFind = true;
  262. ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 1;
  263. break;
  264. }
  265. }
  266. }
  267. ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
  268. PsuAddressAssignment(phy_id, serial_number, ShmPsuData->SystemPresentPsuQuantity, group);
  269. ShmPsuData->GroupCount = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
  270. }
  271. }
  272. void SaveStatusCallback(byte group, byte address, int alarm, int fault)
  273. {
  274. //EVSE
  275. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  276. {
  277. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  278. {
  279. ShmPsuData->PsuGroup[group].PsuModule[index].AlarmCode = alarm;
  280. ShmPsuData->PsuGroup[group].PsuModule[index].FaultCode = fault;
  281. //printf("index = %d, alarm = %d, fault = %d \n", index, alarm, fault);
  282. break;
  283. }
  284. }
  285. }
  286. void SaveAlarmNotifyCallback(byte group, byte address, unsigned char *alarm)
  287. {
  288. //EVSE
  289. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  290. {
  291. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  292. {
  293. AbnormalStopAnalysis(group, alarm);
  294. break;
  295. }
  296. }
  297. }
  298. void SaveFaultNotifyCallback(byte group, byte address, int fault)
  299. {
  300. //EVSE
  301. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  302. {
  303. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  304. {
  305. ShmPsuData->PsuGroup[group].PsuModule[index].FaultCode = fault;
  306. break;
  307. }
  308. }
  309. }
  310. void SaveFirmwareVersion(byte group, byte address, unsigned char packageIndex, unsigned char type , unsigned char *data)
  311. {
  312. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  313. {
  314. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  315. {
  316. if (packageIndex == 0 || packageIndex == 1)
  317. strncpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion + (packageIndex * 6), (char *)data, 6);
  318. else
  319. strncpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion + (packageIndex * 6), (char *)data, 4);
  320. }
  321. }
  322. if (packageIndex == 1)
  323. {
  324. char string[3];
  325. memcpy(string, (data + 2), 2);
  326. string[2] = '\0';
  327. for (byte i = 0; i < _gunCount; i++)
  328. {
  329. if (maxChargingVol != 0)
  330. {
  331. chargingInfo[i]->MaximumChargingVoltage = maxChargingVol;
  332. }
  333. else
  334. {
  335. if (strcmp(string, "50") == 0)
  336. chargingInfo[i]->MaximumChargingVoltage = 5000;
  337. else if (strcmp(string, "70") == 0)
  338. chargingInfo[i]->MaximumChargingVoltage = 7000;
  339. else if (strcmp(string, "75") == 0)
  340. chargingInfo[i]->MaximumChargingVoltage = 7500;
  341. else if (strcmp(string, "80") == 0)
  342. chargingInfo[i]->MaximumChargingVoltage = 8000;
  343. else if (strcmp(string, "95") == 0)
  344. chargingInfo[i]->MaximumChargingVoltage = 9500;
  345. else if (strcmp(string, "A0") == 0)
  346. chargingInfo[i]->MaximumChargingVoltage = 10000;
  347. else if (strcmp(string, "C0") == 0)
  348. chargingInfo[i]->MaximumChargingVoltage = 12000;
  349. else if (strcmp(string, "F0") == 0)
  350. chargingInfo[i]->MaximumChargingVoltage = 15000;
  351. }
  352. printf("index = %d, max vol = %f \n", i, chargingInfo[i]->MaximumChargingVoltage);
  353. }
  354. }
  355. }
  356. void SaveFanSpeedCallback(byte group, byte address, byte fan1, byte fan2, byte fan3, byte fan4)
  357. {
  358. //EVSE
  359. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  360. {
  361. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  362. {
  363. ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_1 = fan1;
  364. ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_2 = fan2;
  365. ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_3 = fan3;
  366. ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_4 = fan4;
  367. break;
  368. }
  369. }
  370. }
  371. void SaveTemperatureCallback(byte group, byte address, char cri_temp1, char cri_temp2, char cri_temp3, char ex_temp, char in_temp1, char in_temp2, char out_temp)
  372. {
  373. //EVSE
  374. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  375. {
  376. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  377. {
  378. ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp1 = cri_temp1;
  379. ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp2 = cri_temp2;
  380. ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp3 = cri_temp3;
  381. ShmPsuData->PsuGroup[group].PsuModule[index].ExletTemp = ex_temp;
  382. ShmPsuData->PsuGroup[group].PsuModule[index].InletTemp_1 = in_temp1;
  383. ShmPsuData->PsuGroup[group].PsuModule[index].InletTemp_2 = in_temp2;
  384. ShmPsuData->PsuGroup[group].PsuModule[index].OutletTemp = out_temp;
  385. break;
  386. }
  387. }
  388. }
  389. void SavePresentInputVoltageCallback(byte group, byte address, byte vol_type, unsigned short vol1, unsigned short vol2, unsigned short vol3)
  390. {
  391. //EVSE
  392. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  393. {
  394. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  395. {
  396. ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltage_Type = vol_type;
  397. ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL1 = vol1;
  398. ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL2 = vol2;
  399. ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL3 = vol3;
  400. break;
  401. }
  402. }
  403. }
  404. // 模塊輸出的電壓電流
  405. void SavePresentOutputCallback(byte group, byte address, unsigned short out_vol, unsigned short out_cur)
  406. {
  407. unsigned short outputVol = 0;
  408. unsigned short outputCur = 0;
  409. bool isChange = false;
  410. // PSU
  411. for (int index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  412. {
  413. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  414. {
  415. ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage = out_vol;
  416. ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent = out_cur;
  417. isChange = true;
  418. }
  419. if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > outputVol)
  420. outputVol = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
  421. outputCur += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
  422. }
  423. if (isChange)
  424. {
  425. // PSU Group
  426. // 電壓
  427. ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
  428. // 電流
  429. ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
  430. //EVSE - 槍端的輸出電壓
  431. chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
  432. //EVSE - 槍端的輸出電流
  433. chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
  434. }
  435. printf("group = %d, GroupPresentOutputVoltage = %d \n", group, ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage);
  436. printf("group = %d, GroupPresentOutputCurrent = %d \n", group, ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent);
  437. }
  438. void SaveAvailableCapCallback(byte group, byte address, unsigned short able_power, unsigned short able_cur)
  439. {
  440. unsigned int power = 0;
  441. unsigned int current = 0;
  442. unsigned int power_derating = 0;
  443. unsigned int current_derating = 0;
  444. bool isChange = false;
  445. for (int index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  446. {
  447. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  448. {
  449. ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower = able_power;
  450. ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent = able_cur;
  451. isChange = true;
  452. }
  453. // 降載
  454. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP)
  455. {
  456. if (ShmPsuData->PsuGroup[group].PsuModule[index].FireWireIndex == group)
  457. {
  458. power_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
  459. current_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
  460. }
  461. }
  462. power += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
  463. current += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
  464. }
  465. if (current_derating == 0)
  466. current_derating = current;
  467. if (power_derating == 0)
  468. power_derating = power;
  469. if (isChange)
  470. {
  471. // PSU Group
  472. // Available Power
  473. ShmPsuData->PsuGroup[group].GroupAvailablePower = power;
  474. // Available Current
  475. ShmPsuData->PsuGroup[group].GroupAvailableCurrent = current;
  476. chargingInfo[group]->AvailableChargingCurrent = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
  477. chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
  478. chargingInfo[group]->DeratingChargingCurrent = current_derating;
  479. chargingInfo[group]->DeratingChargingPower = power_derating;
  480. printf("group = %d, AvailableChargingCurrent = %f, GroupAvailablePower = %f, DeratingChargingCurrent = %f, DeratingChargingPower = %f \n",
  481. group, chargingInfo[group]->AvailableChargingCurrent, chargingInfo[group]->AvailableChargingPower,
  482. chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->DeratingChargingPower);
  483. }
  484. }
  485. void SavePresentInputCurrentCallback(byte group, byte address, unsigned short in_cur1, unsigned short in_cur2, unsigned short in_cur3)
  486. {
  487. //EVSE
  488. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  489. {
  490. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  491. {
  492. ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL1 = in_cur1;
  493. ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL2 = in_cur2;
  494. ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL3 = in_cur3;
  495. break;
  496. }
  497. }
  498. }
  499. void SaveHardwareVersion(byte group, byte address, int hw_ver)
  500. {
  501. //EVSE
  502. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  503. {
  504. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  505. {
  506. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[0] = (hw_ver >> 24) & 0xFF;
  507. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[1] = (hw_ver >> 16) & 0xFF;
  508. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[2] = (hw_ver >> 8) & 0xFF;
  509. ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[3] = hw_ver & 0xFF;
  510. break;
  511. }
  512. }
  513. }
  514. void SaveStatusNotifyCallback(byte group, byte address, byte st_machine, unsigned short out_vol, unsigned short out_cur)
  515. {
  516. //EVSE
  517. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  518. {
  519. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  520. {
  521. ShmPsuData->PsuGroup[group].PsuModule[index].StateMachine = st_machine;
  522. //ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage = out_vol;
  523. //ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent = out_cur;
  524. //printf("psu state = %d, vol = %d, cur = %d \n", st_machine, out_vol, out_cur);
  525. break;
  526. }
  527. }
  528. }
  529. void GetSerialNumberCallback(byte group, byte address, unsigned char packageIndex, unsigned char *data)
  530. {
  531. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  532. {
  533. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  534. {
  535. strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber + (packageIndex * 7), (char *)data);
  536. break;
  537. }
  538. }
  539. }
  540. void GetOutputPowerSwitchStatusCallback(byte group, byte address, unsigned char value)
  541. {
  542. for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
  543. {
  544. if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
  545. {
  546. //printf("PowerSwitch = %d, group = %d, address = %d \n", value, group, address);
  547. ShmPsuData->PsuGroup[group].PsuModule[index].OutputPowerSwitch = value;
  548. break;
  549. }
  550. }
  551. }
  552. //==========================================
  553. // Init all share memory
  554. //==========================================
  555. int InitShareMemory()
  556. {
  557. int result = PASS;
  558. int MeterSMId;
  559. //creat ShmSysConfigAndInfo
  560. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  561. {
  562. #ifdef SystemLogMessage
  563. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
  564. #endif
  565. result = FAIL;
  566. }
  567. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  568. {
  569. #ifdef SystemLogMessage
  570. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
  571. #endif
  572. result = FAIL;
  573. }
  574. else
  575. {}
  576. //creat ShmStatusCodeData
  577. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  578. {
  579. #ifdef SystemLogMessage
  580. DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
  581. #endif
  582. result = FAIL;
  583. }
  584. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  585. {
  586. #ifdef SystemLogMessage
  587. DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
  588. #endif
  589. result = FAIL;
  590. }
  591. else
  592. {}
  593. //creat ShmPsuData
  594. if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
  595. {
  596. #ifdef SystemLogMessage
  597. DEBUG_ERROR("shmget ShmPsuData NG \n");
  598. #endif
  599. result = FAIL;
  600. }
  601. else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  602. {
  603. #ifdef SystemLogMessage
  604. DEBUG_ERROR("shmat ShmPsuData NG \n");
  605. #endif
  606. result = FAIL;
  607. }
  608. memset(ShmPsuData,0,sizeof(struct PsuData));
  609. return result;
  610. }
  611. //================================================
  612. // Main process
  613. //================================================
  614. void InitialPsuData()
  615. {
  616. ShmPsuData->SystemPresentPsuQuantity = 0;
  617. for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup); _groupCount++)
  618. {
  619. ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
  620. ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
  621. ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
  622. }
  623. }
  624. void Initialization()
  625. {
  626. bool isPass = false;
  627. while(!isPass)
  628. {
  629. isPass = true;
  630. for (byte _index = 0; _index < _gunCount; _index++)
  631. {
  632. if (!FindChargingInfoData(_index, &chargingInfo[0]))
  633. {
  634. DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
  635. isPass = false;
  636. break;
  637. }
  638. }
  639. }
  640. conn_1_count = sizeof(connector_1)/sizeof(connector_1[0]);
  641. conn_2_count = sizeof(connector_2)/sizeof(connector_2[0]);
  642. }
  643. int main(void)
  644. {
  645. printf("Psu Task boot .... \n");
  646. if(InitShareMemory() == FAIL)
  647. {
  648. #ifdef SystemLogMessage
  649. DEBUG_ERROR("InitShareMemory NG\n");
  650. #endif
  651. if(ShmStatusCodeData != NULL)
  652. {
  653. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
  654. }
  655. sleep(5);
  656. return 0;
  657. }
  658. printf("InitShareMemory OK\n");
  659. // register callback function
  660. GetPsuAddressReq(&GetPsuRequestCallback);
  661. RefreshStatus(&SaveStatusCallback);
  662. RefreshFanSpeed(&SaveFanSpeedCallback);
  663. RefreshTemp(&SaveTemperatureCallback);
  664. RefreshInputVol(&SavePresentInputVoltageCallback);
  665. RefreshGetOutput(&SavePresentOutputCallback);
  666. RefreshAvailableCap(&SaveAvailableCapCallback);
  667. RefreshInputCur(&SavePresentInputCurrentCallback);
  668. RefreshAlarmNotify(&SaveAlarmNotifyCallback);
  669. RefreshFaultNotify(&SaveFaultNotifyCallback);
  670. RefreshStatusNotify(&SaveStatusNotifyCallback);
  671. RefreshSerialNumber(&GetSerialNumberCallback);
  672. RefreshOutputPowerSwitch(&GetOutputPowerSwitchStatusCallback);
  673. RefreshFWVersion(&SaveFirmwareVersion);
  674. //RefreshHWVersion(&SaveHardwareVersion);
  675. // initial object
  676. InitialPsuData();
  677. Initialization();
  678. libInitialize = InitialCommunication();
  679. byte priorityLow = 1;
  680. //main loop
  681. while (libInitialize)
  682. {
  683. // 斷電狀態
  684. if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
  685. {
  686. InitialPsuData();
  687. sleep(1);
  688. ShmPsuData->Work_Step = ASSIGN_START;
  689. continue;
  690. }
  691. // update psu fw req
  692. // if(psu update req ?)
  693. // {
  694. //
  695. // continue;
  696. // }
  697. // 自檢失敗
  698. if (ShmPsuData->Work_Step == _NO_WORKING)
  699. {
  700. DEBUG_ERROR("(PSU) self test fail. \n");
  701. printf("(PSU) self test fail. \n");
  702. sleep(5);
  703. }
  704. switch(ShmPsuData->Work_Step)
  705. {
  706. case ASSIGN_START:
  707. {
  708. printf("PSU ASSIGN_START........ \n");
  709. gettimeofday(&_id_assign_time, NULL);
  710. ShmPsuData->Work_Step = ASSIGN_COMP;
  711. }
  712. break;
  713. case ASSIGN_COMP:
  714. {
  715. if (priorityLow == 1)
  716. {
  717. byte targetGp = 0;
  718. if (ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOTTING)
  719. targetGp = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
  720. for (byte psuIndex = 0; psuIndex < ShmPsuData->PsuGroup[targetGp].GroupPresentPsuQuantity; psuIndex++)
  721. {
  722. if (ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address == NONE_CARE_ADDRESS)
  723. continue;
  724. GetStatus(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address);
  725. usleep(cmdDelayTime);
  726. if (strlen((char *)ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].FwVersion) == 0 &&
  727. ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].FwVersion[0] == '\0')
  728. {
  729. GetFwVersion(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address, 0x02);
  730. usleep(cmdDelayTime);
  731. }
  732. if (strlen((char *)ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].SerialNumber) == 0 &&
  733. ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].SerialNumber[0] == '\0')
  734. {
  735. GetSerialNumber(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address);
  736. usleep(cmdDelayTime);
  737. }
  738. }
  739. }
  740. priorityLow >= 20 ? priorityLow = 1 : priorityLow++;
  741. // 等待十秒
  742. if (GetTimeoutValue(_id_assign_time) >= 15000000)
  743. {
  744. ShmPsuData->Work_Step = ENABLE_POW;
  745. }
  746. }
  747. break;
  748. case ENABLE_POW:
  749. {
  750. if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
  751. {
  752. // 電樁在 Booting 的狀態 - 自檢
  753. ShmPsuData->Work_Step = _TEST_LINE_STEP;
  754. }
  755. else
  756. {
  757. ShmPsuData->Work_Step = _WORK_CHARGING;
  758. gettimeofday(&_workModePriority_time, NULL);
  759. }
  760. }
  761. break;
  762. case _TEST_LINE_STEP:
  763. {
  764. printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  765. if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0)
  766. {
  767. sleep(1);
  768. continue;
  769. }
  770. #if (SELF_TEST)
  771. // 對整個 Group 保持通訊
  772. bool isFind = false;
  773. while(ShmPsuData->Work_Step != _NO_WORKING &&
  774. _curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  775. {
  776. GetStatus(0, NONE_CARE_ADDRESS);
  777. usleep(cmdDelayTime);
  778. GetAvailableCap(0, NONE_CARE_ADDRESS, getAvailableCapOffset);
  779. usleep(cmdDelayTime);
  780. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
  781. usleep(cmdDelayTime);
  782. if (ShmPsuData->NeedBackTest == YES)
  783. {
  784. ShmPsuData->NeedBackTest = NO;
  785. _curCheckPsuIndexForFireLine = 0x00;
  786. }
  787. if (isFind)
  788. {
  789. GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
  790. usleep(cmdDelayTime);
  791. //printf("stop vor = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  792. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage <= 200)
  793. {
  794. // 檢查下一個
  795. _curCheckPsuIndexForFireLine++;
  796. isFind = false;
  797. }
  798. SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
  799. ZERO_VOL, ZERO_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
  800. usleep(cmdDelayTime);
  801. }
  802. else
  803. {
  804. printf("AvailableCurrent = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent);
  805. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent > 0)
  806. {
  807. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage == 0)
  808. {
  809. //printf("set output vol = %d, cur = %d \n", SELF_TEST_VOL, SELF_TEST_CUR);
  810. SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
  811. SELF_TEST_VOL, SELF_TEST_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
  812. usleep(cmdDelayTime);
  813. }
  814. if(!isCheckOutputTimeStart)
  815. {
  816. gettimeofday(&_chk_output_time, NULL);
  817. isCheckOutputTimeStart = true;
  818. }
  819. else
  820. {
  821. // 如果五秒內火線上都沒有偵測到電壓,則代表異常
  822. if (GetTimeoutValue(_chk_output_time) >= 10000000)
  823. {
  824. // 自檢失敗
  825. printf("self test timeout \n");
  826. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
  827. usleep(cmdDelayTime);
  828. ShmPsuData->Work_Step = _NO_WORKING;
  829. continue;
  830. }
  831. }
  832. for (byte gunIndex = 0; gunIndex < _gunCount; gunIndex ++)
  833. {
  834. GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
  835. usleep(cmdDelayTime);
  836. printf("Cur psu output voltage = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  837. printf("Fire voltage = %f \n", chargingInfo[gunIndex]->FuseChargingVoltage);
  838. // 該模組的輸出電壓與火線上的電壓一致
  839. if (chargingInfo[gunIndex]->FuseChargingVoltage >= 50 &&
  840. ((chargingInfo[gunIndex]->FuseChargingVoltage >= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage - 300) &&
  841. (chargingInfo[gunIndex]->FuseChargingVoltage <= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage + 300)))
  842. {
  843. // 找到火線上的電壓了,這邊紀錄火線是紀錄屬於哪一把槍的火線
  844. if (_curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  845. {
  846. // 紀錄當前 PSU 是哪個火線上的
  847. ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].FireWireIndex = gunIndex;
  848. //recordPsuData[_curCheckPsuIndexForFireLine]._fire_index = gunIndex;
  849. //recordPsuData[_curCheckPsuIndexForFireLine]._phy_addr = ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID;
  850. //strcpy(recordPsuData[_curCheckPsuIndexForFireLine]._serial_num, (char *)ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].SerialNumber);
  851. printf("Find Fire Line Number end~~~~~~~~~~~~~~~ = %d \n", gunIndex);
  852. usleep(100000);
  853. isCheckOutputTimeStart = false;
  854. isFind = true;
  855. break;
  856. }
  857. }
  858. }
  859. }
  860. }
  861. usleep(100000);
  862. }
  863. if (ShmPsuData->Work_Step != _NO_WORKING)
  864. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  865. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
  866. usleep(cmdDelayTime);
  867. #else
  868. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  869. #endif
  870. }
  871. break;
  872. case _TEST_POWER_STEP:
  873. {
  874. if(!_chkTotalCapStart)
  875. {
  876. _chkTotalCapStart = true;
  877. gettimeofday(&_chk_cap_time, NULL);
  878. }
  879. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  880. {
  881. GetStatus(groupIndex, NONE_CARE_ADDRESS);
  882. usleep(cmdDelayTime);
  883. GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
  884. usleep(cmdDelayTime);
  885. }
  886. if (GetTimeoutValue(_chk_cap_time) >= 2000000)
  887. {
  888. printf("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n",
  889. chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower);
  890. for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++)
  891. {
  892. printf("index = %d, fire index = %d, phy addr = %s \n",
  893. index, ShmPsuData->PsuGroup[0].PsuModule[index].FireWireIndex, ShmPsuData->PsuGroup[0].PsuModule[index].SerialNumber);
  894. }
  895. ShmPsuData->Work_Step = _TEST_COMPLETE;
  896. }
  897. }
  898. break;
  899. case _TEST_COMPLETE:
  900. {
  901. priorityLow = 1;
  902. sleep(1);
  903. }
  904. break;
  905. case _WORK_CHARGING:
  906. {
  907. int time = GetTimeoutValue(_workModePriority_time) / 1000;
  908. // 智能分配 : 檢查該槍是否有模塊有用,有則無須重新分配直接進入充電
  909. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE)
  910. {
  911. if (ShmPsuData->PsuGroup[ShmSysConfigAndInfo->SysInfo.CurGunSelected].GroupPresentPsuQuantity > 0)
  912. {
  913. printf("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
  914. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
  915. }
  916. else
  917. {
  918. printf("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
  919. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
  920. }
  921. }
  922. //printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  923. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  924. {
  925. // 每秒
  926. if (time > 1000)
  927. {
  928. GetStatus(groupIndex, NONE_CARE_ADDRESS);
  929. usleep(cmdDelayTime);
  930. GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
  931. usleep(cmdDelayTime);
  932. // 智能分配 : 檢查車端需求電流是否有降低至新的輸出值
  933. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
  934. {
  935. if (groupIndex != ShmSysConfigAndInfo->SysInfo.CurGunSelected)
  936. {
  937. if (chargingInfo[groupIndex]->SystemStatus >= S_CHARGING && chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  938. {
  939. if (chargingInfo[groupIndex]->DeratingChargingCurrent < chargingInfo[groupIndex]->AvailableChargingCurrent)
  940. {
  941. // 車端需求電流降低至降載的電流
  942. printf("Smart Charging : index = %d, EvBatterytargetCurrent = %f, DeratingChargingCurrent = %f \n",
  943. groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->DeratingChargingCurrent);
  944. if ((chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->DeratingChargingCurrent) ||
  945. deratingKeepCount >= DERATING)
  946. {
  947. // 車端降載完成
  948. printf("=============Smart Charging : _REASSIGNED_MAIN============= Step 3 \n");
  949. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_MAIN;
  950. }
  951. else
  952. {
  953. deratingKeepCount++;
  954. }
  955. }
  956. }
  957. }
  958. }
  959. else
  960. deratingKeepCount = 0;
  961. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_MAIN)
  962. {
  963. printf("=============Smart Charging : _REASSIGNED_ADJUST============= Step 4 \n");
  964. //重新分配模組
  965. ReAssignedResource();
  966. gettimeofday(&_derating_time, NULL);
  967. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST;
  968. }
  969. gettimeofday(&_workModePriority_time, NULL);
  970. }
  971. GetPresentOutput(groupIndex, NONE_CARE_ADDRESS);
  972. usleep(cmdDelayTime);
  973. if (carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
  974. {
  975. carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  976. DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
  977. }
  978. if (carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
  979. {
  980. carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  981. DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
  982. }
  983. if (evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
  984. {
  985. evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
  986. printf("evse output v index = %d, vol = %f \n", groupIndex, chargingInfo[groupIndex]->FireChargingVoltage);
  987. }
  988. if (evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
  989. {
  990. evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
  991. printf("evse output c index = %d, cur = %f \n", groupIndex, chargingInfo[groupIndex]->PresentChargingCurrent);
  992. }
  993. if (chargingInfo[groupIndex]->AvailableChargingCurrent <= 0)
  994. continue;
  995. // 針對各槍當前狀態,傳送需要回傳的資料指令
  996. if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
  997. chargingInfo[groupIndex]->SystemStatus == S_REASSIGN ||
  998. (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1)
  999. )
  1000. {
  1001. EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
  1002. usleep(cmdDelayTime);
  1003. if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0)
  1004. {
  1005. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST)
  1006. {
  1007. // 如果車端要求的電流超過降載,則以降載電流為主
  1008. if (chargingInfo[groupIndex]->EvBatterytargetCurrent >= chargingInfo[groupIndex]->DeratingChargingCurrent)
  1009. {
  1010. chargingInfo[groupIndex]->EvBatterytargetCurrent = chargingInfo[groupIndex]->DeratingChargingCurrent;
  1011. }
  1012. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
  1013. {
  1014. deratingTime = GetTimeoutValue(_derating_time) / 1000;
  1015. if (deratingTime > 3000)
  1016. {
  1017. deratingTime = 0;
  1018. printf("=============Smart Charging : _REASSIGNED_RELAY============= Step 5 \n");
  1019. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY;
  1020. }
  1021. }
  1022. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
  1023. {
  1024. for(int i = 0; i < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; i++)
  1025. {
  1026. printf("*********_REASSIGNED_ADJUST : groupIndex = %d, outputCur = %d, outputVol = %d \n",
  1027. groupIndex,
  1028. ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputCurrent,
  1029. ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputVoltage);
  1030. }
  1031. }
  1032. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  1033. float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  1034. if (targetVol != 0)
  1035. {
  1036. if (targetCur <= 10)
  1037. targetCur = 10;
  1038. }
  1039. else
  1040. {
  1041. targetVol = 0;
  1042. targetCur = 0;
  1043. }
  1044. // 該充電槍的目標電壓與目標電流
  1045. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
  1046. targetVol, targetCur,
  1047. chargingInfo[groupIndex]->DeratingChargingCurrent,
  1048. 0x00);
  1049. }
  1050. else
  1051. {
  1052. printf("Set Present Output index = %d, V = %f, C = %f \n", groupIndex,
  1053. chargingInfo[groupIndex]->EvBatterytargetVoltage, chargingInfo[groupIndex]->EvBatterytargetCurrent);
  1054. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  1055. float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  1056. if (targetVol != 0)
  1057. {
  1058. if (targetCur <= 10)
  1059. targetCur = 10;
  1060. }
  1061. else
  1062. {
  1063. targetVol = 0;
  1064. targetCur = 0;
  1065. }
  1066. // 該充電槍的目標電壓與目標電流
  1067. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
  1068. targetVol,
  1069. targetCur,
  1070. chargingInfo[groupIndex]->AvailableChargingCurrent,
  1071. 0x00);
  1072. }
  1073. usleep(cmdDelayTime);
  1074. }
  1075. }
  1076. else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
  1077. chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  1078. {
  1079. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, ZERO_VOL, ZERO_CUR,
  1080. chargingInfo[groupIndex]->AvailableChargingCurrent, 0x00);
  1081. usleep(cmdDelayTime);
  1082. }
  1083. }
  1084. priorityLow >= 200 ? priorityLow = 1 : priorityLow++;
  1085. break;
  1086. }
  1087. }
  1088. usleep(45000);
  1089. }
  1090. return FAIL;
  1091. }