|
@@ -0,0 +1,452 @@
|
|
|
|
+/********************************* (C) РОТЕК ***********************************
|
|
|
|
+ * @module ups_monitor
|
|
|
|
+ * @file ups_monitor.c
|
|
|
|
+ * @version 1.0.0
|
|
|
|
+ * @date XX.XX.XXXX
|
|
|
|
+ * $brief Template
|
|
|
|
+ *******************************************************************************
|
|
|
|
+ * @history Version Author Comment
|
|
|
|
+ * XX.XX.XXXX 1.0.0 Telenkov D.A. First release.
|
|
|
|
+ *******************************************************************************
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include "stm32f4xx.h"
|
|
|
|
+#include "ups_monitor.h"
|
|
|
|
+#include "parameters.h"
|
|
|
|
+#include "settings_api.h"
|
|
|
|
+#include "megatec.h"
|
|
|
|
+#include "led.h"
|
|
|
|
+
|
|
|
|
+#include "FreeRTOS.h"
|
|
|
|
+#include "task.h"
|
|
|
|
+
|
|
|
|
+#include "trap_api.h"
|
|
|
|
+#include "snmp_api.h"
|
|
|
|
+
|
|
|
|
+#include <stdbool.h>
|
|
|
|
+
|
|
|
|
+#define UPS_LOAD 70.0 // Нагрука (граница)
|
|
|
|
+#define UPS_LOAD_HIST 1.0 // Гистерезис нагрузки
|
|
|
|
+
|
|
|
|
+#define UPS_TEMPERATURE 40.0 // Температура (граница)
|
|
|
|
+#define UPS_TEMPERATURE_HIST 1.0 // Гистерезис температуры
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+bool flCriticalAlarm = false;
|
|
|
|
+bool flNonCriticalAlarm = false;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Общая структура настроек
|
|
|
|
+ */
|
|
|
|
+extern SETTINGS_t sSettings;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Задача мониторинга параметров UPS
|
|
|
|
+ */
|
|
|
|
+void UPS_Monitor(void *params)
|
|
|
|
+{
|
|
|
|
+ for (;;)
|
|
|
|
+ {
|
|
|
|
+ flCriticalAlarm = false;
|
|
|
|
+ flNonCriticalAlarm = false;
|
|
|
|
+ // Проверяем флаг подключения UPS
|
|
|
|
+ //if (UPS.Present)
|
|
|
|
+ {
|
|
|
|
+ UPS_LineFailMonitor();
|
|
|
|
+ UPS_LowBatMonitor();
|
|
|
|
+ UPS_PowerMonitor();
|
|
|
|
+ UPS_TemperatureMonitor();
|
|
|
|
+ UPS_BatteryConnectMonitor();
|
|
|
|
+ }
|
|
|
|
+ UPS_ConnectMonitor();
|
|
|
|
+ UPS_DI0Monitor();
|
|
|
|
+
|
|
|
|
+ UPS_CriticalAlarmMonitor();
|
|
|
|
+ UPS_NonCriticalAlarmMonitor();
|
|
|
|
+
|
|
|
|
+ vTaskDelay(1000);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг бита DI0 state
|
|
|
|
+ */
|
|
|
|
+void UPS_DI0Monitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t DI0OldState = 0;
|
|
|
|
+ uint8_t DI0StateCurrent;
|
|
|
|
+
|
|
|
|
+ DI0StateCurrent = get_state_din_outs(DIN1);
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ DI0OldState = DI0StateCurrent;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (DI0StateCurrent)
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (DI0StateCurrent != DI0OldState)
|
|
|
|
+ {
|
|
|
|
+ if(sSettings.sInOuts.din_type_act[0] == SNMP_TRAP)
|
|
|
|
+ {
|
|
|
|
+ if (DI0StateCurrent)
|
|
|
|
+ SNMP_SendUserTrap(DI0_NORM);
|
|
|
|
+ else
|
|
|
|
+ SNMP_SendUserTrap(DI0_ALARM);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ DI0OldState = DI0StateCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг бита CriticalAlarm
|
|
|
|
+ */
|
|
|
|
+void UPS_CriticalAlarmMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t CriticalAlarmOldState = 0;
|
|
|
|
+ uint8_t CriticalAlarmCurrent;
|
|
|
|
+ static uint8_t OldRO0type_Sourse = 0;
|
|
|
|
+ static uint8_t OldRO2type_Sourse = 0;
|
|
|
|
+ uint8_t CurrRO2type_Sourse = 0;
|
|
|
|
+ uint8_t CurrRO1type_Sourse = 0;
|
|
|
|
+
|
|
|
|
+ CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
|
|
|
|
+ CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
|
|
|
|
+ CriticalAlarmCurrent = flCriticalAlarm;
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ CriticalAlarmOldState = CriticalAlarmCurrent;
|
|
|
|
+ OldRO0type_Sourse = CurrRO1type_Sourse;
|
|
|
|
+ OldRO2type_Sourse = CurrRO2type_Sourse;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(CriticalAlarmCurrent){
|
|
|
|
+ if (UPS.Present)
|
|
|
|
+ LED_Toggle(LED_MAJOR_R);
|
|
|
|
+ else
|
|
|
|
+ LED_On(LED_MAJOR_R);
|
|
|
|
+ }
|
|
|
|
+ else{
|
|
|
|
+ LED_Off(LED_MAJOR_R);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (CriticalAlarmCurrent != CriticalAlarmOldState)
|
|
|
|
+ {
|
|
|
|
+ if(OldRO0type_Sourse == CRITICAL){
|
|
|
|
+ if(CriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 0);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 0);
|
|
|
|
+ SNMP_SendUserTrap(DO0_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ if(OldRO2type_Sourse == CRITICAL){
|
|
|
|
+ if(CriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 1);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 1);
|
|
|
|
+ SNMP_SendUserTrap(DO1_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(OldRO0type_Sourse == CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
|
|
|
|
+ if(CriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 0);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 0);
|
|
|
|
+ SNMP_SendUserTrap(DO0_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ if(OldRO2type_Sourse == CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
|
|
|
|
+ if(CriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 1);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 1);
|
|
|
|
+ SNMP_SendUserTrap(DO1_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ OldRO0type_Sourse = CurrRO1type_Sourse;
|
|
|
|
+ OldRO2type_Sourse = CurrRO2type_Sourse;
|
|
|
|
+ CriticalAlarmOldState = CriticalAlarmCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг бита NonCriticalAlarm
|
|
|
|
+ */
|
|
|
|
+void UPS_NonCriticalAlarmMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t NonCriticalAlarmOldState = 0;
|
|
|
|
+ uint8_t NonCriticalAlarmCurrent;
|
|
|
|
+ static uint8_t OldRO0type_Sourse = 0;
|
|
|
|
+ static uint8_t OldRO2type_Sourse = 0;
|
|
|
|
+ uint8_t CurrRO2type_Sourse = 0;
|
|
|
|
+ uint8_t CurrRO1type_Sourse = 0;
|
|
|
|
+
|
|
|
|
+ CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
|
|
|
|
+ CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
|
|
|
|
+ NonCriticalAlarmCurrent = flNonCriticalAlarm;
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
|
|
|
|
+ OldRO0type_Sourse = CurrRO1type_Sourse;
|
|
|
|
+ OldRO2type_Sourse = CurrRO2type_Sourse;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState)
|
|
|
|
+ {
|
|
|
|
+ if(OldRO0type_Sourse == CRITICAL){
|
|
|
|
+ if(NonCriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 0);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 0);
|
|
|
|
+ SNMP_SendUserTrap(DO0_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ if(OldRO2type_Sourse == CRITICAL){
|
|
|
|
+ if(NonCriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 1);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 1);
|
|
|
|
+ SNMP_SendUserTrap(DO1_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(OldRO0type_Sourse == CRITICAL && OldRO0type_Sourse != OldRO0type_Sourse){
|
|
|
|
+ if(NonCriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 0);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 0);
|
|
|
|
+ SNMP_SendUserTrap(DO0_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ if(OldRO2type_Sourse == CRITICAL && OldRO2type_Sourse != OldRO2type_Sourse){
|
|
|
|
+ if(NonCriticalAlarmCurrent)
|
|
|
|
+ SetROInt(1, 1);
|
|
|
|
+ else
|
|
|
|
+ SetROInt(0, 1);
|
|
|
|
+ SNMP_SendUserTrap(DO1_TOGGLED);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ OldRO0type_Sourse = CurrRO1type_Sourse;
|
|
|
|
+ OldRO2type_Sourse = CurrRO2type_Sourse;
|
|
|
|
+ NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг бита LainFail
|
|
|
|
+ */
|
|
|
|
+void UPS_LineFailMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t lineFailOldState = 0;
|
|
|
|
+ uint8_t lineFailCurrent;
|
|
|
|
+
|
|
|
|
+ lineFailCurrent = (UPS.Status >> 7) & 0x01;
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ lineFailOldState = lineFailCurrent;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (lineFailCurrent)
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (lineFailCurrent != lineFailOldState)
|
|
|
|
+ {
|
|
|
|
+ if (lineFailCurrent)
|
|
|
|
+ SNMP_SendUserTrap(LINE_ALARM);
|
|
|
|
+ else
|
|
|
|
+ SNMP_SendUserTrap(LINE_NORM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lineFailOldState = lineFailCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг бита LowBat
|
|
|
|
+ */
|
|
|
|
+void UPS_LowBatMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t lowBatOldState = 0;
|
|
|
|
+ uint8_t lowBatCurrent;
|
|
|
|
+ if((UPS.Status >> 7) & 0x01)
|
|
|
|
+ lowBatCurrent = (UPS.Status >> 6) & 0x01;
|
|
|
|
+ else
|
|
|
|
+ lowBatCurrent = 0;
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ lowBatOldState = lowBatCurrent;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (lowBatCurrent)
|
|
|
|
+ flNonCriticalAlarm = true;
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (lowBatCurrent != lowBatOldState)
|
|
|
|
+ {
|
|
|
|
+ if (lowBatCurrent)
|
|
|
|
+ SNMP_SendUserTrap(LOW_BAT_ALARM);
|
|
|
|
+ else
|
|
|
|
+ SNMP_SendUserTrap(LOW_BAT_NORM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lowBatOldState = lowBatCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг нагрузки
|
|
|
|
+ */
|
|
|
|
+void UPS_PowerMonitor(void)
|
|
|
|
+{
|
|
|
|
+ float load;
|
|
|
|
+ static uint8_t stateCurrent = HYST_IDLE;
|
|
|
|
+
|
|
|
|
+ load = UPS.Load;
|
|
|
|
+
|
|
|
|
+ /* Отслеживается переход через верхнюю границу */
|
|
|
|
+ if (load > UPS_LOAD)
|
|
|
|
+ {
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+ if (stateCurrent == HYST_IDLE)
|
|
|
|
+ {
|
|
|
|
+ LED_On(LED_MINOR_R);
|
|
|
|
+ LED_On(LED_MINOR_G);
|
|
|
|
+ stateCurrent = HYST_UP;
|
|
|
|
+
|
|
|
|
+ // Отправка трапа о завышении
|
|
|
|
+ SNMP_SendUserTrap(POWER_ALARM);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* Отслеживается нормализация */
|
|
|
|
+ else if (load < (UPS_LOAD - UPS_LOAD_HIST))
|
|
|
|
+ {
|
|
|
|
+ if (stateCurrent == HYST_UP)
|
|
|
|
+ {
|
|
|
|
+ LED_Off(LED_MINOR_R);
|
|
|
|
+ LED_Off(LED_MINOR_G);
|
|
|
|
+ stateCurrent = HYST_IDLE;
|
|
|
|
+
|
|
|
|
+ // Отправка трапа о нормализации
|
|
|
|
+ SNMP_SendUserTrap(POWER_NORM);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг температуры
|
|
|
|
+ */
|
|
|
|
+void UPS_TemperatureMonitor(void)
|
|
|
|
+{
|
|
|
|
+ float temperature;
|
|
|
|
+ static uint8_t stateCurrent = HYST_IDLE;
|
|
|
|
+
|
|
|
|
+ temperature = UPS.Temp;
|
|
|
|
+
|
|
|
|
+ /* Отслеживается переход через верхнюю границу */
|
|
|
|
+ if (temperature > UPS_TEMPERATURE)
|
|
|
|
+ {
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+ if (stateCurrent == HYST_IDLE)
|
|
|
|
+ {
|
|
|
|
+ stateCurrent = HYST_UP;
|
|
|
|
+
|
|
|
|
+ // Отправка трапа о завышении
|
|
|
|
+ SNMP_SendUserTrap(BATTERY_TEMPERATURE_ALARM);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* Отслеживается нормализация */
|
|
|
|
+ else if (temperature < (UPS_TEMPERATURE - UPS_TEMPERATURE_HIST))
|
|
|
|
+ {
|
|
|
|
+ if (stateCurrent == HYST_UP)
|
|
|
|
+ {
|
|
|
|
+ stateCurrent = HYST_IDLE;
|
|
|
|
+
|
|
|
|
+ // Отправка трапа о нормализации
|
|
|
|
+ SNMP_SendUserTrap(BATTERY_TEMPERATURE_NORM);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг параметра upsParams.connect
|
|
|
|
+ */
|
|
|
|
+void UPS_ConnectMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t connectOldState = 0;
|
|
|
|
+ uint8_t connectCurrent;
|
|
|
|
+
|
|
|
|
+ connectCurrent = UPS.Present;
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ connectOldState = connectCurrent;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (connectCurrent)
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (connectCurrent != connectOldState)
|
|
|
|
+ {
|
|
|
|
+ if (connectCurrent)
|
|
|
|
+ SNMP_SendUserTrap(CONNECT_MONITOR_NORM);
|
|
|
|
+ else
|
|
|
|
+ SNMP_SendUserTrap(CONNECT_MONITOR_ALARM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ connectOldState = connectCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Мониторинг параметра upsParams.connect
|
|
|
|
+ */
|
|
|
|
+void UPS_BatteryConnectMonitor(void)
|
|
|
|
+{
|
|
|
|
+ static bool isValueRecv = false;
|
|
|
|
+ static uint8_t AKBconnectOldState = 0;
|
|
|
|
+ uint8_t AKBconnectCurrent;
|
|
|
|
+
|
|
|
|
+ if(((UPS.Status >> 7) & 0x01) == 0)
|
|
|
|
+ AKBconnectCurrent = (UPS.Status >> 6) & 0x01;
|
|
|
|
+ else{
|
|
|
|
+ AKBconnectCurrent = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!isValueRecv) {
|
|
|
|
+ isValueRecv = true;
|
|
|
|
+ AKBconnectOldState = AKBconnectCurrent;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (AKBconnectCurrent)
|
|
|
|
+ flCriticalAlarm = true;
|
|
|
|
+ // Значение параметра изменилось
|
|
|
|
+ if (AKBconnectCurrent != AKBconnectOldState)
|
|
|
|
+ {
|
|
|
|
+ if (AKBconnectCurrent)
|
|
|
|
+ SNMP_SendUserTrap(BATTERY_CONNECT_NORM);
|
|
|
|
+ else
|
|
|
|
+ SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ AKBconnectOldState = AKBconnectCurrent;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/********************************* (C) РОТЕК **********************************/
|