eis/eqpalg/algs/trend_slope.cpp

168 lines
6.0 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 <base/BitTool.h>
#include <eqpalg/algs/trend_slope.h>
#include <eqpalg/utility/build_alarm_info.h>
#include <utility/StringHelper.h>
#include <limits>
#include <string>
#include <vector>
#include "mix_cc/ihyper_db/read_data_stats.h"
/*计算次数采用6次出现连续3次*/
#define CS_AVG_SIZE 6
const double MAX_SLOPE = 100000000; ///<用于设置单边区间的无用侧
TrendSlope::TrendSlope(const string name, const mix_cc::json& rule_json,
const string ruleId)
: AlgBase(name, rule_json, ruleId) {
logger_.reset(new LOG("TrendSlope:" + rule_name_, AUTO_CATCH_PID));
}
TrendSlope::~TrendSlope() {
// AlgBase::~AlgBase();
}
int TrendSlope::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_slope_ = std::stod(rule_json_.at("function")
.at("limit_error")
.at("param")
.at("diff")
.at("value")
.get<std::string>());
if (limit_slope_ > 0) {
// this->rule_stat_.limit_down = -MAX_SLOPE;
this->rule_stat_.limit_down = -32768;
this->rule_stat_.limit_up = limit_slope_;
} else {
this->rule_stat_.limit_down = limit_slope_;
// this->rule_stat_.limit_up = MAX_SLOPE;
this->rule_stat_.limit_up = -32768;
}
this->rule_stat_.current_value = 0;
logger_->Debug() << "区间:[" << this->rule_stat_.limit_down << ","
<< this->rule_stat_.limit_up << "]"
<< ",当期值:" << this->rule_stat_.current_value << endl;
error_content_ =
rule_json_.at("output").at("error").at("value").get<std::string>();
logger_->Debug() << "Time interval between:" << limit_time_interval_.count()
<< "ms,slope:" << limit_slope_ << ",报警内容:"
<< 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 TrendSlope::exec_mon() {
AlarmInfo out_alarm{};
int count_error = 0;
this->refresh_now_time();
this->refresh_ihd_cache();
double avg[CS_AVG_SIZE] = {0.0};
double f_slope = 0.0;
double f_slope_max = 0; ///<斜率最大值
try {
/* before --> now*/
// 检查6个周期的时间内数据的斜率是否小于目标斜率
for (int i = 0; i < CS_AVG_SIZE; i++) {
query_time_range_.set_left(now_time_ -
(limit_time_interval_ * (CS_AVG_SIZE - i)));
query_time_range_.set_right(
now_time_ - (limit_time_interval_ * (CS_AVG_SIZE - i - 1)));
if (!query_time_range_.valid()) {
logger_->Error() << "时间数据 不合法" << std::endl;
}
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;
auto data_maybe = mix_cc::ihd::read_data_stats_maybe(
m_tags[0], query_time_range_, HD3_STATS_TYPE_ARITH_MEAN);
if (data_maybe.is_nothing()) {
logger_->Error() << rule_name_ << ":ihd查询异常" << std::endl;
return {};
}
avg[i] = data_maybe.unsafe_get_just();
logger_->Debug() << "avg[" << i << "]:" << avg[i] << endl;
}
string msgslope;
for (int i = 0; i < CS_AVG_SIZE; i++) {
if (i > 0) {
f_slope = static_cast<int>(1000.0 * (avg[i] - avg[i - 1]) + 0.5);
f_slope = f_slope / 1000;
f_slope_max = (abs(f_slope_max) > abs(f_slope)) ? f_slope_max : f_slope;
if ((limit_slope_ > 0 && f_slope > limit_slope_) ||
(limit_slope_ < 0 && f_slope < limit_slope_)) {
msgslope += " " + std::to_string(f_slope);
count_error++;
logger_->Debug() << msgslope << endl;
} else {
if (count_error < 3) {
msgslope = "";
count_error = 0;
} else {
break;
}
}
}
}
rule_stat_.current_value = f_slope_max; ///<共享内存
// if (limit_slope_ > 0) {
// rule_stat_.limit_down = 0;
// rule_stat_.limit_up = limit_slope_;
// } else {
// rule_stat_.limit_down = limit_slope_;
// rule_stat_.limit_up = 0;
// }
if (count_error >= 3) {
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_ -
(limit_time_interval_ * (CS_AVG_SIZE)));
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
"SLOPE", msg, query_time_range_);
}
} 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> TrendSlope::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;
}