Files
checker_host/base/check_cfg.h

651 lines
15 KiB
C
Raw Normal View History

2023-11-26 23:05:35 +08:00
#ifndef CHECK_CFG_H
#define CHECK_CFG_H
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonParseError>
#include "QJsonValue"
#include <QJsonArray>
#include "QByteArray"
#include "stdint-gcc.h"
#include "QList"
#include "QString"
#include <QDebug>
#include "base/mycfg.h"
2023-11-27 14:31:00 +08:00
#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
2023-11-26 23:05:35 +08:00
class check_range;
class check_task;
class check_err;
class check_suberr;
class my_json
{
public:
2023-11-27 14:31:00 +08:00
my_json() {}
~my_json() {}
template <typename T>
void json_to_list(QJsonObject j, QString key, QList<T> &list,
T (my_json::*json_to_value)(QJsonValue v))
{
QJsonValue value = j.value(key);
JVALUE_IS_ARRAY(value)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
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);
2023-11-26 23:05:35 +08:00
};
// 范围
class check_range
{
public:
2023-11-27 14:31:00 +08:00
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;
2023-11-26 23:05:35 +08:00
};
// 任务参数
class check_task
{
public:
2023-11-27 14:31:00 +08:00
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++)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
t.append(uint8_t(params[i] & 0xff));
t.append(uint8_t(params[i] >> 8));
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
if (param_num != params.size())
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
qWarning() << "name=" << brief << " param_num!=params.size().";
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
if (return_num > returns_info.size())
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
qWarning() << "name=" << brief << " return_num>returns_info.size().";
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
if (ch_errcode.size() != ranges.size())
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
qWarning() << "name=" << brief << " ch_errcode.size()!=ranges.size().";
}
return t;
}
QList<check_range> 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)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
// 添加流程错误
j.insert("ExecuteErrCode", failed_code);
ch_errcode.append(failed_code);
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
else
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
j.insert("ExecuteErrCode", 0);
2023-11-26 23:05:35 +08:00
}
{
2023-11-27 14:31:00 +08:00
if ((data.size() / 2) < return_num)
qWarning() << "data size too less.";
else
{
for (int i = 0; i < return_num; i++)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
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:"<<ranges[i].min<<ranges[i].max<<value<<endl;
bool b = ranges[i].in_range(value);
t.insert("InRange", b);
if (b == true)
ret_err.append(0);
2023-11-26 23:05:35 +08:00
else
{
2023-11-27 14:31:00 +08:00
if (ret_failed_code.size() > i)
{
ret_err.append(ret_failed_code[i]);
ch_errcode.append(ret_failed_code[i]);
}
else
ret_err.append(0);
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
else
{
t.insert("InRange", true);
ret_err.append(0);
}
a.append(t);
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
}
}
// qDebug()<<"task="<<get_brief()<<"ch_errcode="<<ch_errcode<<endl;
j.insert("Returns", a);
j.insert("ResultErrCode", ret_err);
return j;
}
QList<uint8_t> get_ch_errcode()
{
// qDebug()<<"task="<<get_brief()<<"ch_errcode="<<ch_errcode<<endl;
return ch_errcode;
}
QString get_brief() { return brief; }
uint8_t get_task_id() { return task_id; }
uint8_t get_index() { return index; }
int get_return_num() { return return_num; }
QList<QString> get_return_info() { return returns_info; }
int get_err_jump() { return err_jump; }
uint8_t get_failed_code() { return failed_code; }
QList<uint8_t> get_ret_failed_code() { return ret_failed_code; }
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
private:
// 任务简要描述
QString brief;
// 对应从机的检测项目
uint8_t task_id;
// 此任务执行的次序
uint8_t index;
// 此任务参数个数
uint8_t param_num;
// 参数介绍
QList<QString> params_info;
// 参数指
QList<uint16_t> params;
// 参数范围
QList<check_range> ranges;
// 返回值个数
uint8_t return_num;
// 返回值说明
QList<QString> returns_info;
// 失败时跳转到任务
uint8_t err_jump;
// 失败后重试次数
uint8_t retry;
// 此任务失败时的错误代码
uint8_t failed_code;
// 此任务返回值错误时的错误代码
QList<uint8_t> ret_failed_code;
// 解析时此任务产生的错误代码
QList<uint8_t> ch_errcode;
2023-11-26 23:05:35 +08:00
};
class check_err
{
public:
2023-11-27 14:31:00 +08:00
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<uint8_t> 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)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
if (i == err)
return true;
2023-11-26 23:05:35 +08:00
}
2023-11-27 14:31:00 +08:00
return false;
}
uint8_t get_code() { return code; }
QList<uint8_t> get_subcodes() { return sub_errs; }
2023-11-26 23:05:35 +08:00
private:
2023-11-27 14:31:00 +08:00
QString info;
uint8_t code;
QList<uint8_t> sub_errs;
2023-11-26 23:05:35 +08:00
};
class check_suberr
{
public:
2023-11-27 14:31:00 +08:00
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;
}
2023-11-26 23:05:35 +08:00
private:
2023-11-27 14:31:00 +08:00
QString info;
uint8_t code;
2023-11-26 23:05:35 +08:00
};
class check_value
{
public:
2023-11-27 14:31:00 +08:00
check_value()
{
}
~check_value()
{
}
2023-11-26 23:05:35 +08:00
private:
2023-11-27 14:31:00 +08:00
QString info;
uint16_t value;
2023-11-26 23:05:35 +08:00
};
#pragma pack(1)
2023-11-27 14:31:00 +08:00
typedef struct
{
2023-11-26 23:05:35 +08:00
uint16_t max;
uint16_t min;
uint8_t err;
2023-11-27 14:31:00 +08:00
} scheme_range_def;
2023-11-26 23:05:35 +08:00
typedef struct
{
uint8_t taskid;
uint8_t taskindex;
uint8_t item_num;
uint8_t err;
scheme_range_def range[16];
2023-11-27 14:31:00 +08:00
} scheme_task_def;
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
typedef struct
{
2023-11-26 23:05:35 +08:00
uint8_t err;
uint8_t suberr_num;
uint8_t suberr[30];
2023-11-27 14:31:00 +08:00
} marerr_def;
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
typedef struct
{
2023-11-26 23:05:35 +08:00
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];
2023-11-27 14:31:00 +08:00
} scheme_def;
2023-11-26 23:05:35 +08:00
#pragma pack()
// 检测序列
class check_cfg
{
public:
2023-11-27 14:31:00 +08:00
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)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
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<uint16_t> &get_slave_soft_versions();
// 获取适配的从机硬件版本号
QList<uint16_t> &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++)
2023-11-26 23:05:35 +08:00
{
2023-11-27 14:31:00 +08:00
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<check_err> get_ch_merrcode();
// 错误代码在范围内时返回true并把对应主错误代码添加进l
bool in_err_range(QList<check_err> &l, uint8_t code);
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
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();
}
2023-11-26 23:05:35 +08:00
2023-11-27 14:31:00 +08:00
private:
mycfg *cfg_;
QJsonDocument json_doc;
myarray check_cfg_data;
int plan_id;
QString brief;
QList<uint16_t> slave_soft_versions;
QList<uint16_t> slave_hard_versions;
int time_out_s; // 小板超时时间
int time_out_m; // 主板超时时间
uint8_t task_id_max;
QList<check_err> errs;
QList<check_suberr> suberrs;
QList<check_task> tasks;
// 检测时产生的错误代码
QList<uint8_t> ch_errcode;
// 返回值项目
QStringList check_ret_items;
// 把方案解析为结构体的形式
scheme_def *scheme_;
int scheme_struct_size;
2023-11-26 23:05:35 +08:00
};
check_cfg *check_plan();
#endif // CHECK_CFG_H