210 lines
6.6 KiB
C
210 lines
6.6 KiB
C
|
|
#pragma once
|
|||
|
|
/**
|
|||
|
|
* @file eqpalg/algs/exp_sample.h
|
|||
|
|
* @brief 表达式-样本的实现 基类
|
|||
|
|
* 这个类只会载入样本相关的信息,与前提表达式无关
|
|||
|
|
* @author Cat (null.null.null@qq.com)
|
|||
|
|
* @version 0.1
|
|||
|
|
* @date 2021-09-13
|
|||
|
|
*
|
|||
|
|
* Copyright: Baosight Co. Ltd.
|
|||
|
|
* DO NOT COPY/USE WITHOUT PERMISSION
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
#include <eqpalg/algs/exp.h>
|
|||
|
|
#include <eqpalg/exp_macro/get_macro_replaced_exp.h>
|
|||
|
|
#include <eqpalg/stat_tools/frame.h>
|
|||
|
|
#include <eqpalg/utility/build_alarm_info.h>
|
|||
|
|
#include <eqpalg/utility/instance_lock.h>
|
|||
|
|
#include <iomanip>
|
|||
|
|
#include <map>
|
|||
|
|
#include <memory>
|
|||
|
|
#include <string>
|
|||
|
|
#include <vector>
|
|||
|
|
#include "mix_cc/ihyper_db/utility.h"
|
|||
|
|
#include "mix_cc/json.h"
|
|||
|
|
#include "mix_cc/type/mix_time.h"
|
|||
|
|
/**
|
|||
|
|
* @brief 表达式-样本类的实现
|
|||
|
|
* @tparam dims 样本的维度
|
|||
|
|
* 为什么使用template dims确定样本的维度?
|
|||
|
|
* 因为目前程序维度较低且相对固定
|
|||
|
|
* 这样可以减少运行时开销
|
|||
|
|
* 如果维度较高或不固定,请更改这个策略
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
class ExpSample : public Exp {
|
|||
|
|
public:
|
|||
|
|
/**
|
|||
|
|
* @brief 构建表达式样本类
|
|||
|
|
* @param name My Param doc
|
|||
|
|
* @param rule_json My Param doc
|
|||
|
|
* @param ruleId My Param doc
|
|||
|
|
*/
|
|||
|
|
ExpSample(const string& name, const mix_cc::json& rule_json,
|
|||
|
|
const string& ruleId, size_t dims, double padding_low,
|
|||
|
|
double padding_up)
|
|||
|
|
: Exp(name, rule_json, ruleId, dims),
|
|||
|
|
last_load_time_(system_clock::now()),
|
|||
|
|
padding_low_(padding_low),
|
|||
|
|
padding_up_(padding_up) {
|
|||
|
|
logger_.reset(new LOG("ExpSample:" + rule_name_, AUTO_CATCH_PID));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
virtual ~ExpSample() {}
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
/**
|
|||
|
|
* @brief 重新载入样本表达式中样本相关的配置
|
|||
|
|
* @return int
|
|||
|
|
*/
|
|||
|
|
int init() override;
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
/**
|
|||
|
|
* @brief 执行监控
|
|||
|
|
* @return AlarmInfo
|
|||
|
|
*/
|
|||
|
|
AlarmInfo exec_mon() override;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief cron 根据ihd的速度数据检查机组状态
|
|||
|
|
* @return true
|
|||
|
|
* @return false
|
|||
|
|
*/
|
|||
|
|
bool cron_check_is_line_start();
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
/**
|
|||
|
|
* @brief 重新载入样本相关配置信息
|
|||
|
|
* @return int
|
|||
|
|
*/
|
|||
|
|
int reload_config_sample();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 打印动作开始行为
|
|||
|
|
* @param result_value My Param doc
|
|||
|
|
* @return int
|
|||
|
|
*/
|
|||
|
|
int log_action_info(double result_value);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 重载定时任务函数
|
|||
|
|
* @return mix_cc::json
|
|||
|
|
*/
|
|||
|
|
mix_cc::json exec_cron() override;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 重写exec_normal_task
|
|||
|
|
*/
|
|||
|
|
AlarmInfo exec_normal_task(mix_cc::time_range_t time_range) override;
|
|||
|
|
/**
|
|||
|
|
* @brief 最小的单元过程
|
|||
|
|
* @tparam T
|
|||
|
|
* @tparam ReturnType
|
|||
|
|
* @return ReturnType
|
|||
|
|
*/
|
|||
|
|
template <typename T, typename ReturnType>
|
|||
|
|
ReturnType base_proc() {
|
|||
|
|
double result_value;
|
|||
|
|
try {
|
|||
|
|
act_triggered_ = static_cast<bool>(exp_act_->evaluate());
|
|||
|
|
// 检测是否是表达式-反馈模式
|
|||
|
|
if (feedback_mode_) {
|
|||
|
|
// 如果是表达式反馈-模式,检测是否满足反馈条件
|
|||
|
|
if (act_start_done() || act_not_hold()) {
|
|||
|
|
if constexpr (is_same_v<T, exec_mon_t>) {
|
|||
|
|
return AlarmInfo{};
|
|||
|
|
} else if constexpr (is_same_v<T, exec_cron_t>) {
|
|||
|
|
return std::nullopt;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
feedback_triggered_ = static_cast<bool>(exp_feedback_->evaluate());
|
|||
|
|
// 如果所有前提动作和条件均满足
|
|||
|
|
if (act_done()) {
|
|||
|
|
result_value = exp_result_->evaluate();
|
|||
|
|
this->log_action_info(result_value);
|
|||
|
|
// 刷 mv2
|
|||
|
|
for (size_t i = 0; i < m_tags.size(); i++) {
|
|||
|
|
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
|
|||
|
|
}
|
|||
|
|
// 并且数据合法
|
|||
|
|
if (result_value != 0 && !std::isnan(result_value)) {
|
|||
|
|
if constexpr (is_same_v<T, exec_mon_t>) {
|
|||
|
|
// 检查是否满足报警条件
|
|||
|
|
auto alarm_info = this->sample_stat_->auto_detect_and_save(
|
|||
|
|
SamplePoint{result_value}, now_time_);
|
|||
|
|
// 如果报警,则把报警新返回
|
|||
|
|
if (alarm_info) {
|
|||
|
|
return utility::build_alarm_info(
|
|||
|
|
MsgLevel::ERROR, rule_id_, rule_name_, "EXPSMP",
|
|||
|
|
error_str_ + alarm_info.alarm_str, alarm_info.value,
|
|||
|
|
alarm_info.range, query_time_range_);
|
|||
|
|
}
|
|||
|
|
} else if constexpr (is_same_v<T, exec_cron_t>) {
|
|||
|
|
return std::make_optional(SamplePoint{result_value});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (act_timeout()) {
|
|||
|
|
// 如果超时,则返回
|
|||
|
|
this->get_timeout_alarm();
|
|||
|
|
// 如果有必要,可以返回超时报警信息
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 表达式-样本,无需反馈,act_triggered_即为报警条件 2021-10-27
|
|||
|
|
else if (act_triggered_) {
|
|||
|
|
// 同上,唯一不同 是这里无需假设反馈的条件
|
|||
|
|
result_value = exp_result_->evaluate();
|
|||
|
|
if (result_value != 0 && !std::isnan(result_value)) {
|
|||
|
|
if constexpr (is_same_v<T, exec_mon_t>) {
|
|||
|
|
auto alarm_info = this->sample_stat_->auto_detect_and_save(
|
|||
|
|
SamplePoint{result_value}, now_time_);
|
|||
|
|
if (alarm_info) {
|
|||
|
|
return utility::build_alarm_info(
|
|||
|
|
MsgLevel::ERROR, rule_id_, rule_name_, "EXPSMP",
|
|||
|
|
error_str_ + alarm_info.alarm_str, alarm_info.value,
|
|||
|
|
alarm_info.range, query_time_range_);
|
|||
|
|
}
|
|||
|
|
} else if constexpr (is_same_v<T, exec_cron_t>) {
|
|||
|
|
return std::make_optional(SamplePoint{result_value});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} catch (const std::exception& e) {
|
|||
|
|
std::throw_with_nested(
|
|||
|
|
mix_cc::Exception(-1, "calc_once error", BOOST_CURRENT_LOCATION));
|
|||
|
|
}
|
|||
|
|
if constexpr (is_same_v<T, exec_mon_t>) {
|
|||
|
|
return AlarmInfo{};
|
|||
|
|
} else if constexpr (is_same_v<T, exec_cron_t>) {
|
|||
|
|
return std::nullopt;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AlarmInfo mon_proc() override { return base_proc<exec_mon_t, AlarmInfo>(); }
|
|||
|
|
|
|||
|
|
virtual std::optional<SamplePoint> cron_proc_sample() {
|
|||
|
|
return base_proc<exec_cron_t, std::optional<SamplePoint>>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
TimePoint last_load_time_; ///< 上一次载入的时间
|
|||
|
|
///< ExpSample构造时,初始化为构造时的时间
|
|||
|
|
|
|||
|
|
double judge_diff_; ///< 评判的数据差值
|
|||
|
|
|
|||
|
|
double padding_up_, padding_low_; ///< 数据浮动
|
|||
|
|
|
|||
|
|
stat_tools::TestMode test_mode_; ///< 0: absolute difference, 1: error
|
|||
|
|
///< percentage (%), 2: normal
|
|||
|
|
|
|||
|
|
TimePoint start_date_; ///< 取样开始时间
|
|||
|
|
|
|||
|
|
TimePoint end_date_; ///< 取样结束时间
|
|||
|
|
|
|||
|
|
bool is_no_down_limit_ = false; ///< 是否是无下限算法
|
|||
|
|
|
|||
|
|
int archive_interval_day_; ///< 归档间隔时间
|
|||
|
|
|
|||
|
|
std::unique_ptr<stat_tools::Frame> sample_stat_; ///< 样本统计
|
|||
|
|
};
|