eis/eqpalg/alg_base.h

364 lines
10 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.

#pragma once
/**
* @file eqpalg/alg_base.h
* @brief 所有算法类的基类
* @author Cat (null.null.null@qq.com)
* @version 0.1
* @date 2021-09-17
*
* Copyright: Baosight Co. Ltd.
* DO NOT COPY/USE WITHOUT PERMISSION
*
*/
#include "mix_cc/ihyper_db.h"
#include "mix_cc/json.h"
#include "mix_cc/matheval/matheval.hpp"
#include <chrono>
#include <dsm/public.h>
#include <eqpalg/define/error_code.h>
#include <eqpalg/define/public.h>
#include <eqpalg/gb_logger.h>
#include <eqpalg/utility/ExpModule.h>
#include <eqpalg/utility/VarsCache.hpp>
#include <eqpalg/utility/XorShift128Plus.hpp>
#include <eqpalg/utility/alarm_poster.h>
#include <eqpalg/utility/condition_monitor.hpp>
#include <eqpalg/utility/eqp_stat.h>
#include <memory>
#include <mutex>
#include <shm/RuleStatShm.h>
#include <shm/SingletonTemp.hpp>
#include <string>
#include <unordered_map>
#include <vector>
#include <zlib/MemVar.h>
using std::string;
using namespace std::chrono;
using std::chrono::system_clock;
using TimePoint = system_clock::time_point;
using TimeDur = milliseconds;
/**
* @brief 所有算法类的基类
*/
class AlgBase {
protected:
std::map<std::string, double> mm_vars; ///< 表达式系统变量map
const size_t pv_num_ = 6;
VarsCache var_cache_; ///< mmvar_变量明 预分配
const string rule_id_; ///< 算法实例id,在AlgBase基类内部初始化
const string rule_name_; ///< 算法实例名称在AlgBase内部初始化
const mix_cc::json rule_json_; ///< 规则json对象,在AlgBase基类内部初始化
std::unique_ptr<GbLogger> gb_logger_; ///< 全局logger指针
std::unique_ptr<LOG>
logger_; ///< 基类的logger指针,子类需要使用使用reset方法重置为子类的指针
TimePoint last_run_start_time_; ///< 上次运行的开始时间
TimePoint last_save_start_time_; ///< 上次调用保存数据函数的开始时间
TimePoint
last_rule_state_updae_start_time_; ///< 上次调用保存数据函数的开始时间
TimePoint last_heart_beat_start_time_; ///< 上次规则运行 活跃 心跳检测日志
TimePoint this_run_start_time_; ///< 本次运行的开始时间
TimePoint now_time_; ///< 当前正在执行时的时间
int data_source_ = 1; ///< 数据来源,0:iHyperDB,1:memory
TimePoint last_alarm_time_; ///< 上次报警的时间,用于外部类使用
TimeDur delay_time_; ///< 每次执行的时间间隔在AlgBase内部初始化
TimeDur query_interval_time_ = hours(
CMemVar::Const()->eis_qihd_interval_time); ///< cron task 查询最大时间区间
// TimeDur ihd_min_time_particles_ = 50ms; ///<
// iHyperDB数据查询最小时间颗粒
TimeDur ihd_min_time_particles_ = 20ms; ///< iHyperDB数据查询最小时间颗粒
vector<string> m_tags; ///< 保存的tag点名
bool is_usable_; ///< 算法是否可用
// bool is_cron_run = false; ///< cron是否已经完成
bool is_running_ = true; ///< 算法是否正在执行
// int smooth_type_ = 0; ///<
// 数据平滑方式0为不更改1为高斯,此部分暂时未完成
utility::AlarmPoster alarm_poster_; ///< 发送报警信息
string remark_ =
"0"; ///<通知方式 0-不通知1-短信+语音单次通知 2-短信单次+语音多次
std::mutex lm;
RuleStatShm::RuleStat rule_stat_; ///<规则的统计参数,给页面
std::string error_message_str_; ///<参数错误提示语
std::vector<ErrorCodeType> error_code_list_; ///<错误码{错误类型,错误位置}
int prr_ = PRR::None; ///<规则运行前提条件
// int spd_th_ = 1; ///<规则运行前提条件
// bool need_prr_ = false; ///<是否需要规则执行的前提条件
// std::string pre_item_; ///<前提条件 item
// double pre_min_ = 0; ///<前提条件最小值
std::unique_ptr<ExpModule> exp_mpdule_ptr_; ///<表达式模块
DataInfo data_info_; ///<运行数据保存信息 保存正常数据
ConditionMonitor con_monitor_; ///<保存正常数据 是否保存判断
bool now_prr_ = false; ///<前提条件是否满足
bool is_exp_alg_ = false; ///<是否是表达式类算法
int task_seq = 0; ///< task线程 线程id
TimeDur save_interval_ms_ = 5000ms; ///< 正常数据保存 间隔时间
TimeDur rule_state_update_interval_ms_ = 500ms; ///< 页面数据更新 间隔时间
public:
void logReset(int task_seq);
/**
* @brief 更新共享内存 map 统计
* @return true
* @return false
*/
bool update_map_rule();
/**
* @brief 创建基类对象
* @param name 算法实例名称
* @param rulejson 算法实例配置
* @param ruleId 算法实例id
*/
AlgBase(const string &name, const mix_cc::json &rule_json,
const string &ruleId);
virtual ~AlgBase();
/**
* @brief 重新载入所有的算法基本信息
* 1.载入数据tag点
* 2.载入执行间隔时间
* 3.载入上次执行时间
* @return int
*/
virtual int init();
/**
* @brief 保持正常数据 start end
*/
virtual void save_rule_norm_data();
/**
* @brief 是否完成执行
* @return true
* @return false
*/
bool get_cycled();
/**
* @brief 是否调用数据保存
* 实现多线程的错峰调度,减少锁竞争
* @return true
* @return false
*/
bool get_save_data_cycled();
/**
* @brief 是否调用 画面数据更新
* 现多线程的错峰调度,减少锁竞争
* @return true
* @return false
*/
bool get_update_rule_stat_cycled();
/**
* @brief 是否打印心跳检测日志 固定 5分钟1条
* @return true
* @return false
*/
bool get_heart_beat_log_cycled();
/**
* @brief 设置算法是否可用
* @param usable 可用性
*/
virtual void set_usable(bool usable);
/**
* @brief 获取是否启用
* @return true
* @return false
*/
bool get_usable() { return this->is_usable_; }
/**
* @brief 获取前提条件是否满足
* @return true
* @return false
*/
virtual bool get_prr();
/**
* @brief Get the rule id object
* @return std::string
*/
std::string get_rule_id() { return this->rule_id_; }
/**
* @brief Get the rule name object
* @return std::string
*/
std::string get_rule_name() { return this->rule_name_; }
/**
* @brief 设置上次报警时间
* @param time_point My Param doc
*/
virtual void set_last_alarm_time(TimePoint time_point = system_clock::now());
/**
* @brief 得到上次报警时间
* @return TimePoint
*/
TimePoint get_last_alarm_time();
/**
* @brief 监控执行,负责执行监控任务
* @return AlarmInfo
*/
virtual AlarmInfo exec_mon() = 0;
/**
* @brief
* 单次执行,负载执行单次任务。在执行单次任务时,对应的监控任务会停止,避免发生重复数据写入
* @param time_range 单次执行的时间
* @return AlarmInfo
*/
virtual std::vector<AlarmInfo> exec_task(mix_cc::time_range_t time_range) = 0;
// normal 单次执行
virtual AlarmInfo exec_normal_task(mix_cc::time_range_t time_range) {
return AlarmInfo{};
};
/**
* @brief
* 定时任务,每隔固定周期对任务进行执行,得到的结果不是报警,而是一个定时任务报告(json形式)
* @return mix_cc::json
*/
virtual mix_cc::json exec_cron();
/**
* @brief 监控执行调用由threads进行调用
* 内部使用纤程保证执行的实时性
*/
void exec_mon_call();
/**
* @brief 单次执行调用
*/
void exec_task_call(const mix_cc::time_range_t &time_range);
void exec_normal_task_call(const mix_cc::time_range_t &time_range);
/**
* @brief 定时任务执行调用
*/
void exec_cron_call();
/**
* @brief Get the is cron run object
* 给线程管理控制停掉cron进程用
* @return true
* @return false
*/
// bool get_is_cron_run(){return this->is_cron_run};
protected:
mix_cc::time_range_t query_time_range_; ///< ihdb查询的时间周期
mix_cc::time_range_t task_time_range_; ////<task进程的时间范围
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>
queried_data_; ///< ihd查询后的数据缓存
std::vector<TimePoint> queried_time_; ///< ihdb查询后的时间缓存
protected:
/**
* @brief 从ihyperdb中刷新该算法所对应的数据
* 共享内存的数据会实时刷新,故不需要此方法
* 这个方法载入的共享内存数据会存放到queried_data_ queried_time_变量中
* @return int
*/
int refresh_ihd_cache();
/**
* @brief 供task用 从ihyperdb中刷新该算法所对应的数据
* @param delay_time 查询ihd间隔时间
* @return int
*/
int refresh_ihd_cache(TimeDur delay_time);
/**
* @brief 指定时间范围查询ihd到 queried_data_
* @param time_range 查询时间范围
* @return int 0-查询成功,其他-查询失败
*/
int refresh_ihd_cache(mix_cc::time_range_t time_range);
/**
* @brief 重新载入tag点名称信息
* @return int
*/
int reload_config_tag();
/**
* @brief 刷新now_time_ 对象,将其置为最新时间
* @return int
*/
int refresh_now_time();
/**
* @brief 指定单个tag和时间范围查询ihd到 queried_data_
* @param tag 数据tag点
* @param time_range 查询时间范围
* @return int 0-查询成功,其他-查询失败
*/
int ihd_get_by_tag(string tag, mix_cc::time_range_t time_range);
public:
/**
* @brief 得到数据来源信息
* @return int
*/
int get_data_source();
/**
* @brief 重置设备管理的累计数据,运行时间、出现次数
* 供类 ExpTimes用
*/
virtual void reset_dev_data(){};
/**
* @brief 更新 通知方式
* 适用于太钢硅钢 弃用
* @return int
*/
// int update_remark();
/**
* @brief
* @param lb 下限
* @param ub 上限
* @param va 当前值
* @param stime 开始时间
* @param etime 结束时间
*/
virtual void update_limit_alarm(double lb, double ub, double va,
int64_t stime = 0, int64_t etime = 0);
protected:
/**
* @brief Get the alarm time object
* @return mix_cc::time_range_t
*/
virtual mix_cc::time_range_t get_alarm_time();
};