eis/eqpalg/.do_not_use/otheralg/exp.cpp

659 lines
24 KiB
C++
Raw Normal View History

/******************************************************************************************************************
* Action instruction algorithm
*
* arg[0] action expression
* arg[1] feedback expression
* arg[2] expression of judgment result
*
* 1.0 2020-12-17 zoufuzhou
******************************************************************************************************************/
#include <eqpalg/algs/exp.h>
#include <eqpalg/exp_macro/get_macro_replaced_exp.h>
#include <eqpalg/utility/build_alarm_info.h>
#include <eqpalg/utility/entCentExit.h>
#include <eqpalg/utility/instance_lock.h>
#include <float.h>
#include <mix_cc/ihyper_db/utility.h>
#include <mix_cc/type/mix_time.h>
#include <memory>
#include <unordered_map>
#include <vector>
Exp::Exp(const string& name, const mix_cc::json& rule_json,
const string& ruleId, size_t dims)
: AlgBase(name, rule_json, ruleId), dims_(dims) {
logger_.reset(new LOG("Exp:" + rule_name_, AUTO_CATCH_PID));
}
Exp::~Exp() {
// utility::unlock_file(rule_id_);
}
int Exp::init() {
int ret = 0;
try {
ret += AlgBase::init(); /*1.tag点2.执行周期*/
// 重新载入数据源配置信息
ret += this->reload_config_data_source(); /*3.数据源*/
// 在载入数据源信息完成后载入表达式配置之前必须刷新变量把变量信息初始化到mm_vars内
ret += this->first_fill_mm_vars(); /*4.数据项*/
// 必须在刷新变量后,才可以初始化表达式
ret += this->reload_config_exp_act(); /*5.动作表达式*/
if (feedback_mode_) {
ret += this->reload_config_exp_feedback(); /*6.反馈表达式*/
}
} catch (const std::exception& e) {
std::throw_with_nested(
mix_cc::Exception(-1, "load error", BOOST_CURRENT_LOCATION));
}
return ret;
}
AlarmInfo Exp::exec_mon() {
AlarmInfo out_alarm{};
try {
this->refresh_now_time();
// 根据数据来源种类,决定最后的执行过程
switch (data_source_) {
// 如果是共享内存,只需要执行当前周期的数据和表达式
// 并判断是否报警
case DataSource::MEMORY: {
refresh_exp_vars_mem();
if (this->refresh_counts_ < 3) {
this->refresh_counts_++;
} else {
out_alarm = mon_proc();
}
} break;
// 如果是ihyperDB
case DataSource::IHDB:
// 需要先重新载入ihyperDB的缓存数据
refresh_ihd_cache();
// 然后刷以此把缓存中的数据取出
for (auto i = 0; i < queried_data_.rows(); i++) {
refresh_exp_vars_ihd(i);
if (!out_alarm.alarmed) {
auto tmp = mon_proc();
if (tmp.alarmed) {
out_alarm = (tmp);
}
}
}
break;
default:
break;
}
} catch (const std::exception& e) {
gb_logger_->log_exception(e);
}
return out_alarm;
}
// 单次执行
std::vector<AlarmInfo> Exp::exec_task(mix_cc::time_range_t time_range) {
std::vector<AlarmInfo> out_alarms;
try {
// 刷一遍 mmvar 防止p1_3数据错误带来的问题
now_time_ = time_range.get_left() - query_interval_time_;
if (this->delay_time_ > this->ihd_min_time_particles_ &&
(this->delay_time_.count() % this->ihd_min_time_particles_.count() ==
0)) {
refresh_ihd_cache(this->delay_time_);
} else {
refresh_ihd_cache();
}
for (auto i = 0; i < queried_data_.rows(); i++) {
refresh_exp_vars_ihd(i);
}
// 对每个ihdb 查询周期的数据,进行处理
for (auto now_time = time_range.get_left();
now_time <= time_range.get_right(); now_time += query_interval_time_) {
this->now_time_ = now_time;
if (this->delay_time_ > this->ihd_min_time_particles_ &&
(this->delay_time_.count() % this->ihd_min_time_particles_.count() ==
0)) {
refresh_ihd_cache(this->delay_time_);
} else {
refresh_ihd_cache();
}
for (auto i = 0; i < queried_data_.rows(); i++) {
refresh_exp_vars_ihd(i);
// gb_logger_->log_info(this->rule_name_+":测试");
auto tmp = mon_proc();
if (tmp.alarmed) {
// gb_logger_->log_info(this->rule_name_+"满足报警");
out_alarms.push_back(tmp);
}
}
}
// utility::unlock_file(rule_id_);
gb_logger_->log_info("本次测试报警数量:" +
std::to_string(out_alarms.size()));
auto msg =
rule_name_ + "本次测试报警数量:" + std::to_string(out_alarms.size());
auto alarm_task = utility::build_alarm_info(
MsgLevel::INFO, rule_id_, rule_name_, "EXPACT", msg, time_range);
out_alarms.clear();
out_alarms.push_back(alarm_task);
} catch (const std::exception& e) {
gb_logger_->log_exception(e);
}
return out_alarms;
}
AlarmInfo Exp::mon_proc() {
// 监控基本过程
double result_value;
try {
// 获得是否满足前提条件表达式
act_triggered_ = static_cast<bool>(exp_act_->evaluate());
// 如果是反馈模式
if (feedback_mode_) {
// 获得是否满足反馈条件表达式
feedback_triggered_ = static_cast<bool>(exp_feedback_->evaluate());
// 如果
if (act_start_done()) {
// print_exp_vars();
return AlarmInfo{};
}
if (act_not_hold()) {
return AlarmInfo{};
}
if (act_done()) {
result_value = exp_result_->evaluate();
print_exp_vars();
logger_->Debug() << " action end:"
<< mix_cc::mix_time_t(query_time_range_.get_right())
.to_formatted_time()
<< " timediff:" << mm_vars["time"]
<< " exp:" << exp_str_ << "=" << result_value << endl;
if (result_value) {
std::string msg_tag = "";
if (exp_str_ == "isEntOK" || exp_str_ == "isCentOK" ||
exp_str_ == "isExitOK") {
for (int i = 0; i < m_tags.size(); i++) {
msg_tag +=
"tag" + std::to_string(i + 1) + ":" +
std::to_string(mm_vars["tag" + std::to_string(i + 1)]) + " ";
}
}
if (exp_str_.find("mx_tag") != std::string::npos) {
for (int i = 0; i < m_tags.size(); i++) {
// msg_tag +=
// "max(tag" + std::to_string(i + 1) + "):" +
// std::to_string(mm_vars["mx_tag" + std::to_string(i + 1)]) +
// " " + "min(tag" + std::to_string(i + 1) + "):" +
// std::to_string(mm_vars["mi_tag" + std::to_string(i + 1)]) +
// " ";
msg_tag +=
std::to_string(mm_vars["mx_tag" + std::to_string(i + 1)] -
mm_vars["mi_tag" + std::to_string(i + 1)]) +
" ";
}
}
auto msg = rule_name_ + " " + error_str_ + msg_tag;
logger_->Debug() << msg << endl;
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_,
rule_name_, "EXPACT", msg,
query_time_range_);
}
} else if (act_timeout()) {
return this->get_timeout_alarm();
}
}
// 不是动作反馈则act_triggered_ 即为报警触发条件 2021-10-27
else {
if (act_triggered_) {
print_exp_vars();
auto msg = rule_name_ + " " + error_str_;
logger_->Debug() << msg << endl;
this->query_time_range_.set_left(query_time_range_.get_right() -
delay_time_); //
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
"EXP", msg, query_time_range_);
}
}
} catch (const std::exception& e) {
std::throw_with_nested(
mix_cc::Exception(-1, "mon_proc error", BOOST_CURRENT_LOCATION));
}
return AlarmInfo{};
}
mix_cc::json Exp::exec_cron() { return {}; }
bool Exp::act_start_done() {
// 如果动作未开始且前提条件满足
if (!act_started_ && act_triggered_) {
// 则认为动作开始,并置动作开始时间为当前时间
act_started_ = true;
act_start_time_ = this->now_time_;
for (unsigned int i = 0; i < m_tags.size(); i++) {
// s[n] 表示tag[n]在动作开始时刻的起始值
mm_vars["s" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["stime"] =
duration_cast<milliseconds>(now_time_.time_since_epoch()).count();
// mv2 变量
mm_vars["mx_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["mi_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
// mm_vars["mx_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
// mm_vars["mi_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
mm_vars["mv2_p" + std::to_string(i + 1)] = 0;
if (mm_vars["tag" + std::to_string(i + 1)] == 1) {
mm_vars["mv2_tag" + std::to_string(i + 1)] = 1;
}
if (mm_vars["p" + std::to_string(i + 1)] == 1) {
mm_vars["mv2_p" + std::to_string(i + 1)] = 1;
}
}
// 重设query time range 的 left使得时间下限为报警的时间开始
this->query_time_range_.set_left(now_time_);
// 检查动作开时间条件是否错误
logger_->Debug() << " action start:"
<< mix_cc::mix_time_t(act_start_time_).to_formatted_time()
<< endl;
return true;
}
return false;
}
AlarmInfo Exp::cron_proc() { return AlarmInfo{}; }
bool Exp::act_not_hold() {
// 如果动作开始,且需要保持,且动作开始没有被触发,
if (act_started_ && keep_mode_ && !act_triggered_) {
// 开始条件act_started置为假即动作停止
act_started_ = false;
logger_->Debug() << " action signal is not holding " << endl;
return true;
}
return false;
}
bool Exp::act_done() {
// 如果动作已开始 刷新 mv2_tag[n]
if (act_started_) {
for (unsigned int i = 0; i < m_tags.size(); i++) {
mm_vars["mx_tag" + std::to_string(i + 1)] =
std::max(mm_vars["tag" + std::to_string(i + 1)],
mm_vars["mx_tag" + std::to_string(i + 1)]);
mm_vars["mi_tag" + std::to_string(i + 1)] =
std::min(mm_vars["tag" + std::to_string(i + 1)],
mm_vars["mi_tag" + std::to_string(i + 1)]);
// mm_vars["mx_p" + std::to_string(i + 1)] =
// std::max(mm_vars["p" + std::to_string(i + 1)],
// mm_vars["mx_p" + std::to_string(i + 1)]);
// mm_vars["mi_p" + std::to_string(i + 1)] =
// std::min(mm_vars["p" + std::to_string(i + 1)],
// mm_vars["mi_p" + std::to_string(i + 1)]);
if (mm_vars["tag" + std::to_string(i + 1)] == 1) {
mm_vars["mv2_tag" + std::to_string(i + 1)] += 1;
}
if (mm_vars["p" + std::to_string(i + 1)] == 1) {
mm_vars["mv2_p" + std::to_string(i + 1)] += 1;
}
}
}
// 如果动作处于开始状态,且反馈模式触发
if (act_started_ && feedback_triggered_) {
// 则记录下结束时间
mm_vars["etime"] = mm_vars["now"];
mm_vars["time"] = mm_vars["etime"] - mm_vars["stime"];
act_started_ = false;
return true;
}
return false;
}
// 表达式系统触发-反馈动作超时
bool Exp::act_timeout() {
if (time_out_ == milliseconds(0)) {
// 重置mv_tag 防止崩溃
for (unsigned int i = 0; i < m_tags.size(); i++) {
if (abs(mm_vars["mv2_tag" + std::to_string(i + 1)] - DBL_MAX) < 2.0) {
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
mm_vars["mv2_p" + std::to_string(i + 1)] = 0;
this->logger_->Debug()
<< "mv2_tag" + std::to_string(i + 1) << "已达上限,被清空" << endl;
act_started_ = false;
return true; //不再继续
}
}
return false;
}
// 如果当动作处于开始状态 当前时间减去开始时间大于超时时间,则认为超时
if (act_started_ && (now_time_ - act_start_time_) > time_out_) {
act_started_ = false;
// 超时 重置 防止崩溃
logger_->Debug() << "动作反馈超时mv2_tag将被重置" << endl;
for (unsigned int i = 0; i < m_tags.size(); i++) {
logger_->Debug() << "当前mv2_tag" << i + 1 << "="
<< mm_vars["mv2_tag" + std::to_string(i + 1)] << "s"
<< endl;
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
mm_vars["mv2_p" + std::to_string(i + 1)] = 0;
}
return true;
}
return false;
}
// 得到报警超时信息
AlarmInfo Exp::get_timeout_alarm() {
auto msg = rule_name_ + " no feedback on the action";
logger_->Debug() << msg << endl;
return utility::build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
"EXPACT", msg, query_time_range_);
}
int Exp::reload_config_exp_feedback() {
// 获取feedback信息
if (rule_json_.at("action_condition").contains("action_hold")) {
// 判断是否保持
keep_mode_ =
rule_json_.at("action_condition").at("action_hold").at(1).get<int>();
logger_->Debug() << "keep:" << keep_mode_ << endl;
time_out_ = milliseconds(
rule_json_.at("interval").at("timeout").at(1).get<int64_t>());
// 如果超时时间小于3分钟则默认为超时时间为3分钟
if (time_out_ < minutes(3) && time_out_ != milliseconds(0)) {
time_out_ = minutes(3);
}
// 获取feedback表达式
logger_->Debug() << "timeout:" << time_out_.count() << endl;
auto tmp_exp = string(rule_json_.at("action_condition")
.at("action_end")
.at(1)
.get<std::string>());
exp_str_ = get_macro_replaced_exp(tmp_exp);
// 构建feedback表达式
// exp_feedback_ =
// std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
// logger_->Debug() << exp_str_ << ":" << exp_feedback_->evaluate() << endl;
// 2022-1-18 测试
try {
exp_feedback_ =
std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
logger_->Debug() << exp_str_ << ":" << exp_feedback_->evaluate() << endl;
} catch (const std::exception& e) {
logger_->Error() << exp_str_ << "计算错误:" << e.what() << endl;
}
} else {
time_out_ = milliseconds(600000);
}
// 获取监控变量信息
auto tmp_exp =
rule_json_.at("alarm_option").at("value").at(1).get<std::string>();
exp_str_ = get_macro_replaced_exp(tmp_exp);
// 获取
error_str_ =
rule_json_.at("alarm_option").at("error").at(1).get<std::string>();
// 如果结果表达式没有初始化,则初始化之后再次使用
try {
if (exp_result_ == nullptr) {
exp_result_ =
std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
logger_->Debug() << exp_str_ << ":" << exp_result_->evaluate() << endl;
} else {
logger_->Info() << "指针已经初始化完成" << exp_str_ << ":"
<< exp_result_->evaluate() << endl;
}
} catch (const std::exception& e) {
logger_->Error() << exp_result_ << "计算错误:" << e.what() << endl;
}
// if (exp_result_ == nullptr) {
// exp_result_ =
// std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
// logger_->Debug() << exp_str_ << ":" << exp_result_->evaluate() << endl;
// } else {
// logger_->Info() << "指针已经初始化完成" << exp_str_ << ":"
// << exp_result_->evaluate() << endl;
// }
if (exp_str_.find("time", 0) != string::npos) {
m_timemode = true;
} else {
m_timemode = false;
}
return 0;
}
// 刷新共享内存所对应的变量
int Exp::refresh_exp_vars_mem() {
refresh_now_time();
for (unsigned int i = 0; i < m_tags.size(); i++) {
// s[n] 表示tag[n]在动作开始时刻的起始值
// p[n] 表示tag[n]在上一个动作周期的数值
mm_vars["p" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["tag" + std::to_string(i + 1)] =
SingletonTemplate<GlobaltemSharedMemory>::GetInstance()[m_tags[i]];
mm_vars["now"] =
duration_cast<milliseconds>(now_time_.time_since_epoch()).count();
auto pv_str = "pv" + std::to_string(i + 1);
mm_vars[pv_str + "_4"] = mm_vars[pv_str + "_3"];
mm_vars[pv_str + "_3"] = mm_vars[pv_str + "_2"];
mm_vars[pv_str + "_2"] = mm_vars[pv_str + "_1"];
mm_vars[pv_str + "_1"] = mm_vars[pv_str + "_0"];
mm_vars[pv_str + "_0"] = mm_vars["tag" + std::to_string(i + 1)];
}
mm_vars["isEntOK"] = SingletonTemplate<entCentExit>::GetInstance().isEntOK();
mm_vars["isCentOK"] =
SingletonTemplate<entCentExit>::GetInstance().isCentOK();
mm_vars["isExitOK"] =
SingletonTemplate<entCentExit>::GetInstance().isExitOK();
// 设置right的时间
this->query_time_range_.set_right(now_time_);
return 0;
}
// 重新载入数据源配置
int Exp::reload_config_data_source() {
int res = 0;
if (!rule_json_.contains("datasource")) {
data_source_ = 0;
logger_->Debug()
<< "默认数据源为iHyerDB data source[0:iHyerDB1:memory]"
<< data_source_ << endl;
return 0;
}
try {
data_source_ =
std::stoi(rule_json_.at("datasource").at("value").get<std::string>());
logger_->Debug() << "data source[0:iHyerDB1:memory]:" << data_source_
<< endl;
} catch (const std::exception& e) {
gb_logger_->log_error(std::string("ExpBase::reload_config_data_source()") +
e.what());
this->error_code_list_.push_back(
{ErrorType::Empty, ErrorLocation::DataSource});
return -1;
}
return 0;
}
// 刷新对应ihd cache内第row行的数据变量
int Exp::refresh_exp_vars_ihd(int row) {
// i <= row 原本查询时间对应的是[t1,t2)
// 则queried_time_内部的时间也一定是[t1,t2)
for (unsigned int i = 0; i < m_tags.size(); i++) {
mm_vars["p" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["tag" + std::to_string(i + 1)] = queried_data_(row, i);
auto pv_str = "pv" + std::to_string(i + 1);
mm_vars[pv_str + "_4"] = mm_vars[pv_str + "_3"];
mm_vars[pv_str + "_3"] = mm_vars[pv_str + "_2"];
mm_vars[pv_str + "_2"] = mm_vars[pv_str + "_1"];
mm_vars[pv_str + "_1"] = mm_vars[pv_str + "_0"];
mm_vars[pv_str + "_0"] = mm_vars["tag" + std::to_string(i + 1)];
//
mm_vars["now"] = mix_cc::mix_time_t(queried_time_[row]).to_milliseconds();
// right一定小于t2
this->query_time_range_.set_right(queried_time_[row]);
// 当前时间 == 上次执行的结束时间
this->now_time_ = queried_time_[row];
}
mm_vars["isEntOK"] =
SingletonTemplate<entCentExit>::GetInstance().isEntOK_ihd();
mm_vars["isCentOK"] =
SingletonTemplate<entCentExit>::GetInstance().isCentOK_ihd();
mm_vars["isExitOK"] =
SingletonTemplate<entCentExit>::GetInstance().isExitOK_ihd();
return 0;
}
// 程序启动时刻的,首次刷新变量数据
// 防止程序因为p1 pv1类似的变量导致程序的变量差值信息错误
int Exp::first_fill_mm_vars() {
if (data_source_ == DataSource::MEMORY) {
mm_vars["isEntOK"] = false;
mm_vars["isCentOK"] = false;
mm_vars["isExitOK"] = false;
for (unsigned int i = 0; i < m_tags.size(); i++) {
auto pv_str = "pv" + std::to_string(i + 1);
auto value =
SingletonTemplate<GlobaltemSharedMemory>::GetInstance()[m_tags[i]];
mm_vars["s" + std::to_string(i + 1)] = value;
mm_vars["p" + std::to_string(i + 1)] = value;
mm_vars["tag" + std::to_string(i + 1)] = value;
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
mm_vars["mv2_p" + std::to_string(i + 1)] = 0;
mm_vars["mx_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["mi_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
// mm_vars["mx_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
// mm_vars["mi_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
mm_vars[pv_str + "_0"] = value;
mm_vars[pv_str + "_1"] = value;
mm_vars[pv_str + "_2"] = value;
mm_vars[pv_str + "_3"] = value;
mm_vars[pv_str + "_4"] = value;
mm_vars["stime"] = 0;
mm_vars["now"] = 0;
mm_vars["etime"] = 0;
mm_vars["time"] = 0;
}
} else if (data_source_ == DataSource::IHDB) {
this->refresh_now_time();
this->refresh_ihd_cache();
if (queried_data_.rows() == 0) {
logger_->Error() << "first_fill_mm_vars(),IHDB查询异常未查到数据"
<< endl;
this->error_code_list_.push_back(
{ErrorType::Empty, ErrorLocation::DataValue});
return -1;
}
mm_vars["isEntOK"] = false;
mm_vars["isCentOK"] = false;
mm_vars["isExitOK"] = false;
for (unsigned int i = 0; i < m_tags.size(); i++) {
auto pv_str = "pv" + std::to_string(i + 1);
auto rows = queried_data_.rows() - 1;
auto tmp_val = queried_data_(rows, i);
mm_vars["s" + std::to_string(i + 1)] = tmp_val;
mm_vars["p" + std::to_string(i + 1)] = tmp_val;
mm_vars["tag" + std::to_string(i + 1)] = tmp_val;
mm_vars["mv2_tag" + std::to_string(i + 1)] = 0;
mm_vars["mv2_p" + std::to_string(i + 1)] = 0;
mm_vars["mx_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
mm_vars["mi_tag" + std::to_string(i + 1)] =
mm_vars["tag" + std::to_string(i + 1)];
// mm_vars["mx_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
// mm_vars["mi_p" + std::to_string(i + 1)] =
// mm_vars["p" + std::to_string(i + 1)];
mm_vars[pv_str + "_0"] = tmp_val;
mm_vars[pv_str + "_1"] = tmp_val;
mm_vars[pv_str + "_2"] = tmp_val;
mm_vars[pv_str + "_3"] = tmp_val;
mm_vars[pv_str + "_4"] = tmp_val;
mm_vars["stime"] = 0;
mm_vars["now"] = 0;
mm_vars["etime"] = 0;
mm_vars["time"] = 0;
}
}
return 0;
}
int Exp::reload_config_exp_act() {
// 根据key对不同版本的算法都进行取值
if (rule_json_.at("action_condition").contains("action_start")) {
auto tmp_exp = rule_json_.at("action_condition")
.at("action_start")
.at(1)
.get<std::string>();
exp_str_ = get_macro_replaced_exp(tmp_exp);
feedback_mode_ = true;
} else if (rule_json_.at("action_condition").contains("value")) {
auto tmp_exp =
rule_json_.at("action_condition").at("value").at(1).get<std::string>();
exp_str_ = get_macro_replaced_exp(tmp_exp);
if (rule_json_.at("action_condition").contains("error")) {
error_str_ = rule_json_.at("action_condition")
.at("error")
.at(1)
.get<std::string>();
}
feedback_mode_ = false;
}
if (exp_act_ == nullptr && exp_str_ != "") {
// exp_act_ =
// std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
// logger_->Debug() << "exp_act:" << exp_str_ << "=" << exp_act_->evaluate()
// << endl;
// 2022-1-18 测试
try {
exp_act_ =
std::make_unique<mix_cc::matheval::Expression>(exp_str_, &mm_vars);
logger_->Debug() << "exp_act:" << exp_str_ << "=" << exp_act_->evaluate()
<< endl;
} catch (const std::exception& e) {
logger_->Error() << "exp_act:" << exp_str_ << "计算出错:" << e.what()
<< endl;
}
}
return 0;
}
// 打印表达式信息
void Exp::print_exp_vars(const string& expstr) {
std::map<std::string, double>::iterator it;
logger_->Debug() << "exp:" << expstr << " parameter:";
for (it = mm_vars.begin(); it != mm_vars.end(); it++) {
logger_->Debug() << " " << it->first << ":" << it->second;
}
logger_->Debug() << endl;
}
void Exp::set_last_alarm_time(TimePoint time_point) {
this->refresh_counts_ = 0;
if (this->is_usable_) {
this->first_fill_mm_vars(); ///<打破原动作状态
}
AlgBase::set_last_alarm_time(time_point);
}
void Exp::set_usable(bool usable) {
this->refresh_counts_ = 0;
if (this->is_usable_) {
this->first_fill_mm_vars(); ///<打破原动作状态
}
AlgBase::set_usable(usable);
}