<修改> 1、调整参数逻辑,参数定值文件分为可配置文件与自动生成文件。可配置文件下载后,自动文件同步相关信息
This commit is contained in:
parent
7549032700
commit
7c18f5ee9d
|
|
@ -477,7 +477,7 @@ LOCAL void mms_s_da_values_init(stru_icd &icd, std::string da_name, stru_all_DA
|
|||
return;
|
||||
}
|
||||
|
||||
if(NULL != g_iec61850s_value_init_cb_map[p_all_da->bType])
|
||||
if(NULL != g_iec61850s_value_init_cb_map[p_all_da->bType] && !p_all_da->val.empty())
|
||||
{
|
||||
g_iec61850s_value_init_cb_map[p_all_da->bType](p_all_da->DA, p_all_da->val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ int main(void)
|
|||
MY_LOG_E("app_cfg_parse failed !");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(0 != app_sys_init())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ bool dc_param_metadata_lookup(const std::string &saddr, stru_signal_param &out_p
|
|||
return false;
|
||||
}
|
||||
|
||||
int dc_param_cfg_parse(const std::string &path)
|
||||
// 解析 param.xml,只提取元数据存入 g_param_metadata,不注册信号
|
||||
static int dc_param_parse_metadata(const std::string &path)
|
||||
{
|
||||
using namespace tinyxml2;
|
||||
|
||||
|
|
@ -38,7 +39,136 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// 解析 Ao 段:单值参数(一份值 + 一份缺省值)
|
||||
// 解析 Ao 段
|
||||
XMLElement *ao_elem = root->FirstChildElement("Ao");
|
||||
if (ao_elem)
|
||||
{
|
||||
for (XMLElement *sig = ao_elem->FirstChildElement("Signal"); sig != nullptr;
|
||||
sig = sig->NextSiblingElement("Signal"))
|
||||
{
|
||||
const char *saddr = sig->Attribute("saddr");
|
||||
if (nullptr == saddr)
|
||||
{
|
||||
MY_LOG_E("Ao Signal missing saddr, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
stru_signal_param param;
|
||||
param.min = sig->FloatAttribute("min", 0.0f);
|
||||
param.max = sig->FloatAttribute("max", 0.0f);
|
||||
param.step = sig->FloatAttribute("step", 0.0f);
|
||||
const char *unit = sig->Attribute("unit");
|
||||
param.unit = unit ? std::string(unit) : std::string();
|
||||
|
||||
g_param_metadata[saddr] = param;
|
||||
}
|
||||
}
|
||||
|
||||
// 解析 Param 段
|
||||
XMLElement *param_elem = root->FirstChildElement("Param");
|
||||
if (param_elem)
|
||||
{
|
||||
for (XMLElement *sig = param_elem->FirstChildElement("Signal"); sig != nullptr;
|
||||
sig = sig->NextSiblingElement("Signal"))
|
||||
{
|
||||
const char *saddr = sig->Attribute("saddr");
|
||||
if (nullptr == saddr)
|
||||
{
|
||||
MY_LOG_E("Param Signal missing saddr, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
stru_signal_param param;
|
||||
param.min = sig->FloatAttribute("min", 0.0f);
|
||||
param.max = sig->FloatAttribute("max", 0.0f);
|
||||
param.step = sig->FloatAttribute("step", 0.0f);
|
||||
const char *unit = sig->Attribute("unit");
|
||||
param.unit = unit ? std::string(unit) : std::string();
|
||||
|
||||
g_param_metadata[saddr] = param;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 从 self_param.xml 加载运行时值,返回 saddr → value字符串 的映射
|
||||
// Ao段: key=saddr, value="value_attr"
|
||||
// Param段: key=saddr + "_" + index, value="value_attr"
|
||||
static std::unordered_map<std::string, std::string> dc_self_param_load(const std::string &path)
|
||||
{
|
||||
using namespace tinyxml2;
|
||||
std::unordered_map<std::string, std::string> values;
|
||||
|
||||
XMLDocument doc;
|
||||
if (XML_SUCCESS != doc.LoadFile(path.c_str()))
|
||||
return values; // 文件不存在或解析失败,返回空映射
|
||||
|
||||
XMLElement *root = doc.RootElement();
|
||||
if (nullptr == root) return values;
|
||||
|
||||
// 加载 Ao 段值
|
||||
XMLElement *ao_elem = root->FirstChildElement("Ao");
|
||||
if (ao_elem)
|
||||
{
|
||||
for (XMLElement *sig = ao_elem->FirstChildElement("Signal"); sig != nullptr;
|
||||
sig = sig->NextSiblingElement("Signal"))
|
||||
{
|
||||
const char *saddr = sig->Attribute("saddr");
|
||||
const char *val = sig->Attribute("value");
|
||||
if (saddr && val)
|
||||
values[saddr] = std::string(val);
|
||||
}
|
||||
}
|
||||
|
||||
// 加载 Param 段值
|
||||
XMLElement *param_elem = root->FirstChildElement("Param");
|
||||
if (param_elem)
|
||||
{
|
||||
for (XMLElement *sig = param_elem->FirstChildElement("Signal"); sig != nullptr;
|
||||
sig = sig->NextSiblingElement("Signal"))
|
||||
{
|
||||
const char *saddr = sig->Attribute("saddr");
|
||||
if (nullptr == saddr) continue;
|
||||
|
||||
for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr;
|
||||
item = item->NextSiblingElement("Item"))
|
||||
{
|
||||
int index = item->IntAttribute("index", -1);
|
||||
const char *val = item->Attribute("value");
|
||||
if (index >= 1 && val)
|
||||
{
|
||||
std::string key = std::string(saddr) + "_" + std::to_string(index);
|
||||
values[key] = std::string(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
// 根据 param.xml 和 self_param.xml 的值生成信号并注册
|
||||
static int dc_param_register_signals(const std::string ¶m_path,
|
||||
const std::unordered_map<std::string, std::string> &self_values)
|
||||
{
|
||||
using namespace tinyxml2;
|
||||
|
||||
XMLDocument doc;
|
||||
if (XML_SUCCESS != doc.LoadFile(param_path.c_str()))
|
||||
{
|
||||
MY_LOG_E("failed to reload param file: %s", param_path.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
XMLElement *root = doc.RootElement();
|
||||
if (nullptr == root)
|
||||
{
|
||||
MY_LOG_E("param file has no root element");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 注册 Ao 段信号
|
||||
XMLElement *ao_elem = root->FirstChildElement("Ao");
|
||||
if (ao_elem)
|
||||
{
|
||||
|
|
@ -61,22 +191,25 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
continue;
|
||||
}
|
||||
|
||||
float min = sig->FloatAttribute("min", 0.0f);
|
||||
float max = sig->FloatAttribute("max", 0.0f);
|
||||
float step = sig->FloatAttribute("step", 0.0f);
|
||||
const char *unit = sig->Attribute("unit");
|
||||
|
||||
// Ao 段:从 Signal 属性读取单值
|
||||
const char *val = sig->Attribute("value");
|
||||
// 默认值始终从 param.xml 读取
|
||||
const char *default_val = sig->Attribute("default");
|
||||
|
||||
// 运行时值:优先使用 self_param.xml 中的值,否则使用 param.xml 的 value 属性
|
||||
const char *val_attr = sig->Attribute("value");
|
||||
std::string run_val;
|
||||
auto it = self_values.find(std::string(saddr));
|
||||
if (it != self_values.end())
|
||||
run_val = it->second;
|
||||
else if (val_attr && strlen(val_attr) > 0)
|
||||
run_val = std::string(val_attr);
|
||||
else if (default_val && strlen(default_val) > 0)
|
||||
run_val = std::string(default_val);
|
||||
|
||||
void *p_data = dc_create_data_ptr_by_type(data_type);
|
||||
if (p_data)
|
||||
{
|
||||
if (val && strlen(val) > 0)
|
||||
dc_set_signal_val_from_str(p_data, data_type, std::string(val));
|
||||
else if (default_val && strlen(default_val) > 0)
|
||||
dc_set_signal_val_from_str(p_data, data_type, std::string(default_val));
|
||||
if (!run_val.empty())
|
||||
dc_set_signal_val_from_str(p_data, data_type, run_val);
|
||||
}
|
||||
|
||||
void *p_default_data = dc_create_data_ptr_by_type(data_type);
|
||||
|
|
@ -88,14 +221,6 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
|
||||
if (p_data && p_default_data)
|
||||
{
|
||||
stru_signal_param param;
|
||||
param.min = min;
|
||||
param.max = max;
|
||||
param.step = step;
|
||||
param.unit = unit ? std::string(unit) : std::string();
|
||||
|
||||
// 先存入中央元数据表,再注册信号
|
||||
dc_param_metadata_store(saddr, param);
|
||||
dc_signal_ao(saddr, desc, data_type,
|
||||
SIGNAL_CTRL_TYPE::SBO_NORMAL,
|
||||
p_data, p_default_data, nullptr);
|
||||
|
|
@ -103,7 +228,7 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
}
|
||||
}
|
||||
|
||||
// 解析 Param 段:多值参数(多份值 + 多份缺省值)
|
||||
// 注册 Param 段信号
|
||||
XMLElement *param_elem = root->FirstChildElement("Param");
|
||||
if (param_elem)
|
||||
{
|
||||
|
|
@ -126,58 +251,49 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
continue;
|
||||
}
|
||||
|
||||
float min = sig->FloatAttribute("min", 0.0f);
|
||||
float max = sig->FloatAttribute("max", 0.0f);
|
||||
float step = sig->FloatAttribute("step", 0.0f);
|
||||
const char *unit = sig->Attribute("unit");
|
||||
int num = sig->IntAttribute("num", -1);
|
||||
if (num < 1) continue;
|
||||
|
||||
std::vector<void *> vec_p_data;
|
||||
std::vector<void *> vec_p_default_data;
|
||||
|
||||
int num = sig->IntAttribute("num", -1);
|
||||
if (num >= 1)
|
||||
for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr;
|
||||
item = item->NextSiblingElement("Item"))
|
||||
{
|
||||
for (XMLElement *item = sig->FirstChildElement("Item"); item != nullptr;
|
||||
item = item->NextSiblingElement("Item"))
|
||||
int index = item->IntAttribute("index", -1);
|
||||
const char *default_val = item->Attribute("default");
|
||||
const char *val_attr = item->Attribute("value");
|
||||
|
||||
// 运行时值:优先使用 self_param.xml 中的值
|
||||
std::string key = std::string(saddr) + "_" + std::to_string(index);
|
||||
std::string run_val;
|
||||
auto it = self_values.find(key);
|
||||
if (it != self_values.end())
|
||||
run_val = it->second;
|
||||
else if (val_attr && strlen(val_attr) > 0)
|
||||
run_val = std::string(val_attr);
|
||||
else if (default_val && strlen(default_val) > 0)
|
||||
run_val = std::string(default_val);
|
||||
|
||||
void *p_data = dc_create_data_ptr_by_type(data_type);
|
||||
if (p_data)
|
||||
{
|
||||
const char *val = item->Attribute("value");
|
||||
const char *default_val = item->Attribute("default");
|
||||
|
||||
void *p_data = dc_create_data_ptr_by_type(data_type);
|
||||
if (p_data)
|
||||
{
|
||||
if (val && strlen(val) > 0)
|
||||
dc_set_signal_val_from_str(p_data, data_type, std::string(val));
|
||||
else if (default_val && strlen(default_val) > 0)
|
||||
dc_set_signal_val_from_str(p_data, data_type, std::string(default_val));
|
||||
vec_p_data.push_back(p_data);
|
||||
}
|
||||
|
||||
void *p_default_data = dc_create_data_ptr_by_type(data_type);
|
||||
if (p_default_data)
|
||||
{
|
||||
if (default_val && strlen(default_val) > 0)
|
||||
dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val));
|
||||
vec_p_default_data.push_back(p_default_data);
|
||||
}
|
||||
if (!run_val.empty())
|
||||
dc_set_signal_val_from_str(p_data, data_type, run_val);
|
||||
vec_p_data.push_back(p_data);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
void *p_default_data = dc_create_data_ptr_by_type(data_type);
|
||||
if (p_default_data)
|
||||
{
|
||||
if (default_val && strlen(default_val) > 0)
|
||||
dc_set_signal_val_from_str(p_default_data, data_type, std::string(default_val));
|
||||
vec_p_default_data.push_back(p_default_data);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vec_p_data.empty())
|
||||
if (!vec_p_data.empty() && vec_p_data.size() == vec_p_default_data.size())
|
||||
{
|
||||
stru_signal_param param;
|
||||
param.min = min;
|
||||
param.max = max;
|
||||
param.step = step;
|
||||
param.unit = unit ? std::string(unit) : std::string();
|
||||
|
||||
// 先存入中央元数据表,再注册信号
|
||||
dc_param_metadata_store(saddr, param);
|
||||
dc_signal_param(saddr, desc, data_type,
|
||||
SIGNAL_CTRL_TYPE::SBO_NORMAL,
|
||||
vec_p_data.data(), vec_p_default_data.data(), num, nullptr);
|
||||
|
|
@ -185,5 +301,42 @@ int dc_param_cfg_parse(const std::string &path)
|
|||
}
|
||||
}
|
||||
|
||||
// 首次注册后标记变更,触发 self_param.xml 生成
|
||||
dc_set_param_cfg_change(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dc_param_cfg_parse(const std::string &path)
|
||||
{
|
||||
// 1. 从 param.xml 提取元数据到 g_param_metadata
|
||||
if (0 != dc_param_parse_metadata(path))
|
||||
{
|
||||
MY_LOG_E("dc_param_parse_metadata failed, path:%s", path.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. 构造 self_param.xml 路径
|
||||
std::string self_path = path;
|
||||
size_t pos = self_path.rfind("param.xml");
|
||||
if (pos != std::string::npos)
|
||||
self_path.replace(pos, 9, "self_param.xml");
|
||||
else
|
||||
self_path = path.substr(0, path.rfind('/') + 1) + "self_param.xml";
|
||||
|
||||
// 3. 尝试加载 self_param.xml 中的运行时值
|
||||
std::unordered_map<std::string, std::string> self_values = dc_self_param_load(self_path);
|
||||
if (!self_values.empty())
|
||||
MY_LOG_I("loaded %zu saved values from self_param.xml", self_values.size());
|
||||
else
|
||||
MY_LOG_I("no self_param.xml found, using default values from param.xml");
|
||||
|
||||
// 4. 用合并后的值注册所有信号
|
||||
if (0 != dc_param_register_signals(path, self_values))
|
||||
{
|
||||
MY_LOG_E("dc_param_register_signals failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2177,14 +2177,20 @@ void dc_param_cfg_check(const std::string &path)
|
|||
root->InsertEndChild(ao_elem);
|
||||
root->InsertEndChild(param_elem);
|
||||
|
||||
if (XML_SUCCESS == doc.SaveFile(path.c_str()))
|
||||
// 保存到 self_param.xml,不覆盖参数模板 param.xml
|
||||
std::string self_path = path;
|
||||
size_t pos = self_path.rfind("param.xml");
|
||||
if (pos != std::string::npos)
|
||||
self_path.replace(pos, 9, "self_param.xml");
|
||||
|
||||
if (XML_SUCCESS == doc.SaveFile(self_path.c_str()))
|
||||
{
|
||||
dc_set_param_cfg_change(false);
|
||||
MY_LOG_I("param config file saved to %s", path.c_str());
|
||||
MY_LOG_I("param runtime saved to %s", self_path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
MY_LOG_E("failed to save param config file to %s", path.c_str());
|
||||
MY_LOG_E("failed to save param runtime to %s", self_path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ int app_iec61850s_init1(void *arg)
|
|||
}
|
||||
|
||||
|
||||
mms_s_dbg_switch(true);
|
||||
mms_s_dbg_switch(false);
|
||||
mms_s_file_path_set(base_path.c_str());
|
||||
mms_s_value_update_register(&g_mms_s_value_update_cb);
|
||||
if(NULL == g_mms_s_value_update_cb)
|
||||
|
|
|
|||
|
|
@ -892,13 +892,6 @@ int self_ptl_do_signal_out(stru_app *p_app)
|
|||
stru_self_ptl_cfg_param_data *p_ao = &p_app_cfg_data->ao_vec.at(i);
|
||||
if(p_ao && p_ao->p_param)
|
||||
{
|
||||
stru_signal_param param;
|
||||
param.min = safeStringToFloat(p_ao->p_param->min);
|
||||
param.max = safeStringToFloat(p_ao->p_param->max);
|
||||
param.step = safeStringToFloat(p_ao->p_param->step);
|
||||
param.unit = p_ao->p_param->unit;
|
||||
// dc_param_metadata_store(p_ao->p_param->base.saddr, param);
|
||||
|
||||
ret |= dc_signal_ao(p_ao->p_param->base.saddr, p_ao->p_param->base.desc, p_ao->p_param->type, SIGNAL_CTRL_TYPE::SBO_NORMAL, p_ao->vec_p_data[0], p_ao->vec_p_default_data[0], self_ptl_signal_change_callback);
|
||||
}
|
||||
}
|
||||
|
|
@ -913,14 +906,7 @@ int self_ptl_do_signal_out(stru_app *p_app)
|
|||
stru_self_ptl_cfg_param_data *p_param = &p_app_cfg_data->param_vec.at(i);
|
||||
if(p_param && p_param->p_param)
|
||||
{
|
||||
stru_signal_param param;
|
||||
param.min = safeStringToFloat(p_param->p_param->min);
|
||||
param.max = safeStringToFloat(p_param->p_param->max);
|
||||
param.step = safeStringToFloat(p_param->p_param->step);
|
||||
param.unit = p_param->p_param->unit;
|
||||
// dc_param_metadata_store(p_param->p_param->base.saddr, param);
|
||||
|
||||
ret |= dc_signal_param(p_param->p_param->base.saddr, p_param->p_param->base.desc, p_param->p_param->type,
|
||||
ret |= dc_signal_param(p_param->p_param->base.saddr, p_param->p_param->base.desc, p_param->p_param->type,
|
||||
SIGNAL_CTRL_TYPE::SBO_NORMAL, p_param->vec_p_data.data(), p_param->vec_p_default_data.data(), p_param->p_param->num, self_ptl_signal_change_callback);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue