ups_monitor.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  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[20];
  110. memset(str, 0, 20);
  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, 0);
  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. if(CriticalAlarmCurrent){
  149. SetROInt(1, 0);
  150. strcat(str, "Замкнуто");
  151. }
  152. else{
  153. SetROInt(0, 0);
  154. strcat(str, "Разомкнуто");
  155. }
  156. SNMP_SendUserTrap(DO0_TOGGLED);
  157. log_event_data(LOG_DO0_STATE, str);
  158. }
  159. if(OldRO2type_Sourse == CRITICAL){
  160. if(CriticalAlarmCurrent){
  161. SetROInt(1, 0);
  162. strcat(str, "Замкнуто");
  163. }
  164. else{
  165. SetROInt(0, 0);
  166. strcat(str, "Разомкнуто");
  167. }
  168. SNMP_SendUserTrap(DO1_TOGGLED);
  169. log_event_data(LOG_DO1_STATE, str);
  170. }
  171. }
  172. else
  173. {
  174. if(OldRO0type_Sourse == CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  175. if(CriticalAlarmCurrent){
  176. SetROInt(1, 0);
  177. strcat(str, "Замкнуто");
  178. }
  179. else{
  180. SetROInt(0, 0);
  181. strcat(str, "Разомкнуто");
  182. }
  183. SNMP_SendUserTrap(DO0_TOGGLED);
  184. log_event_data(LOG_DO0_STATE, str);
  185. }
  186. if(OldRO2type_Sourse == CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  187. if(CriticalAlarmCurrent){
  188. SetROInt(1, 0);
  189. strcat(str, "Замкнуто");
  190. }
  191. else{
  192. SetROInt(0, 0);
  193. strcat(str, "Разомкнуто");
  194. }
  195. SNMP_SendUserTrap(DO1_TOGGLED);
  196. log_event_data(LOG_DO1_STATE, str);
  197. }
  198. }
  199. OldRO0type_Sourse = CurrRO1type_Sourse;
  200. OldRO2type_Sourse = CurrRO2type_Sourse;
  201. CriticalAlarmOldState = CriticalAlarmCurrent;
  202. }
  203. /**
  204. * @brief Мониторинг бита NonCriticalAlarm
  205. */
  206. void UPS_NonCriticalAlarmMonitor(void)
  207. {
  208. static bool isValueRecv = false;
  209. static uint8_t NonCriticalAlarmOldState = 0;
  210. uint8_t NonCriticalAlarmCurrent;
  211. static uint8_t OldRO0type_Sourse = 0;
  212. static uint8_t OldRO2type_Sourse = 0;
  213. uint8_t CurrRO2type_Sourse = 0;
  214. uint8_t CurrRO1type_Sourse = 0;
  215. char str[20];
  216. memset(str, 0, 20);
  217. CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
  218. CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
  219. NonCriticalAlarmCurrent = flNonCriticalAlarm;
  220. if (!isValueRecv) {
  221. isValueRecv = true;
  222. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  223. OldRO0type_Sourse = CurrRO1type_Sourse;
  224. OldRO2type_Sourse = CurrRO2type_Sourse;
  225. if(OldRO0type_Sourse == NON_CRITICAL){
  226. if(NonCriticalAlarmCurrent){
  227. SetROInt(1, 0);
  228. SNMP_SendUserTrap(DO0_TOGGLED);
  229. log_event_data(LOG_DO0_STATE, "Замкнуто");
  230. }
  231. }
  232. if(OldRO2type_Sourse == NON_CRITICAL){
  233. if(NonCriticalAlarmCurrent){
  234. SetROInt(1, 0);
  235. SNMP_SendUserTrap(DO1_TOGGLED);
  236. log_event_data(LOG_DO1_STATE, "Замкнуто");
  237. }
  238. }
  239. return;
  240. }
  241. // Значение параметра изменилось
  242. if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState)
  243. {
  244. if(OldRO0type_Sourse == NON_CRITICAL){
  245. if(NonCriticalAlarmCurrent){
  246. SetROInt(1, 0);
  247. strcat(str, "Замкнуто");
  248. }
  249. else{
  250. SetROInt(0, 0);
  251. strcat(str, "Разомкнуто");
  252. }
  253. SNMP_SendUserTrap(DO0_TOGGLED);
  254. log_event_data(LOG_DO0_STATE, str);
  255. }
  256. if(OldRO2type_Sourse == NON_CRITICAL){
  257. if(NonCriticalAlarmCurrent){
  258. SetROInt(1, 1);
  259. strcat(str, "Разомкнуто");
  260. }
  261. else{
  262. SetROInt(0, 1);
  263. strcat(str, "Замкнуто");
  264. }
  265. SNMP_SendUserTrap(DO1_TOGGLED);
  266. log_event_data(LOG_DO1_STATE, str);
  267. }
  268. }
  269. else
  270. {
  271. if(OldRO0type_Sourse == NON_CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  272. if(NonCriticalAlarmCurrent){
  273. SetROInt(1, 0);
  274. strcat(str, "Замкнуто");
  275. }
  276. else{
  277. SetROInt(0, 0);
  278. strcat(str, "Разомкнуто");
  279. }
  280. SNMP_SendUserTrap(DO0_TOGGLED);
  281. log_event_data(LOG_DO0_STATE, str);
  282. }
  283. if(OldRO2type_Sourse == NON_CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  284. if(NonCriticalAlarmCurrent){
  285. SetROInt(1, 0);
  286. strcat(str, "Замкнуто");
  287. }
  288. else{
  289. SetROInt(0, 0);
  290. strcat(str, "Разомкнуто");
  291. }
  292. SNMP_SendUserTrap(DO1_TOGGLED);
  293. log_event_data(LOG_DO1_STATE, str);
  294. }
  295. }
  296. OldRO0type_Sourse = CurrRO1type_Sourse;
  297. OldRO2type_Sourse = CurrRO2type_Sourse;
  298. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  299. }
  300. /**
  301. * @brief Мониторинг бита LainFail
  302. */
  303. void UPS_LineFailMonitor(void)
  304. {
  305. static bool isValueRecv = false;
  306. static uint8_t lineFailOldState = 0;
  307. uint8_t lineFailCurrent;
  308. lineFailCurrent = (UPS.Status >> 7) & 0x01;
  309. if (!isValueRecv) {
  310. isValueRecv = true;
  311. lineFailOldState = lineFailCurrent;
  312. if (lineFailCurrent){
  313. log_event_data(LOG_ALARM_LINE, "Авария");
  314. SNMP_SendUserTrap(LINE_ALARM);
  315. }
  316. return;
  317. }
  318. if (lineFailCurrent)
  319. flCriticalAlarm = true;
  320. // Значение параметра изменилось
  321. if (lineFailCurrent != lineFailOldState)
  322. {
  323. if (lineFailCurrent){
  324. log_event_data(LOG_ALARM_LINE, "Авария");
  325. SNMP_SendUserTrap(LINE_ALARM);
  326. }
  327. else{
  328. log_event_data(LOG_ALARM_LINE, "Норма");
  329. SNMP_SendUserTrap(LINE_NORM);
  330. }
  331. }
  332. lineFailOldState = lineFailCurrent;
  333. }
  334. /**
  335. * @brief Мониторинг бита LowBat
  336. */
  337. void UPS_LowBatMonitor(void)
  338. {
  339. static bool isValueRecv = false;
  340. static uint8_t lowBatOldState = 0;
  341. uint8_t lowBatCurrent;
  342. if((UPS.Status >> 7) & 0x01)
  343. lowBatCurrent = (UPS.Status >> 6) & 0x01;
  344. else
  345. lowBatCurrent = 0;
  346. if (!isValueRecv) {
  347. isValueRecv = true;
  348. lowBatOldState = lowBatCurrent;
  349. if (lowBatCurrent){
  350. log_event_data(LOG_ALARM_LOW_BAT, "Авария");
  351. SNMP_SendUserTrap(LOW_BAT_ALARM);
  352. }
  353. return;
  354. }
  355. if (lowBatCurrent)
  356. flNonCriticalAlarm = true;
  357. // Значение параметра изменилось
  358. if (lowBatCurrent != lowBatOldState)
  359. {
  360. if (lowBatCurrent){
  361. SNMP_SendUserTrap(LOW_BAT_ALARM);
  362. log_event_data(LOG_ALARM_LOW_BAT, "Авария");
  363. }
  364. else{
  365. SNMP_SendUserTrap(LOW_BAT_NORM);
  366. log_event_data(LOG_ALARM_LOW_BAT, "Норма");
  367. }
  368. }
  369. lowBatOldState = lowBatCurrent;
  370. }
  371. /**
  372. * @brief Мониторинг нагрузки
  373. */
  374. void UPS_PowerMonitor(void)
  375. {
  376. float load;
  377. static uint8_t stateCurrent = HYST_IDLE;
  378. load = UPS.Load;
  379. /* Отслеживается переход через верхнюю границу */
  380. if (load > UPS_LOAD)
  381. {
  382. flCriticalAlarm = true;
  383. UPS.Alarm = (UPS.Alarm & 0x0e) | (1 << 0);
  384. if (stateCurrent == HYST_IDLE)
  385. {
  386. LED_On(LED_MINOR_R);
  387. LED_On(LED_MINOR_G);
  388. stateCurrent = HYST_UP;
  389. log_event_data(LOG_ALARM_POWER, "Авария");
  390. // Отправка трапа о завышении
  391. SNMP_SendUserTrap(POWER_ALARM);
  392. }
  393. }
  394. /* Отслеживается нормализация */
  395. else if (load < (UPS_LOAD - UPS_LOAD_HIST))
  396. {
  397. UPS.Alarm = (UPS.Alarm & 0x0e);
  398. if (stateCurrent == HYST_UP)
  399. {
  400. LED_Off(LED_MINOR_R);
  401. LED_Off(LED_MINOR_G);
  402. stateCurrent = HYST_IDLE;
  403. log_event_data(LOG_ALARM_POWER, "Норма");
  404. // Отправка трапа о нормализации
  405. SNMP_SendUserTrap(POWER_NORM);
  406. }
  407. }
  408. }
  409. /**
  410. * @brief Мониторинг температуры
  411. */
  412. void UPS_TemperatureMonitor(void)
  413. {
  414. float temperature;
  415. static uint8_t stateCurrent = HYST_IDLE;
  416. temperature = UPS.Temp;
  417. /* Отслеживается переход через верхнюю границу */
  418. if (temperature > UPS_TEMPERATURE)
  419. {
  420. flCriticalAlarm = true;
  421. UPS.Alarm = (UPS.Alarm & 0x0d) | (1 << 1);
  422. if (stateCurrent == HYST_IDLE)
  423. {
  424. stateCurrent = HYST_UP;
  425. log_event_data(LOG_ALARM_TEMP, "Авария");
  426. // Отправка трапа о завышении
  427. SNMP_SendUserTrap(BATTERY_TEMPERATURE_ALARM);
  428. }
  429. }
  430. /* Отслеживается нормализация */
  431. else if (temperature < (UPS_TEMPERATURE - UPS_TEMPERATURE_HIST))
  432. {
  433. UPS.Alarm = (UPS.Alarm & 0x0d);
  434. if (stateCurrent == HYST_UP)
  435. {
  436. stateCurrent = HYST_IDLE;
  437. log_event_data(LOG_ALARM_TEMP, "Норма");
  438. // Отправка трапа о нормализации
  439. SNMP_SendUserTrap(BATTERY_TEMPERATURE_NORM);
  440. }
  441. }
  442. }
  443. /**
  444. * @brief Мониторинг параметра upsParams.connect
  445. */
  446. void UPS_ConnectMonitor(void)
  447. {
  448. static bool isValueRecv = false;
  449. static uint8_t connectOldState = 0;
  450. uint8_t connectCurrent;
  451. connectCurrent = UPS.Present;
  452. UPS.Alarm = (UPS.Alarm & 0x0b) | ((connectCurrent^1) << 2);
  453. if (!isValueRecv) {
  454. isValueRecv = true;
  455. connectOldState = connectCurrent;
  456. if (!connectCurrent){
  457. log_event_data(LOG_ALARM_UPS, "Авария");
  458. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  459. }
  460. return;
  461. }
  462. if (!connectCurrent)
  463. flCriticalAlarm = true;
  464. // Значение параметра изменилось
  465. if (connectCurrent != connectOldState)
  466. {
  467. if (connectCurrent){
  468. log_event_data(LOG_ALARM_UPS, "Норма");
  469. SNMP_SendUserTrap(CONNECT_MONITOR_NORM);
  470. }
  471. else{
  472. log_event_data(LOG_ALARM_UPS, "Авария");
  473. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  474. }
  475. }
  476. connectOldState = connectCurrent;
  477. }
  478. /**
  479. * @brief Мониторинг параметра upsParams.connect
  480. */
  481. void UPS_BatteryConnectMonitor(void)
  482. {
  483. static bool isValueRecv = false;
  484. static uint8_t AKBconnectOldState = 0;
  485. uint8_t AKBconnectCurrent;
  486. if(((UPS.Status >> 7) & 0x01) == 0)
  487. AKBconnectCurrent = (UPS.Status >> 6) & 0x01;
  488. else{
  489. AKBconnectCurrent = 0;
  490. }
  491. UPS.Alarm = (UPS.Alarm & 0x07) | (AKBconnectCurrent << 3);
  492. if (!isValueRecv) {
  493. isValueRecv = true;
  494. AKBconnectOldState = AKBconnectCurrent;
  495. if (AKBconnectCurrent){
  496. log_event_data(LOG_ALARM_AKB, "Авария");
  497. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  498. }
  499. return;
  500. }
  501. if (AKBconnectCurrent)
  502. flCriticalAlarm = true;
  503. // Значение параметра изменилось
  504. if (AKBconnectCurrent != AKBconnectOldState)
  505. {
  506. if (!AKBconnectCurrent){
  507. log_event_data(LOG_ALARM_AKB, "Норма");
  508. SNMP_SendUserTrap(BATTERY_CONNECT_NORM);
  509. }
  510. else{
  511. log_event_data(LOG_ALARM_AKB, "Авария");
  512. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  513. }
  514. }
  515. AKBconnectOldState = AKBconnectCurrent;
  516. }
  517. /********************************* (C) РОТЕК **********************************/