eis/eqpalg/algs/trend_slope3.cpp

197 lines
7.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "mix_cc/ihyper_db/read_data_stats.h"
#include <base/BitTool.h>
#include <eqpalg/algs/trend_slope3.h>
#include <eqpalg/feature_extraction/daa.h>
#include <eqpalg/utility/build_alarm_info.h>
#include <limits>
#include <string>
#include <utility/StringHelper.h>
#include <vector>
// const double MAX_SLOPE = 100000000; ///<用于设置单边区间的无用侧
TrendSlope3::TrendSlope3(const string name, const mix_cc::json &rule_json,
const string ruleId)
: AlgBase(name, rule_json, ruleId) {
logger_.reset(new LOG("TrendSlope3:" + rule_name_, AUTO_CATCH_PID));
}
TrendSlope3::~TrendSlope3() {
// AlgBase::~AlgBase();
}
int TrendSlope3::init() {
int res = 0;
try {
res += AlgBase::init();
double interval_time = std::stod(rule_json_.at("function")
.at("limit_error")
.at("param")
.at("interval_time")
.at("value")
.get<std::string>());
// limit_time_interval_ = seconds(int(interval_time * 60));
limit_time_interval_ = seconds(int(interval_time));
if (limit_time_interval_ < seconds(1)) {
limit_time_interval_ = seconds(1);
}
/*监控量变化率[%](减少为用负值)*/
limit_slope_ = std::stod(rule_json_.at("function")
.at("limit_error")
.at("param")
.at("diff")
.at("value")
.get<std::string>());
/*单位间隔时间 minutes */
double deltaX = std::stod(rule_json_.at("function")
.at("limit_error")
.at("param")
.at("deltaX")
.at("value")
.get<std::string>());
deltaX_ = seconds(int(deltaX * 60));
/*连续出现次数*/
CS_AVG_SIZE_ = std::stoi(rule_json_.at("function")
.at("limit_error")
.at("param")
.at("CS_AVG_SIZE")
.at("value")
.get<std::string>());
this->rule_stat_.current_value = 0;
error_content_ =
rule_json_.at("output").at("error").at("value").get<std::string>();
logger_->Debug() << "查询均值时间[s]:"
<< limit_time_interval_.count() / 1000
<< ",监控量变化率[%]:" << limit_slope_ << ",单位间隔时间:"
<< deltaX_.count() << "ms,连续出现次数:" << CS_AVG_SIZE_
<< ",报警内容:" << error_content_ << endl;
this->data_source_ = DataSource::IHDB;
} catch (const std::exception &e) {
std::throw_with_nested(
mix_cc::Exception(-1, "load error", BOOST_CURRENT_LOCATION));
}
return res;
}
AlarmInfo TrendSlope3::exec_mon() {
AlarmInfo out_alarm{};
int count_error = 0;
// this->refresh_now_time();
now_time_ =
system_clock::now() - 60s; ///<当前时间 往前1分钟防止查不到ihd数据
vector<double> avg;
double f_slope = 0.0;
double f_slope_max = 0; ///<斜率最大值
try {
/* before --> now*/
auto start_time = now_time_ - this->deltaX_ * CS_AVG_SIZE_;
logger_->Info() << "----开始计算---数据查询" << std::endl;
for (int i = 0; i < CS_AVG_SIZE_ + 1; i++) {
query_time_range_.set_left(start_time - limit_time_interval_);
query_time_range_.set_right(start_time);
if (!query_time_range_.valid()) {
logger_->Error() << "时间数据 不合法" << std::endl;
return out_alarm;
}
logger_->Debug() << "时间范围"
<< mix_cc::mix_time_t(query_time_range_.get_left())
.to_formatted_time()
<< " "
<< mix_cc::mix_time_t(query_time_range_.get_right())
.to_formatted_time()
<< std::endl;
if (refresh_ihd_cache(query_time_range_) != 0) {
logger_->Error() << rule_name_ << ":ihd查询异常" << std::endl;
return out_alarm;
}
if (!get_prr2()) {
logger_->Error() << rule_name_ << ":不满足前提表达式" << std::endl;
return out_alarm;
}
double avgi = queried_data_.col(need_tag_seq_).mean();
avg.push_back(avgi);
logger_->Debug() << "avg[" << i << "]:" << avgi << endl;
start_time = start_time + this->deltaX_;
}
logger_->Info() << "----开始计算---斜率计算" << std::endl;
string msgslope;
for (int i = 0; i < CS_AVG_SIZE_ + 1; i++) {
if (i > 0) {
f_slope =
static_cast<int>(1000.0 * (avg[i] - avg[i - 1]) + 0.5); /// delta Y
f_slope = f_slope / 1000;
if (avg[i - 1] == 0) {
f_slope_max =
(abs(f_slope_max) > abs(f_slope)) ? f_slope_max : f_slope;
} else {
f_slope_max = (abs(f_slope_max) > abs(100 * f_slope / avg[i - 1]))
? f_slope_max
: (100 * f_slope / avg[i - 1]);
}
if ((limit_slope_ > 0 &&
f_slope > abs(limit_slope_ * avg[i - 1] / 100)) ||
(limit_slope_ < 0 &&
-f_slope > abs(limit_slope_ * avg[i - 1]) / 100)) {
msgslope += " " + DAA::double2str(f_slope, 3);
count_error++;
logger_->Debug() << msgslope << endl;
} else {
msgslope = "";
count_error = 0;
break;
}
}
}
// rule_stat_.current_value = f_slope_max; ///<共享内存
if (count_error == CS_AVG_SIZE_) {
rule_stat_.current_value = 1;
rule_stat_.alarm_value = rule_stat_.current_value;
string msg = error_content_ + " 斜率变化量:" + msgslope;
logger_->Debug() << msg << endl;
query_time_range_.set_right(now_time_);
query_time_range_.set_left(
now_time_ - (deltaX_ * (CS_AVG_SIZE_)-limit_time_interval_));
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
"SLOPE", msg, query_time_range_);
}
rule_stat_.current_value = 0;
} catch (const std::exception &e) {
std::throw_with_nested(
mix_cc::Exception(-1, "calc error", BOOST_CURRENT_LOCATION));
}
// return AlarmInfo{};
return out_alarm;
}
std::vector<AlarmInfo> TrendSlope3::exec_task(mix_cc::time_range_t time_range) {
std::vector<AlarmInfo> result;
for (auto now_time = time_range.get_left();
now_time <= time_range.get_right(); now_time += delay_time_) {
this->now_time_ = now_time;
auto rr1 = this->exec_mon();
if (rr1.alarmed) {
result.push_back(rr1);
}
}
return result;
}
bool TrendSlope3::get_prr2() {
if (this->prr_ == 1) {
exp_mpdule_ptr_->update(queried_data_, queried_time_);
bool prr_result = (bool)exp_mpdule_ptr_->get_value("pre_result");
this->now_prr_ = prr_result;
logger_->Debug() << "ruleid:" << this->rule_id_
<< ",rulename:" << this->rule_name_
<< " get_prr():" << prr_result << std::endl;
return prr_result;
}
this->now_prr_ = true;
return true;
}