ups_monitor.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /********************************* (C) РОТЕК ***********************************
  2. * @module ups_monitor
  3. * @file ups_monitor.c
  4. * @version 1.0.0
  5. * @date XX.XX.XXXX
  6. * $brief Template
  7. *******************************************************************************
  8. * @history Version Author Comment
  9. * XX.XX.XXXX 1.0.0 Telenkov D.A. First release.
  10. *******************************************************************************
  11. */
  12. #include "stm32f4xx.h"
  13. #include "ups_monitor.h"
  14. #include "parameters.h"
  15. #include "settings_api.h"
  16. #include "megatec.h"
  17. #include "led.h"
  18. #include "log.h"
  19. #include "FreeRTOS.h"
  20. #include "task.h"
  21. #include "trap_api.h"
  22. #include "snmp_api.h"
  23. #include <stdbool.h>
  24. #define UPS_LOAD 70.0 // Нагрука (граница)
  25. #define UPS_LOAD_HIST 1.0 // Гистерезис нагрузки
  26. #define UPS_TEMPERATURE 40.0 // Температура (граница)
  27. #define UPS_TEMPERATURE_HIST 1.0 // Гистерезис температуры
  28. bool flCriticalAlarm = false;
  29. bool flNonCriticalAlarm = false;
  30. /**
  31. * @brief Общая структура настроек
  32. */
  33. extern SETTINGS_t sSettings;
  34. extern bool flUpdateLog;
  35. /**
  36. * @brief Задача мониторинга параметров UPS
  37. */
  38. void UPS_Monitor(void *params)
  39. {
  40. vTaskDelay(5000);
  41. for (;;)
  42. {
  43. flCriticalAlarm = false;
  44. flNonCriticalAlarm = false;
  45. // Проверяем флаг подключения UPS
  46. if (UPS.Present)
  47. {
  48. UPS_LineFailMonitor();
  49. UPS_LowBatMonitor();
  50. UPS_PowerMonitor();
  51. UPS_TemperatureMonitor();
  52. UPS_BatteryConnectMonitor();
  53. }
  54. UPS_ConnectMonitor();
  55. UPS_DI0Monitor();
  56. UPS_CriticalAlarmMonitor();
  57. UPS_NonCriticalAlarmMonitor();
  58. vTaskDelay(1000);
  59. }
  60. }
  61. /**
  62. * @brief Мониторинг бита DI0 state
  63. */
  64. void UPS_DI0Monitor(void)
  65. {
  66. static bool isValueRecv = false;
  67. static uint8_t DI0OldState = 0;
  68. uint8_t DI0StateCurrent;
  69. DI0StateCurrent = get_state_din_outs(DIN1);
  70. if (!isValueRecv) {
  71. isValueRecv = true;
  72. DI0OldState = DI0StateCurrent;
  73. if (!DI0StateCurrent){
  74. log_event_data(LOG_ALARM_DIO, "Авария");
  75. SNMP_SendUserTrap(DI0_ALARM);
  76. flUpdateLog = true;
  77. }
  78. return;
  79. }
  80. if (!DI0StateCurrent)
  81. flCriticalAlarm = true;
  82. // Значение параметра изменилось
  83. if (DI0StateCurrent != DI0OldState)
  84. {
  85. if(sSettings.sInOuts.din_type_act[0] == SNMP_TRAP)
  86. {
  87. if (DI0StateCurrent){
  88. log_event_data(LOG_ALARM_DIO, "Норма");
  89. SNMP_SendUserTrap(DI0_NORM);
  90. flUpdateLog = true;
  91. }
  92. else{
  93. log_event_data(LOG_ALARM_DIO, "Авария");
  94. SNMP_SendUserTrap(DI0_ALARM);
  95. flUpdateLog = true;
  96. }
  97. }
  98. }
  99. DI0OldState = DI0StateCurrent;
  100. }
  101. /**
  102. * @brief Мониторинг бита CriticalAlarm
  103. */
  104. void UPS_CriticalAlarmMonitor(void)
  105. {
  106. static bool isValueRecv = false;
  107. static uint8_t CriticalAlarmOldState = 0;
  108. uint8_t CriticalAlarmCurrent;
  109. static uint8_t OldRO0type_Sourse = 0;
  110. static uint8_t OldRO2type_Sourse = 0;
  111. uint8_t CurrRO2type_Sourse = 0;
  112. uint8_t CurrRO1type_Sourse = 0;
  113. char str[30];
  114. memset(str, 0, 30);
  115. CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
  116. CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
  117. CriticalAlarmCurrent = flCriticalAlarm;
  118. if (!isValueRecv) {
  119. isValueRecv = true;
  120. CriticalAlarmOldState = CriticalAlarmCurrent;
  121. OldRO0type_Sourse = CurrRO1type_Sourse;
  122. OldRO2type_Sourse = CurrRO2type_Sourse;
  123. if(OldRO0type_Sourse == CRITICAL){
  124. if(CriticalAlarmCurrent){
  125. SetROInt(1, 0);
  126. SNMP_SendUserTrap(DO0_TOGGLED);
  127. log_event_data(LOG_DO0_STATE, "Замкнуто");
  128. }
  129. }
  130. if(OldRO2type_Sourse == CRITICAL){
  131. if(CriticalAlarmCurrent){
  132. SetROInt(1, 1);
  133. SNMP_SendUserTrap(DO1_TOGGLED);
  134. log_event_data(LOG_DO1_STATE, "Замкнуто");
  135. }
  136. }
  137. return;
  138. }
  139. if(CriticalAlarmCurrent){
  140. if (UPS.Present)
  141. LED_Toggle(LED_MAJOR_R);
  142. else
  143. LED_On(LED_MAJOR_R);
  144. }
  145. else{
  146. LED_Off(LED_MAJOR_R);
  147. }
  148. // Значение параметра изменилось
  149. if (CriticalAlarmCurrent != CriticalAlarmOldState)
  150. {
  151. if(OldRO0type_Sourse == CRITICAL){
  152. memset(str, 0, 30);
  153. if(CriticalAlarmCurrent){
  154. SetROInt(1, 0);
  155. strcat(str, "Замкнуто");
  156. }
  157. else{
  158. SetROInt(0, 0);
  159. strcat(str, "Разомкнуто");
  160. }
  161. SNMP_SendUserTrap(DO0_TOGGLED);
  162. log_event_data(LOG_DO0_STATE, str);
  163. }
  164. if(OldRO2type_Sourse == CRITICAL){
  165. memset(str, 0, 30);
  166. if(CriticalAlarmCurrent){
  167. SetROInt(1, 1);
  168. strcat(str, "Замкнуто");
  169. }
  170. else{
  171. SetROInt(0, 1);
  172. strcat(str, "Разомкнуто");
  173. }
  174. SNMP_SendUserTrap(DO1_TOGGLED);
  175. log_event_data(LOG_DO1_STATE, str);
  176. }
  177. }
  178. else
  179. {
  180. if(OldRO0type_Sourse == CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  181. memset(str, 0, 30);
  182. if(CriticalAlarmCurrent){
  183. SetROInt(1, 0);
  184. strcat(str, "Замкнуто");
  185. }
  186. else{
  187. SetROInt(0, 0);
  188. strcat(str, "Разомкнуто");
  189. }
  190. SNMP_SendUserTrap(DO0_TOGGLED);
  191. log_event_data(LOG_DO0_STATE, str);
  192. }
  193. if(OldRO2type_Sourse == CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  194. memset(str, 0, 30);
  195. if(CriticalAlarmCurrent){
  196. SetROInt(1, 1);
  197. strcat(str, "Замкнуто");
  198. }
  199. else{
  200. SetROInt(0, 1);
  201. strcat(str, "Разомкнуто");
  202. }
  203. SNMP_SendUserTrap(DO1_TOGGLED);
  204. log_event_data(LOG_DO1_STATE, str);
  205. }
  206. }
  207. OldRO0type_Sourse = CurrRO1type_Sourse;
  208. OldRO2type_Sourse = CurrRO2type_Sourse;
  209. CriticalAlarmOldState = CriticalAlarmCurrent;
  210. }
  211. /**
  212. * @brief Мониторинг бита NonCriticalAlarm
  213. */
  214. void UPS_NonCriticalAlarmMonitor(void)
  215. {
  216. static bool isValueRecv = false;
  217. static uint8_t NonCriticalAlarmOldState = 0;
  218. uint8_t NonCriticalAlarmCurrent;
  219. static uint8_t OldRO0type_Sourse = 0;
  220. static uint8_t OldRO2type_Sourse = 0;
  221. uint8_t CurrRO2type_Sourse = 0;
  222. uint8_t CurrRO1type_Sourse = 0;
  223. char str[30];
  224. memset(str, 0, 30);
  225. CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
  226. CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
  227. NonCriticalAlarmCurrent = flNonCriticalAlarm;
  228. if (!isValueRecv) {
  229. isValueRecv = true;
  230. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  231. OldRO0type_Sourse = CurrRO1type_Sourse;
  232. OldRO2type_Sourse = CurrRO2type_Sourse;
  233. if(OldRO0type_Sourse == NON_CRITICAL){
  234. if(NonCriticalAlarmCurrent){
  235. SetROInt(1, 0);
  236. SNMP_SendUserTrap(DO0_TOGGLED);
  237. log_event_data(LOG_DO0_STATE, "Замкнуто");
  238. }
  239. }
  240. if(OldRO2type_Sourse == NON_CRITICAL){
  241. if(NonCriticalAlarmCurrent){
  242. SetROInt(1, 1);
  243. SNMP_SendUserTrap(DO1_TOGGLED);
  244. log_event_data(LOG_DO1_STATE, "Замкнуто");
  245. }
  246. }
  247. return;
  248. }
  249. // Значение параметра изменилось
  250. if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState)
  251. {
  252. if(OldRO0type_Sourse == NON_CRITICAL){
  253. memset(str, 0, 30);
  254. if(NonCriticalAlarmCurrent){
  255. SetROInt(1, 0);
  256. strcat(str, "Замкнуто");
  257. }
  258. else{
  259. SetROInt(0, 0);
  260. strcat(str, "Разомкнуто");
  261. }
  262. SNMP_SendUserTrap(DO0_TOGGLED);
  263. log_event_data(LOG_DO0_STATE, str);
  264. }
  265. if(OldRO2type_Sourse == NON_CRITICAL){
  266. memset(str, 0, 30);
  267. if(NonCriticalAlarmCurrent){
  268. SetROInt(1, 1);
  269. strcat(str, "Разомкнуто");
  270. }
  271. else{
  272. SetROInt(0, 1);
  273. strcat(str, "Замкнуто");
  274. }
  275. SNMP_SendUserTrap(DO1_TOGGLED);
  276. log_event_data(LOG_DO1_STATE, str);
  277. }
  278. }
  279. else
  280. {
  281. if(OldRO0type_Sourse == NON_CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  282. memset(str, 0, 30);
  283. if(NonCriticalAlarmCurrent){
  284. SetROInt(1, 0);
  285. strcat(str, "Замкнуто");
  286. }
  287. else{
  288. SetROInt(0, 0);
  289. strcat(str, "Разомкнуто");
  290. }
  291. SNMP_SendUserTrap(DO0_TOGGLED);
  292. log_event_data(LOG_DO0_STATE, str);
  293. }
  294. if(OldRO2type_Sourse == NON_CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  295. memset(str, 0, 30);
  296. if(NonCriticalAlarmCurrent){
  297. SetROInt(1, 1);
  298. strcat(str, "Замкнуто");
  299. }
  300. else{
  301. SetROInt(0, 1);
  302. strcat(str, "Разомкнуто");
  303. }
  304. SNMP_SendUserTrap(DO1_TOGGLED);
  305. log_event_data(LOG_DO1_STATE, str);
  306. }
  307. }
  308. OldRO0type_Sourse = CurrRO1type_Sourse;
  309. OldRO2type_Sourse = CurrRO2type_Sourse;
  310. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  311. }
  312. /**
  313. * @brief Мониторинг бита LainFail
  314. */
  315. void UPS_LineFailMonitor(void)
  316. {
  317. static bool isValueRecv = false;
  318. static uint8_t lineFailOldState = 0;
  319. uint8_t lineFailCurrent;
  320. lineFailCurrent = (UPS.Status >> 7) & 0x01;
  321. if (!isValueRecv) {
  322. isValueRecv = true;
  323. lineFailOldState = lineFailCurrent;
  324. if (lineFailCurrent){
  325. log_event_data(LOG_ALARM_LINE, "Авария");
  326. SNMP_SendUserTrap(LINE_ALARM);
  327. flUpdateLog = true;
  328. }
  329. return;
  330. }
  331. if (lineFailCurrent)
  332. flCriticalAlarm = true;
  333. // Значение параметра изменилось
  334. if (lineFailCurrent != lineFailOldState)
  335. {
  336. if (lineFailCurrent){
  337. log_event_data(LOG_ALARM_LINE, "Авария");
  338. SNMP_SendUserTrap(LINE_ALARM);
  339. flUpdateLog = true;
  340. }
  341. else{
  342. log_event_data(LOG_ALARM_LINE, "Норма");
  343. SNMP_SendUserTrap(LINE_NORM);
  344. flUpdateLog = true;
  345. }
  346. }
  347. lineFailOldState = lineFailCurrent;
  348. }
  349. /**
  350. * @brief Мониторинг бита LowBat
  351. */
  352. void UPS_LowBatMonitor(void)
  353. {
  354. static bool isValueRecv = false;
  355. static uint8_t lowBatOldState = 0;
  356. uint8_t lowBatCurrent;
  357. if((UPS.Status >> 7) & 0x01)
  358. lowBatCurrent = (UPS.Status >> 6) & 0x01;
  359. else
  360. lowBatCurrent = 0;
  361. if (!isValueRecv) {
  362. isValueRecv = true;
  363. lowBatOldState = lowBatCurrent;
  364. if (lowBatCurrent){
  365. log_event_data(LOG_ALARM_LOW_BAT, "Авария");
  366. SNMP_SendUserTrap(LOW_BAT_ALARM);
  367. flUpdateLog = true;
  368. }
  369. return;
  370. }
  371. if (lowBatCurrent)
  372. flNonCriticalAlarm = true;
  373. // Значение параметра изменилось
  374. if (lowBatCurrent != lowBatOldState)
  375. {
  376. if (lowBatCurrent){
  377. SNMP_SendUserTrap(LOW_BAT_ALARM);
  378. log_event_data(LOG_ALARM_LOW_BAT, "Авария");
  379. flUpdateLog = true;
  380. }
  381. else{
  382. SNMP_SendUserTrap(LOW_BAT_NORM);
  383. log_event_data(LOG_ALARM_LOW_BAT, "Норма");
  384. flUpdateLog = true;
  385. }
  386. }
  387. lowBatOldState = lowBatCurrent;
  388. }
  389. /**
  390. * @brief Мониторинг нагрузки
  391. */
  392. void UPS_PowerMonitor(void)
  393. {
  394. float load;
  395. static uint8_t stateCurrent = HYST_IDLE;
  396. load = UPS.Load;
  397. /* Отслеживается переход через верхнюю границу */
  398. if (load > UPS_LOAD)
  399. {
  400. flCriticalAlarm = true;
  401. UPS.Alarm = (UPS.Alarm & 0x0e) | (1 << 0);
  402. if (stateCurrent == HYST_IDLE)
  403. {
  404. LED_On(LED_MINOR_R);
  405. LED_On(LED_MINOR_G);
  406. stateCurrent = HYST_UP;
  407. log_event_data(LOG_ALARM_POWER, "Авария");
  408. // Отправка трапа о завышении
  409. SNMP_SendUserTrap(POWER_ALARM);
  410. flUpdateLog = true;
  411. }
  412. }
  413. /* Отслеживается нормализация */
  414. else if (load < (UPS_LOAD - UPS_LOAD_HIST))
  415. {
  416. UPS.Alarm = (UPS.Alarm & 0x0e);
  417. if (stateCurrent == HYST_UP)
  418. {
  419. LED_Off(LED_MINOR_R);
  420. LED_Off(LED_MINOR_G);
  421. stateCurrent = HYST_IDLE;
  422. log_event_data(LOG_ALARM_POWER, "Норма");
  423. // Отправка трапа о нормализации
  424. SNMP_SendUserTrap(POWER_NORM);
  425. flUpdateLog = true;
  426. }
  427. }
  428. }
  429. /**
  430. * @brief Мониторинг температуры
  431. */
  432. void UPS_TemperatureMonitor(void)
  433. {
  434. float temperature;
  435. static uint8_t stateCurrent = HYST_IDLE;
  436. temperature = UPS.Temp;
  437. /* Отслеживается переход через верхнюю границу */
  438. if (temperature > UPS_TEMPERATURE)
  439. {
  440. flCriticalAlarm = true;
  441. UPS.Alarm = (UPS.Alarm & 0x0d) | (1 << 1);
  442. if (stateCurrent == HYST_IDLE)
  443. {
  444. stateCurrent = HYST_UP;
  445. log_event_data(LOG_ALARM_TEMP, "Авария");
  446. // Отправка трапа о завышении
  447. SNMP_SendUserTrap(BATTERY_TEMPERATURE_ALARM);
  448. flUpdateLog = true;
  449. }
  450. }
  451. /* Отслеживается нормализация */
  452. else if (temperature < (UPS_TEMPERATURE - UPS_TEMPERATURE_HIST))
  453. {
  454. UPS.Alarm = (UPS.Alarm & 0x0d);
  455. if (stateCurrent == HYST_UP)
  456. {
  457. stateCurrent = HYST_IDLE;
  458. log_event_data(LOG_ALARM_TEMP, "Норма");
  459. // Отправка трапа о нормализации
  460. SNMP_SendUserTrap(BATTERY_TEMPERATURE_NORM);
  461. flUpdateLog = true;
  462. }
  463. }
  464. }
  465. /**
  466. * @brief Мониторинг параметра upsParams.connect
  467. */
  468. void UPS_ConnectMonitor(void)
  469. {
  470. static bool isValueRecv = false;
  471. static uint8_t connectOldState = 0;
  472. uint8_t connectCurrent;
  473. connectCurrent = UPS.Present;
  474. UPS.Alarm = (UPS.Alarm & 0x0b) | ((connectCurrent^1) << 2);
  475. if (!isValueRecv) {
  476. isValueRecv = true;
  477. connectOldState = connectCurrent;
  478. if (!connectCurrent){
  479. log_event_data(LOG_ALARM_UPS, "Авария");
  480. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  481. flUpdateLog = true;
  482. }
  483. return;
  484. }
  485. if (!connectCurrent)
  486. flCriticalAlarm = true;
  487. // Значение параметра изменилось
  488. if (connectCurrent != connectOldState)
  489. {
  490. if (connectCurrent){
  491. log_event_data(LOG_ALARM_UPS, "Норма");
  492. SNMP_SendUserTrap(CONNECT_MONITOR_NORM);
  493. flUpdateLog = true;
  494. }
  495. else{
  496. log_event_data(LOG_ALARM_UPS, "Авария");
  497. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  498. flUpdateLog = true;
  499. }
  500. }
  501. connectOldState = connectCurrent;
  502. }
  503. /**
  504. * @brief Мониторинг параметра upsParams.connect
  505. */
  506. void UPS_BatteryConnectMonitor(void)
  507. {
  508. static bool isValueRecv = false;
  509. static uint8_t AKBconnectOldState = 0;
  510. uint8_t AKBconnectCurrent;
  511. if(((UPS.Status >> 7) & 0x01) == 0)
  512. AKBconnectCurrent = (UPS.Status >> 6) & 0x01;
  513. else{
  514. AKBconnectCurrent = 0;
  515. }
  516. UPS.Alarm = (UPS.Alarm & 0x07) | (AKBconnectCurrent << 3);
  517. if (!isValueRecv) {
  518. isValueRecv = true;
  519. AKBconnectOldState = AKBconnectCurrent;
  520. if (AKBconnectCurrent){
  521. log_event_data(LOG_ALARM_AKB, "Авария");
  522. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  523. flUpdateLog = true;
  524. }
  525. return;
  526. }
  527. if (AKBconnectCurrent)
  528. flCriticalAlarm = true;
  529. // Значение параметра изменилось
  530. if (AKBconnectCurrent != AKBconnectOldState)
  531. {
  532. if (!AKBconnectCurrent){
  533. log_event_data(LOG_ALARM_AKB, "Норма");
  534. SNMP_SendUserTrap(BATTERY_CONNECT_NORM);
  535. flUpdateLog = true;
  536. }
  537. else{
  538. log_event_data(LOG_ALARM_AKB, "Авария");
  539. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  540. flUpdateLog = true;
  541. }
  542. }
  543. AKBconnectOldState = AKBconnectCurrent;
  544. }
  545. /********************************* (C) РОТЕК **********************************/