187 lines
6.5 KiB
C++
187 lines
6.5 KiB
C++
|
|
/******************************************************************************************************************
|
|||
|
|
* Action instruction algorithm
|
|||
|
|
*
|
|||
|
|
* arg[0] data determination expression
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
* 1.0 2020-12-17 zoufuzhou
|
|||
|
|
******************************************************************************************************************/
|
|||
|
|
#include <T_PDO_RULE.h>
|
|||
|
|
#include <algorithm>
|
|||
|
|
#include <base/BitTool.h>
|
|||
|
|
#include <base/TCMTime.h>
|
|||
|
|
#include <cmath>
|
|||
|
|
#include <eqpalg/algs/AlgExpHS.h>
|
|||
|
|
#include <mix_cc/algorithm/polyfit.h>
|
|||
|
|
#include <utility/StringHelper.h>
|
|||
|
|
|
|||
|
|
extern std::map<std::string, ITEM> glob_items;
|
|||
|
|
|
|||
|
|
int AlgExpHS::init() {
|
|||
|
|
LOG d("AlgExpHS::init", AUTO_CATCH_PID);
|
|||
|
|
int ret = 0;
|
|||
|
|
try {
|
|||
|
|
|
|||
|
|
mp_trk = new CMemTrk();
|
|||
|
|
|
|||
|
|
} catch (const std::exception &e) {
|
|||
|
|
d.Error() << mix_cc::get_nested_exception(e) << std::endl;
|
|||
|
|
ret = -1;
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AlgExpHS::AlgExpHS(const string name, const Json::Value rulejson,
|
|||
|
|
const string ruleId)
|
|||
|
|
: AlgBase(name, rulejson, ruleId), AlgExp(name, rulejson, ruleId) {
|
|||
|
|
LOG d("AlgExpHS::AlgExpHS", AUTO_CATCH_PID);
|
|||
|
|
try {
|
|||
|
|
|
|||
|
|
m_modest = m_json_param["action_condition"]["mode"][1].asInt();
|
|||
|
|
m_expstr = string(m_json_param["action_condition"]["action_start"][1].asString());
|
|||
|
|
m_zone = m_json_param["action_condition"]["zone"][1].asInt();
|
|||
|
|
d.Debug() << "zone:" << m_zone << endl;
|
|||
|
|
sample_tag_str_ =
|
|||
|
|
m_tags[stoi(m_json_param["alarm_option"]["var"][1].asString().substr(3)) - 1];
|
|||
|
|
temp_tag_str_ =
|
|||
|
|
m_tags[stoi(m_json_param["alarm_option"]["temp"][1].asString().substr(3)) - 1];
|
|||
|
|
test_mode_ = m_json_param["alarm_option"]["mode"][1].asInt();
|
|||
|
|
judge_diff_ = m_json_param["alarm_option"]["value"][1].asDouble();
|
|||
|
|
d.Debug()
|
|||
|
|
<< "modejudge(0: absolute difference, 1: error percentage (%), 2: "
|
|||
|
|
"normal value signal (%) 3: trend 4:polyfit):"
|
|||
|
|
<< test_mode_ << " samplediff:" << judge_diff_ << endl;
|
|||
|
|
|
|||
|
|
this->init();
|
|||
|
|
exp_act_ = new MathExpression(m_expstr.c_str(), mm_vars);
|
|||
|
|
// d.Debug() << m_expstr << ":" << exp_act_->evaluate() << endl;
|
|||
|
|
|
|||
|
|
this->LoadData();
|
|||
|
|
|
|||
|
|
// if(m_expstr.find("time",0) != string::npos)
|
|||
|
|
// if (m_expstr == "time") {
|
|||
|
|
// m_timemode = true;
|
|||
|
|
// } else {
|
|||
|
|
// m_timemode = false;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
if (m_modest == DATA_STAT::HISTORY) {
|
|||
|
|
this->malloc_ihd_mem();
|
|||
|
|
}
|
|||
|
|
d.Debug() << "Init Success" << std::endl;
|
|||
|
|
} catch (const std::exception &e) {
|
|||
|
|
d.Error() << mix_cc::get_nested_exception(e) << std::endl;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AlgExpHS::~AlgExpHS() {
|
|||
|
|
delete mp_trk;
|
|||
|
|
delete exp_act_;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int AlgExpHS::LoadData() {
|
|||
|
|
auto data = db_com_.query_value("T_STA_RULE_MATERIAL_VAG", {},
|
|||
|
|
{{"RULEID", rule_id_, "="}},
|
|||
|
|
"ORDER BY SAMPLEDATE FETCH FIRST 5 ROWS ONLY");
|
|||
|
|
for (auto x : data) {
|
|||
|
|
auto specif = std::string(x.at("STEELGRADECODE").as_string().c_str()) +
|
|||
|
|
std::to_string(x.at("THICKNESS").as_double()) +
|
|||
|
|
std::to_string(x.at("WIDTH").as_double()) +
|
|||
|
|
std::to_string(x.at("SPEED").as_double());
|
|||
|
|
inner_data_[specif].x_.emplace_back(x.at("DATA").as_double());
|
|||
|
|
inner_data_[specif].y_.emplace_back(x.at("TEMP").as_double());
|
|||
|
|
}
|
|||
|
|
for (auto x : inner_data_) {
|
|||
|
|
if (x.second.x_.size() > 20) {
|
|||
|
|
x.second.coeff_ = mix_cc::Polyfit(x.second.x_, x.second.y_, 4);
|
|||
|
|
x.second.calculated_ = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int AlgExpHS::StorageData(std::string steel_grade, double thickness,
|
|||
|
|
double width, double speed, double temp,
|
|||
|
|
std::string tag_name, double data) {
|
|||
|
|
db_com_.insert_value("T_STA_RULE_MATERIAL_VAG",
|
|||
|
|
{{"RULEID", rule_id_},
|
|||
|
|
{"STEELGRADECODE", steel_grade},
|
|||
|
|
{"THICKNESS", std::to_string(thickness)},
|
|||
|
|
{"WIDTH", std::to_string(width)},
|
|||
|
|
{"SPEED", std::to_string(speed)},
|
|||
|
|
{"TEMP", std::to_string(temp)},
|
|||
|
|
{"TAGNAME", tag_name},
|
|||
|
|
{"DATA", std::to_string(data)},
|
|||
|
|
{"SAMPLE_DATE", mix_cc::mix_time_t(time(0)).to_db2_str()}});
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::tuple<std::string, int, int> AlgExpHS::GetSteelGrade(std::string ent_id) {
|
|||
|
|
auto data = db_com_.query_value("T_PDI_ED", {}, {{"ENTID", ent_id, "="}});
|
|||
|
|
if (!data.empty()) {
|
|||
|
|
return std::make_tuple(data[0].at("STEELGRADE").as_string().c_str(),
|
|||
|
|
data[0].at("THICK").as_double(),
|
|||
|
|
data[0].at("WIDTH").as_double());
|
|||
|
|
}
|
|||
|
|
return std::make_tuple("UNKNOWN", 0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int AlgExpHS::calculate(string &outjson) {
|
|||
|
|
LOG d("AlgExpHS::calculate|" + rule_name_, AUTO_CATCH_PID);
|
|||
|
|
|
|||
|
|
// 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)] = glob_items[m_tags[i]].value;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
outjson = "";
|
|||
|
|
|
|||
|
|
int ret = 0;
|
|||
|
|
try {
|
|||
|
|
// 先把数据除以10,降低分辨率,提高样本数量
|
|||
|
|
m_entId = (*mp_trk)(m_zone)->entId;
|
|||
|
|
// if ((bool)exp_act_->evaluate()) {
|
|||
|
|
std::string steel_grade;
|
|||
|
|
int width, thickness;
|
|||
|
|
d.Debug() << "EntId:" << m_entId << std::endl;
|
|||
|
|
|
|||
|
|
std::tie(steel_grade, thickness, width) =
|
|||
|
|
this->GetSteelGrade(this->m_entId);
|
|||
|
|
|
|||
|
|
d.Debug() << "GRADE:" << steel_grade << " Thickness:" << thickness
|
|||
|
|
<< " width:" << width << std::endl;
|
|||
|
|
|
|||
|
|
int speed = (int)(glob_items["FUR_SPEED"].value / 10) * 10;
|
|||
|
|
|
|||
|
|
d.Debug() << "SPEED:" << speed << std::endl;
|
|||
|
|
|
|||
|
|
double temp = (glob_items[temp_tag_str_].value);
|
|||
|
|
|
|||
|
|
auto sample_data = glob_items[sample_tag_str_].value;
|
|||
|
|
|
|||
|
|
this->StorageData(steel_grade, thickness, width, speed, temp,
|
|||
|
|
sample_tag_str_, sample_data);
|
|||
|
|
|
|||
|
|
auto tmp_fit_data =
|
|||
|
|
inner_data_[steel_grade + std::to_string(thickness) +
|
|||
|
|
std::to_string(width) + std::to_string(speed)];
|
|||
|
|
|
|||
|
|
if (tmp_fit_data.calculated_) {
|
|||
|
|
auto fitted_data = mix_cc::GetPolyTest(tmp_fit_data.coeff_, sample_data);
|
|||
|
|
if (temp * (1 - judge_diff_) > fitted_data ||
|
|||
|
|
temp * (1 + judge_diff_) < fitted_data) {
|
|||
|
|
msg = rule_name_ + " " + m_json_param["alarm_option"]["error"][1].asString();
|
|||
|
|
msg = this->build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_, "EXP_HS",
|
|||
|
|
msg, query_time_region_);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
} catch (const std::exception &e) {
|
|||
|
|
d.Error() << mix_cc::get_nested_exception(e) << std::endl;
|
|||
|
|
ret = -1;
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
}
|