/****************************************************************************************************************** * Action instruction algorithm * * arg[0] data determination expression * * * * 1.0 2020-12-17 zoufuzhou ******************************************************************************************************************/ #include #include #include #include #include #include #include #include extern std::map 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 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; }