ups_monitor.c 15 KB

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