#ifndef CHECK_CFG_H #define CHECK_CFG_H #include #include #include #include #include "QJsonValue" #include #include "QByteArray" #include "stdint-gcc.h" #include "QList" #include "QString" #include #include "base/mycfg.h" #define JVALUE_TO_BOOL(v, j) \ { \ if (j.type() == QJsonValue::Bool) \ v = j.toBool(); \ else \ qWarning() << #j << "json not a bool value"; \ } #define JVALUE_TO_INT(v, j) \ { \ if (j.type() == QJsonValue::Double) \ v = j.toInt(); \ else \ { \ v = 0; \ qWarning() << #j << "json not a int value"; \ } \ } #define JVALUE_TO_U8(v, j) \ { \ if (j.type() == QJsonValue::Double) \ v = (uint8_t)j.toInt(); \ else \ { \ v = 0; \ qWarning() << #j << "json not a int value"; \ } \ } #define JVALUE_TO_U16(v, j) \ { \ if (j.type() == QJsonValue::Double) \ v = (uint16_t)j.toInt(); \ else \ { \ v = 0; \ qWarning() << #j << "json not a int value"; \ } \ } #define JVALUE_TO_STR(v, j) \ { \ if (j.type() == QJsonValue::String) \ v = j.toString(); \ else \ qWarning() << #j << "json not a string value"; \ } #define JVALUE_IS_ARRAY(j) \ if (j.type() != QJsonValue::Array) \ { \ qWarning() << #j << "json not a array"; \ } \ else class check_range; class check_task; class check_err; class check_suberr; class my_json { public: my_json() {} ~my_json() {} template void json_to_list(QJsonObject j, QString key, QList &list, T (my_json::*json_to_value)(QJsonValue v)) { QJsonValue value = j.value(key); JVALUE_IS_ARRAY(value) { QJsonArray array = value.toArray(); for (int i = 0; i < array.size(); i++) { QJsonValue item = array.at(i); list.append((this->*json_to_value)(item)); } } } uint8_t json_to_u8(QJsonValue v) { uint8_t r; JVALUE_TO_U8(r, v); return r; } uint16_t json_to_u16(QJsonValue v) { uint16_t r; JVALUE_TO_U16(r, v); return r; } int json_to_int(QJsonValue v) { int r; JVALUE_TO_INT(r, v); return r; } QString json_to_str(QJsonValue v) { QString r; JVALUE_TO_STR(r, v); return r; } check_range json_to_range(QJsonValue v); check_task json_to_task(QJsonValue v); check_err json_to_err(QJsonValue v); check_suberr json_to_suberr(QJsonValue v); }; // 范围 class check_range { public: check_range(uint16_t min, uint16_t max) { this->min = min; this->max = max; } check_range(QJsonObject j) { JVALUE_TO_U16(min, j.value("Min")); JVALUE_TO_U16(max, j.value("Max")); if (min > max) qWarning() << "the range min=" << min << "max=" << max << "is empty."; } check_range(const check_range &b) { min = b.min; max = b.max; } ~check_range() { } check_range &operator=(const check_range &b) { min = b.min; max = b.max; return *this; } // 如果在范围内则范围true bool in_range(uint16_t a) { if (a >= min && a <= max) return true; else return false; } // private: uint16_t min; uint16_t max; }; // 任务参数 class check_task { public: check_task() { task_id = 0; index = 0; param_num = 0; return_num = 0; err_jump = 0; retry = 0; } check_task(QJsonObject j) { my_json m; JVALUE_TO_STR(brief, j.value("TaskBrief")); JVALUE_TO_U8(task_id, j.value("TaskID")); JVALUE_TO_U8(index, j.value("TaskIndex")); JVALUE_TO_U8(err_jump, j.value("ErrJumpTo")); JVALUE_TO_U8(retry, j.value("RetryCount")); JVALUE_TO_U8(param_num, j.value("ParamCount")); JVALUE_TO_U8(return_num, j.value("ReturnCount")); m.json_to_list(j, "ParamInfo", params_info, &my_json::json_to_str); m.json_to_list(j, "ReturnInfo", returns_info, &my_json::json_to_str); m.json_to_list(j, "ParamVal", params, &my_json::json_to_u16); m.json_to_list(j, "TestStandard", ranges, &my_json::json_to_range); JVALUE_TO_U8(failed_code, j.value("ExecuteErrCode")); m.json_to_list(j, "ResultErrCode", ret_failed_code, &my_json::json_to_u8); } check_task(const check_task &b) { brief = b.brief; task_id = b.task_id; index = b.index; param_num = b.param_num; params_info = b.params_info; params = b.params; ranges = b.ranges; return_num = b.return_num; returns_info = b.returns_info; err_jump = b.err_jump; retry = b.retry; failed_code = b.failed_code; ret_failed_code = b.ret_failed_code; } ~check_task() { } check_task &operator=(const check_task &b) { brief = b.brief; task_id = b.task_id; index = b.index; param_num = b.param_num; params_info = b.params_info; params = b.params; ranges = b.ranges; return_num = b.return_num; returns_info = b.returns_info; err_jump = b.err_jump; retry = b.retry; failed_code = b.failed_code; ret_failed_code = b.ret_failed_code; return *this; } myarray to_byte_array() { myarray t; t.append(task_id); t.append(index); t.append(retry); t.append(err_jump); t.append((param_num & 0x0f) | (return_num << 4)); for (int i = 0; i < params.size(); i++) { t.append(uint8_t(params[i] & 0xff)); t.append(uint8_t(params[i] >> 8)); } if (param_num != params.size()) { qWarning() << "name=" << brief << " param_num!=params.size()."; } if (return_num > returns_info.size()) { qWarning() << "name=" << brief << " return_num>returns_info.size()."; } if (ch_errcode.size() != ranges.size()) { qWarning() << "name=" << brief << " ch_errcode.size()!=ranges.size()."; } return t; } QList get_ranges() { return ranges; } QJsonObject returns_to_json(bool ack, myarray data) { QJsonObject j; QJsonArray a; QJsonArray ret_err; ch_errcode.clear(); j.insert("TaskBrief", brief); j.insert("TaskIndex", get_index()); j.insert("TaskID", get_task_id()); j.insert("Ack", ack); if (ack != true) { // 添加流程错误 j.insert("ExecuteErrCode", failed_code); ch_errcode.append(failed_code); } else { j.insert("ExecuteErrCode", 0); } { if ((data.size() / 2) < return_num) qWarning() << "data size too less."; else { for (int i = 0; i < return_num; i++) { QJsonObject t; int value = data[i * 2] | (data[i * 2 + 1] << 8); if (returns_info.size() > i) t.insert("ReturnInfo", returns_info[i]); else t.insert("ReturnInfo", "unknown"); t.insert("Return", value); // 判断值域 if (ranges.size() > i) { // qDebug()<<"rang:"< i) { ret_err.append(ret_failed_code[i]); ch_errcode.append(ret_failed_code[i]); } else ret_err.append(0); } } else { t.insert("InRange", true); ret_err.append(0); } a.append(t); } } } // qDebug()<<"task="< get_ch_errcode() { // qDebug()<<"task="< get_return_info() { return returns_info; } int get_err_jump() { return err_jump; } uint8_t get_failed_code() { return failed_code; } QList get_ret_failed_code() { return ret_failed_code; } private: // 任务简要描述 QString brief; // 对应从机的检测项目 uint8_t task_id; // 此任务执行的次序 uint8_t index; // 此任务参数个数 uint8_t param_num; // 参数介绍 QList params_info; // 参数指 QList params; // 参数范围 QList ranges; // 返回值个数 uint8_t return_num; // 返回值说明 QList returns_info; // 失败时跳转到任务 uint8_t err_jump; // 失败后重试次数 uint8_t retry; // 此任务失败时的错误代码 uint8_t failed_code; // 此任务返回值错误时的错误代码 QList ret_failed_code; // 解析时此任务产生的错误代码 QList ch_errcode; }; class check_err { public: check_err() {} check_err(QJsonObject j) { my_json m; JVALUE_TO_STR(info, j.value("Info")); JVALUE_TO_U8(code, j.value("MajorErrCode")); m.json_to_list(j, "SubErrCode", sub_errs, &my_json::json_to_u8); } check_err(const check_err &b) { info = b.info; code = b.code; sub_errs = b.sub_errs; } ~check_err() {} check_err &operator=(const check_err &b) { info = b.info; code = b.code; sub_errs = b.sub_errs; return *this; } void append(uint8_t suberr) { sub_errs.append(suberr); } void append(QList suberrs) { this->sub_errs.append(suberrs); } bool operator==(const uint8_t code) { return this->code == code; } QString get_err_string() { return info; } QString operator()() { return info; } bool in_range(uint8_t err) { foreach (uint8_t i, sub_errs) { if (i == err) return true; } return false; } uint8_t get_code() { return code; } QList get_subcodes() { return sub_errs; } private: QString info; uint8_t code; QList sub_errs; }; class check_suberr { public: check_suberr() {} check_suberr(QJsonObject j) { JVALUE_TO_STR(info, j.value("Info")); JVALUE_TO_U8(code, j.value("ErrCode")); } check_suberr(const check_suberr &b) { info = b.info; code = b.code; } ~check_suberr() {} check_suberr &operator=(const check_suberr &b) { info = b.info; code = b.code; return *this; } bool operator==(const uint8_t code) { return this->code == code; } QString get_err_string() { return info; } QString operator()() { return info; } private: QString info; uint8_t code; }; class check_value { public: check_value() { } ~check_value() { } private: QString info; uint16_t value; }; #pragma pack(1) typedef struct { uint16_t max; uint16_t min; uint8_t err; } scheme_range_def; typedef struct { uint8_t taskid; uint8_t taskindex; uint8_t item_num; uint8_t err; scheme_range_def range[16]; } scheme_task_def; typedef struct { uint8_t err; uint8_t suberr_num; uint8_t suberr[30]; } marerr_def; typedef struct { uint8_t slave_data[2048]; uint32_t plan_id; uint32_t timeout_m; uint32_t task_num; uint32_t marerr_num; marerr_def marerr[21]; scheme_task_def task[0]; } scheme_def; #pragma pack() // 检测序列 class check_cfg { public: check_cfg(); ~check_cfg(); void reload(); bool updata(QString jstring); myarray tasks_to_byte_array(); myarray tasksid_to_byte_array(); myarray scheme_to_byte_array(); void scheme_json_to_struct(); const scheme_def *check_scheme(void) { if (scheme_ == nullptr) { qWarning() << "scheme_ ptr is null,application will failed."; } return scheme_; } int check_scheme_size() { return scheme_struct_size; } // 获取检测方案id int get_plan_id(); // 把方案id转化为具体信息 QString planid_to_String(int id); QString get_brief() { return brief; } // 获取适配的从机软件版本号 QList &get_slave_soft_versions(); // 获取适配的从机硬件版本号 QList &get_slave_hard_versions(); // 获取方案执行最长时间 int get_check_time_out(); // 获取任务id最大值 uint8_t get_task_id_max(); // 根据错误号返回错误字符串 QString get_err_string(int err); // 获取检测任务个数 int get_check_task_num(); // 根据序列指获取对应的任务参数 check_task get_task(int index); // 返回返回值个数 int get_return_num() { int ret = 0; for (int i = 0; i < tasks.size(); i++) { ret += tasks[i].get_return_num(); } return ret; } // 返回返回值参数 QStringList get_return_info() { return check_ret_items; } // 返回参数错误位 data为原始检测数据(去除16字节执行结果) myarray returns_to_paramerr(myarray data); // 返回任务执行结果的json data为原始检测数据(包含16字节执行结果) QJsonObject returns_to_json(myarray data); // 返回执行结果的json字符串 QString returns_to_jstring(myarray data) { QJsonDocument doc; doc.setObject(returns_to_json(data)); return doc.toJson(); } QString scheme_to_jstring() { return json_doc.toJson(); } // 返回主错误列表 QList get_ch_merrcode(); // 错误代码在范围内时返回true并把对应主错误代码添加进l bool in_err_range(QList &l, uint8_t code); private: // 提取指定任务的执行结果 bool get_return_ack_by_index(myarray data, int index); void clear() { slave_soft_versions.clear(); slave_hard_versions.clear(); errs.clear(); suberrs.clear(); tasks.clear(); check_ret_items.clear(); } private: mycfg *cfg_; QJsonDocument json_doc; myarray check_cfg_data; int plan_id; QString brief; QList slave_soft_versions; QList slave_hard_versions; int time_out_s; // 小板超时时间 int time_out_m; // 主板超时时间 uint8_t task_id_max; QList errs; QList suberrs; QList tasks; // 检测时产生的错误代码 QList ch_errcode; // 返回值项目 QStringList check_ret_items; // 把方案解析为结构体的形式 scheme_def *scheme_; int scheme_struct_size; }; check_cfg *check_plan(); #endif // CHECK_CFG_H