267 lines
9.5 KiB
C++
267 lines
9.5 KiB
C++
|
|
#include <T_TIME_SET.h>
|
|
#include <base/BitTool.h>
|
|
#include <eqpalg/algs/AlgCarJam.h>
|
|
#include <utility/StringHelper.h>
|
|
// std::map<std::string,int> event_no_of_item;
|
|
#include <cstdio>
|
|
#include <queue>
|
|
extern iDA::Connection cn;
|
|
int AlgCarJam::init() {
|
|
LOG d("AlgCarJam::init", AUTO_CATCH_PID);
|
|
int ret = 0;
|
|
try {
|
|
|
|
// p_tele->ReBuild(event_no_of_item[m_tags[0]]);
|
|
// p_btel->ReBuild(1010);
|
|
|
|
// d.Debug()<<"tags:"<<m_feedback.addr_action<<"
|
|
// "<<m_feedback.addr_feedback<<endl;
|
|
// mp_timeset = new CMemTable<T_TIME_SET::STR_T_TIME_SET>("T_LOV_TAB1",
|
|
// 999); pFDAA = new
|
|
// CMemTable<T_LOV_FDAAITEM::STR_T_LOV_FDAAITEM>("T_LOV_FDAAITEM", 1);
|
|
} catch (const std::exception &e) {
|
|
d.Error() << mix_cc::get_nested_exception(e) << std::endl;
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
AlgCarJam::AlgCarJam(const string name, const Json::Value rulejson,
|
|
const string ruleId)
|
|
: AlgBase(name, rulejson, ruleId) {
|
|
LOG d("AlgCarJam::AlgCarJam", AUTO_CATCH_PID);
|
|
// d.Debug("aaa",AUTO_CATCH_PID);
|
|
have_sample = true;
|
|
// CMemTable<MOD_CACHE> mod1("ZONE0",1);
|
|
// gb_data = mod1();
|
|
this->init();
|
|
records_queried_ = new HD3Record *[m_tags.size()];
|
|
memset(&ave_curr_noload, 0, sizeof(ave_curr_noload));
|
|
memset(&ave_curr_load, 0, sizeof(ave_curr_load));
|
|
memset(&limit_curr_noload, 0, sizeof(limit_curr_noload));
|
|
memset(&limit_curr_load, 0, sizeof(limit_curr_load));
|
|
memset(&timeRegion, 0, sizeof(timeRegion));
|
|
timeRegion.bLeftClosed = true;
|
|
timeRegion.bRightClosed = true;
|
|
work_finished = true;
|
|
m_curr = this->mstime();
|
|
int dltime = m_json_param["interval"]["time"][1].asInt();
|
|
m_start = m_curr - dltime;
|
|
m_end = m_curr - dltime;
|
|
this->set_cycle_time(max(50, m_json_param["interval"]["time"][1].asInt()));
|
|
string sql = "Select count(*) , data from T_STA_SAMPLE where tagname = '" +
|
|
m_json_param["tags"]["tag1"][1].asString() + "'";
|
|
// d.Debug()<<"sql:"<<sql<<endl;
|
|
iDA::Command cmd(&cn, sql); // command object
|
|
try {
|
|
// Select BLob from our test table
|
|
cmd.Execute();
|
|
long cnt = cmd.Field(0).AsLong();
|
|
// fetch results row by row and print results
|
|
if (cnt == 0) {
|
|
d.Debug() << " 无样本数据! " << endl;
|
|
have_sample = false;
|
|
} else {
|
|
while (cmd.FetchNext()) {
|
|
string json_str = cmd.Field(1).AsString();
|
|
// d.Debug() << "json_str: " << json_str << endl;
|
|
Json::Reader reader;
|
|
Json::Value val;
|
|
if (reader.parse(json_str, val)) {
|
|
// d.Debug() << "val.size: " << val["data"].size() << endl;
|
|
for (int i = 0; i < val["data"].size(); i++) {
|
|
limit_curr_noload[i] += val["data"][i].asDouble() / cnt;
|
|
// d.Debug() << "data[" << i << "]: " << val["data"][i].asDouble()
|
|
// << endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (iDA::Exception &x) {
|
|
try {
|
|
// on error rollback changes
|
|
cn.Rollback();
|
|
} catch (iDA::Exception &) {
|
|
}
|
|
// print error message
|
|
printf("%s\n", x.ErrMsg().c_str());
|
|
}
|
|
}
|
|
|
|
AlgCarJam::~AlgCarJam() { delete[] records_queried_; }
|
|
|
|
int AlgCarJam::calculate(string &outjson) {
|
|
LOG d("AlgCarJam::calculate", AUTO_CATCH_PID);
|
|
outjson = "";
|
|
|
|
if (!have_sample)
|
|
return 0;
|
|
int ret = 0;
|
|
try {
|
|
m_curr = this->mstime();
|
|
int dltime = m_json_param["interval"]["time"][1].asInt();
|
|
if (m_curr - m_start < dltime) {
|
|
// d.Debug() << " 时间间隔太小! " << endl;
|
|
return 0;
|
|
} else {
|
|
//先判断上一次取的数据是不是一个完整的自动步
|
|
//若上一次不是完整自动步,开始时间开始上一次的开始时间,不更新为上一次的结束时间
|
|
if (work_finished) {
|
|
m_start = m_end;
|
|
}
|
|
m_end = m_curr;
|
|
}
|
|
timeRegion.left.nSec = m_start / 1000;
|
|
timeRegion.left.nMsec = m_start % 1000;
|
|
timeRegion.right.nSec = m_end / 1000;
|
|
timeRegion.right.nMsec = m_end % 1000;
|
|
|
|
//先做空载的
|
|
//"tags": ["电流","钢卷",方向","速度"]
|
|
int min_tagCnt = INT_MAX;
|
|
for (unsigned int i = 0; i < m_tags.size(); i++) {
|
|
int tagcnt = ihd_tools_->GetDataCount(m_tags[i], timeRegion);
|
|
// records_queried_[i] = new HD3Record[tagcnt];
|
|
if (tagcnt < 1) {
|
|
d.Debug() << m_tags[i] << " tagcnt = 0 ! " << endl;
|
|
return 0;
|
|
}
|
|
min_tagCnt = min(min_tagCnt, tagcnt);
|
|
}
|
|
// if((m_end - m_start) / (min_tagCnt + 1) > IHD_FREQUENCY * 1.1){
|
|
// d.Debug() << " 该时间段内IHDB数据不完整! " << endl;
|
|
// return 0;
|
|
// }
|
|
for (unsigned int i = 0; i < m_tags.size(); i++) {
|
|
records_queried_[i] = new HD3Record[min_tagCnt];
|
|
ret = ihd_tools_->QueryDataByTime(m_tags[i], records_queried_[i],
|
|
timeRegion, &min_tagCnt);
|
|
}
|
|
// records_queried_[0][i].value.fFloat32 : 电流
|
|
// records_queried_[1][i].value.nInt8 : 钢卷
|
|
// records_queried_[2][i].value.fFloat32 : 小车移动方向(后退:1)
|
|
// records_queried_[3][i].value.fFloat32 : 小车速度
|
|
queue<double> m_que;
|
|
bool have_data = false;
|
|
bool work_end = false;
|
|
for (int i = 0; i < min_tagCnt; i++) {
|
|
// d.Debug() << "tagcnt: " << tagcnt << endl;
|
|
if ((fabs(records_queried_[2][i].value.fFloat32 - BACK_WORD) > EPS) &&
|
|
have_data == true) {
|
|
work_end = true;
|
|
break;
|
|
}
|
|
if (fabs(records_queried_[2][i].value.fFloat32 - BACK_WORD) < EPS) {
|
|
// if(fabs(records_queried_[0][i].value.fFloat32) > EPS){
|
|
m_que.push(records_queried_[0][i].value.fFloat32);
|
|
have_data = true;
|
|
//}
|
|
}
|
|
}
|
|
for (unsigned int i = 0; i < m_tags.size(); i++) {
|
|
delete[] records_queried_[i];
|
|
}
|
|
int m_size = m_que.size();
|
|
// d.Debug() << "m_que.size: " << m_que.size() << endl;
|
|
if (!have_data) {
|
|
d.Debug() << " 小车不在工作! " << endl;
|
|
return 0;
|
|
}
|
|
if (!work_end) {
|
|
// d.Debug() << " 小车自动步未结束! " << endl;
|
|
work_finished = false;
|
|
return 0;
|
|
}
|
|
if (m_size <= SAMPLE_NUM) {
|
|
int cnt_makeup = 0;
|
|
for (int i = 0; i < SAMPLE_NUM % m_size; i++) {
|
|
ave_curr_noload[cnt_makeup] = m_que.front();
|
|
m_que.pop();
|
|
double ave_makeup = (m_que.front() - ave_curr_noload[cnt_makeup]) /
|
|
((SAMPLE_NUM - m_size) / m_size + 2);
|
|
for (int j = 1; j <= (SAMPLE_NUM - m_size) / m_size + 1; j++) {
|
|
ave_curr_noload[cnt_makeup + j] =
|
|
ave_curr_noload[cnt_makeup + j - 1] + ave_makeup;
|
|
}
|
|
cnt_makeup += (SAMPLE_NUM - m_size) / m_size + 2;
|
|
}
|
|
for (int i = SAMPLE_NUM % m_size; i < m_size; i++) {
|
|
ave_curr_noload[cnt_makeup] = m_que.front();
|
|
m_que.pop();
|
|
if (!m_que.empty()) {
|
|
double ave_makeup = (m_que.front() - ave_curr_noload[cnt_makeup]) /
|
|
((SAMPLE_NUM - m_size) / m_size + 1);
|
|
for (int j = 1; j <= (SAMPLE_NUM - m_size) / m_size; j++) {
|
|
ave_curr_noload[cnt_makeup + j] =
|
|
ave_curr_noload[cnt_makeup + j - 1] + ave_makeup;
|
|
}
|
|
cnt_makeup += (SAMPLE_NUM - m_size) / m_size + 1;
|
|
} else {
|
|
for (int j = 1; j <= (SAMPLE_NUM - m_size) / m_size; j++) {
|
|
ave_curr_noload[cnt_makeup + j] =
|
|
ave_curr_noload[cnt_makeup + j - 1];
|
|
}
|
|
cnt_makeup += (SAMPLE_NUM - m_size) / m_size + 1;
|
|
}
|
|
}
|
|
}
|
|
// m_size大于1000个
|
|
// 所有下标乘系数k,下标范围为[0.0,m.size-1],每个整数下标取离他最近的那个点的数据
|
|
else {
|
|
double k = m_size * 1.0 / SAMPLE_NUM;
|
|
ave_curr_noload[0] = m_que.front();
|
|
vector<double> m_vec;
|
|
while (!m_que.empty()) {
|
|
m_vec.push_back(m_que.front());
|
|
m_que.pop();
|
|
}
|
|
for (int now_pos = 1; now_pos < SAMPLE_NUM; now_pos++) {
|
|
int tmp_pos = (int)(now_pos * k);
|
|
// double m_min = fabs(now_pos * k - tmp_pos);
|
|
// ave_curr_noload[now_pos] = m_vec[tmp_pos];
|
|
// if(tmp_pos + 1 < m_size && fabs(now_pos * k - tmp_pos - 1) < m_min){
|
|
// ave_curr_noload[now_pos] = m_vec[tmp_pos + 1];
|
|
// }
|
|
ave_curr_noload[now_pos] =
|
|
((tmp_pos + 1 < m_size) &&
|
|
(fabs(now_pos * k - tmp_pos - 1) < fabs(now_pos * k - tmp_pos)))
|
|
? m_vec[tmp_pos + 1]
|
|
: m_vec[tmp_pos];
|
|
}
|
|
}
|
|
string msg = "";
|
|
for (int i = 0; i < SAMPLE_NUM; i++) {
|
|
// d.Debug() << "实际:" << ave_curr_noload[i] << " 阈值: " <<
|
|
// limit_curr_noload[i] << endl;
|
|
if (fabs(ave_curr_noload[i] - limit_curr_noload[i]) >
|
|
m_json_param["limit_alarm_noload"]["value"][1].asDouble()) {
|
|
msg = msg + " 小车实际电流为:" +
|
|
std::to_string(ave_curr_noload[i]) +
|
|
" 电流阈值为 : " +
|
|
std::to_string(limit_curr_noload[i]);
|
|
break;
|
|
}
|
|
}
|
|
if (!msg.empty()) {
|
|
msg = rule_name_ + m_json_param["limit_alarm_noload"]["name"][1].asString() +
|
|
m_json_param["limit_alarm_noload"]["content"][1].asString() + msg;
|
|
// d.Debug() << msg << endl;
|
|
d.Debug() << msg << endl;
|
|
string tmp = this->build_alarm_info(MsgLevel::ERROR, rule_id_, rule_name_,
|
|
"CAR_JAM", msg, timeRegion);
|
|
if (!tmp.empty())
|
|
outjson = tmp;
|
|
}
|
|
//不报警,数据正常
|
|
else {
|
|
d.Debug() << " 小车自动步数据正常! " << endl;
|
|
}
|
|
|
|
} catch (const std::exception &e) {
|
|
d.Error() << mix_cc::get_nested_exception(e) << std::endl;
|
|
ret = -1;
|
|
}
|
|
return ret;
|
|
}
|