ups_monitor.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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 "FreeRTOS.h"
  19. #include "task.h"
  20. #include "trap_api.h"
  21. #include "snmp_api.h"
  22. #include <stdbool.h>
  23. #define UPS_LOAD 70.0 // Нагрука (граница)
  24. #define UPS_LOAD_HIST 1.0 // Гистерезис нагрузки
  25. #define UPS_TEMPERATURE 40.0 // Температура (граница)
  26. #define UPS_TEMPERATURE_HIST 1.0 // Гистерезис температуры
  27. bool flCriticalAlarm = false;
  28. bool flNonCriticalAlarm = false;
  29. /**
  30. * @brief Общая структура настроек
  31. */
  32. extern SETTINGS_t sSettings;
  33. /**
  34. * @brief Задача мониторинга параметров UPS
  35. */
  36. void UPS_Monitor(void *params)
  37. {
  38. for (;;)
  39. {
  40. flCriticalAlarm = false;
  41. flNonCriticalAlarm = false;
  42. // Проверяем флаг подключения UPS
  43. //if (UPS.Present)
  44. {
  45. UPS_LineFailMonitor();
  46. UPS_LowBatMonitor();
  47. UPS_PowerMonitor();
  48. UPS_TemperatureMonitor();
  49. UPS_BatteryConnectMonitor();
  50. }
  51. UPS_ConnectMonitor();
  52. UPS_DI0Monitor();
  53. UPS_CriticalAlarmMonitor();
  54. UPS_NonCriticalAlarmMonitor();
  55. vTaskDelay(1000);
  56. }
  57. }
  58. /**
  59. * @brief Мониторинг бита DI0 state
  60. */
  61. void UPS_DI0Monitor(void)
  62. {
  63. static bool isValueRecv = false;
  64. static uint8_t DI0OldState = 0;
  65. uint8_t DI0StateCurrent;
  66. DI0StateCurrent = get_state_din_outs(DIN1);
  67. if (!isValueRecv) {
  68. isValueRecv = true;
  69. DI0OldState = DI0StateCurrent;
  70. return;
  71. }
  72. if (!DI0StateCurrent)
  73. flCriticalAlarm = true;
  74. // Значение параметра изменилось
  75. if (DI0StateCurrent != DI0OldState)
  76. {
  77. if(sSettings.sInOuts.din_type_act[0] == SNMP_TRAP)
  78. {
  79. if (!DI0StateCurrent)
  80. SNMP_SendUserTrap(DI0_NORM);
  81. else
  82. SNMP_SendUserTrap(DI0_ALARM);
  83. }
  84. }
  85. DI0OldState = DI0StateCurrent;
  86. }
  87. /**
  88. * @brief Мониторинг бита CriticalAlarm
  89. */
  90. void UPS_CriticalAlarmMonitor(void)
  91. {
  92. static bool isValueRecv = false;
  93. static uint8_t CriticalAlarmOldState = 0;
  94. uint8_t CriticalAlarmCurrent;
  95. static uint8_t OldRO0type_Sourse = 0;
  96. static uint8_t OldRO2type_Sourse = 0;
  97. uint8_t CurrRO2type_Sourse = 0;
  98. uint8_t CurrRO1type_Sourse = 0;
  99. CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
  100. CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
  101. CriticalAlarmCurrent = flCriticalAlarm;
  102. if (!isValueRecv) {
  103. isValueRecv = true;
  104. CriticalAlarmOldState = CriticalAlarmCurrent;
  105. OldRO0type_Sourse = CurrRO1type_Sourse;
  106. OldRO2type_Sourse = CurrRO2type_Sourse;
  107. return;
  108. }
  109. if(CriticalAlarmCurrent){
  110. if (UPS.Present)
  111. LED_Toggle(LED_MAJOR_R);
  112. else
  113. LED_On(LED_MAJOR_R);
  114. }
  115. else{
  116. LED_Off(LED_MAJOR_R);
  117. }
  118. // Значение параметра изменилось
  119. if (CriticalAlarmCurrent != CriticalAlarmOldState)
  120. {
  121. if(OldRO0type_Sourse == CRITICAL){
  122. if(CriticalAlarmCurrent)
  123. SetROInt(1, 0);
  124. else
  125. SetROInt(0, 0);
  126. SNMP_SendUserTrap(DO0_TOGGLED);
  127. }
  128. if(OldRO2type_Sourse == CRITICAL){
  129. if(CriticalAlarmCurrent)
  130. SetROInt(1, 1);
  131. else
  132. SetROInt(0, 1);
  133. SNMP_SendUserTrap(DO1_TOGGLED);
  134. }
  135. }
  136. else
  137. {
  138. if(OldRO0type_Sourse == CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  139. if(CriticalAlarmCurrent)
  140. SetROInt(1, 0);
  141. else
  142. SetROInt(0, 0);
  143. SNMP_SendUserTrap(DO0_TOGGLED);
  144. }
  145. if(OldRO2type_Sourse == CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  146. if(CriticalAlarmCurrent)
  147. SetROInt(1, 1);
  148. else
  149. SetROInt(0, 1);
  150. SNMP_SendUserTrap(DO1_TOGGLED);
  151. }
  152. }
  153. OldRO0type_Sourse = CurrRO1type_Sourse;
  154. OldRO2type_Sourse = CurrRO2type_Sourse;
  155. CriticalAlarmOldState = CriticalAlarmCurrent;
  156. }
  157. /**
  158. * @brief Мониторинг бита NonCriticalAlarm
  159. */
  160. void UPS_NonCriticalAlarmMonitor(void)
  161. {
  162. static bool isValueRecv = false;
  163. static uint8_t NonCriticalAlarmOldState = 0;
  164. uint8_t NonCriticalAlarmCurrent;
  165. static uint8_t OldRO0type_Sourse = 0;
  166. static uint8_t OldRO2type_Sourse = 0;
  167. uint8_t CurrRO2type_Sourse = 0;
  168. uint8_t CurrRO1type_Sourse = 0;
  169. CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
  170. CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
  171. NonCriticalAlarmCurrent = flNonCriticalAlarm;
  172. if (!isValueRecv) {
  173. isValueRecv = true;
  174. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  175. OldRO0type_Sourse = CurrRO1type_Sourse;
  176. OldRO2type_Sourse = CurrRO2type_Sourse;
  177. return;
  178. }
  179. // Значение параметра изменилось
  180. if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState)
  181. {
  182. if(OldRO0type_Sourse == NON_CRITICAL){
  183. if(NonCriticalAlarmCurrent)
  184. SetROInt(1, 0);
  185. else
  186. SetROInt(0, 0);
  187. SNMP_SendUserTrap(DO0_TOGGLED);
  188. }
  189. if(OldRO2type_Sourse == NON_CRITICAL){
  190. if(NonCriticalAlarmCurrent)
  191. SetROInt(1, 1);
  192. else
  193. SetROInt(0, 1);
  194. SNMP_SendUserTrap(DO1_TOGGLED);
  195. }
  196. }
  197. else
  198. {
  199. if(OldRO0type_Sourse == NON_CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
  200. if(NonCriticalAlarmCurrent)
  201. SetROInt(1, 0);
  202. else
  203. SetROInt(0, 0);
  204. SNMP_SendUserTrap(DO0_TOGGLED);
  205. }
  206. if(OldRO2type_Sourse == NON_CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
  207. if(NonCriticalAlarmCurrent)
  208. SetROInt(1, 1);
  209. else
  210. SetROInt(0, 1);
  211. SNMP_SendUserTrap(DO1_TOGGLED);
  212. }
  213. }
  214. OldRO0type_Sourse = CurrRO1type_Sourse;
  215. OldRO2type_Sourse = CurrRO2type_Sourse;
  216. NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
  217. }
  218. /**
  219. * @brief Мониторинг бита LainFail
  220. */
  221. void UPS_LineFailMonitor(void)
  222. {
  223. static bool isValueRecv = false;
  224. static uint8_t lineFailOldState = 0;
  225. uint8_t lineFailCurrent;
  226. lineFailCurrent = (UPS.Status >> 7) & 0x01;
  227. if (!isValueRecv) {
  228. isValueRecv = true;
  229. lineFailOldState = lineFailCurrent;
  230. if (lineFailCurrent)
  231. SNMP_SendUserTrap(LINE_ALARM);
  232. return;
  233. }
  234. if (lineFailCurrent)
  235. flCriticalAlarm = true;
  236. // Значение параметра изменилось
  237. if (lineFailCurrent != lineFailOldState)
  238. {
  239. if (lineFailCurrent)
  240. SNMP_SendUserTrap(LINE_ALARM);
  241. else
  242. SNMP_SendUserTrap(LINE_NORM);
  243. }
  244. lineFailOldState = lineFailCurrent;
  245. }
  246. /**
  247. * @brief Мониторинг бита LowBat
  248. */
  249. void UPS_LowBatMonitor(void)
  250. {
  251. static bool isValueRecv = false;
  252. static uint8_t lowBatOldState = 0;
  253. uint8_t lowBatCurrent;
  254. if((UPS.Status >> 7) & 0x01)
  255. lowBatCurrent = (UPS.Status >> 6) & 0x01;
  256. else
  257. lowBatCurrent = 0;
  258. if (!isValueRecv) {
  259. isValueRecv = true;
  260. lowBatOldState = lowBatCurrent;
  261. if (lowBatCurrent)
  262. SNMP_SendUserTrap(LOW_BAT_ALARM);
  263. return;
  264. }
  265. if (lowBatCurrent)
  266. flNonCriticalAlarm = true;
  267. // Значение параметра изменилось
  268. if (lowBatCurrent != lowBatOldState)
  269. {
  270. if (lowBatCurrent)
  271. SNMP_SendUserTrap(LOW_BAT_ALARM);
  272. else
  273. SNMP_SendUserTrap(LOW_BAT_NORM);
  274. }
  275. lowBatOldState = lowBatCurrent;
  276. }
  277. /**
  278. * @brief Мониторинг нагрузки
  279. */
  280. void UPS_PowerMonitor(void)
  281. {
  282. float load;
  283. static uint8_t stateCurrent = HYST_IDLE;
  284. load = UPS.Load;
  285. /* Отслеживается переход через верхнюю границу */
  286. if (load > UPS_LOAD)
  287. {
  288. flCriticalAlarm = true;
  289. UPS.Alarm = (UPS.Alarm & 0x0e) | (1 << 0);
  290. if (stateCurrent == HYST_IDLE)
  291. {
  292. LED_On(LED_MINOR_R);
  293. LED_On(LED_MINOR_G);
  294. stateCurrent = HYST_UP;
  295. // Отправка трапа о завышении
  296. SNMP_SendUserTrap(POWER_ALARM);
  297. }
  298. }
  299. /* Отслеживается нормализация */
  300. else if (load < (UPS_LOAD - UPS_LOAD_HIST))
  301. {
  302. UPS.Alarm = (UPS.Alarm & 0x0e);
  303. if (stateCurrent == HYST_UP)
  304. {
  305. LED_Off(LED_MINOR_R);
  306. LED_Off(LED_MINOR_G);
  307. stateCurrent = HYST_IDLE;
  308. // Отправка трапа о нормализации
  309. SNMP_SendUserTrap(POWER_NORM);
  310. }
  311. }
  312. }
  313. /**
  314. * @brief Мониторинг температуры
  315. */
  316. void UPS_TemperatureMonitor(void)
  317. {
  318. float temperature;
  319. static uint8_t stateCurrent = HYST_IDLE;
  320. temperature = UPS.Temp;
  321. /* Отслеживается переход через верхнюю границу */
  322. if (temperature > UPS_TEMPERATURE)
  323. {
  324. flCriticalAlarm = true;
  325. UPS.Alarm = (UPS.Alarm & 0x0d) | (1 << 1);
  326. if (stateCurrent == HYST_IDLE)
  327. {
  328. stateCurrent = HYST_UP;
  329. // Отправка трапа о завышении
  330. SNMP_SendUserTrap(BATTERY_TEMPERATURE_ALARM);
  331. }
  332. }
  333. /* Отслеживается нормализация */
  334. else if (temperature < (UPS_TEMPERATURE - UPS_TEMPERATURE_HIST))
  335. {
  336. UPS.Alarm = (UPS.Alarm & 0x0d);
  337. if (stateCurrent == HYST_UP)
  338. {
  339. stateCurrent = HYST_IDLE;
  340. // Отправка трапа о нормализации
  341. SNMP_SendUserTrap(BATTERY_TEMPERATURE_NORM);
  342. }
  343. }
  344. }
  345. /**
  346. * @brief Мониторинг параметра upsParams.connect
  347. */
  348. void UPS_ConnectMonitor(void)
  349. {
  350. static bool isValueRecv = false;
  351. static uint8_t connectOldState = 0;
  352. uint8_t connectCurrent;
  353. connectCurrent = UPS.Present;
  354. UPS.Alarm = (UPS.Alarm & 0x0b) | ((connectCurrent^1) << 2);
  355. if (!isValueRecv) {
  356. isValueRecv = true;
  357. connectOldState = connectCurrent;
  358. if (!connectCurrent)
  359. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  360. return;
  361. }
  362. if (!connectCurrent)
  363. flCriticalAlarm = true;
  364. // Значение параметра изменилось
  365. if (connectCurrent != connectOldState)
  366. {
  367. if (connectCurrent)
  368. SNMP_SendUserTrap(CONNECT_MONITOR_NORM);
  369. else
  370. SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
  371. }
  372. connectOldState = connectCurrent;
  373. }
  374. /**
  375. * @brief Мониторинг параметра upsParams.connect
  376. */
  377. void UPS_BatteryConnectMonitor(void)
  378. {
  379. static bool isValueRecv = false;
  380. static uint8_t AKBconnectOldState = 0;
  381. uint8_t AKBconnectCurrent;
  382. if(((UPS.Status >> 7) & 0x01) == 0)
  383. AKBconnectCurrent = (UPS.Status >> 6) & 0x01;
  384. else{
  385. AKBconnectCurrent = 0;
  386. }
  387. UPS.Alarm = (UPS.Alarm & 0x07) | (AKBconnectCurrent << 3);
  388. if (!isValueRecv) {
  389. isValueRecv = true;
  390. AKBconnectOldState = AKBconnectCurrent;
  391. if (AKBconnectCurrent)
  392. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  393. return;
  394. }
  395. if (AKBconnectCurrent)
  396. flCriticalAlarm = true;
  397. // Значение параметра изменилось
  398. if (AKBconnectCurrent != AKBconnectOldState)
  399. {
  400. if (!AKBconnectCurrent)
  401. SNMP_SendUserTrap(BATTERY_CONNECT_NORM);
  402. else
  403. SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
  404. }
  405. AKBconnectOldState = AKBconnectCurrent;
  406. }
  407. /********************************* (C) РОТЕК **********************************/