/********************************* (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. ******************************************************************************* */ #pragma GCC diagnostic error "-Wall" #pragma GCC diagnostic error "-Wextra" #include "FreeRTOS.h" #include "task.h" #include "fr_timers.h" #include "stm32f4xx.h" #include "ups_monitor.h" #include "parameters.h" #include "settings_api.h" #include "megatec.h" #include "led.h" #include "log.h" #include "rtc.h" #include "hal.h" #include "FreeRTOS.h" #include "task.h" #include "trap_api.h" #include "snmp_api.h" #include "syslog.h" #include #ifdef PRINTF_STDLIB #include #endif #ifdef PRINTF_CUSTOM #include "tinystdio.h" #endif bool flCriticalAlarm = false; bool flNonCriticalAlarm = false; bool flLedAlarm = false; /** * @brief Общая структура настроек */ extern SETTINGS_t sSettings; extern bool flUpdateLog; extern int test_time; #if defined(INVERTERHIGHVOLTAGE_MONITOR) || defined(OVERTEMPRATURE_MONITOR) TimerHandle_t UPSRestartTimer; void UPSRestartCallback(TimerHandle_t pxTimer) { UPScmd(ups_remote_turn_on); } #endif #ifdef INVERTERHIGHVOLTAGE_MONITOR TimerHandle_t UPSTurnOffTimer; void UPSTurnOffCallback(TimerHandle_t pxTimer) { UPScmd(ups_remote_turn_off); xTimerStart(UPSRestartTimer, 0); } #endif /** * @brief Задача мониторинга параметров UPS */ void UPS_Monitor(void *params) { (void)params; #if defined(INVERTERHIGHVOLTAGE_MONITOR) || defined(OVERTEMPRATURE_MONITOR) UPSRestartTimer = xTimerCreate("UPSRestartTmr", configTICK_RATE_HZ*10, pdFALSE, ( void * ) 0, UPSRestartCallback); #endif #ifdef INVERTERHIGHVOLTAGE_MONITOR UPSTurnOffTimer = xTimerCreate("UPSTurnOffTmr", configTICK_RATE_HZ*300, pdFALSE, ( void * ) 0, UPSTurnOffCallback); #endif vTaskDelay(5000); for (;;) { flCriticalAlarm = false; flNonCriticalAlarm = false; flLedAlarm = false; #define XMONITOR(monitor_func, present) if (present) { monitor_func(); } MONITOR_TABLE #undef XMONITOR #ifdef LED_ALARM if(flLedAlarm){ if (UPS.Present == UPS_CONNECTED) LED_On(LED_ALARM); else LED_Toggle(LED_ALARM); } else{ LED_Off(LED_ALARM); } #endif vTaskDelay(1000); } } #ifdef DINS_ENABLE /** * @brief Мониторинг бита DI0 state */ void UPS_DI0Monitor(void) { #ifdef DIN_MONITOR static bool isValueRecv = false; static uint8_t DI0OldState[INPUTS_TOTAL_COUNT]; uint8_t DI0StateCurrent; for(uint8_t i = 0; i < INPUTS_TOTAL_COUNT; i ++) { DI0StateCurrent = get_state_din_outs((DIN1+i)) ^ sSettings.sDINs[i].din_type_act; UPS.Alarm = (UPS.Alarm & ~(1 << (4 + i))) | (DI0StateCurrent << (4 + i)); if (!isValueRecv) { DI0OldState[i] = DI0StateCurrent; if (DI0StateCurrent){ log_event_data((LOG_ALARM_DIO + i), "Авария"); SNMP_SendUserTrap(DI0_ALARM + 2*i); flUpdateLog = true; } else{ log_event_data((LOG_ALARM_DIO + i), "Норма"); SNMP_SendUserTrap(DI0_NORM + 2*i); flUpdateLog = true; } if (i == (INPUTS_TOTAL_COUNT - 1)) { isValueRecv = true; break; } continue; } if (DI0StateCurrent) { flLedAlarm = true; } // Значение параметра изменилось if (DI0StateCurrent != DI0OldState[i]) { if (!DI0StateCurrent){ log_event_data((LOG_ALARM_DIO + i), "Норма"); SNMP_SendUserTrap((DI0_NORM + 2*i)); flUpdateLog = true; } else{ log_event_data((LOG_ALARM_DIO + i), "Авария"); SNMP_SendUserTrap(DI0_ALARM + 2*i); flUpdateLog = true; } } DI0OldState[i] = DI0StateCurrent; } #endif } #endif #ifdef DOUTS_ENABLE void relay_setup_log(uint8_t *curr_source, ro_type_source_t src_act_ro, uint8_t state_relay) { uint8_t i = 0; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ if(curr_source[i] == src_act_ro){ SetROInt(state_relay, i); SNMP_SendUserTrap((DO0_TOGGLED+i)); if(state_relay){ flUpdateLog = true; #if defined RELAY_NC log_event_data((LOG_DO0_STATE + i), "Разомкнуто"); #else log_event_data((LOG_DO0_STATE + i), "Замкнуто"); #endif } else{ flUpdateLog = true; #if defined RELAY_NC log_event_data((LOG_DO0_STATE + i), "Замкнуто"); #else log_event_data((LOG_DO0_STATE + i), "Разомкнуто"); #endif } } } } void relay_setup_log_change(uint8_t *curr_source, uint8_t *prev_source, ro_type_source_t src_act_ro) { uint8_t i = 0; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ if(curr_source[i] != prev_source[i] && (prev_source[i] == src_act_ro || curr_source[i] == src_act_ro)){ #if defined RELAY_NC if(curr_source[i] != src_act_ro){ flUpdateLog = true; SetROInt(0, i); SNMP_SendUserTrap((DO0_TOGGLED+i)); log_event_data((LOG_DO0_STATE + i), "Замкнуто"); } else{ flUpdateLog = true; SetROInt(1, i); SNMP_SendUserTrap((DO0_TOGGLED+i)); log_event_data((LOG_DO0_STATE + i), "Разомкнуто"); } #else if(curr_source[i] != src_act_ro){ flUpdateLog = true; SetROInt(0, i); SNMP_SendUserTrap((DO0_TOGGLED+i)); log_event_data((LOG_DO0_STATE + i), "Разомкнуто"); } else{ flUpdateLog = true; SetROInt(1, i); SNMP_SendUserTrap((DO0_TOGGLED+i)); log_event_data((LOG_DO0_STATE + i), "Замкнуто"); } #endif } } } #endif #ifdef TYPE_CRITICAL_ALARM_MONITOR /** * @brief Мониторинг бита CriticalAlarm */ void UPS_CriticalAlarmMonitor(void) { static bool isValueRecv = false; static uint8_t CriticalAlarmOldState = 0; uint8_t CriticalAlarmCurrent; uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; CriticalAlarmCurrent = flCriticalAlarm; if (!isValueRecv) { isValueRecv = true; CriticalAlarmOldState = CriticalAlarmCurrent; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) OldROtype_Sourse[i] = CurrROtype_Sourse[i]; if(CriticalAlarmCurrent){ relay_setup_log(CurrROtype_Sourse, CRITICAL, 1); } else{ relay_setup_log(CurrROtype_Sourse, CRITICAL, 0); } return; } // Значение параметра изменилось if (CriticalAlarmCurrent != CriticalAlarmOldState) { if(CriticalAlarmCurrent){ relay_setup_log(CurrROtype_Sourse, CRITICAL, 1); } else{ relay_setup_log(CurrROtype_Sourse, CRITICAL, 0); } } else { if(CriticalAlarmCurrent) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CRITICAL); } for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } CriticalAlarmOldState = CriticalAlarmCurrent; } /** * @brief Мониторинг бита NonCriticalAlarm */ void UPS_NonCriticalAlarmMonitor(void) { static bool isValueRecv = false; static uint8_t NonCriticalAlarmOldState = 0; uint8_t NonCriticalAlarmCurrent; uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; NonCriticalAlarmCurrent = flNonCriticalAlarm; if (!isValueRecv) { isValueRecv = true; NonCriticalAlarmOldState = NonCriticalAlarmCurrent; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) OldROtype_Sourse[i] = CurrROtype_Sourse[i]; if(NonCriticalAlarmCurrent) relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 1); else relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 0); return; } // Значение параметра изменилось if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState) { if(NonCriticalAlarmCurrent){ relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 1); } else{ relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 0); } } else { if(NonCriticalAlarmCurrent) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, NON_CRITICAL); } for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } NonCriticalAlarmOldState = NonCriticalAlarmCurrent; } #endif static bool test_akb_flag = false; /** * @brief Мониторинг бита Test in progress */ void UPS_TestFinishMonitor(void) { #ifdef TEST_AKB_FINISH_MONITOR static uint8_t TestFinishState = 0; uint8_t TestFinishStateCurrent; char log_string[50]; static uint32_t start_time_test = 0; TestFinishStateCurrent = (UPS.Status >> 2) & 0x01; // Значение параметра изменилось if (TestFinishStateCurrent != TestFinishState) { if (!TestFinishStateCurrent){ printf("Test finish\r\n"); #ifdef TEST_ALARM_AKB_MONITOR float time_test_actual = ((float)(xTaskGetTickCount() - start_time_test)) / (1000*60); UPSReadTestStatus(); #ifdef RELAY_ALARM_AKB static uint8_t AKBAlarmState = 0; uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; #endif float Uakb_av = voltage_bat_average(); float Pload_av = power_load_average(); float k_eff; printf("Uakb_av: %0.2f", Uakb_av); printf("Pload_av: %0.2f", Pload_av); if(UPS.Test_Status != 2 && Pload_av >= 3) { GetUPSEfficiencyFactorInt(&k_eff); float Ccalc = (sSettings.UPS_Setting.ups_power*Pload_av*time_test_actual)/(100*60*Uakb_av*(k_eff)); printf("Ccalc: %0.2f", Ccalc); float Ccalc_percent = (100*Ccalc)/sSettings.UPS_Setting.common_capacity; if (Ccalc_percent >= 80) { sprintf(log_string, "Авария(%0.2f Ач)", Ccalc); log_event_data(LOG_TEST_ALARM_AKB, log_string); syslog(SYSLOG_INFORMATIONAL, "Ёмкость АКБ: %s", log_string); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 SNMP_SendUserTrap(BATTERY_FAIL); #endif #ifdef RELAY_ALARM_AKB relay_setup_log(CurrROtype_Sourse, ALARM_AKB, 1); AKBAlarmState = 1; #endif } else { sprintf(log_string, "Норма(%0.2f Ач)", Ccalc); log_event_data(LOG_TEST_ALARM_AKB, log_string); syslog(SYSLOG_INFORMATIONAL, "Ёмкость АКБ: %s", log_string); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 SNMP_SendUserTrap(BATTERY_NORM); #endif #ifdef RELAY_ALARM_AKB relay_setup_log(CurrROtype_Sourse, ALARM_AKB, 0); AKBAlarmState = 0; #endif } } #ifdef RELAY_ALARM_AKB if (AKBAlarmState) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, ALARM_AKB); for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) OldROtype_Sourse[i] = CurrROtype_Sourse[i]; #endif memset(log_string, 0, sizeof(log_string)); if(UPS.Test_Status == 2 ||( (time_test_actual <= 0.9*test_time || time_test_actual >= 1.1*test_time) && (test_time != 0 && test_time != 100))){// strcpy(log_string, "Ошибка"); } else { strcpy(log_string, "Завершен"); } uint8_t len1 = strlen(log_string); sprintf(&log_string[len1], "(%0.1f мин)", time_test_actual); log_event_data(LOG_TEST_UPS, log_string); syslog(SYSLOG_INFORMATIONAL, "Тест батареи: %s", log_string); test_time = 0; #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 SNMP_SendUserTrap(TEST_BAT_STOP); #endif #else log_event_data(LOG_TEST_UPS, "Завершен"); syslog_str(SYSLOG_INFORMATIONAL, "Тест батареи: Завершён"); #endif flUpdateLog = true; } else { test_akb_flag = true; memset(log_string, 0, sizeof(log_string)); switch (get_act_source()) { case WEB_ACT: strcpy(log_string, name_login); break; case SNMP_ACT: case OTHER_ACT: strcpy(log_string, "Администратор"); break; #ifdef CLI_ENABLE case CLI_ACT: strcpy(log_string, "Администратор"); break; #endif case AUTO_ACT: strcpy(log_string, "Автоматический"); break; default: break; } #ifdef TEST_ALARM_AKB_MONITOR start_time_test = xTaskGetTickCount(); if (test_time == 0) { strcat(log_string, " (авто)"); } else if (test_time == 100) { strcat(log_string, " (до разряда)"); } else { uint8_t len = strlen(log_string); sprintf(&log_string[len], "(%i мин)", test_time); } #else strcat(log_string, " (Запущен)"); #endif printf("Test start\r\n"); log_event_data(LOG_TEST_UPS, log_string); syslog(SYSLOG_INFORMATIONAL, "Тест батареи: %s", log_string); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 SNMP_SendUserTrap(TEST_BAT_RUN); #endif flUpdateLog = true; } } TestFinishState = TestFinishStateCurrent; #endif } uint8_t UPS_VACinputRangeAlarm(void) { #ifdef VAC_IN_MONITOR uint8_t flag = 0; static uint8_t stateCurrentVACinput_low = HYST_IDLE; static uint8_t stateCurrentVACinput_high = HYST_IDLE; float VACinputCurrent = UPS.VAC_in; static uint8_t cnt = 0; if(test_akb_flag) { if (UPS.VAC_in>255) { test_akb_flag = false; cnt = 0; ups_metac_service_pdu(ups_cancel_test); log_event_data(LOG_TEST_UPS, "Ошибка"); } else { if(cnt < 20){ cnt++; } else { if (UPS.Mode == 'L') { test_akb_flag = false; } cnt = 0; } } } /* Отслеживается переход через нижнию границу */ if (VACinputCurrent < sSettings.sAlarmManager.ac_input_range.low) { if (stateCurrentVACinput_low == HYST_IDLE || stateCurrentVACinput_low == HYST_DOWN) { stateCurrentVACinput_low = HYST_DOWN; flag |= (1 << 1); } } else if (VACinputCurrent > (sSettings.sAlarmManager.ac_input_range.low + sSettings.sAlarmManager.ac_input_range.hyst)) { if (stateCurrentVACinput_low == HYST_DOWN) { stateCurrentVACinput_low = HYST_IDLE; flag &= 0xfd; } } else { if (stateCurrentVACinput_low == HYST_DOWN) { flag |= (1 << 1); } } /* Отслеживается переход через верхнюю границу */ if (VACinputCurrent > sSettings.sAlarmManager.ac_input_range.high) { if (stateCurrentVACinput_high == HYST_IDLE || stateCurrentVACinput_high == HYST_UP) { stateCurrentVACinput_high = HYST_UP; flag |= (1 << 2); } } else if (VACinputCurrent < (sSettings.sAlarmManager.ac_input_range.high - sSettings.sAlarmManager.ac_input_range.hyst)) { if (stateCurrentVACinput_high == HYST_UP) { stateCurrentVACinput_high = HYST_IDLE; flag &= 0xfb; } } else { if (stateCurrentVACinput_high == HYST_UP) { flag |= (1 << 2); } } return flag; #endif } /** * @brief Мониторинг бита LainFail */ void UPS_LineFailMonitor(void) { #ifdef LINE_FAIL_MONITOR static bool isValueRecv = false; static uint8_t lineFailOldState = 0; uint8_t lineFailCurrent; char log_string[50]; uint8_t len; #if defined RELAY_AC_PRESENT uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; #endif #ifdef VAC_IN_MONITOR lineFailCurrent = ((UPS.Status >> 7) & 0x01); lineFailCurrent |= UPS_VACinputRangeAlarm(); #else lineFailCurrent = (UPS.Status >> 7) & 0x01; #endif if (!isValueRecv) { isValueRecv = true; lineFailOldState = lineFailCurrent; if (lineFailCurrent != 0){ memset(log_string, 0, sizeof(log_string)); strcat(log_string, "Авария"); len = strlen(log_string); sprintf(&log_string[len], " (%0.1f В)", UPS.VAC_in); log_event_data(LOG_ALARM_LINE, log_string); SNMP_SendUserTrap(LINE_ALARM); syslog(SYSLOG_ERROR, "Авария сети (%0.1f В)", UPS.VAC_in); flUpdateLog = true; #if defined RELAY_AC_PRESENT relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 1); #endif } else{ #if defined RELAY_AC_PRESENT relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 0); #endif log_event_data(LOG_ALARM_LINE, "Норма"); SNMP_SendUserTrap(LINE_NORM); syslog(SYSLOG_NOTICE, "Сеть в норме (%0.1f В)", UPS.VAC_in); flUpdateLog = true; } return; } if (lineFailCurrent != 0){ flCriticalAlarm = true; flLedAlarm = true; } // Значение параметра изменилось if (lineFailCurrent != lineFailOldState) { if (lineFailCurrent != 0){ #if defined RELAY_AC_PRESENT relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 1); #endif memset(log_string, 0, sizeof(log_string)); strcat(log_string, "Авария"); len = strlen(log_string); sprintf(&log_string[len], " (%0.1f В)", UPS.VAC_in); log_event_data(LOG_ALARM_LINE, log_string); SNMP_SendUserTrap(LINE_ALARM); syslog(SYSLOG_ERROR, "Авария сети (%0.1f В)", UPS.VAC_in); #ifdef AKB_CHANGE_MONITOR if(UPS.Alarm & 0x40) { log_event_data(LOG_ALARM_CHANGE_AKB, "Авария"); SNMP_SendUserTrap(BATTERY_CHANGE_ALARM); } #endif flUpdateLog = true; } else{ if (UPS.VAC_in == 0) { return; } #if defined RELAY_AC_PRESENT relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 0); #endif log_event_data(LOG_ALARM_LINE, "Норма"); SNMP_SendUserTrap(LINE_NORM); syslog(SYSLOG_NOTICE, "Сеть в норме (%0.1f В)", UPS.VAC_in); flUpdateLog = true; } } #if defined RELAY_AC_PRESENT else{ if (lineFailCurrent != 0) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, AC_PRESENT); } for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif lineFailOldState = lineFailCurrent; #endif } #ifdef VAC_OUT_MONITOR /** * @brief Мониторинг аварии выходного напряжения по нижней границе */ void UPS_VACoutputLowRangeMonitor(void) { static uint8_t stateCurrentVACoutput = HYST_IDLE; float VACoutputCurrent; #if defined RELAY_DC_PRESENT uint8_t i = 0; static bool isValueRecv = false; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; if(!isValueRecv) OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif VACoutputCurrent = UPS.VAC_out; /* Отслеживается переход через нижнию границу */ if (VACoutputCurrent < sSettings.sAlarmManager.ac_output_range.low) { if (stateCurrentVACoutput == HYST_IDLE) { UPS.Alarm |= (1 << 7); stateCurrentVACoutput = HYST_DOWN; #if defined RELAY_DC_PRESENT relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 1); #endif log_event_data(LOG_ALARM_VAC_LOW_OUTPUT, "Авария"); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 // Отправка трапа о занижении SNMP_SendUserTrap(VAC_LOW_OUTPUT_ALARM); syslog(SYSLOG_ERROR, "Низкое входное напряжение (%0.1f В)", VACoutputCurrent); #endif flUpdateLog = true; } else { #if defined RELAY_DC_PRESENT relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, DC_PRESENT); #endif } } /* Отслеживается нормализация */ else if (VACoutputCurrent > (sSettings.sAlarmManager.ac_output_range.low + sSettings.sAlarmManager.ac_output_range.hyst)) { if (stateCurrentVACoutput == HYST_DOWN) { UPS.Alarm &= 0xffffff7f; stateCurrentVACoutput = HYST_IDLE; #if defined RELAY_DC_PRESENT relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 0); #endif log_event_data(LOG_ALARM_VAC_LOW_OUTPUT, "Норма"); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 // Отправка трапа о нормализации SNMP_SendUserTrap(VAC_LOW_OUTPUT_NORM); syslog(SYSLOG_NOTICE, "Выходное напряжение в норме (%0.1f В)", VACoutputCurrent); #endif flUpdateLog = true; } } if (UPS.Alarm & 0x80) { flLedAlarm = true; } #if defined RELAY_DC_PRESENT for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif } /** * @brief Мониторинг аварии выходного напряжения по верхней границе */ void UPS_VACoutputHighRangeMonitor(void) { static uint8_t stateCurrentVACoutput = HYST_IDLE; float VACoutputCurrent; #if defined RELAY_DC_PRESENT uint8_t i = 0; static bool isValueRecv = false; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; if(!isValueRecv) OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif VACoutputCurrent = UPS.VAC_out; /* Отслеживается переход через верхнюю границу */ if (VACoutputCurrent > sSettings.sAlarmManager.ac_output_range.high) { if (stateCurrentVACoutput == HYST_IDLE) { UPS.Alarm |= (1 << 7); stateCurrentVACoutput = HYST_UP; #if defined RELAY_DC_PRESENT relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 1); #endif log_event_data(LOG_ALARM_VAC_HIGH_OUTPUT, "Авария"); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 // Отправка трапа о завышении SNMP_SendUserTrap(VAC_HIGH_OUTPUT_ALARM); syslog(SYSLOG_ERROR, "Высокое входное напряжение (%0.1f В)", VACoutputCurrent); #endif flUpdateLog = true; } else { #if defined RELAY_DC_PRESENT relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, DC_PRESENT); #endif } } /* Отслеживается нормализация */ else if (VACoutputCurrent < (sSettings.sAlarmManager.ac_output_range.high - sSettings.sAlarmManager.ac_output_range.hyst)) { if (stateCurrentVACoutput == HYST_UP) { UPS.Alarm &= 0xffffff7f; stateCurrentVACoutput = HYST_IDLE; #if defined RELAY_DC_PRESENT relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 0); #endif log_event_data(LOG_ALARM_VAC_HIGH_OUTPUT, "Норма"); #if HARDWARE_BT6711 || HARDWARE_BT6711_V1 // Отправка трапа о нормализации SNMP_SendUserTrap(VAC_HIGH_OUTPUT_NORM); syslog(SYSLOG_NOTICE, "Выходное напряжение в норме (%0.1f В)", VACoutputCurrent); #endif flUpdateLog = true; } } if (UPS.Alarm & 0x80) { flLedAlarm = true; } #if defined RELAY_DC_PRESENT for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif } #endif /** * @brief Мониторинг бита LowBat */ void UPS_LowBatMonitor(void) { #ifdef LOW_BAT_MONITOR static bool isValueRecv = false; static uint8_t lowBatOldState = 0; static bool flag_alarm_time = false; uint8_t lowBatCurrent; #if defined RELAY_CHARGE_AKB uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; #endif if((UPS.Status >> 7) & 0x01) lowBatCurrent = (UPS.Status >> 6) & 0x01; else lowBatCurrent = 0; if (!isValueRecv) { isValueRecv = true; lowBatOldState = lowBatCurrent; if (lowBatCurrent){ log_event_data(LOG_ALARM_LOW_BAT, "Авария"); SNMP_SendUserTrap(LOW_BAT_ALARM); syslog(SYSLOG_ERROR, "Низкий заряд АКБ (%d%%)", UPS.SOC); flUpdateLog = true; #if defined RELAY_CHARGE_AKB relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 1); #endif } else{ SNMP_SendUserTrap(LOW_BAT_NORM); log_event_data(LOG_ALARM_LOW_BAT, "Норма"); syslog(SYSLOG_NOTICE, "Заряд АКБ в норме (%d%%)", UPS.SOC); flUpdateLog = true; #if defined RELAY_CHARGE_AKB relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 0); #endif } return; } // Значение параметра изменилось if (lowBatCurrent != lowBatOldState) { if(flag_alarm_time){ flag_alarm_time = false; if (lowBatCurrent){ SNMP_SendUserTrap(LOW_BAT_ALARM); syslog(SYSLOG_ERROR, "Низкий заряд АКБ (%d%%)", UPS.SOC); log_event_data(LOG_ALARM_LOW_BAT, "Авария"); flUpdateLog = true; #ifdef RELAY_CHARGE_AKB relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 1); #endif } else{ SNMP_SendUserTrap(LOW_BAT_NORM); syslog(SYSLOG_NOTICE, "Заряд АКБ в норме (%d%%)", UPS.SOC); log_event_data(LOG_ALARM_LOW_BAT, "Норма"); flUpdateLog = true; #if defined RELAY_CHARGE_AKB relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 0); #endif } } else{ flag_alarm_time = true; } } #if defined RELAY_CHARGE_AKB else{ flag_alarm_time = false; if (lowBatCurrent) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CHARGE_AKB); } for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif if(!flag_alarm_time){ if (lowBatCurrent){ flNonCriticalAlarm = true; flLedAlarm = true; } lowBatOldState = lowBatCurrent; } else{ if (lowBatOldState){ flNonCriticalAlarm = true; flLedAlarm = true; } } #endif } static uint8_t UPS_LoadRangeAlarm(void) { #ifdef LOAD_MONITOR uint8_t flag = 0; static uint8_t stateCurrent = HYST_IDLE; float load = UPS.Load; /* Отслеживается переход через верхнюю границу */ if (load > sSettings.sAlarmManager.load_range.high) { if (stateCurrent == HYST_IDLE || stateCurrent == HYST_UP) { stateCurrent = HYST_UP; flag = 1; } } else if (load < (sSettings.sAlarmManager.load_range.high - sSettings.sAlarmManager.load_range.hyst)) { if (stateCurrent == HYST_UP) { stateCurrent = HYST_IDLE; flag = 0; } } else { if (stateCurrent == HYST_UP) { flag = 1; } } return flag; #endif } /** * @brief Мониторинг нагрузки */ void UPS_PowerMonitor(void) { #ifdef LOAD_MONITOR uint8_t powerStatusCurrent; static uint8_t powerStatusOld = 0; if(!get_sync_data()) { return; } powerStatusCurrent = ((UPS.warn_status >> 5) & 0x01); powerStatusCurrent |= UPS_LoadRangeAlarm(); if (powerStatusCurrent) { UPS.Alarm = (UPS.Alarm & 0xfffffffe) | (1 << 0); if (powerStatusCurrent != powerStatusOld) { #ifdef LED_RED_MINOR LED_On(LED_RED_MINOR); #endif #ifdef LED_GREEN_MINOR LED_On(LED_GREEN_MINOR); #endif log_event_data(LOG_ALARM_POWER, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(POWER_ALARM); syslog(SYSLOG_ERROR, "Авария нагрузки (%d%%)", UPS.Load); flUpdateLog = true; } } /* Отслеживается нормализация */ else { UPS.Alarm = (UPS.Alarm & 0xfffffffe); if (powerStatusCurrent != powerStatusOld) { #ifdef LED_RED_MINOR LED_Off(LED_RED_MINOR); #endif #ifdef LED_GREEN_MINOR LED_Off(LED_GREEN_MINOR); #endif log_event_data(LOG_ALARM_POWER, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(POWER_NORM); syslog(SYSLOG_NOTICE, "Авария нагрузки нормализовалась (%d%%)", UPS.Load); flUpdateLog = true; } } powerStatusOld = powerStatusCurrent; if (UPS.Alarm & 0x00000001) { flCriticalAlarm = true; flLedAlarm = true; } #endif } #ifdef SENSOR_TEMP_MONITOR /** * @brief Мониторинг аварии датчика температуры */ void sensorTemperatureMonitor(void) { float temperature; static uint8_t type_sensor[MAX_T_SENSORS]; static uint8_t alarm[MAX_T_SENSORS]; static uint8_t start_monitor = 0; if (start_monitor == 0) { start_monitor = 1; for(uint8_t i = 0; i < MAX_T_SENSORS; i ++){ type_sensor[i] = sSettings.sTempControl[i].type_sensor; } } for(uint8_t i = 0; i < MAX_T_SENSORS; i ++){ if (alarm[i] && sSettings.sTempControl[i].type_sensor != type_sensor[i]) { alarm[i] = 0; if (type_sensor[i] == TS_AKB) { log_event_data(LOG_ALARM_SENSOR_AKB, "Норма"); flUpdateLog = true; } else if (type_sensor[i] == TS_CABINET) { log_event_data(LOG_ALARM_SENSOR_CABINET, "Норма"); flUpdateLog = true; } } if (sSettings.sTempControl[i].type_sensor == TS_AKB) { GetInternalTempInt(&temperature); if(temperature == 85) { if(!alarm[i]) { log_event_data(LOG_ALARM_SENSOR_AKB, "Авария"); flUpdateLog = true; flLedAlarm = true; alarm[i] = 1; } } else { if(alarm[i]) { log_event_data(LOG_ALARM_SENSOR_AKB, "Норма"); flUpdateLog = true; alarm[i] = 0; } } } else if (sSettings.sTempControl[i].type_sensor == TS_CABINET) { GetTempCaseInt(&temperature); if(temperature == 85) { if(!alarm[i]) { log_event_data(LOG_ALARM_SENSOR_CABINET, "Авария"); flUpdateLog = true; flLedAlarm = true; alarm[i] = 1; } } else { if(alarm[i]) { log_event_data(LOG_ALARM_SENSOR_CABINET, "Норма"); flUpdateLog = true; alarm[i] = 0; } } } type_sensor[i] = sSettings.sTempControl[i].type_sensor; } } #endif #ifdef TEMP_AKB_MONITOR static uint8_t UPS_TempHighRangeAlarm(void) { uint8_t flag = 0; float temperature; static uint8_t stateCurrent = HYST_IDLE; GetInternalTempInt(&temperature); if(temperature == 85) { if (stateCurrent == HYST_UP) { stateCurrent = HYST_IDLE; flag = 0; } return flag; } /* Отслеживается переход через верхнюю границу */ if (temperature > sSettings.sAlarmManager.Temprature_range.high) { if (stateCurrent == HYST_IDLE || stateCurrent == HYST_UP) { stateCurrent = HYST_UP; flag = 1; } } else if (temperature < (sSettings.sAlarmManager.Temprature_range.high - sSettings.sAlarmManager.Temprature_range.hyst)) { if (stateCurrent == HYST_UP) { stateCurrent = HYST_IDLE; flag = 0; } } else { if (stateCurrent == HYST_UP) { flag = 1; } } return flag; } /** * @brief Мониторинг температуры по верхней границе */ void UPS_TemperatureHighRangeMonitor(void) { float temperature; uint8_t tempStatusCurrent; static uint8_t tempStatusOld = 0; GetInternalTempInt(&temperature); tempStatusCurrent = ((UPS.warn_status >> 6) & 0x01); tempStatusCurrent |= UPS_TempHighRangeAlarm(); if (tempStatusCurrent) { UPS.Alarm = (UPS.Alarm & 0xfffffffd) | (1 << 1); if (tempStatusCurrent != tempStatusOld) { log_event_data(LOG_ALARM_HIGH_TEMP, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(BATTERY_HIGH_TEMPERATURE_ALARM); syslog(SYSLOG_ERROR, "Высокая температура (%0.1f C)", temperature); flUpdateLog = true; } } /* Отслеживается нормализация */ else { UPS.Alarm = (UPS.Alarm & 0xfffffffd); if (tempStatusCurrent != tempStatusOld) { log_event_data(LOG_ALARM_HIGH_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(BATTERY_HIGH_TEMPERATURE_NORM); syslog(SYSLOG_NOTICE, "Температура в норме (%0.1f C)", temperature); flUpdateLog = true; } } tempStatusOld = tempStatusCurrent; if (UPS.Alarm & 0x00000002) { flCriticalAlarm = true; flLedAlarm = true; } } /** * @brief Мониторинг температуры по нижней границе */ void UPS_TemperatureLowRangeMonitor(void) { float temperature; static uint8_t stateCurrent = HYST_IDLE; GetInternalTempInt(&temperature); if(temperature == 85) { UPS.Alarm = (UPS.Alarm & 0xfffffeff) | (1 << 8); if (stateCurrent == HYST_DOWN) { stateCurrent = HYST_IDLE; log_event_data(LOG_ALARM_LOW_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(BATTERY_LOW_TEMPERATURE_NORM); syslog(SYSLOG_NOTICE, "Температура в норме (%0.1f C)", temperature); flUpdateLog = true; } return; } else { if (stateCurrent == HYST_IDLE) { UPS.Alarm = (UPS.Alarm & 0xfffffeff); } } /* Отслеживается переход через нипжнюю границу */ if (temperature < sSettings.sAlarmManager.Temprature_range.low) { if (stateCurrent == HYST_IDLE) { stateCurrent = HYST_DOWN; UPS.Alarm = (UPS.Alarm & 0xfffffeff) | (1 << 8); log_event_data(LOG_ALARM_LOW_TEMP, "Авария"); // Отправка трапа о занижении SNMP_SendUserTrap(BATTERY_LOW_TEMPERATURE_ALARM); syslog(SYSLOG_ERROR, "Низкая температура (%0.1f C)", temperature); flUpdateLog = true; } } /* Отслеживается нормализация */ else if (temperature > (sSettings.sAlarmManager.Temprature_range.low + sSettings.sAlarmManager.Temprature_range.hyst)) { if (stateCurrent == HYST_DOWN) { stateCurrent = HYST_IDLE; UPS.Alarm = (UPS.Alarm & 0xfffffeff); log_event_data(LOG_ALARM_LOW_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(BATTERY_LOW_TEMPERATURE_NORM); syslog(SYSLOG_NOTICE, "Температура в норме (%0.1f C)", temperature); flUpdateLog = true; } } if (UPS.Alarm & 0x00000100) { flCriticalAlarm = true; flLedAlarm = true; } } #endif #ifdef TEMP_CABINET_MONITOR /** * @brief Мониторинг температуры шкафа по верхней границе */ void Cabinet_TemperatureHighRangeMonitor(void) { float temperature; static uint8_t stateCurrent = HYST_IDLE; GetTempCaseInt(&temperature); if(temperature == 85) { UPS.Alarm = (UPS.Alarm & 0xfffffdff) | (1 << 9); if (stateCurrent == HYST_UP) { stateCurrent = HYST_IDLE; log_event_data(LOG_ALARM_HIGH_CABINET_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(CABINET_HIGH_TEMPERATURE_NORM); flUpdateLog = true; } return; } else { if (stateCurrent == HYST_IDLE) { UPS.Alarm = (UPS.Alarm & 0xfffffdff); } } /* Отслеживается переход через верхнюю границу */ if (temperature > sSettings.sAlarmManager.Temprature_cabinet_range.high) { if (stateCurrent == HYST_IDLE) { UPS.Alarm = (UPS.Alarm & 0xfffffdff) | (1 << 9); stateCurrent = HYST_UP; log_event_data(LOG_ALARM_HIGH_CABINET_TEMP, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(CABINET_HIGH_TEMPERATURE_ALARM); flUpdateLog = true; } } /* Отслеживается нормализация */ else if (temperature < (sSettings.sAlarmManager.Temprature_cabinet_range.high - sSettings.sAlarmManager.Temprature_cabinet_range.hyst)) { if (stateCurrent == HYST_UP) { UPS.Alarm = (UPS.Alarm & 0xfffffdff); stateCurrent = HYST_IDLE; log_event_data(LOG_ALARM_HIGH_CABINET_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(CABINET_HIGH_TEMPERATURE_NORM); flUpdateLog = true; } } if (UPS.Alarm & 0x00000200) { flLedAlarm = true; } } /** * @brief Мониторинг температуры шкафа по нижней границе */ void Cabinet_TemperatureLowRangeMonitor(void) { float temperature; static uint8_t stateCurrent = HYST_IDLE; GetTempCaseInt(&temperature); if(temperature == 85) { UPS.Alarm = (UPS.Alarm & 0xfffffbff) | (1 << 10); if (stateCurrent == HYST_DOWN) { stateCurrent = HYST_IDLE; log_event_data(LOG_ALARM_LOW_CABINET_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(CABINET_LOW_TEMPERATURE_NORM); flUpdateLog = true; } return; } else { if (stateCurrent == HYST_IDLE) { UPS.Alarm = (UPS.Alarm & 0xfffffbff); } } /* Отслеживается переход через нипжнюю границу */ if (temperature < sSettings.sAlarmManager.Temprature_cabinet_range.low) { if (stateCurrent == HYST_IDLE) { stateCurrent = HYST_DOWN; UPS.Alarm = (UPS.Alarm & 0xfffffbff) | (1 << 10); log_event_data(LOG_ALARM_LOW_CABINET_TEMP, "Авария"); // Отправка трапа о занижении SNMP_SendUserTrap(CABINET_LOW_TEMPERATURE_ALARM); flUpdateLog = true; } } /* Отслеживается нормализация */ else if (temperature > (sSettings.sAlarmManager.Temprature_cabinet_range.low + sSettings.sAlarmManager.Temprature_cabinet_range.hyst)) { if (stateCurrent == HYST_DOWN) { UPS.Alarm = (UPS.Alarm & 0xfffffbff); stateCurrent = HYST_IDLE; log_event_data(LOG_ALARM_LOW_CABINET_TEMP, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(CABINET_LOW_TEMPERATURE_NORM); flUpdateLog = true; } } if (UPS.Alarm & 0x00000400) { flLedAlarm = true; } } #endif /** * @brief Мониторинг параметра upsParams.connect */ void UPS_ConnectMonitor(void) { #ifdef UPS_CONNECT_MONITOR static bool isValueRecv = false; static ups_state_connection_t connectOldState; ups_state_connection_t connectCurrent; connectCurrent = UPS.Present; if(connectCurrent == UPS_WAIT_CONNECT) { return; } UPS.Alarm = (UPS.Alarm & 0xfffffffb) | ((connectCurrent^1) << 2); if (!isValueRecv) { isValueRecv = true; connectOldState = connectCurrent; if (connectCurrent == UPS_FAIL_CONNECT){ log_event_data(LOG_ALARM_UPS, "Авария"); SNMP_SendUserTrap(CONNECT_MONITOR_ALARM); syslog_str(SYSLOG_ERROR, "Потеряна связь с ИБП"); } else{ log_event_data(LOG_ALARM_UPS, "Норма"); SNMP_SendUserTrap(CONNECT_MONITOR_NORM); syslog_str(SYSLOG_NOTICE, "Восстановлена связь с ИБП"); flUpdateLog = true; } return; } if (connectCurrent == UPS_FAIL_CONNECT){ flCriticalAlarm = true; flLedAlarm = true; } // Значение параметра изменилось if (connectCurrent != connectOldState) { if (connectCurrent == UPS_CONNECTED){ log_event_data(LOG_ALARM_UPS, "Норма"); SNMP_SendUserTrap(CONNECT_MONITOR_NORM); syslog_str(SYSLOG_NOTICE, "Восстановлена связь с ИБП"); flUpdateLog = true; } else{ log_event_data(LOG_ALARM_UPS, "Авария"); SNMP_SendUserTrap(CONNECT_MONITOR_ALARM); syslog_str(SYSLOG_ERROR, "Потеряна связь с ИБП"); } } connectOldState = connectCurrent; #endif } /** * @brief Мониторинг параметра upsParams.connect */ void UPS_BatteryConnectMonitor(void) { #ifdef BAT_CONNECT_MONITOR static bool isValueRecv = false; static bool flag_alarm_time = false; static uint8_t AKBconnectOldState = 0; uint8_t AKBconnectCurrent; #if defined RELAY_OFF_AKB uint8_t i = 0; static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0}; for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++) CurrROtype_Sourse[i] = sSettings.sRelays[i].ro_type_source; #endif if(((UPS.Status >> 7) & 0x01) == 0) AKBconnectCurrent = (UPS.Status >> 6) & 0x01; else{ AKBconnectCurrent = 0; } AKBconnectCurrent |= UPS.warn_status & 0x01; UPS.Alarm = (UPS.Alarm & 0xfffffff7) | (AKBconnectCurrent << 3); if (!isValueRecv) { isValueRecv = true; AKBconnectOldState = AKBconnectCurrent; if (AKBconnectCurrent){ log_event_data(LOG_ALARM_AKB, "Авария"); SNMP_SendUserTrap(BATTERY_CONNECT_ALARM); syslog_str(SYSLOG_ERROR, "Авария связи с АКБ"); flUpdateLog = true; #if defined RELAY_OFF_AKB relay_setup_log(CurrROtype_Sourse, OFF_AKB, 1); #endif } else{ log_event_data(LOG_ALARM_AKB, "Норма"); SNMP_SendUserTrap(BATTERY_CONNECT_NORM); syslog_str(SYSLOG_NOTICE, "Связь с АКБ восстановлена"); flUpdateLog = true; #if defined RELAY_OFF_AKB relay_setup_log(CurrROtype_Sourse, OFF_AKB, 0); #endif } return; } // Значение параметра изменилось if (AKBconnectCurrent != AKBconnectOldState) { if(flag_alarm_time){ flag_alarm_time = false; if (!AKBconnectCurrent){ log_event_data(LOG_ALARM_AKB, "Норма"); SNMP_SendUserTrap(BATTERY_CONNECT_NORM); syslog_str(SYSLOG_NOTICE, "Связь с АКБ восстановлена"); flUpdateLog = true; #if defined RELAY_OFF_AKB relay_setup_log(CurrROtype_Sourse, OFF_AKB, 0); #endif } else{ log_event_data(LOG_ALARM_AKB, "Авария"); SNMP_SendUserTrap(BATTERY_CONNECT_ALARM); syslog_str(SYSLOG_ERROR, "Авария связи с АКБ"); flUpdateLog = true; #if defined RELAY_OFF_AKB relay_setup_log(CurrROtype_Sourse, OFF_AKB, 1); #endif } } else{ flag_alarm_time = true; } } #if defined RELAY_OFF_AKB else{ flag_alarm_time = false; if (AKBconnectCurrent) relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, OFF_AKB); } for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){ OldROtype_Sourse[i] = CurrROtype_Sourse[i]; } #endif if(!flag_alarm_time){ if (AKBconnectCurrent){ flCriticalAlarm = true; flLedAlarm = true; } AKBconnectOldState = AKBconnectCurrent; } else{ if (AKBconnectOldState){ flCriticalAlarm = true; flLedAlarm = true; } } #endif } #ifdef AKB_CHANGE_MONITOR /** * @brief Мониторинг параметра замены АКБ */ void AKB_Change_Monitor(void) { uint32_t data_change = sSettings.UPS_Setting.set_data + (31536000*sSettings.UPS_Setting.life_time); TM_RTC_t tmp_data; static bool isValueRecv = false; static uint8_t status_change_akb = 0; uint8_t curr_status_change_akb = 0; TM_RTC_GetDateTime(&tmp_data, TM_RTC_Format_BIN); if (tmp_data.unix >= data_change) { UPS.Alarm |= (1 << 6); curr_status_change_akb = 1; flCriticalAlarm = true; flLedAlarm = true; } else { UPS.Alarm &= 0xffffffbf; curr_status_change_akb = 0; } if (!isValueRecv) { isValueRecv = true; status_change_akb = curr_status_change_akb; if (curr_status_change_akb){ log_event_data(LOG_ALARM_CHANGE_AKB, "Авария"); SNMP_SendUserTrap(BATTERY_CHANGE_ALARM); flUpdateLog = true; } else{ log_event_data(LOG_ALARM_CHANGE_AKB, "Норма"); SNMP_SendUserTrap(BATTERY_CHANGE_MORM); flUpdateLog = true; } return; } // Значение параметра изменилось if (status_change_akb != curr_status_change_akb) { if (curr_status_change_akb){ log_event_data(LOG_ALARM_CHANGE_AKB, "Авария"); SNMP_SendUserTrap(BATTERY_CHANGE_ALARM); flUpdateLog = true; } else { log_event_data(LOG_ALARM_CHANGE_AKB, "Норма"); SNMP_SendUserTrap(BATTERY_CHANGE_MORM); flUpdateLog = true; } } status_change_akb = curr_status_change_akb; } #endif #ifdef UPS_FAILED_MONITOR void UPS_Failed_Monitor(void) { static bool isValueRecv = false; static uint8_t UPSFailOldState = 0; uint8_t UPSFailCurrent; UPSFailCurrent = (UPS.Status >> 4) & 0x01; if (!isValueRecv) { isValueRecv = true; UPSFailOldState = UPSFailCurrent; if (UPSFailCurrent){ log_event_data(LOG_ALARM_UPS_FAILED, "Авария"); SNMP_SendUserTrap(UPS_ALARM); flUpdateLog = true; } else{ log_event_data(LOG_ALARM_UPS_FAILED, "Норма"); SNMP_SendUserTrap(UPS_NORM); flUpdateLog = true; } return; } if (UPSFailCurrent){ flCriticalAlarm = true; flLedAlarm = true; } // Значение параметра изменилось if (UPSFailCurrent != UPSFailOldState) { if (UPSFailCurrent){ log_event_data(LOG_ALARM_UPS_FAILED, "Авария"); SNMP_SendUserTrap(UPS_ALARM); flUpdateLog = true; } else{ log_event_data(LOG_ALARM_UPS_FAILED, "Норма"); SNMP_SendUserTrap(UPS_NORM); flUpdateLog = true; } } UPSFailOldState = UPSFailCurrent; } #endif #ifdef PHASE_FAIL_MONITOR void UPS_PhaseFailMonitor(void) { static bool isValueRecv = false; uint8_t phaseStatusCurrent; static uint8_t phaseStatusOld = 0; phaseStatusCurrent = ((UPS.warn_status >> 1) & 0x01); if (phaseStatusCurrent != 0){ flCriticalAlarm = true; flLedAlarm = true; UPS.Alarm = (UPS.Alarm & 0xfffffeff) | (1 << 8); } else { UPS.Alarm = (UPS.Alarm & 0xfffffeff); } if (!isValueRecv) { isValueRecv = true; phaseStatusOld = phaseStatusCurrent; if (phaseStatusCurrent != 0){ log_event_data(LOG_PHASE_FAIL, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(PHASE_FAIL); syslog(SYSLOG_ERROR, "Ошибка подкл. вх. напряжения"); flUpdateLog = true; } else{ log_event_data(LOG_PHASE_FAIL, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(PHASE_NORM); syslog(SYSLOG_NOTICE, "Подкл. вх. напряжения в норме"); flUpdateLog = true; } return; } if (phaseStatusCurrent) { if (phaseStatusCurrent != phaseStatusOld) { log_event_data(LOG_PHASE_FAIL, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(PHASE_FAIL); syslog(SYSLOG_ERROR, "Ошибка подкл. вх. напряжения"); flUpdateLog = true; } } /* Отслеживается нормализация */ else { if (phaseStatusCurrent != phaseStatusOld) { log_event_data(LOG_PHASE_FAIL, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(PHASE_NORM); syslog(SYSLOG_NOTICE, "Подкл. вх. напряжения в норме"); flUpdateLog = true; } } phaseStatusOld = phaseStatusCurrent; } #endif #ifdef EPO_MONITOR void UPS_EPOMonitor(void) { static bool isValueRecv = false; uint8_t EPOStatusCurrent; static uint8_t EPOStatusOld = 0; EPOStatusCurrent = ((UPS.warn_status >> 8) & 0x01); if (EPOStatusCurrent != 0){ flCriticalAlarm = true; flLedAlarm = true; UPS.Alarm = (UPS.Alarm & 0xfffffdff) | (1 << 9); } else { UPS.Alarm = (UPS.Alarm & 0xfffffdff); } if (!isValueRecv) { isValueRecv = true; EPOStatusOld = EPOStatusCurrent; if (EPOStatusCurrent != 0){ log_event_data(LOG_EPO_FAIL, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(EPO_FAIL); syslog(SYSLOG_ERROR, "Срабатывание EPO"); flUpdateLog = true; } else{ log_event_data(LOG_EPO_FAIL, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(EPO_NORM); syslog(SYSLOG_NOTICE, "EPO в норме"); flUpdateLog = true; } return; } if (EPOStatusCurrent) { if (EPOStatusCurrent != EPOStatusOld) { log_event_data(LOG_EPO_FAIL, "Авария"); // Отправка трапа о завышении SNMP_SendUserTrap(EPO_FAIL); syslog(SYSLOG_ERROR, "Ошибка EPO"); flUpdateLog = true; } } /* Отслеживается нормализация */ else { if (EPOStatusCurrent != EPOStatusOld) { log_event_data(LOG_EPO_FAIL, "Норма"); // Отправка трапа о нормализации SNMP_SendUserTrap(EPO_NORM); syslog(SYSLOG_NOTICE, "EPO в норме"); flUpdateLog = true; } } EPOStatusOld = EPOStatusCurrent; } #endif #ifdef OVERTEMPRATURE_MONITOR void UPS_OverTempratureMonitor(void) { if ((UPS.fault_type == 0x41) && (UPS.Temp < 55) && ((UPS.Status >> 7) & 0x01)) { UPScmd(ups_remote_turn_off); xTimerStart(UPSRestartTimer, 0); UPS.fault_type = 0; } } #endif #ifdef INVERTERHIGHVOLTAGE_MONITOR void UPS_InventerHighVoltageMonitor(void) { if(UPS.fault_type == 0x12) { xTimerStart(UPSTurnOffTimer, 0); UPS.fault_type = 0; } } #endif /********************************* (C) РОТЕК **********************************/