364 lines
10 KiB
C++
364 lines
10 KiB
C++
#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();
|
||
};
|