megatec.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  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 "syslog.h"
  16. #include "settings_api.h"
  17. #include "parameters.h"
  18. #ifdef PRINTF_STDLIB
  19. #include <stdio.h>
  20. #endif
  21. #ifdef PRINTF_CUSTOM
  22. #include "tinystdio.h"
  23. #endif
  24. #include <string.h>
  25. #include <math.h>
  26. #define DBG if (0)
  27. TimerHandle_t UPSRestoreTimer;
  28. /**
  29. * @brief Общая структура настроек
  30. */
  31. extern SETTINGS_t sSettings;
  32. #define UPS_PDU_MAX_LEN 80
  33. float TimeParamFloat = 0;
  34. uint16_t TimeParam = 0;
  35. uint16_t TimeParam2 = 0;
  36. bool megatec_send = true;
  37. UPS_value_t UPS;
  38. int test_time = 0;
  39. static bool flag_buzzer_on = false;
  40. static float Ubat_sum = 0;
  41. static float Pload_sum = 0;
  42. uint32_t Period_testing = 0;
  43. static bool sync_data = false;
  44. static bool QFLAG_L = false;
  45. enum {
  46. NORMAL = 0x00,
  47. VER_ERROR = 0x01,
  48. CHKSUM_ERROR = 0x02,
  49. LCHKSUM_ERROR = 0x03,
  50. CID2_INVALID = 0x04,
  51. CMD_FMT_ERROR = 0x05,
  52. INVALID_DATA = 0x06,
  53. };
  54. static struct {
  55. uint8_t data[UPS_PDU_MAX_LEN];
  56. uint16_t len;
  57. } ups_pdu;
  58. const char *MegaTecCMD[] = {
  59. "Q1\r",
  60. "T\r",
  61. "TL\r",
  62. "T",
  63. "Q\r",
  64. "S",
  65. "R",
  66. "C\r",
  67. "CT\r",
  68. "I\r",
  69. "F\r",
  70. "Q2\r",
  71. "QGS\r",
  72. "QBV\r",
  73. "QMD\r",
  74. "QVFW\r",
  75. "QVFW2\r",
  76. "QID\r",
  77. "QPI\r",
  78. "QS\r",
  79. "M\r",
  80. "PDA\r",
  81. "QMOD\r",
  82. "SON\r",
  83. "QWS\r",
  84. "QBYV\r",
  85. "PHV264\r",//264
  86. "QFLAG\r",
  87. "PEL\r",
  88. };
  89. extern bool flUpdateLog;
  90. static bool flag_WPHVR2K0L = false;
  91. void init_UPS_value(void)
  92. {
  93. UPS.Freq_in = 0;
  94. UPS.VAC_in = 0;
  95. UPS.VAC_out = 0;
  96. UPS.Temp = 0;
  97. UPS.Load = 0;
  98. UPS.SOC = 0;
  99. UPS.work_time = 0;
  100. UPS.akb_work_time = 0;
  101. UPS.Status = 0;
  102. UPS.Mode = 0;
  103. UPS.Alarm = 0;
  104. UPS.warn_status = 0;
  105. UPS.Test_Status = 0;
  106. UPS.cnt_err_ups = 0;
  107. UPS.Flag_Present = false;
  108. UPS.Present = UPS_WAIT_CONNECT;
  109. memset(UPS.model, 0, sizeof(UPS.model));
  110. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  111. memset(UPS.serial, 0, sizeof(UPS.serial));
  112. }
  113. void init_var_for_testing(void)
  114. {
  115. Ubat_sum = 0;
  116. Pload_sum = 0;
  117. Period_testing = 0;
  118. }
  119. float voltage_bat_average(void)
  120. {
  121. return (Ubat_sum / Period_testing);
  122. }
  123. float power_load_average(void)
  124. {
  125. return (Pload_sum / Period_testing);
  126. }
  127. void send_MegaTec_cmd(cmdMegaTecEnums_t command)
  128. {
  129. DBG printf("MegaTecCMD: %s\r\n", MegaTecCMD[command]);
  130. if (command == ups_test_time) {
  131. uint8_t req[10];
  132. memset(req, 0, 10);
  133. if (TimeParam < 10) {
  134. sprintf(req, "%s0%d\r", MegaTecCMD[command], TimeParam);
  135. } else {
  136. sprintf(req, "%s%d\r", MegaTecCMD[command], TimeParam);
  137. }
  138. ups_send_block(req, strlen(req));
  139. } else if (command == ups_shutdown) {
  140. uint8_t req[10];
  141. memset(req, 0, 10);
  142. if (TimeParamFloat >= 1 && TimeParamFloat < 10) {
  143. sprintf(req, "%s0%d\r", MegaTecCMD[command], (uint16_t)TimeParamFloat);
  144. } else if (TimeParamFloat < 1) {
  145. sprintf(req, "%s.%d\r", MegaTecCMD[command], (uint16_t)(10 * TimeParamFloat));
  146. } else {
  147. sprintf(req, "%s%d\r", MegaTecCMD[command], (uint16_t)TimeParamFloat);
  148. }
  149. ups_send_block(req, strlen(req));
  150. } else if (command == ups_shutdown_restore) {
  151. uint8_t req[10];
  152. memset(req, 0, 10);
  153. if (TimeParamFloat >= 1 && TimeParamFloat < 10) {
  154. sprintf(req, "%s0%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)TimeParamFloat, MegaTecCMD[command], TimeParam2);
  155. } else if (TimeParamFloat < 1) {
  156. sprintf(req, "%s.%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)(10 * TimeParamFloat), MegaTecCMD[command], TimeParam2);
  157. } else {
  158. sprintf(req, "%s%d%s000%d\r", MegaTecCMD[command - 1], (uint16_t)TimeParamFloat, MegaTecCMD[command], TimeParam2);
  159. }
  160. ups_send_block(req, strlen(req));
  161. } else {
  162. // TODO ����������� ���������
  163. //ups_send_block(MegaTecCMD[command], strlen(MegaTecCMD[command]));
  164. ups_send_block((void *)MegaTecCMD[command], strlen(MegaTecCMD[command]));
  165. }
  166. }
  167. bool ups_megatec_rx_pdu(void)
  168. {
  169. int c = 0;
  170. uint8_t cnt_answer = 0;
  171. ups_pdu.len = 0;
  172. while (c >= 0) {
  173. c = ups_getchar(300);//portMAX_DELAY200
  174. if (c >= 0) {
  175. ups_pdu.len = 0;
  176. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  177. ups_pdu.data[ups_pdu.len++] = c;
  178. while ((ups_pdu.len < UPS_PDU_MAX_LEN) && (c != 0x0d)) {
  179. c = ups_getchar(100);//portMAX_DELAY200
  180. if (c < 0) {
  181. ups_pdu.len = 0;
  182. return false;
  183. }
  184. ups_pdu.data[ups_pdu.len++] = c;
  185. }
  186. DBG printf("UPS raw data: %s\r\n", ups_pdu.data);
  187. cnt_answer ++;
  188. } else {
  189. if (ups_pdu.len == 0) {
  190. return false;
  191. }
  192. }
  193. }
  194. if (cnt_answer > 1) {
  195. DBG printf("MegaTecCMD: false\r\n");
  196. return false;
  197. }
  198. DBG printf("UPS raw data: %s\r\n", ups_pdu.data);
  199. DBG printf("UPS raw data len: %d\r\n", ups_pdu.len);
  200. return true;
  201. }
  202. int8_t get_ups_param(char *buf, char *param, char *val)
  203. {
  204. char *endValue;
  205. int8_t param_len;
  206. memset(val, 0, 20);
  207. endValue = strpbrk(buf, param);
  208. if (endValue != NULL) {
  209. param_len = endValue - buf;
  210. if (param_len < 20) {
  211. strncpy(val, buf, param_len);
  212. } else {
  213. param_len = 0;
  214. }
  215. } else {
  216. param_len = 0;
  217. }
  218. DBG printf("UPS parameter: %s\r\n", val);
  219. return param_len;
  220. }
  221. void ups_status_response(char *data)
  222. {
  223. uint8_t i;
  224. char value[20];
  225. float tmp;
  226. uint8_t len = 0;
  227. DBG printf("ups_status_response: %s\r\n", data);
  228. if (data[0] != '(') {
  229. return;
  230. }
  231. DBG printf("ups_status_parser_start\r\n");
  232. UPS.Present = UPS_CONNECTED;
  233. UPS.Flag_Present = true;
  234. UPS.cnt_err_ups = 0;
  235. #ifdef UPS_BUZZER_OFF
  236. if (flag_buzzer_on) {
  237. data[45] = '0';
  238. }
  239. #endif
  240. if (flUpdateLog) {
  241. flUpdateLog = false;
  242. log_add(data);
  243. }
  244. data++;
  245. DBG printf("UPS ups_status_parser_startr: %s\r\n", data);
  246. len = get_ups_param(data, " ", value);
  247. data += (len + 1);
  248. if (len > 0) {
  249. tmp = atof(value);
  250. if (tmp > 20) {
  251. UPS.VAC_in = tmp;
  252. } else {
  253. UPS.VAC_in = 0;
  254. }
  255. }
  256. //TODO
  257. len = get_ups_param(data, " ", value);
  258. data += (len + 1);
  259. len = get_ups_param(data, " ", value);
  260. data += (len + 1);
  261. if (len > 0) {
  262. UPS.VAC_out = atof(value);
  263. }
  264. len = get_ups_param(data, " ", value);
  265. data += (len + 1);
  266. if (len > 0) {
  267. UPS.Load = atoi(value);
  268. }
  269. sync_data = true;
  270. len = get_ups_param(data, " ", value);
  271. data += (len + 1);
  272. if (len > 0) {
  273. UPS.Freq_in = atof(value);
  274. }
  275. //TODO
  276. len = get_ups_param(data, " ", value);
  277. data += (len + 1);
  278. if (len > 0) {
  279. UPS.Vcell_curr = atof(value);
  280. }
  281. // if (sSettings.UPS_Setting.type_ups == ups_kestar || sSettings.UPS_Setting.type_ups == ups_offline) {
  282. if (UPS.Vcell_curr < 7) {
  283. UPS.SOC = round(100 * (UPS.Vcell_curr - sSettings.UPS_Setting.Ucellmin) / (sSettings.UPS_Setting.Ucellmax -
  284. sSettings.UPS_Setting.Ucellmin));
  285. } else {
  286. UPS.SOC = round(100 * (UPS.Vcell_curr / AKB_NUM_CELL - sSettings.UPS_Setting.Ucellmin) /
  287. (sSettings.UPS_Setting.Ucellmax - sSettings.UPS_Setting.Ucellmin));
  288. }
  289. // }
  290. len = get_ups_param(data, " ", value);
  291. data += (len + 1);
  292. if (len > 0) {
  293. UPS.Temp = atof(value);
  294. }
  295. len = get_ups_param(data, "\r", value);
  296. data += (len + 1);
  297. if (len > 0) {
  298. uint8_t stat = 0;
  299. for (i = 0; i < len; i ++) {
  300. stat |= (value[i] - 0x30) << (7 - i);
  301. }
  302. UPS.Status = stat;
  303. }
  304. }
  305. void ups_general_status_response(char *data)
  306. {
  307. uint8_t i;
  308. char value[20];
  309. float tmp;
  310. uint8_t len = 0;
  311. DBG printf("ups_status_response: %s\r\n", data);
  312. if (data[0] != '(') {
  313. return;
  314. }
  315. DBG printf("ups_status_parser_start\r\n");
  316. UPS.Present = UPS_CONNECTED;
  317. UPS.Flag_Present = true;
  318. UPS.cnt_err_ups = 0;
  319. data++;
  320. DBG printf("UPS ups_status_parser_startr: %s\r\n", data);
  321. data = data + 72;
  322. uint8_t stat = 0;
  323. UPS.Test_Status = 0;
  324. for (i = 0; i < 2; i ++) {
  325. UPS.Test_Status |= (data[i] - 0x30) << (1 - i);
  326. }
  327. /*
  328. len = get_ups_param(data, " ", value);
  329. data += (len + 1);
  330. if (len > 0) {
  331. tmp = atof(value);
  332. if (tmp > 20) {
  333. UPS.VAC_in = tmp;
  334. } else {
  335. UPS.VAC_in = 0;
  336. }
  337. }
  338. len = get_ups_param(data, " ", value);
  339. data += (len + 1);
  340. if (len > 0) {
  341. UPS.Freq_in = atof(value);
  342. }
  343. len = get_ups_param(data, " ", value);
  344. data += (len + 1);
  345. if (len > 0) {
  346. UPS.VAC_out = atof(value);
  347. }
  348. //TODO
  349. len = get_ups_param(data, " ", value);
  350. data += (len + 1);
  351. //TODO
  352. len = get_ups_param(data, " ", value);
  353. data += (len + 1);
  354. len = get_ups_param(data, " ", value);
  355. data += (len + 1);
  356. if (len > 0) {
  357. UPS.Load = atoi(value);
  358. }
  359. //TODO
  360. len = get_ups_param(data, " ", value);
  361. data += (len + 1);
  362. //TODO
  363. len = get_ups_param(data, " ", value);
  364. data += (len + 1);
  365. //TODO
  366. len = get_ups_param(data, " ", value);
  367. data += (len + 1);
  368. //TODO
  369. len = get_ups_param(data, " ", value);
  370. data += (len + 1);
  371. len = get_ups_param(data, " ", value);
  372. data += (len + 1);
  373. if (len > 0) {
  374. UPS.Temp = atof(value);
  375. }
  376. len = get_ups_param(data, "\r", value);
  377. data += (len + 1);
  378. if (len > 0) {
  379. uint8_t stat = 0;
  380. for (i = 2; i < (len - 2); i ++) {
  381. stat |= (value[i] - 0x30) << (7 - i);
  382. }
  383. UPS.Status = stat;
  384. }
  385. value[len - 2] = 0;
  386. if (flUpdateLog) {
  387. flUpdateLog = false;
  388. memset(data, 0, UPS_PDU_MAX_LEN);
  389. 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.Vcell_curr, UPS.Temp, &value[2]);
  390. log_add(data);
  391. }
  392. */
  393. }
  394. void ups_info_response(char *data)
  395. {
  396. uint8_t i = 0, j = 0;
  397. char value[20];
  398. DBG printf("ups_info_response: %s\r\n", data);
  399. if (data[0] != '#') {
  400. return;
  401. }
  402. DBG printf("ups_info_response_startr: %s\r\n", data);
  403. UPS.Present = UPS_CONNECTED;
  404. UPS.Flag_Present = true;
  405. UPS.cnt_err_ups = 0;
  406. data++;
  407. data += 16; //пропускаем поле название компании
  408. memset(value, 0, sizeof(value));
  409. for (uint8_t i = 0; i < KSTAR_MODEL_LENGTH; i ++) {
  410. if (data[i] != ' ') {
  411. value[j] = data[i];
  412. j ++;
  413. }
  414. }
  415. if (j != 0) {
  416. if (UPS.model[0] == 0) {
  417. strncpy(UPS.model, value, strlen(value));
  418. SNMP_SetObjDescr();
  419. } else {
  420. strncpy(UPS.model, data, strlen(value));
  421. }
  422. } else {
  423. if (UPS.model[0] == 0) {
  424. strcpy(UPS.model, "RTMP-II");
  425. SNMP_SetObjDescr();
  426. } else {
  427. strcpy(UPS.model, "RTMP-II");
  428. }
  429. }
  430. data += (KSTAR_MODEL_LENGTH + 1);
  431. strncpy(UPS.serial, data, 8);
  432. data += 8;
  433. strncpy(UPS.vertion, data, 2);
  434. SNMP_SetObjDescr();
  435. }
  436. void ups_remain_time_response(char *data)
  437. {
  438. char value[20];
  439. if (data[0] != '(') {
  440. return;
  441. }
  442. DBG printf("ups_remain_time_response: %s\r\n", data);
  443. UPS.Present = UPS_CONNECTED;
  444. UPS.Flag_Present = true;
  445. UPS.cnt_err_ups = 0;
  446. data++;
  447. if (strlen(data) > 5) {
  448. return;
  449. }
  450. memset(value, 0, 10);
  451. strcpy(value, data);
  452. //if((UPS.Status >> 7) & 0x01)
  453. UPS.work_time = atoi(value);
  454. //else
  455. // UPS.work_time = 0;
  456. }
  457. void ups_akb_info_response(char *data)
  458. {
  459. char value[20];
  460. uint8_t len = 0;
  461. DBG printf("ups_akb_info_response: %s\r\n", data);
  462. if (data[0] != '(') {
  463. return;
  464. }
  465. DBG printf("ups_akb_info_parser_start\r\n");
  466. UPS.Present = UPS_CONNECTED;
  467. UPS.Flag_Present = true;
  468. UPS.cnt_err_ups = 0;
  469. data++;
  470. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  471. len = get_ups_param(data, " ", value);
  472. data += (len + 1);
  473. if(len > 0) {
  474. UPS.Vakb_curr = atof(value);
  475. }
  476. #ifdef TEST_ALARM_AKB_MONITOR
  477. if((UPS.Status >> 2) & 0x01) {
  478. Ubat_sum += UPS.Vakb_curr;
  479. Pload_sum += UPS.Load;
  480. Period_testing ++;
  481. }
  482. #endif
  483. //TODO
  484. len = get_ups_param(data, " ", value);
  485. data += (len + 1);
  486. //TODO
  487. len = get_ups_param(data, " ", value);
  488. data += (len + 1);
  489. len = get_ups_param(data, " ", value);
  490. data += (len + 1);
  491. /* if (len > 0) {
  492. UPS.SOC = atoi(value);
  493. }*/
  494. len = get_ups_param(data, "\r", value);
  495. data += (len + 1);
  496. if (len > 0) {
  497. UPS.work_time = atoi(value);
  498. }
  499. }
  500. void ups_model_response(char *data)
  501. {
  502. uint8_t j = 0;
  503. char value[20];
  504. uint8_t len = 0;
  505. DBG printf("ups_akb_info_response: %s\r\n", data);
  506. if (data[0] != '(') {
  507. return;
  508. }
  509. DBG printf("ups_akb_info_parser_start\r\n");
  510. UPS.Present = UPS_CONNECTED;
  511. UPS.Flag_Present = true;
  512. UPS.cnt_err_ups = 0;
  513. data++;
  514. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  515. memset(value, 0, 20);
  516. if (UPS.model[0] == 0) {
  517. for (uint8_t i = 0; i < VOLTRONIC_MODEL_LENGTH; i ++) {
  518. if (data[i] != '#') {
  519. value[j] = data[i];
  520. j ++;
  521. }
  522. }
  523. if(strncmp(value, "WPHV", 4) == 0 || strncmp(value, "G2", 2) == 0 || value[0] == 0) {
  524. #if HARDWARE_BT6711_V1
  525. if(UPS.serial[0] == 0) {
  526. return;
  527. }
  528. if(strncmp(value, "WPHVR2K0L", 9) == 0) {
  529. strcpy(UPS.model, "RTMP-II v1rih");
  530. flag_WPHVR2K0L = true;
  531. } else if(strncmp(UPS.serial, "83122103100051", 14) == 0) {
  532. strcpy(UPS.model, "RTMP-II v0hi v1");
  533. //flag_WPHVR2K0L = true;
  534. }
  535. else
  536. #endif
  537. #if HARDWARE_BT6709_MTS
  538. if(UPS.serial[0] == 0) {
  539. return;
  540. }
  541. if(strncmp(value, "WPHVR3K0", 8) == 0) {
  542. strcpy(UPS.model, "RTMP-II v3r");
  543. } else if(strncmp(value, "WPHVR2K0", 8) == 0) {
  544. strcpy(UPS.model, "RTMP-II v2r");
  545. } else if(strncmp(value, "WPHVR1K0", 8) == 0) {
  546. strcpy(UPS.model, "RTMP-II r");
  547. } else
  548. #endif
  549. {
  550. strcpy(UPS.model, "RTMP-II");
  551. }
  552. } else {
  553. #ifdef HARDWARE_BT6709
  554. if(UPS.serial[0] == 0) {
  555. return;
  556. }
  557. if(strncmp(UPS.serial, "83122104100", 11) == 0) {
  558. char str[15];
  559. strncpy(str, &UPS.serial[11], 3);
  560. int32_t tmp = atoi(str);
  561. if (tmp >= 281 && tmp <= 770) {
  562. strcpy(UPS.model, "RTMP-II hi");
  563. } else {
  564. len = strlen(value);
  565. strncpy(UPS.model, value, len);
  566. }
  567. } else
  568. #endif
  569. {
  570. len = strlen(value);
  571. strncpy(UPS.model, value, len);
  572. }
  573. }
  574. #if HARDWARE_BT6711_V1
  575. if(UPS.serial[0] == 0) {
  576. memset(UPS.model, 0, sizeof(UPS.model));
  577. return;
  578. }
  579. if(strncmp(UPS.serial, "83122103100051", 14) == 0) {
  580. strcpy(UPS.model, "RTMP-II v0hi v1");
  581. //flag_WPHVR2K0L = true;
  582. } else if (strncmp(UPS.serial, "83122204100", 11) == 0) {
  583. char str[15];
  584. strncpy(str, &UPS.serial[11], 3);
  585. int32_t tmp = atoi(str);
  586. if (tmp >= 139 && tmp <= 938) {
  587. strcpy(UPS.model, "RTMP-II v0hi v1");
  588. }
  589. }
  590. #endif
  591. SNMP_SetObjDescr();
  592. data += (VOLTRONIC_MODEL_LENGTH + 1);
  593. memset(value, 0, sizeof(value));
  594. j = 0;
  595. for (uint8_t i = 0; i < VOLTRONIC_OUTPUT_RATED_LENGTH; i ++) {
  596. if (data[i] != '#') {
  597. value[j] = data[i];
  598. j ++;
  599. }
  600. }
  601. float temp_value = atof(value);
  602. if (sSettings.UPS_Setting.ups_power != temp_value) {
  603. sSettings.UPS_Setting.ups_power = temp_value;
  604. SETTINGS_Save();
  605. }
  606. } else {
  607. return;
  608. }
  609. }
  610. void ups_version_response(char *data)
  611. {
  612. char value[20];
  613. uint8_t len = 0;
  614. DBG printf("ups_akb_info_response: %s\r\n", data);
  615. if (data[0] != '(') {
  616. return;
  617. }
  618. DBG printf("ups_akb_info_parser_start\r\n");
  619. UPS.Present = UPS_CONNECTED;
  620. UPS.Flag_Present = true;
  621. UPS.cnt_err_ups = 0;
  622. data++;
  623. if (UPS.vertion[0] != 0) {
  624. if(strncmp(data, UPS.vertion, strlen(UPS.vertion)) == 0){
  625. return;
  626. }
  627. }
  628. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  629. len = get_ups_param(data, ":", value);
  630. data += (len + 1);
  631. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  632. len = get_ups_param(data, "\r", value);
  633. if (len > VOLTRONIC_VERSION_LENGTH) {
  634. len = VOLTRONIC_VERSION_LENGTH;
  635. }
  636. strncpy(UPS.vertion, value, len);
  637. }
  638. void ups_version_part2_response(char *data)
  639. {
  640. char value[20];
  641. uint8_t len = 0;
  642. DBG printf("ups_akb_info_response: %s\r\n", data);
  643. if (data[0] != '(') {
  644. return;
  645. }
  646. DBG printf("ups_akb_info_parser_start\r\n");
  647. UPS.Present = UPS_CONNECTED;
  648. UPS.Flag_Present = true;
  649. UPS.cnt_err_ups = 0;
  650. if (strncmp(ups_pdu.data, "(NAK", 4) == 0) {
  651. return;
  652. }
  653. data++;
  654. if (UPS.vertion[VOLTRONIC_VERSION_LENGTH] != 0) {
  655. return;
  656. }
  657. DBG printf("UPS ups_akb_info_parser_start: %s\r\n", data);
  658. len = get_ups_param(data, ":", value);
  659. data += (len + 1);
  660. len = get_ups_param(data, "\r", value);
  661. if (len > VOLTRONIC_VERSION_LENGTH) {
  662. len = VOLTRONIC_VERSION_LENGTH;
  663. }
  664. strncat(UPS.vertion, "/", 1);
  665. strncat(UPS.vertion, value, len);
  666. }
  667. void ups_serial_response(char *data)
  668. {
  669. char value[20];
  670. uint8_t len = 0;
  671. DBG printf("ups_serialresponse: %s\r\n", data);
  672. if (data[0] != '(') {
  673. return;
  674. }
  675. DBG printf("ups_serial_parser_start\r\n");
  676. UPS.Present = UPS_CONNECTED;
  677. UPS.Flag_Present = true;
  678. UPS.cnt_err_ups = 0;
  679. data++;
  680. DBG printf("UPS ups_serial_parser_start: %s\r\n", data);
  681. len = get_ups_param(data, "\r", value);
  682. strncpy(UPS.serial, value, VOLTRONIC_SN_LENGTH);
  683. }
  684. void ups_protocol_id_response(char *data)
  685. {
  686. DBG printf("ups_protocol_id_response: %s\r\n", data);
  687. UPS.Present = UPS_CONNECTED;
  688. UPS.Flag_Present = true;
  689. UPS.cnt_err_ups = 0;
  690. if (data[0] != '(') {
  691. if (strncmp(data, "NAK", 3) == 0 || strncmp(data, " \r", 2) == 0) {
  692. sSettings.UPS_Setting.type_ups = ups_kestar;
  693. }
  694. else if(strncmp(data, "QPI", 3) == 0) {
  695. sSettings.UPS_Setting.type_ups = ups_offline;
  696. }
  697. return;
  698. }
  699. data++;
  700. sSettings.UPS_Setting.type_ups = ups_voltronic;
  701. DBG printf("UPS ups_protocol_id_parser_start: %s\r\n", data);
  702. }
  703. void ups_buzzer_cntrl_response(char *data)
  704. {
  705. UPS.Present = UPS_CONNECTED;
  706. UPS.Flag_Present = true;
  707. UPS.cnt_err_ups = 0;
  708. if (strlen(data) != 0) {
  709. if (strncmp(data, "(ACK", 4) == 0) {
  710. flag_buzzer_on = true;
  711. }
  712. }
  713. DBG printf("UPS ups_buzzer_cntrl_parser_start: %s\r\n", data);
  714. }
  715. void ups_mode_response(char *data)
  716. {
  717. char value[20];
  718. uint8_t len = 0;
  719. DBG printf("ups_serialresponse: %s\r\n", data);
  720. if (data[0] != '(') {
  721. return;
  722. }
  723. DBG printf("ups_serial_parser_start\r\n");
  724. UPS.Present = UPS_CONNECTED;
  725. UPS.Flag_Present = true;
  726. UPS.cnt_err_ups = 0;
  727. data++;
  728. DBG printf("UPS ups_mode_parser_start: %s\r\n", data);
  729. if (UPS.Mode != data[0]) {
  730. UPS.Mode = data[0];
  731. #ifdef UPS_MODE_MONITOR
  732. memset(value, 0, sizeof(value));
  733. GetModeStr(value, &len);
  734. SNMP_SendUserTrap(UPS_MODE);
  735. syslog(SYSLOG_INFORMATIONAL, "Режим ИБП: %s", value);
  736. log_event_data(LOG_UPS_MODE, value);
  737. #endif
  738. }
  739. }
  740. #define BIT_OFFSET(c, offset) ((c - 0x30) << offset)
  741. void ups_warn_status_response(char *data)
  742. {
  743. if (data[0] != '(') {
  744. return;
  745. }
  746. UPS.Present = UPS_CONNECTED;
  747. UPS.Flag_Present = true;
  748. UPS.cnt_err_ups = 0;
  749. data++;
  750. sync_data = false;
  751. UPS.warn_status = BIT_OFFSET(data[0], 0) + + BIT_OFFSET(data[2], 1) + BIT_OFFSET(data[5], 2) + BIT_OFFSET(data[6], 3)
  752. + BIT_OFFSET(data[7], 4) + BIT_OFFSET(data[8], 5) + BIT_OFFSET(data[12], 6) + BIT_OFFSET(data[13], 7);
  753. }
  754. void ups_get_ack(char *data)
  755. {
  756. UPS.Present = UPS_CONNECTED;
  757. UPS.Flag_Present = true;
  758. UPS.cnt_err_ups = 0;
  759. if (strlen(data) != 0) {
  760. if (strncmp(data, "(ACK", 4) == 0) {
  761. return;
  762. }
  763. }
  764. DBG printf("UPS ups_buzzer_cntrl_parser_start: %s\r\n", data);
  765. }
  766. void ups_qflag_status_get(char *data)
  767. {
  768. char *ptr1, *ptr2;
  769. UPS.Present = UPS_CONNECTED;
  770. UPS.Flag_Present = true;
  771. UPS.cnt_err_ups = 0;
  772. if (strlen(data) != 0) {
  773. ptr1 = strchr(data, 'l');
  774. ptr2 = strchr(data, 'D');
  775. if (ptr1 != NULL && ptr2 != NULL) {
  776. if (ptr2 < ptr1) {
  777. QFLAG_L = true;
  778. }
  779. }
  780. }
  781. }
  782. void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
  783. {
  784. switch (command) {
  785. case ups_status_req:
  786. case ups_offline_status_req:
  787. ups_status_response(ups_pdu.data);
  788. break;
  789. case ups_info:
  790. ups_info_response(ups_pdu.data);
  791. break;
  792. case ups_rating_info:
  793. break;
  794. case ups_remain_time_reg:
  795. ups_remain_time_response(ups_pdu.data);
  796. break;
  797. case ups_general_status_req:
  798. ups_general_status_response(ups_pdu.data);
  799. break;
  800. case ups_akb_info:
  801. ups_akb_info_response(ups_pdu.data);
  802. break;
  803. case ups_model_req:
  804. ups_model_response(ups_pdu.data);
  805. break;
  806. case ups_version_req:
  807. ups_version_response(ups_pdu.data);
  808. break;
  809. case ups_version2_req:
  810. ups_version_part2_response(ups_pdu.data);
  811. break;
  812. case ups_serial_req:
  813. ups_serial_response(ups_pdu.data);
  814. break;
  815. case ups_protocol_id_req:
  816. ups_protocol_id_response(ups_pdu.data);
  817. break;
  818. case ups_buzzer_cntrl:
  819. ups_buzzer_cntrl_response(ups_pdu.data);
  820. break;
  821. case ups_mode_req:
  822. ups_mode_response(ups_pdu.data);
  823. break;
  824. case ups_warning_status:
  825. ups_warn_status_response(ups_pdu.data);
  826. break;
  827. case ups_bypass_hvolt_264_set:
  828. case ups_cmd_enable_flag_l:
  829. ups_get_ack(ups_pdu.data);
  830. break;
  831. case ups_qflag_status:
  832. ups_qflag_status_get(ups_pdu.data);
  833. break;
  834. default:
  835. break;
  836. }
  837. }
  838. int ups_metac_service_pdu(cmdMegaTecEnums_t command)
  839. {
  840. uint8_t UPS_Status_prev;
  841. if (UPS.Present == UPS_CONNECTED) {
  842. while (!megatec_send) {
  843. vTaskDelay(50);
  844. }
  845. UPS_Status_prev = UPS.Status;
  846. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  847. megatec_send = false;
  848. if (command == ups_shutdown) {//sSettings.UPS_Setting.type_ups == ups_offline &&
  849. TimeParam2 = 1;
  850. send_MegaTec_cmd(ups_shutdown_restore);
  851. } else {
  852. if((UPS.Status >> 2) & 0x01) {
  853. if (command == ups_cancel_test) {
  854. test_time = 100;
  855. }
  856. } else {
  857. if (command == ups_test_low_bat) {
  858. test_time = 100;
  859. } else {
  860. test_time = (int)TimeParam;
  861. }
  862. }
  863. send_MegaTec_cmd(command);
  864. }
  865. if (ups_megatec_rx_pdu()) {
  866. megatec_send = true;
  867. if (strncmp(ups_pdu.data, "ACK", 3) == 0 || strncmp(ups_pdu.data, "(ACK", 4) == 0) {
  868. if (command == ups_shutdown) {
  869. xTimerChangePeriod(UPSRestoreTimer, (TimeParamFloat + 0.3)*60*configTICK_RATE_HZ, 0);
  870. xTimerStart(UPSRestoreTimer, 0);
  871. } else if(command == ups_cancel_shut_down) {
  872. xTimerStop(UPSRestoreTimer, 0);
  873. } else if (command == ups_test_time) {
  874. init_var_for_testing();
  875. }
  876. return 1;
  877. } else if (strncmp(ups_pdu.data, "NAK", 3) == 0 || strncmp(ups_pdu.data, "(NAK", 4) == 0) {
  878. return 0;
  879. }
  880. }
  881. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  882. megatec_send = false;
  883. UPS.Flag_Present = false;
  884. send_MegaTec_cmd(ups_status_req);
  885. if (ups_megatec_rx_pdu()) {
  886. ups_megatec_process_pdu(ups_status_req);
  887. }
  888. megatec_send = true;
  889. if (command == ups_shutdown) {
  890. if ((((UPS.Status >> 1) & 0x01) != ((UPS_Status_prev >> 1) & 0x01))
  891. && ((UPS.Status >> 1) & 0x01)) {
  892. return 1;
  893. }
  894. } else if (command == ups_cancel_shut_down) {
  895. if ((((UPS.Status >> 1) & 0x01) != ((UPS_Status_prev >> 1) & 0x01))
  896. && !((UPS.Status >> 1) & 0x01)) {
  897. return 1;
  898. }
  899. } else if (command == ups_cancel_test) {
  900. if ((((UPS.Status >> 2) & 0x01) != ((UPS_Status_prev >> 2) & 0x01))
  901. && !((UPS.Status >> 2) & 0x01)) {
  902. return 1;
  903. }
  904. } else {
  905. if ((((UPS.Status >> 2) & 0x01) != ((UPS_Status_prev >> 2) & 0x01))
  906. && ((UPS.Status >> 2) & 0x01)) {
  907. init_var_for_testing();
  908. return 1;
  909. }
  910. }
  911. megatec_send = true;
  912. }
  913. return -1;
  914. }
  915. void kstar_mode(void)
  916. {
  917. uint8_t mode = UPS.Mode;
  918. if((UPS.Status >> 4) & 0x01) {
  919. UPS.Mode = 'F';
  920. } else if(!((UPS.Status >> 4) & 0x01) && UPS.VAC_out == 0) {
  921. UPS.Mode = 'D';
  922. } else if(((UPS.Status >> 5) & 0x01) && UPS.VAC_out > 120 && UPS.VAC_in != 0) {
  923. UPS.Mode = 'Y';
  924. } else if(((UPS.Status >> 7) & 0x01) && UPS.VAC_out > 190) {
  925. UPS.Mode = 'B';
  926. } else if(!((UPS.Status >> 7) & 0x01) && UPS.VAC_out > 190) {
  927. UPS.Mode = 'L';
  928. }
  929. #ifdef UPS_MODE_MONITOR
  930. if (UPS.Mode != mode) {
  931. char value[20];
  932. uint8_t len = 0;
  933. memset(value, 0, sizeof(value));
  934. GetModeStr(value, &len);
  935. SNMP_SendUserTrap(UPS_MODE);
  936. syslog(SYSLOG_INFORMATIONAL, "Режим ИБП: %s", value);
  937. log_event_data(LOG_UPS_MODE, value);
  938. }
  939. #endif
  940. }
  941. // TODO ����������� ���������
  942. //void request_task(void)
  943. void request_task(void *params)
  944. {
  945. uint8_t kestar_req[3] = { ups_status_req, ups_remain_time_reg, ups_info};
  946. uint8_t voltronic_req[8] = {ups_status_req, ups_akb_info, ups_model_req, ups_mode_req, ups_version_req, ups_version2_req, ups_serial_req, ups_warning_status};//
  947. uint8_t num_req = 0;
  948. uint8_t *req;
  949. bool flag_init_ups = false;
  950. ups_megatec_rx_pdu();
  951. for (;;) {
  952. if (UPS.Present != UPS_FAIL_CONNECT) {
  953. if (UPS.Flag_Present == false) {
  954. if (UPS.cnt_err_ups != 2) {
  955. UPS.cnt_err_ups++;
  956. } else {
  957. UPS.Freq_in = 0;
  958. UPS.VAC_in = 0;
  959. UPS.VAC_out = 0;
  960. UPS.Temp = 0;
  961. UPS.Load = 0;
  962. UPS.SOC = 0;
  963. UPS.work_time = 0;
  964. UPS.Status = 0;
  965. UPS.Mode = 0;
  966. UPS.Test_Status = 0;
  967. UPS.Alarm = 0;
  968. UPS.warn_status = 0;
  969. UPS.Present = UPS_FAIL_CONNECT;
  970. //memset(UPS.model, 0, 11);
  971. memset(UPS.vertion, 0, sizeof(UPS.vertion));
  972. init_ups_rbuf();
  973. flag_init_ups = false;
  974. }
  975. }
  976. }
  977. if (megatec_send) {
  978. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  979. megatec_send = false;
  980. UPS.Flag_Present = false;
  981. send_MegaTec_cmd(ups_protocol_id_req);
  982. if (ups_megatec_rx_pdu()) {
  983. ups_megatec_process_pdu(ups_protocol_id_req);
  984. }
  985. megatec_send = true;
  986. }
  987. switch (sSettings.UPS_Setting.type_ups) {
  988. case ups_kestar:
  989. case ups_offline:
  990. num_req = sizeof(kestar_req);
  991. req = kestar_req;
  992. break;
  993. case ups_voltronic:
  994. num_req = sizeof(voltronic_req);
  995. req = voltronic_req;
  996. #ifdef UPS_BUZZER_OFF
  997. if (!flag_buzzer_on) {
  998. if (megatec_send) {
  999. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1000. megatec_send = false;
  1001. UPS.Flag_Present = false;
  1002. send_MegaTec_cmd(ups_buzzer_cntrl);
  1003. if (ups_megatec_rx_pdu()) {
  1004. ups_megatec_process_pdu(ups_buzzer_cntrl);
  1005. }
  1006. megatec_send = true;
  1007. }
  1008. }
  1009. #endif
  1010. if(!flag_init_ups) {
  1011. flag_init_ups = true;
  1012. if (megatec_send) {
  1013. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1014. megatec_send = false;
  1015. UPS.Flag_Present = false;
  1016. send_MegaTec_cmd(ups_bypass_hvolt_264_set);
  1017. if (ups_megatec_rx_pdu()) {
  1018. ups_megatec_process_pdu(ups_bypass_hvolt_264_set);
  1019. }
  1020. megatec_send = true;
  1021. }
  1022. if (megatec_send) {
  1023. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1024. megatec_send = false;
  1025. UPS.Flag_Present = false;
  1026. send_MegaTec_cmd(ups_qflag_status);
  1027. if (ups_megatec_rx_pdu()) {
  1028. ups_megatec_process_pdu(ups_qflag_status);
  1029. }
  1030. megatec_send = true;
  1031. }
  1032. if (QFLAG_L) {
  1033. if (megatec_send) {
  1034. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1035. megatec_send = false;
  1036. UPS.Flag_Present = false;
  1037. send_MegaTec_cmd(ups_cmd_enable_flag_l);
  1038. if (ups_megatec_rx_pdu()) {
  1039. ups_megatec_process_pdu(ups_cmd_enable_flag_l);
  1040. }
  1041. megatec_send = true;
  1042. }
  1043. }
  1044. }
  1045. break;
  1046. default:
  1047. num_req = sizeof(kestar_req);
  1048. req = kestar_req;
  1049. break;
  1050. }
  1051. vTaskDelay(1000);
  1052. for (uint8_t i = 0; i < num_req; i++) {
  1053. if (megatec_send) {
  1054. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1055. megatec_send = false;
  1056. UPS.Flag_Present = false;
  1057. send_MegaTec_cmd(req[i]);
  1058. if (ups_megatec_rx_pdu()) {
  1059. ups_megatec_process_pdu(req[i]);
  1060. }
  1061. megatec_send = true;
  1062. }
  1063. }
  1064. if(UPS.Flag_Present && (sSettings.UPS_Setting.type_ups == ups_kestar
  1065. || sSettings.UPS_Setting.type_ups == ups_offline)) {
  1066. kstar_mode();
  1067. }
  1068. }
  1069. }
  1070. bool get_sync_data(void)
  1071. {
  1072. return sync_data;
  1073. }
  1074. void akb_time_work_task(void *params)
  1075. {
  1076. static uint32_t tick_prev = 0;
  1077. static uint32_t cnt_sec = 0;
  1078. for (;;) {
  1079. if (UPS.Present == UPS_CONNECTED && ((UPS.Status >> 7) & 0x01)) {
  1080. if (tick_prev == 0) {
  1081. tick_prev = xTaskGetTickCount();
  1082. }
  1083. UPS.akb_work_time += (xTaskGetTickCount() - tick_prev) / 1000;
  1084. tick_prev = xTaskGetTickCount();
  1085. } else {
  1086. tick_prev = 0;
  1087. UPS.akb_work_time = 0;
  1088. }
  1089. if(flag_WPHVR2K0L) {
  1090. cnt_sec ++;
  1091. if (cnt_sec == 3600) {
  1092. cnt_sec = 0;
  1093. int res = ups_metac_service_pdu(ups_test_10sec);
  1094. }
  1095. }
  1096. vTaskDelay(1000);
  1097. }
  1098. }
  1099. void UPSRestoreCallback(TimerHandle_t pxTimer)
  1100. {
  1101. if (UPS.Present == UPS_CONNECTED) {
  1102. while (!megatec_send) {
  1103. vTaskDelay(50);
  1104. }
  1105. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1106. megatec_send = false;
  1107. //UPS.Flag_Present = false;
  1108. send_MegaTec_cmd(ups_remote_turn_on);
  1109. if (ups_megatec_rx_pdu()) {
  1110. ups_megatec_process_pdu(ups_remote_turn_on);
  1111. }
  1112. megatec_send = true;
  1113. }
  1114. }
  1115. void UPSReadTestStatus(void)
  1116. {
  1117. if(sSettings.UPS_Setting.type_ups == ups_kestar
  1118. || sSettings.UPS_Setting.type_ups == ups_offline) {
  1119. return;
  1120. }
  1121. if (UPS.Present == UPS_CONNECTED) {
  1122. while (!megatec_send) {
  1123. vTaskDelay(50);
  1124. }
  1125. memset(ups_pdu.data, 0, UPS_PDU_MAX_LEN);
  1126. megatec_send = false;
  1127. //UPS.Flag_Present = false;
  1128. send_MegaTec_cmd(ups_general_status_req);
  1129. if (ups_megatec_rx_pdu()) {
  1130. ups_megatec_process_pdu(ups_general_status_req);
  1131. }
  1132. megatec_send = true;
  1133. }
  1134. }
  1135. void ups_megatec_init(void)
  1136. {
  1137. init_UPS_value();
  1138. xTaskCreate(request_task, ( char * ) "request_task", configMINIMAL_STACK_SIZE * 3, NULL, tskIDLE_PRIORITY, NULL);
  1139. xTaskCreate(akb_time_work_task, ( char * ) "akb_time_work_task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY,
  1140. NULL);
  1141. UPSRestoreTimer = xTimerCreate("UPSRestoreTmr", configTICK_RATE_HZ*30, pdFALSE, ( void * ) 0, UPSRestoreCallback);
  1142. }