megatec.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. /*
  2. * megatec.c
  3. *
  4. * Created on: 22.05.2017
  5. * Author: balbekova
  6. */
  7. #include "FreeRTOS.h"
  8. #include "task.h"
  9. #include "fr_timers.h"
  10. #include "usart.h"
  11. #include "megatec.h"
  12. #include "ups_monitor.h"
  13. #include "log.h"
  14. #include "snmp_api.h"
  15. #include "settings_api.h"
  16. #ifdef PRINTF_STDLIB
  17. #include <stdio.h>
  18. #endif
  19. #ifdef PRINTF_CUSTOM
  20. #include "tinystdio.h"
  21. #endif
  22. #include <string.h>
  23. #include <math.h>
  24. #define DBG if (0)
  25. TimerHandle_t UPSRestoreTimer;
  26. /**
  27. * @brief Общая структура настроек
  28. */
  29. extern SETTINGS_t sSettings;
  30. #define UPS_PDU_MAX_LEN 80
  31. float TimeParamFloat = 0;
  32. uint16_t TimeParam = 0;
  33. uint16_t TimeParam2 = 0;
  34. bool megatec_send = true;
  35. UPS_value_t UPS;
  36. int test_time = 0;
  37. static bool flag_buzzer_on = false;
  38. enum {
  39. NORMAL = 0x00,
  40. VER_ERROR = 0x01,
  41. CHKSUM_ERROR = 0x02,
  42. LCHKSUM_ERROR = 0x03,
  43. CID2_INVALID = 0x04,
  44. CMD_FMT_ERROR = 0x05,
  45. INVALID_DATA = 0x06,
  46. };
  47. static struct {
  48. uint8_t data[UPS_PDU_MAX_LEN];
  49. uint16_t len;
  50. } ups_pdu;
  51. const char *MegaTecCMD[] = {
  52. "Q1\r",
  53. "T\r",
  54. "TL\r",
  55. "T",
  56. "Q\r",
  57. "S",
  58. "R",
  59. "C\r",
  60. "CT\r",
  61. "I\r",
  62. "F\r",
  63. "Q2\r",
  64. "QGS\r",
  65. "QBV\r",
  66. "QMD\r",
  67. "QVFW\r",
  68. "QVFW2\r",
  69. "QID\r",
  70. "QPI\r",
  71. "QS\r",
  72. "M\r",
  73. "PDA\r",
  74. "QMOD\r",
  75. "SON\r",
  76. };
  77. extern bool flUpdateLog;
  78. void init_UPS_value(void)
  79. {
  80. UPS.Freq_in = 0;
  81. UPS.VAC_in = 0;
  82. UPS.VAC_out = 0;
  83. UPS.Temp = 0;
  84. UPS.Load = 0;
  85. UPS.SOC = 0;
  86. UPS.SOC_test = 0;
  87. UPS.work_time = 0;
  88. UPS.akb_work_time = 0;
  89. UPS.Status = 0;
  90. UPS.Mode = 0;
  91. UPS.Alarm = 0;
  92. UPS.Test_Status = 0;
  93. UPS.cnt_err_ups = 0;
  94. UPS.Flag_Present = false;
  95. UPS.Present = false;
  96. memset(UPS.model, 0, sizeof(UPS.model));
  97. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  98. memset(UPS.serial, 0, sizeof(UPS.serial));
  99. }
  100. void send_MegaTec_cmd(cmdMegaTecEnums_t command)
  101. {
  102. DBG printf("MegaTecCMD: %s\r\n", MegaTecCMD[command]);
  103. if (command == ups_test_time) {
  104. uint8_t req[10];
  105. memset(req, 0, 10);
  106. if (TimeParam < 10) {
  107. sprintf(req, "%s0%d\r", MegaTecCMD[command], TimeParam);
  108. } else {
  109. sprintf(req, "%s%d\r", MegaTecCMD[command], TimeParam);
  110. }
  111. ups_send_block(req, strlen(req));
  112. } else if (command == ups_shutdown) {
  113. uint8_t req[10];
  114. memset(req, 0, 10);
  115. if (TimeParamFloat >= 1 && TimeParamFloat < 10) {
  116. sprintf(req, "%s0%d\r", MegaTecCMD[command], (uint16_t)TimeParamFloat);
  117. } else if (TimeParamFloat < 1) {
  118. sprintf(req, "%s.%d\r", MegaTecCMD[command], (uint16_t)(10 * TimeParamFloat));
  119. } else {
  120. sprintf(req, "%s%d\r", MegaTecCMD[command], (uint16_t)TimeParamFloat);
  121. }
  122. ups_send_block(req, strlen(req));
  123. } else if (command == ups_shutdown_restore) {
  124. uint8_t req[10];
  125. memset(req, 0, 10);
  126. if (TimeParamFloat >= 1 && TimeParamFloat < 10) {
  127. sprintf(req, "%s0%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)TimeParamFloat, MegaTecCMD[command], TimeParam2);
  128. } else if (TimeParamFloat < 1) {
  129. sprintf(req, "%s.%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)(10 * TimeParamFloat), MegaTecCMD[command], TimeParam2);
  130. } else {
  131. sprintf(req, "%s%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)TimeParamFloat, MegaTecCMD[command], TimeParam2);
  132. }
  133. ups_send_block(req, strlen(req));
  134. } else {
  135. // TODO ����������� ���������
  136. //ups_send_block(MegaTecCMD[command], strlen(MegaTecCMD[command]));
  137. ups_send_block((void *)MegaTecCMD[command], strlen(MegaTecCMD[command]));
  138. }
  139. }
  140. bool ups_megatec_rx_pdu(void)
  141. {
  142. int c = 0;
  143. uint8_t cnt_answer = 0;
  144. ups_pdu.len = 0;
  145. while (c >= 0) {
  146. c = ups_getchar(300);//portMAX_DELAY200
  147. if (c >= 0) {
  148. ups_pdu.len = 0;
  149. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  150. ups_pdu.data[ups_pdu.len++] = c;
  151. while ((ups_pdu.len < UPS_PDU_MAX_LEN) && (c != 0x0d)) {
  152. c = ups_getchar(100);//portMAX_DELAY200
  153. if (c < 0) {
  154. ups_pdu.len = 0;
  155. return false;
  156. }
  157. ups_pdu.data[ups_pdu.len++] = c;
  158. }
  159. DBG printf("UPS raw data: %s\r\n", ups_pdu.data);
  160. cnt_answer ++;
  161. } else {
  162. if (ups_pdu.len == 0) {
  163. return false;
  164. }
  165. }
  166. }
  167. if (cnt_answer > 1) {
  168. DBG printf("MegaTecCMD: false\r\n");
  169. return false;
  170. }
  171. DBG printf("UPS raw data: %s\r\n", ups_pdu.data);
  172. DBG printf("UPS raw data len: %d\r\n", ups_pdu.len);
  173. return true;
  174. }
  175. int8_t get_ups_param(char *buf, char *param, char *val)
  176. {
  177. char *endValue;
  178. int8_t param_len;
  179. memset(val, 0, 20);
  180. endValue = strpbrk(buf, param);
  181. if (endValue != NULL) {
  182. param_len = endValue - buf;
  183. if (param_len < 20) {
  184. strncpy(val, buf, param_len);
  185. } else {
  186. param_len = 0;
  187. }
  188. } else {
  189. param_len = 0;
  190. }
  191. DBG printf("UPS parameter: %s\r\n", val);
  192. return param_len;
  193. }
  194. void ups_status_response(char *data)
  195. {
  196. uint8_t i;
  197. char value[20];
  198. float tmp;
  199. uint8_t len = 0;
  200. DBG printf("ups_status_response: %s\r\n", data);
  201. if (data[0] != '(') {
  202. return;
  203. }
  204. DBG printf("ups_status_parser_start\r\n");
  205. UPS.Present = true;
  206. UPS.Flag_Present = true;
  207. UPS.cnt_err_ups = 0;
  208. #ifdef UPS_BUZZER_OFF
  209. if (flag_buzzer_on) {
  210. data[45] = '0';
  211. }
  212. #endif
  213. if (flUpdateLog) {
  214. flUpdateLog = false;
  215. log_add(data);
  216. }
  217. data++;
  218. DBG printf("UPS ups_status_parser_startr: %s\r\n", data);
  219. len = get_ups_param(data, " ", value);
  220. data += (len + 1);
  221. if (len > 0) {
  222. tmp = atof(value);
  223. if (tmp > 20) {
  224. UPS.VAC_in = tmp;
  225. } else {
  226. UPS.VAC_in = 0;
  227. }
  228. }
  229. //TODO
  230. len = get_ups_param(data, " ", value);
  231. data += (len + 1);
  232. len = get_ups_param(data, " ", value);
  233. data += (len + 1);
  234. if (len > 0) {
  235. UPS.VAC_out = atof(value);
  236. }
  237. len = get_ups_param(data, " ", value);
  238. data += (len + 1);
  239. if (len > 0) {
  240. UPS.Load = atoi(value);
  241. }
  242. len = get_ups_param(data, " ", value);
  243. data += (len + 1);
  244. if (len > 0) {
  245. UPS.Freq_in = atof(value);
  246. }
  247. //TODO
  248. len = get_ups_param(data, " ", value);
  249. data += (len + 1);
  250. if (len > 0) {
  251. UPS.Vakb_curr = atof(value);
  252. }
  253. if (sSettings.UPS_Setting.type_ups == ups_kestar || sSettings.UPS_Setting.type_ups == ups_offline) {
  254. if (UPS.Vakb_curr < 7) {
  255. UPS.SOC = round(100 * (UPS.Vakb_curr - sSettings.UPS_Setting.Ucellmin) / (sSettings.UPS_Setting.Ucellmax -
  256. sSettings.UPS_Setting.Ucellmin));
  257. } else {
  258. UPS.SOC = round(100 * (UPS.Vakb_curr / AKB_NUM_CELL - sSettings.UPS_Setting.Ucellmin) /
  259. (sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
  260. }
  261. }
  262. len = get_ups_param(data, " ", value);
  263. data += (len + 1);
  264. if (len > 0) {
  265. UPS.Temp = atof(value);
  266. }
  267. len = get_ups_param(data, "\r", value);
  268. data += (len + 1);
  269. if (len > 0) {
  270. uint8_t stat = 0;
  271. for (i = 0; i < len; i ++) {
  272. stat |= (value[i] - 0x30) << (7 - i);
  273. }
  274. UPS.Status = stat;
  275. }
  276. #ifdef RELAY_ALARM_AKB
  277. if (sSettings.UPS_Setting.type_ups == ups_kestar || sSettings.UPS_Setting.type_ups == ups_offline) {
  278. UPS_TestSOCMonitor();
  279. }
  280. #endif
  281. }
  282. void ups_general_status_response(char *data)
  283. {
  284. uint8_t i;
  285. char value[20];
  286. float tmp;
  287. uint8_t len = 0;
  288. DBG printf("ups_status_response: %s\r\n", data);
  289. if (data[0] != '(') {
  290. return;
  291. }
  292. DBG printf("ups_status_parser_start\r\n");
  293. UPS.Present = true;
  294. UPS.Flag_Present = true;
  295. UPS.cnt_err_ups = 0;
  296. data++;
  297. DBG printf("UPS ups_status_parser_startr: %s\r\n", data);
  298. data = data + 72;
  299. uint8_t stat = 0;
  300. UPS.Test_Status = 0;
  301. for (i = 0; i < 2; i ++) {
  302. UPS.Test_Status |= (data[i] - 0x30) << (1 - i);
  303. }
  304. /*
  305. len = get_ups_param(data, " ", value);
  306. data += (len + 1);
  307. if (len > 0) {
  308. tmp = atof(value);
  309. if (tmp > 20) {
  310. UPS.VAC_in = tmp;
  311. } else {
  312. UPS.VAC_in = 0;
  313. }
  314. }
  315. len = get_ups_param(data, " ", value);
  316. data += (len + 1);
  317. if (len > 0) {
  318. UPS.Freq_in = atof(value);
  319. }
  320. len = get_ups_param(data, " ", value);
  321. data += (len + 1);
  322. if (len > 0) {
  323. UPS.VAC_out = atof(value);
  324. }
  325. //TODO
  326. len = get_ups_param(data, " ", value);
  327. data += (len + 1);
  328. //TODO
  329. len = get_ups_param(data, " ", value);
  330. data += (len + 1);
  331. len = get_ups_param(data, " ", value);
  332. data += (len + 1);
  333. if (len > 0) {
  334. UPS.Load = atoi(value);
  335. }
  336. //TODO
  337. len = get_ups_param(data, " ", value);
  338. data += (len + 1);
  339. //TODO
  340. len = get_ups_param(data, " ", value);
  341. data += (len + 1);
  342. //TODO
  343. len = get_ups_param(data, " ", value);
  344. data += (len + 1);
  345. //TODO
  346. len = get_ups_param(data, " ", value);
  347. data += (len + 1);
  348. len = get_ups_param(data, " ", value);
  349. data += (len + 1);
  350. if (len > 0) {
  351. UPS.Temp = atof(value);
  352. }
  353. len = get_ups_param(data, "\r", value);
  354. data += (len + 1);
  355. if (len > 0) {
  356. uint8_t stat = 0;
  357. for (i = 2; i < (len - 2); i ++) {
  358. stat |= (value[i] - 0x30) << (7 - i);
  359. }
  360. UPS.Status = stat;
  361. }
  362. value[len - 2] = 0;
  363. if (flUpdateLog) {
  364. flUpdateLog = false;
  365. memset(data, 0, UPS_PDU_MAX_LEN);
  366. sprintf(data, "(%0.1f n/a %0.1f %d %0.1f %0.2f %0.1f %s", UPS.VAC_in, UPS.VAC_out, UPS.Load, UPS.Freq_in, UPS.Vakb_curr, UPS.Temp, &value[2]);
  367. log_add(data);
  368. }
  369. */
  370. }
  371. void ups_info_response(char *data)
  372. {
  373. uint8_t i = 0, j = 0;
  374. char value[20];
  375. DBG printf("ups_info_response: %s\r\n", data);
  376. if (data[0] != '#') {
  377. return;
  378. }
  379. DBG printf("ups_info_response_startr: %s\r\n", data);
  380. UPS.Present = true;
  381. UPS.Flag_Present = true;
  382. UPS.cnt_err_ups = 0;
  383. data++;
  384. data += 16; //пропускаем поле название компании
  385. memset(value, 0, sizeof(value));
  386. for (uint8_t i = 0; i < KSTAR_MODEL_LENGTH; i ++) {
  387. if (data[i] != ' ') {
  388. value[j] = data[i];
  389. j ++;
  390. }
  391. }
  392. if (j != 0) {
  393. if (UPS.model[0] == 0) {
  394. strncpy(UPS.model, value, strlen(value));
  395. SNMP_SetObjDescr();
  396. } else {
  397. strncpy(UPS.model, data, strlen(value));
  398. }
  399. } else {
  400. if (UPS.model[0] == 0) {
  401. strcpy(UPS.model, "RTMP-II");
  402. SNMP_SetObjDescr();
  403. } else {
  404. strcpy(UPS.model, "RTMP-II");
  405. }
  406. }
  407. data += (KSTAR_MODEL_LENGTH + 1);
  408. strncpy(UPS.serial, data, 8);
  409. data += 8;
  410. strncpy(UPS.vertion, data, 2);
  411. SNMP_SetObjDescr();
  412. }
  413. void ups_remain_time_response(char *data)
  414. {
  415. char value[20];
  416. if (data[0] != '(') {
  417. return;
  418. }
  419. DBG printf("ups_remain_time_response: %s\r\n", data);
  420. UPS.Present = true;
  421. UPS.Flag_Present = true;
  422. UPS.cnt_err_ups = 0;
  423. data++;
  424. if (strlen(data) > 5) {
  425. return;
  426. }
  427. memset(value, 0, 10);
  428. strcpy(value, data);
  429. //if((UPS.Status >> 7) & 0x01)
  430. UPS.work_time = atoi(value);
  431. //else
  432. // UPS.work_time = 0;
  433. }
  434. void ups_akb_info_response(char *data)
  435. {
  436. char value[20];
  437. uint8_t len = 0;
  438. DBG printf("ups_akb_info_response: %s\r\n", data);
  439. if (data[0] != '(') {
  440. return;
  441. }
  442. DBG printf("ups_akb_info_parser_start\r\n");
  443. UPS.Present = true;
  444. UPS.Flag_Present = true;
  445. UPS.cnt_err_ups = 0;
  446. data++;
  447. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  448. //TODO
  449. len = get_ups_param(data, " ", value);
  450. data += (len + 1);
  451. //TODO
  452. len = get_ups_param(data, " ", value);
  453. data += (len + 1);
  454. //TODO
  455. len = get_ups_param(data, " ", value);
  456. data += (len + 1);
  457. len = get_ups_param(data, " ", value);
  458. data += (len + 1);
  459. if (len > 0) {
  460. UPS.SOC = atoi(value);
  461. }
  462. #ifdef RELAY_ALARM_AKB
  463. UPS_TestSOCMonitor();
  464. #endif
  465. len = get_ups_param(data, "\r", value);
  466. data += (len + 1);
  467. if (len > 0) {
  468. UPS.work_time = atoi(value);
  469. }
  470. }
  471. void ups_model_response(char *data)
  472. {
  473. uint8_t j = 0;
  474. char value[20];
  475. uint8_t len = 0;
  476. DBG printf("ups_akb_info_response: %s\r\n", data);
  477. if (data[0] != '(') {
  478. return;
  479. }
  480. DBG printf("ups_akb_info_parser_start\r\n");
  481. UPS.Present = true;
  482. UPS.Flag_Present = true;
  483. UPS.cnt_err_ups = 0;
  484. data++;
  485. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  486. memset(value, 0, 20);
  487. if (UPS.model[0] == 0) {
  488. for (uint8_t i = 0; i < VOLTRONIC_MODEL_LENGTH; i ++) {
  489. if (data[i] != '#') {
  490. value[j] = data[i];
  491. j ++;
  492. }
  493. }
  494. if(strncmp(value, "WPHV", 4) == 0 || strncmp(value, "G2", 2) == 0 || value[0] == 0) {
  495. strcpy(UPS.model, "RTMP-II");
  496. } else {
  497. len = strlen(value);
  498. strncpy(UPS.model, value, len);
  499. }
  500. SNMP_SetObjDescr();
  501. } else {
  502. return;
  503. }
  504. }
  505. void ups_version_response(char *data)
  506. {
  507. char value[20];
  508. uint8_t len = 0;
  509. DBG printf("ups_akb_info_response: %s\r\n", data);
  510. if (data[0] != '(') {
  511. return;
  512. }
  513. DBG printf("ups_akb_info_parser_start\r\n");
  514. UPS.Present = true;
  515. UPS.Flag_Present = true;
  516. UPS.cnt_err_ups = 0;
  517. data++;
  518. if (UPS.vertion[0] != 0) {
  519. if(strncmp(data, UPS.vertion, strlen(UPS.vertion)) == 0){
  520. return;
  521. }
  522. }
  523. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  524. len = get_ups_param(data, ":", value);
  525. data += (len + 1);
  526. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  527. len = get_ups_param(data, "\r", value);
  528. if (len > VOLTRONIC_VERSION_LENGTH) {
  529. len = VOLTRONIC_VERSION_LENGTH;
  530. }
  531. strncpy(UPS.vertion, value, len);
  532. }
  533. void ups_version_part2_response(char *data)
  534. {
  535. char value[20];
  536. uint8_t len = 0;
  537. DBG printf("ups_akb_info_response: %s\r\n", data);
  538. if (data[0] != '(') {
  539. return;
  540. }
  541. DBG printf("ups_akb_info_parser_start\r\n");
  542. UPS.Present = true;
  543. UPS.Flag_Present = true;
  544. UPS.cnt_err_ups = 0;
  545. if (strncmp(ups_pdu.data, "(NAK", 4) == 0) {
  546. return;
  547. }
  548. data++;
  549. if (UPS.vertion[VOLTRONIC_VERSION_LENGTH] != 0) {
  550. return;
  551. }
  552. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  553. len = get_ups_param(data, ":", value);
  554. data += (len + 1);
  555. len = get_ups_param(data, "\r", value);
  556. if (len > VOLTRONIC_VERSION_LENGTH) {
  557. len = VOLTRONIC_VERSION_LENGTH;
  558. }
  559. strncat(UPS.vertion, "/", 1);
  560. strncat(UPS.vertion, value, len);
  561. }
  562. void ups_serial_response(char *data)
  563. {
  564. char value[20];
  565. uint8_t len = 0;
  566. DBG printf("ups_serialresponse: %s\r\n", data);
  567. if (data[0] != '(') {
  568. return;
  569. }
  570. DBG printf("ups_serial_parser_start\r\n");
  571. UPS.Present = true;
  572. UPS.Flag_Present = true;
  573. UPS.cnt_err_ups = 0;
  574. data++;
  575. DBG printf("UPS ups_serial_parser_start: %s\r\n", data);
  576. len = get_ups_param(data, "\r", value);
  577. strncpy(UPS.serial, value, VOLTRONIC_SN_LENGTH);
  578. }
  579. void ups_protocol_id_response(char *data)
  580. {
  581. DBG printf("ups_protocol_id_response: %s\r\n", data);
  582. UPS.Present = true;
  583. UPS.Flag_Present = true;
  584. UPS.cnt_err_ups = 0;
  585. if (data[0] != '(') {
  586. if (strncmp(data, "NAK", 3) == 0 || strncmp(data, " \r", 2) == 0) {
  587. sSettings.UPS_Setting.type_ups = ups_kestar;
  588. }
  589. else if(strncmp(data, "QPI", 3) == 0) {
  590. sSettings.UPS_Setting.type_ups = ups_offline;
  591. }
  592. return;
  593. }
  594. data++;
  595. sSettings.UPS_Setting.type_ups = ups_voltronic;
  596. DBG printf("UPS ups_protocol_id_parser_start: %s\r\n", data);
  597. }
  598. void ups_buzzer_cntrl_response(char *data)
  599. {
  600. UPS.Present = true;
  601. UPS.Flag_Present = true;
  602. UPS.cnt_err_ups = 0;
  603. if (strlen(data) != 0) {
  604. if (strncmp(data, "(ACK", 4) == 0) {
  605. flag_buzzer_on = true;
  606. }
  607. }
  608. DBG printf("UPS ups_buzzer_cntrl_parser_start: %s\r\n", data);
  609. }
  610. void ups_mode_response(char *data)
  611. {
  612. char value[20];
  613. uint8_t len = 0;
  614. DBG printf("ups_serialresponse: %s\r\n", data);
  615. if (data[0] != '(') {
  616. return;
  617. }
  618. DBG printf("ups_serial_parser_start\r\n");
  619. UPS.Present = true;
  620. UPS.Flag_Present = true;
  621. UPS.cnt_err_ups = 0;
  622. data++;
  623. DBG printf("UPS ups_mode_parser_start: %s\r\n", data);
  624. UPS.Mode = data[0];
  625. }
  626. void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
  627. {
  628. switch (command) {
  629. case ups_status_req:
  630. case ups_offline_status_req:
  631. ups_status_response(ups_pdu.data);
  632. break;
  633. case ups_info:
  634. ups_info_response(ups_pdu.data);
  635. break;
  636. case ups_rating_info:
  637. break;
  638. case ups_remain_time_reg:
  639. ups_remain_time_response(ups_pdu.data);
  640. break;
  641. case ups_general_status_req:
  642. ups_general_status_response(ups_pdu.data);
  643. break;
  644. case ups_akb_info:
  645. ups_akb_info_response(ups_pdu.data);
  646. break;
  647. case ups_model_req:
  648. ups_model_response(ups_pdu.data);
  649. break;
  650. case ups_version_req:
  651. ups_version_response(ups_pdu.data);
  652. break;
  653. case ups_version2_req:
  654. ups_version_part2_response(ups_pdu.data);
  655. break;
  656. case ups_serial_req:
  657. ups_serial_response(ups_pdu.data);
  658. break;
  659. case ups_protocol_id_req:
  660. ups_protocol_id_response(ups_pdu.data);
  661. break;
  662. case ups_buzzer_cntrl:
  663. ups_buzzer_cntrl_response(ups_pdu.data);
  664. break;
  665. case ups_mode_req:
  666. ups_mode_response(ups_pdu.data);
  667. break;
  668. default:
  669. break;
  670. }
  671. }
  672. int ups_metac_service_pdu(cmdMegaTecEnums_t command)
  673. {
  674. uint8_t UPS_Status_prev;
  675. if (UPS.Present) {
  676. while (!megatec_send) {
  677. vTaskDelay(50);
  678. }
  679. UPS_Status_prev = UPS.Status;
  680. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  681. megatec_send = false;
  682. if (command == ups_shutdown) {//sSettings.UPS_Setting.type_ups == ups_offline &&
  683. TimeParam2 = 1;
  684. send_MegaTec_cmd(ups_shutdown_restore);
  685. } else {
  686. UPS.SOC_test = UPS.SOC;
  687. if (command == ups_test_low_bat) {
  688. test_time = 0;
  689. } else {
  690. test_time = (int)TimeParam;
  691. }
  692. send_MegaTec_cmd(command);
  693. }
  694. if (ups_megatec_rx_pdu()) {
  695. megatec_send = true;
  696. if (strncmp(ups_pdu.data, "ACK", 3) == 0 || strncmp(ups_pdu.data, "(ACK", 4) == 0) {
  697. if (command == ups_shutdown) {
  698. xTimerChangePeriod(UPSRestoreTimer, (TimeParamFloat + 0.3)*60*configTICK_RATE_HZ, 0);
  699. xTimerStart(UPSRestoreTimer, 0);
  700. } else if(command == ups_cancel_shut_down) {
  701. xTimerStop(UPSRestoreTimer, 0);
  702. }
  703. return 1;
  704. } else if (strncmp(ups_pdu.data, "NAK", 3) == 0 || strncmp(ups_pdu.data, "(NAK", 4) == 0) {
  705. return 0;
  706. }
  707. }
  708. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  709. megatec_send = false;
  710. UPS.Flag_Present = false;
  711. send_MegaTec_cmd(ups_status_req);
  712. if (ups_megatec_rx_pdu()) {
  713. ups_megatec_process_pdu(ups_status_req);
  714. }
  715. megatec_send = true;
  716. if (command == ups_shutdown) {
  717. if ((((UPS.Status >> 1) & 0x01) != ((UPS_Status_prev >> 1) & 0x01))
  718. && ((UPS.Status >> 1) & 0x01)) {
  719. return 1;
  720. }
  721. } else if (command == ups_cancel_shut_down) {
  722. if ((((UPS.Status >> 1) & 0x01) != ((UPS_Status_prev >> 1) & 0x01))
  723. && !((UPS.Status >> 1) & 0x01)) {
  724. return 1;
  725. }
  726. } else if (command == ups_cancel_test) {
  727. if ((((UPS.Status >> 2) & 0x01) != ((UPS_Status_prev >> 2) & 0x01))
  728. && !((UPS.Status >> 2) & 0x01)) {
  729. return 1;
  730. }
  731. } else {
  732. if ((((UPS.Status >> 2) & 0x01) != ((UPS_Status_prev >> 2) & 0x01))
  733. && ((UPS.Status >> 2) & 0x01)) {
  734. return 1;
  735. }
  736. }
  737. megatec_send = true;
  738. }
  739. return -1;
  740. }
  741. void kstar_mode(void)
  742. {
  743. if((UPS.Status >> 4) & 0x01) {
  744. UPS.Mode = 'F';
  745. return;
  746. }
  747. if(!((UPS.Status >> 4) & 0x01) && UPS.VAC_out == 0) {
  748. UPS.Mode = 'D';
  749. return;
  750. }
  751. if(((UPS.Status >> 5) & 0x01) && UPS.VAC_out > 120 && UPS.VAC_in != 0) {
  752. UPS.Mode = 'Y';
  753. return;
  754. }
  755. if(((UPS.Status >> 7) & 0x01) && UPS.VAC_out > 190) {
  756. UPS.Mode = 'B';
  757. return;
  758. }
  759. if(!((UPS.Status >> 7) & 0x01) && UPS.VAC_out > 190) {
  760. UPS.Mode = 'L';
  761. return;
  762. }
  763. }
  764. // TODO ����������� ���������
  765. //void request_task(void)
  766. void request_task(void *params)
  767. {
  768. uint8_t kestar_req[3] = { ups_status_req, ups_remain_time_reg, ups_info};
  769. uint8_t voltronic_req[7] = {ups_status_req, ups_akb_info, ups_model_req, ups_version_req, ups_version2_req, ups_serial_req, ups_mode_req};//
  770. uint8_t num_req = 0;
  771. uint8_t *req;
  772. ups_megatec_rx_pdu();
  773. for (;;) {
  774. if (UPS.Present == true) {
  775. if (UPS.Flag_Present == false) {
  776. if (UPS.cnt_err_ups != 2) {
  777. UPS.cnt_err_ups++;
  778. } else {
  779. UPS.Freq_in = 0;
  780. UPS.VAC_in = 0;
  781. UPS.VAC_out = 0;
  782. UPS.Temp = 0;
  783. UPS.Load = 0;
  784. UPS.SOC = 0;
  785. UPS.work_time = 0;
  786. UPS.Status = 0;
  787. UPS.Mode = 0;
  788. UPS.Test_Status = 0;
  789. UPS.Alarm = 0;
  790. UPS.Present = false;
  791. //memset(UPS.model, 0, 11);
  792. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  793. init_ups_rbuf();
  794. }
  795. }
  796. }
  797. if (megatec_send) {
  798. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  799. megatec_send = false;
  800. UPS.Flag_Present = false;
  801. send_MegaTec_cmd(ups_protocol_id_req);
  802. if (ups_megatec_rx_pdu()) {
  803. ups_megatec_process_pdu(ups_protocol_id_req);
  804. }
  805. megatec_send = true;
  806. }
  807. switch (sSettings.UPS_Setting.type_ups) {
  808. case ups_kestar:
  809. case ups_offline:
  810. num_req = sizeof(kestar_req);
  811. req = kestar_req;
  812. break;
  813. case ups_voltronic:
  814. num_req = sizeof(voltronic_req);
  815. req = voltronic_req;
  816. #ifdef UPS_BUZZER_OFF
  817. if (!flag_buzzer_on) {
  818. if (megatec_send) {
  819. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  820. megatec_send = false;
  821. UPS.Flag_Present = false;
  822. send_MegaTec_cmd(ups_buzzer_cntrl);
  823. if (ups_megatec_rx_pdu()) {
  824. ups_megatec_process_pdu(ups_buzzer_cntrl);
  825. }
  826. megatec_send = true;
  827. }
  828. }
  829. #endif
  830. break;
  831. default:
  832. num_req = sizeof(kestar_req);
  833. req = kestar_req;
  834. break;
  835. }
  836. vTaskDelay(1000);
  837. for (uint8_t i = 0; i < num_req; i++) {
  838. if (megatec_send) {
  839. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  840. megatec_send = false;
  841. UPS.Flag_Present = false;
  842. send_MegaTec_cmd(req[i]);
  843. if (ups_megatec_rx_pdu()) {
  844. ups_megatec_process_pdu(req[i]);
  845. }
  846. megatec_send = true;
  847. }
  848. }
  849. if(sSettings.UPS_Setting.type_ups == ups_kestar
  850. || sSettings.UPS_Setting.type_ups == ups_offline) {
  851. kstar_mode();
  852. }
  853. }
  854. }
  855. void akb_time_work_task(void *params)
  856. {
  857. static uint32_t tick_prev = 0;
  858. for (;;) {
  859. if (UPS.Present && ((UPS.Status >> 7) & 0x01)) {
  860. if (tick_prev == 0) {
  861. tick_prev = xTaskGetTickCount();
  862. }
  863. UPS.akb_work_time += (xTaskGetTickCount() - tick_prev) / 1000;
  864. tick_prev = xTaskGetTickCount();
  865. } else {
  866. tick_prev = 0;
  867. UPS.akb_work_time = 0;
  868. }
  869. vTaskDelay(1000);
  870. }
  871. }
  872. void UPSRestoreCallback(TimerHandle_t pxTimer)
  873. {
  874. if (UPS.Present) {
  875. while (!megatec_send) {
  876. vTaskDelay(50);
  877. }
  878. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  879. megatec_send = false;
  880. //UPS.Flag_Present = false;
  881. send_MegaTec_cmd(ups_remote_turn_on);
  882. if (ups_megatec_rx_pdu()) {
  883. ups_megatec_process_pdu(ups_remote_turn_on);
  884. }
  885. megatec_send = true;
  886. }
  887. }
  888. void UPSReadTestStatus(void)
  889. {
  890. if(sSettings.UPS_Setting.type_ups == ups_kestar
  891. || sSettings.UPS_Setting.type_ups == ups_offline) {
  892. return;
  893. }
  894. if (UPS.Present) {
  895. while (!megatec_send) {
  896. vTaskDelay(50);
  897. }
  898. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  899. megatec_send = false;
  900. //UPS.Flag_Present = false;
  901. send_MegaTec_cmd(ups_general_status_req);
  902. if (ups_megatec_rx_pdu()) {
  903. ups_megatec_process_pdu(ups_general_status_req);
  904. }
  905. megatec_send = true;
  906. }
  907. }
  908. void ups_megatec_init(void)
  909. {
  910. init_UPS_value();
  911. UPS.Present = true;
  912. xTaskCreate(request_task, ( char * ) "request_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
  913. xTaskCreate(akb_time_work_task, ( char * ) "akb_time_work_task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY,
  914. NULL);
  915. UPSRestoreTimer = xTimerCreate("UPSRestoreTmr", configTICK_RATE_HZ*30, pdFALSE, ( void * ) 0, UPSRestoreCallback);
  916. }