Module_PsuComm.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  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. for (byte psuIndex = 0; psuIndex < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; psuIndex++)
  718. {
  719. if (ShmPsuData->PsuGroup[0].PsuModule[psuIndex].Address == NONE_CARE_ADDRESS)
  720. continue;
  721. GetStatus(0, ShmPsuData->PsuGroup[0].PsuModule[psuIndex].Address);
  722. usleep(cmdDelayTime);
  723. if (strlen((char *)ShmPsuData->PsuGroup[0].PsuModule[psuIndex].FwVersion) == 0 &&
  724. ShmPsuData->PsuGroup[0].PsuModule[psuIndex].FwVersion[0] == '\0')
  725. {
  726. GetFwVersion(0, ShmPsuData->PsuGroup[0].PsuModule[psuIndex].Address, 0x02);
  727. usleep(cmdDelayTime);
  728. }
  729. if (strlen((char *)ShmPsuData->PsuGroup[0].PsuModule[psuIndex].SerialNumber) == 0 &&
  730. ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev[0] == '\0')
  731. {
  732. GetSerialNumber(0, ShmPsuData->PsuGroup[0].PsuModule[psuIndex].Address);
  733. usleep(cmdDelayTime);
  734. }
  735. }
  736. }
  737. priorityLow >= 20 ? priorityLow = 1 : priorityLow++;
  738. // 等待十秒
  739. if (GetTimeoutValue(_id_assign_time) >= 15000000)
  740. {
  741. ShmPsuData->Work_Step = ENABLE_POW;
  742. }
  743. }
  744. break;
  745. case ENABLE_POW:
  746. {
  747. if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
  748. {
  749. // 電樁在 Booting 的狀態 - 自檢
  750. ShmPsuData->Work_Step = _TEST_LINE_STEP;
  751. }
  752. else
  753. {
  754. ShmPsuData->Work_Step = _WORK_CHARGING;
  755. gettimeofday(&_workModePriority_time, NULL);
  756. }
  757. }
  758. break;
  759. case _TEST_LINE_STEP:
  760. {
  761. printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  762. if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0)
  763. {
  764. sleep(1);
  765. continue;
  766. }
  767. #if (SELF_TEST)
  768. // 對整個 Group 保持通訊
  769. bool isFind = false;
  770. while(ShmPsuData->Work_Step != _NO_WORKING &&
  771. _curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  772. {
  773. GetStatus(0, NONE_CARE_ADDRESS);
  774. usleep(cmdDelayTime);
  775. GetAvailableCap(0, NONE_CARE_ADDRESS, getAvailableCapOffset);
  776. usleep(cmdDelayTime);
  777. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
  778. usleep(cmdDelayTime);
  779. if (ShmPsuData->NeedBackTest == YES)
  780. {
  781. ShmPsuData->NeedBackTest = NO;
  782. _curCheckPsuIndexForFireLine = 0x00;
  783. }
  784. if (isFind)
  785. {
  786. GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
  787. usleep(cmdDelayTime);
  788. //printf("stop vor = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  789. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage <= 200)
  790. {
  791. // 檢查下一個
  792. _curCheckPsuIndexForFireLine++;
  793. isFind = false;
  794. }
  795. SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
  796. ZERO_VOL, ZERO_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
  797. usleep(cmdDelayTime);
  798. }
  799. else
  800. {
  801. printf("AvailableCurrent = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent);
  802. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent > 0)
  803. {
  804. if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage == 0)
  805. {
  806. //printf("set output vol = %d, cur = %d \n", SELF_TEST_VOL, SELF_TEST_CUR);
  807. SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
  808. SELF_TEST_VOL, SELF_TEST_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
  809. usleep(cmdDelayTime);
  810. }
  811. if(!isCheckOutputTimeStart)
  812. {
  813. gettimeofday(&_chk_output_time, NULL);
  814. isCheckOutputTimeStart = true;
  815. }
  816. else
  817. {
  818. // 如果五秒內火線上都沒有偵測到電壓,則代表異常
  819. if (GetTimeoutValue(_chk_output_time) >= 10000000)
  820. {
  821. // 自檢失敗
  822. printf("self test timeout \n");
  823. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
  824. usleep(cmdDelayTime);
  825. ShmPsuData->Work_Step = _NO_WORKING;
  826. continue;
  827. }
  828. }
  829. for (byte gunIndex = 0; gunIndex < _gunCount; gunIndex ++)
  830. {
  831. GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
  832. usleep(cmdDelayTime);
  833. printf("Cur psu output voltage = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
  834. printf("Fire voltage = %f \n", chargingInfo[gunIndex]->FuseChargingVoltage);
  835. // 該模組的輸出電壓與火線上的電壓一致
  836. if (chargingInfo[gunIndex]->FuseChargingVoltage >= 50 &&
  837. ((chargingInfo[gunIndex]->FuseChargingVoltage >= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage - 300) &&
  838. (chargingInfo[gunIndex]->FuseChargingVoltage <= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage + 300)))
  839. {
  840. // 找到火線上的電壓了,這邊紀錄火線是紀錄屬於哪一把槍的火線
  841. if (_curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
  842. {
  843. // 紀錄當前 PSU 是哪個火線上的
  844. ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].FireWireIndex = gunIndex;
  845. //recordPsuData[_curCheckPsuIndexForFireLine]._fire_index = gunIndex;
  846. //recordPsuData[_curCheckPsuIndexForFireLine]._phy_addr = ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID;
  847. //strcpy(recordPsuData[_curCheckPsuIndexForFireLine]._serial_num, (char *)ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].SerialNumber);
  848. printf("Find Fire Line Number end~~~~~~~~~~~~~~~ = %d \n", gunIndex);
  849. usleep(100000);
  850. isCheckOutputTimeStart = false;
  851. isFind = true;
  852. break;
  853. }
  854. }
  855. }
  856. }
  857. }
  858. usleep(100000);
  859. }
  860. if (ShmPsuData->Work_Step != _NO_WORKING)
  861. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  862. EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
  863. usleep(cmdDelayTime);
  864. #else
  865. ShmPsuData->Work_Step = _TEST_POWER_STEP;
  866. #endif
  867. }
  868. break;
  869. case _TEST_POWER_STEP:
  870. {
  871. if(!_chkTotalCapStart)
  872. {
  873. _chkTotalCapStart = true;
  874. gettimeofday(&_chk_cap_time, NULL);
  875. }
  876. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  877. {
  878. GetStatus(groupIndex, NONE_CARE_ADDRESS);
  879. usleep(cmdDelayTime);
  880. GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
  881. usleep(cmdDelayTime);
  882. }
  883. if (GetTimeoutValue(_chk_cap_time) >= 2000000)
  884. {
  885. printf("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n",
  886. chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower);
  887. for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++)
  888. {
  889. printf("index = %d, fire index = %d, phy addr = %s \n",
  890. index, ShmPsuData->PsuGroup[0].PsuModule[index].FireWireIndex, ShmPsuData->PsuGroup[0].PsuModule[index].SerialNumber);
  891. }
  892. ShmPsuData->Work_Step = _TEST_COMPLETE;
  893. }
  894. }
  895. break;
  896. case _TEST_COMPLETE:
  897. {
  898. priorityLow = 1;
  899. sleep(1);
  900. }
  901. break;
  902. case _WORK_CHARGING:
  903. {
  904. int time = GetTimeoutValue(_workModePriority_time) / 1000;
  905. // 智能分配 : 檢查該槍是否有模塊有用,有則無須重新分配直接進入充電
  906. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE)
  907. {
  908. if (ShmPsuData->PsuGroup[ShmSysConfigAndInfo->SysInfo.CurGunSelected].GroupPresentPsuQuantity > 0)
  909. {
  910. printf("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
  911. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
  912. }
  913. else
  914. {
  915. printf("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
  916. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
  917. }
  918. }
  919. //printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
  920. for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
  921. {
  922. // 每秒
  923. if (time > 1000)
  924. {
  925. GetStatus(groupIndex, NONE_CARE_ADDRESS);
  926. usleep(cmdDelayTime);
  927. GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
  928. usleep(cmdDelayTime);
  929. // 智能分配 : 檢查車端需求電流是否有降低至新的輸出值
  930. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
  931. {
  932. if (groupIndex != ShmSysConfigAndInfo->SysInfo.CurGunSelected)
  933. {
  934. if (chargingInfo[groupIndex]->SystemStatus >= S_CHARGING && chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  935. {
  936. if (chargingInfo[groupIndex]->DeratingChargingCurrent < chargingInfo[groupIndex]->AvailableChargingCurrent)
  937. {
  938. // 車端需求電流降低至降載的電流
  939. printf("Smart Charging : index = %d, EvBatterytargetCurrent = %f, DeratingChargingCurrent = %f \n",
  940. groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->DeratingChargingCurrent);
  941. if ((chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->DeratingChargingCurrent) ||
  942. deratingKeepCount >= DERATING)
  943. {
  944. // 車端降載完成
  945. printf("=============Smart Charging : _REASSIGNED_MAIN============= Step 3 \n");
  946. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_MAIN;
  947. }
  948. else
  949. {
  950. deratingKeepCount++;
  951. }
  952. }
  953. }
  954. }
  955. }
  956. else
  957. deratingKeepCount = 0;
  958. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_MAIN)
  959. {
  960. printf("=============Smart Charging : _REASSIGNED_ADJUST============= Step 4 \n");
  961. //重新分配模組
  962. ReAssignedResource();
  963. gettimeofday(&_derating_time, NULL);
  964. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST;
  965. }
  966. gettimeofday(&_workModePriority_time, NULL);
  967. }
  968. GetPresentOutput(groupIndex, NONE_CARE_ADDRESS);
  969. usleep(cmdDelayTime);
  970. if (carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
  971. {
  972. carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  973. DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
  974. }
  975. if (carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
  976. {
  977. carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  978. DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
  979. }
  980. if (evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
  981. {
  982. evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
  983. printf("evse output v index = %d, vol = %f \n", groupIndex, chargingInfo[groupIndex]->FireChargingVoltage);
  984. }
  985. if (evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
  986. {
  987. evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
  988. printf("evse output c index = %d, cur = %f \n", groupIndex, chargingInfo[groupIndex]->PresentChargingCurrent);
  989. }
  990. if (chargingInfo[groupIndex]->AvailableChargingCurrent <= 0)
  991. continue;
  992. // 針對各槍當前狀態,傳送需要回傳的資料指令
  993. if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
  994. chargingInfo[groupIndex]->SystemStatus == S_REASSIGN ||
  995. (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1)
  996. )
  997. {
  998. EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
  999. usleep(cmdDelayTime);
  1000. if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0)
  1001. {
  1002. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST)
  1003. {
  1004. // 如果車端要求的電流超過降載,則以降載電流為主
  1005. if (chargingInfo[groupIndex]->EvBatterytargetCurrent >= chargingInfo[groupIndex]->DeratingChargingCurrent)
  1006. {
  1007. chargingInfo[groupIndex]->EvBatterytargetCurrent = chargingInfo[groupIndex]->DeratingChargingCurrent;
  1008. }
  1009. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
  1010. {
  1011. deratingTime = GetTimeoutValue(_derating_time) / 1000;
  1012. if (deratingTime > 3000)
  1013. {
  1014. deratingTime = 0;
  1015. printf("=============Smart Charging : _REASSIGNED_RELAY============= Step 5 \n");
  1016. ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY;
  1017. }
  1018. }
  1019. if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
  1020. {
  1021. for(int i = 0; i < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; i++)
  1022. {
  1023. printf("*********_REASSIGNED_ADJUST : groupIndex = %d, outputCur = %d, outputVol = %d \n",
  1024. groupIndex,
  1025. ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputCurrent,
  1026. ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputVoltage);
  1027. }
  1028. }
  1029. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  1030. float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  1031. if (targetVol != 0)
  1032. {
  1033. if (targetCur <= 10)
  1034. targetCur = 10;
  1035. }
  1036. else
  1037. {
  1038. targetVol = 0;
  1039. targetCur = 0;
  1040. }
  1041. // 該充電槍的目標電壓與目標電流
  1042. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
  1043. targetVol, targetCur,
  1044. chargingInfo[groupIndex]->DeratingChargingCurrent,
  1045. 0x00);
  1046. }
  1047. else
  1048. {
  1049. printf("Set Present Output index = %d, V = %f, C = %f \n", groupIndex,
  1050. chargingInfo[groupIndex]->EvBatterytargetVoltage, chargingInfo[groupIndex]->EvBatterytargetCurrent);
  1051. float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
  1052. float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
  1053. if (targetVol != 0)
  1054. {
  1055. if (targetCur <= 10)
  1056. targetCur = 10;
  1057. }
  1058. else
  1059. {
  1060. targetVol = 0;
  1061. targetCur = 0;
  1062. }
  1063. // 該充電槍的目標電壓與目標電流
  1064. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
  1065. targetVol,
  1066. targetCur,
  1067. chargingInfo[groupIndex]->AvailableChargingCurrent,
  1068. 0x00);
  1069. }
  1070. usleep(cmdDelayTime);
  1071. }
  1072. }
  1073. else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
  1074. chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
  1075. {
  1076. SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, ZERO_VOL, ZERO_CUR,
  1077. chargingInfo[groupIndex]->AvailableChargingCurrent, 0x00);
  1078. usleep(cmdDelayTime);
  1079. }
  1080. }
  1081. priorityLow >= 200 ? priorityLow = 1 : priorityLow++;
  1082. break;
  1083. }
  1084. }
  1085. usleep(45000);
  1086. }
  1087. return FAIL;
  1088. }