You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

507 lines
18 KiB

#include "../include/config.h"
sSysConfig gSysConfig;
static sECatData *pECatData;
void map_add_ccu(sCCU *p) {
pECatData->map_ccu[pECatData->idx_ccu] = p;
pECatData->idx_ccu++;
}
void map_add_eau(sEAU *p) {
pECatData->map_eau[pECatData->idx_eau] = p;
pECatData->idx_eau++;
}
void map_add_pcc(sPCC *p) {
pECatData->map_pcc[pECatData->idx_pcc] = p;
pECatData->idx_pcc++;
}
#if 1
float str2float(const char *str, float multiple) {
float f0 = atof(str);
float f = f0 / multiple;
// printf("f0 = %f, multiple = %f, f = %f \n", f0, multiple, f);
return f;
}
#else
float str2float(const char *str) {
float f=atof(str);
return f;
}
#endif
uint16_t str2val(const char *str, int multiple) {
float f=atof(str) * float(multiple);
return uint16_t(f);
}
bool is_string(const char *str_src, const char *str_dest) {
string sname(str_src);
if(sname.compare(str_dest) == 0) {
return true;
}
return false;
}
void parse_ccu(XMLElement* xccu, sEAU *eau) {
const char *name;
const char *value;
const XMLAttribute* ccuAttr = xccu->FirstAttribute();
sCCU *ccu = new sCCU();
list_add_tail(eau->ccu_head, ccu);
map_add_ccu(ccu);
ccu->ai_len = sizeof(sCCUAI);
ccu->ao_len = sizeof(sCCUAO);
while (ccuAttr) {
name = ccuAttr->Name();
value = ccuAttr->Value();
//cout << "\t" << name << " = " << value << endl;
if(is_string(name, "address")) {
ccu->cfg.address = str2val(value, 1);
my_setbit((uint8_t *)(&eau->ccu_id_table), ccu->cfg.address-1, 1);
}else if(is_string(name, "pcs0_enable")) {
ccu->cfg.pcs_enable[0] = str2val(value, 1);
}else if(is_string(name, "pcs0_address")) {
ccu->cfg.pcs_address[0] = str2val(value, 1);
}else if(is_string(name, "pcs1_enable")) {
ccu->cfg.pcs_enable[1] = str2val(value, 1);
}else if(is_string(name, "pcs1_address")) {
ccu->cfg.pcs_address[1] = str2val(value, 1);
}else if(is_string(name, "pcs2_enable")) {
ccu->cfg.pcs_enable[2] = str2val(value, 1);
}else if(is_string(name, "pcs2_address")) {
ccu->cfg.pcs_address[2] = str2val(value, 1);
}else if(is_string(name, "pcs3_enable")) {
ccu->cfg.pcs_enable[3] = str2val(value, 1);
}else if(is_string(name, "pcs3_address")) {
ccu->cfg.pcs_address[3] = str2val(value, 1);
}
for(int i=0; i<4; i++) {
if(ccu->cfg.pcs_enable[i] == 0) {
continue;
}
my_setbit((uint8_t *)(&eau->pcs_id_table), ccu->cfg.pcs_address[i]-1, 1);
}
ccuAttr = ccuAttr->Next();
}
}
void parse_eau(XMLElement* xeau, sPCC *pcc) {
// 遍历属性列表
const char *name;
const char *value;
const XMLAttribute* eauAttr = xeau->FirstAttribute();
sEAU *eau = new sEAU();
list_add_tail(pcc->eau_head, eau);
map_add_eau(eau);
eau->ai_len = sizeof(sEAUAI);
eau->ao_len = sizeof(sEAUAO);
while (eauAttr) {
name = eauAttr->Name();
value = eauAttr->Value();
//cout << "\t" << name << " = " << value << endl;
if(is_string(name, "address")) {
eau->cfg.address = str2val(value, 1);
eau->address = eau->cfg.address;
}else if(is_string(name, "rated_active_power")) {
eau->cfg.rated_active_power = str2val(value, 100);
}else if(is_string(name, "rated_reactive_power")) {
eau->cfg.rated_reactive_power = str2val(value, 100);
}else if(is_string(name, "ccu_number")) {
eau->cfg.ccu_number = str2val(value, 1);
}else if(is_string(name, "pcs_number")) {
eau->cfg.pcs_number= str2val(value, 1);
}
eauAttr = eauAttr->Next();
}
//cout << endl;
XMLElement* eauChild = xeau->FirstChildElement();
while (eauChild) {
if(is_string(eauChild->Name(), "CCU")) {
parse_ccu(eauChild, eau);
}
eauChild = eauChild->NextSiblingElement();
}
//cout << endl;
}
void parse_pcc(XMLElement* xpcc) {
const char *name;
const char *value;
const XMLAttribute* pccAttr = xpcc->FirstAttribute();
sPCC *pcc = new sPCC();
list_add_tail(pECatData->pcc_head, pcc);
map_add_pcc(pcc);
while ( pccAttr ) {
name = pccAttr->Name();
value = pccAttr->Value();
//cout << "\t" << name << " = " << value << endl;
if(is_string(name, "address")) {
pcc->cfg.address = str2val(value, 1);
}else if(is_string(name, "eau_number")) {
pcc->cfg.eau_number = str2val(value, 1);
}else if(is_string(name, "ccu_number")) {
pcc->cfg.ccu_number = str2val(value, 1);
}else if(is_string(name, "pcs_number")) {
pcc->cfg.pcs_number = str2val(value, 1);
}else if(is_string(name, "bind_eau")) {
pcc->cfg.bind_eau = str2val(value, 1);
}else if(is_string(name, "rated_active_power")) {
pcc->cfg.rated_active_power = str2val(value, 100);
}else if(is_string(name, "rated_reactive_power")) {
pcc->cfg.rated_reactive_power = str2val(value, 100);
}else if(is_string(name, "fvr_power_regulate_ratio")) {
pcc->cfg.fvr_power_regulate_ratio = str2float(value, 1.0);
}
pccAttr = pccAttr->Next();
}
XMLElement* pccChild = xpcc->FirstChildElement();
while (pccChild) {
if(is_string(pccChild->Name(), "EAU")) {
parse_eau(pccChild, pcc);
}
pccChild = pccChild->NextSiblingElement();
}
}
void parse_network(XMLElement* ccs) {
const XMLAttribute* netAttr = ccs->FirstAttribute();
if(netAttr != NULL) {
pECatData->cfg.fvr_pcc_number = str2val(ccs->Attribute("fvr_pcc_number"), 1);
//cout << "fvr_pcc_number" << ":" << pECatData->cfg.fvr_pcc_number << endl;
}
XMLElement* pccChild = ccs->FirstChildElement();
while (pccChild) {
if(is_string(pccChild->Name(), "FVR_PCC")) {
parse_pcc(pccChild);
}
//cout << endl;
pccChild = pccChild->NextSiblingElement();
}
//cout << endl;
}
void parse_signal(XMLElement* ccs) {
//以下两个变量 将要存储 目录节点 下的 信息节点
const char *name;
const char *value;
//XMLAttribute* netAttr 表示 目录节点下的第一个 信息节点
const XMLAttribute* netAttr = ccs->FirstAttribute();
//循环遍历 目录节点下的所有 数据节点
while (netAttr) {
//获取第 n 个 目录节点 下的 信息节点
name = netAttr->Name();
value = netAttr->Value();
if(value != NULL) {
//并将遍历到的 本目录节点 下的所有的 信息节点 中所有的数据信息 存储到对应的全局pECatData中
// cout << "\t" << name << " = " << value << endl;
if(is_string(name, "remote_local_switch_related_di_address")) {
pECatData->cfg.signal.remote_local_switch_related_di_address = str2val(value, 1);
}else if(is_string(name, "ccs_enable_switch_related_di_address")) {
pECatData->cfg.signal.ccs_enable_switch_related_di_address = str2val(value, 1);
}else if(is_string(name, "ffr_enable_switch_related_di_address")) {
pECatData->cfg.signal.ffr_enable_switch_related_di_address = str2val(value, 1);
}else if(is_string(name, "fvr_enable_switch_related_di_address")) {
pECatData->cfg.signal.fvr_enable_switch_related_di_address = str2val(value, 1);
}else if(is_string(name, "fpu_enable_switch_related_di_address")) {
pECatData->cfg.signal.fpu_enable_switch_related_di_address = str2val(value, 1);
}else if(is_string(name, "fpu_start_signal_1_related_di_address")) {
pECatData->cfg.signal.fpu_start_signal_1_related_di_address = str2val(value, 1);
}else if(is_string(name, "fpu_start_signal_2_related_di_address")) {
pECatData->cfg.signal.fpu_start_signal_2_related_di_address = str2val(value, 1);
}
}else{
// cout << "\t" << name << endl;
}
//获取下一个信息节点
netAttr = netAttr->Next();
}
//cout << endl;
}
void parse_ffr(XMLElement* ccs) {
const char *name;
const char *value;
const XMLAttribute* netAttr = ccs->FirstAttribute();
while (netAttr) {
name = netAttr->Name();
value = netAttr->Value();
if(value != NULL) {
// 频率的精度为0.0005, 所有频率值需要除精度
// cout << "\t" << name << " = " << value << endl;
if(is_string(name, "enable")) {
pECatData->cfg.ffr.enable = str2val(value,1);
}else if(is_string(name, "rated_frequency")) {
pECatData->cfg.ffr.rated_frequency = str2float(value,FRE_UNIT);
}else if(is_string(name, "frequency_frozen_zone")) {
pECatData->cfg.ffr.frequency_frozen_zone = str2float(value,FRE_UNIT);
}else if(is_string(name, "power_regulate_ratio")) {
pECatData->cfg.ffr.power_regulate_ratio = str2float(value,1.0);
}else if(is_string(name, "power_limit_ratio")) {
pECatData->cfg.ffr.power_limit_ratio = str2float(value,1.0);
}else if(is_string(name, "frequency_return_difference")) {
pECatData->cfg.ffr.frequency_return_difference = str2float(value,FRE_UNIT);
}else if(is_string(name, "frequency_offset_difference")) {
pECatData->cfg.ffr.frequency_offset_difference = str2val(value,1);
}else if(is_string(name, "hold_time")) {
pECatData->cfg.ffr.hold_time = str2float(value,1.0);
// str2val(value, 1);
}else if(is_string(name, "simulate_timeout_time")) {
pECatData->cfg.ffr.simulate_timeout_time = str2val(value, 1);
}else if(is_string(name, "wavetest_start_frequency")) {
pECatData->cfg.ffr.wavetest_start_frequency= str2float(value,FRE_UNIT);
}else if(is_string(name, "wavetest_end_frequency")) {
pECatData->cfg.ffr.wavetest_end_frequency= str2float(value,FRE_UNIT);
}else if(is_string(name, "wavetest_step_frequency")) {
pECatData->cfg.ffr.wavetest_step_frequency = str2float(value,FRE_UNIT);
}else if(is_string(name, "wavetest_step_time")) {
pECatData->cfg.ffr.wavetest_step_time = str2val(value, 1);
}
}else{
// //cout << "\t" << name << endl;
}
netAttr = netAttr->Next();
}
//cout << endl;
}
void parse_fvr(XMLElement* ccs) {
const char *name;
const char *value;
const XMLAttribute* netAttr = ccs->FirstAttribute();
while (netAttr) {
name = netAttr->Name();
value = netAttr->Value();
if(value != NULL) {
// cout << "\t" << name << " = " << value << endl;
if(is_string(name, "enable")) {
pECatData->cfg.fvr.enable = str2val(value,1);
}else if(is_string(name, "rated_voltage")) {
pECatData->cfg.fvr.rated_voltage = str2val(value, 1);
}else if(is_string(name, "voltage_frozen_zone")) {
pECatData->cfg.fvr.voltage_frozen_zone = str2val(value, 1);
// }else if(is_string(name, "power_regulate_ratio")) {
// pECatData->cfg.fvr.power_regulate_ratio = str2float(value, 1.0);
}else if(is_string(name, "power_limit_ratio")) {
pECatData->cfg.fvr.power_limit_ratio = str2float(value, 1.0);
// printf(" -- ratio= %f.\n", pECatData->cfg.fvr.power_limit_ratio);
}else if(is_string(name, "voltage_return_difference")) {
pECatData->cfg.fvr.voltage_return_difference = str2val(value, 1);
}else if(is_string(name, "hold_time")) {
pECatData->cfg.fvr.hold_time = str2val(value, 1);
}else if(is_string(name, "simulate_timeout_time")) {
pECatData->cfg.fvr.simulate_timeout_time = str2val(value, 1);
}else if(is_string(name, "wavetest_start_voltage")) {
pECatData->cfg.fvr.wavetest_start_voltage= str2val(value, 1);
}else if(is_string(name, "wavetest_end_voltage")) {
pECatData->cfg.fvr.wavetest_end_voltage= str2val(value, 1);
}else if(is_string(name, "wavetest_step_voltage")) {
pECatData->cfg.fvr.wavetest_step_voltage = str2val(value, 1);
}else if(is_string(name, "wavetest_step_time")) {
pECatData->cfg.fvr.wavetest_step_time = str2val(value, 1);
}
}else{
//cout << "\t" << name << endl;
}
netAttr = netAttr->Next();
}
//cout << endl;
}
void parse_fpu(XMLElement* ccs) {
const char *name;
const char *value;
const XMLAttribute* netAttr = ccs->FirstAttribute();
while (netAttr) {
name = netAttr->Name();
value = netAttr->Value();
if(value != NULL) {
//cout << "\t" << name << " = " << value << endl;
if(is_string(name, "enable")) {
pECatData->cfg.fpu.enable = str2val(value,1);
}else if(is_string(name, "start_signal_mode")) {
pECatData->cfg.fpu.start_signal_mode = str2val(value, 1);
}else if(is_string(name, "hold_time")) {
pECatData->cfg.fpu.hold_time = str2val(value, 1);
}
}else{
//cout << "\t" << name << endl;
}
netAttr = netAttr->Next();
}
//cout << endl;
}
void parse_ip(XMLElement* ccs) {
const char *name;
const char *value;
const XMLAttribute* netAttr = ccs->FirstAttribute();
while (netAttr) {
name = netAttr->Name();
value = netAttr->Value();
if(value != NULL) {
//cout << "\t" << name << " = " << value << endl;
if(is_string(name, "ccm0_a_ip_address")) {
pECatData->cfg.ip.ccm0_a_ip_address = str2val(value, 1);
}else if(is_string(name, "ccm0_b_ip_address")) {
pECatData->cfg.ip.ccm0_b_ip_address = str2val(value, 1);
}else if(is_string(name, "ccm0_a_104_port")) {
pECatData->cfg.ip.ccm0_a_104_port = str2val(value, 1);
}else if(is_string(name, "ccm0_a_modbus_port")) {
pECatData->cfg.ip.ccm0_a_modbus_port = str2val(value, 1);
}else if(is_string(name, "ccm0_b_104_port")) {
pECatData->cfg.ip.ccm0_b_104_port = str2val(value, 1);
}else if(is_string(name, "ccm0_b_modbus_port")) {
pECatData->cfg.ip.ccm0_b_modbus_port = str2val(value, 1);
}else if(is_string(name, "ccm1_a_ip_address")) {
pECatData->cfg.ip.ccm1_a_ip_address = str2val(value, 1);
}else if(is_string(name, "ccm1_b_ip_address")) {
pECatData->cfg.ip.ccm1_b_ip_address = str2val(value, 1);
}else if(is_string(name, "ccm1_a_104_port")) {
pECatData->cfg.ip.ccm1_a_104_port = str2val(value, 1);
}else if(is_string(name, "ccm1_a_modbus_port")) {
pECatData->cfg.ip.ccm1_a_modbus_port = str2val(value, 1);
}else if(is_string(name, "ccm1_b_104_port")) {
pECatData->cfg.ip.ccm1_b_104_port = str2val(value, 1);
}else if(is_string(name, "ccm1_b_modbus_port")) {
pECatData->cfg.ip.ccm1_b_modbus_port = str2val(value, 1);
}
}
netAttr = netAttr->Next();
}
//cout << endl;
}
//将CCS节点下的所有信息节点全部送往该函数中进行处理
int parse_ccs(XMLElement* ccs) {
//获取该节点的名字 以及 其节点中存放的数值
const char *name = ccs->Name();
const char *value = ccs->GetText();
//首先通过value值来判断其是 信息节点 还是 目录节点
if(value != NULL) {
//再通过其信息节点的 名称来做不通的处理
// //cout << name << " = " << value << endl;
// 将数据信息的值 由 数字字符串转换为浮点数 并计入全局变量pECatData表中 就是其属性ECatData表中
if(is_string(name, "ct_signal_ratio")) {
pECatData->cfg.ct_signal_ratio = str2val(value, 1);
}else if(is_string(name, "pt_signal_ratio")) {
pECatData->cfg.pt_signal_ratio = str2val(value, 1);
}else if(is_string(name, "rated_active_power")) {
pECatData->cfg.rated_active_power = str2val(value, 100);
}else if(is_string(name, "rated_reactive_power")) {
pECatData->cfg.rated_reactive_power = str2val(value, 100);
}else if(is_string(name, "pcs_rated_active_power")) {
pECatData->cfg.pcs_rated_active_power = str2val(value, 1);
}else if(is_string(name, "pcs_rated_reactive_power")) {
pECatData->cfg.pcs_rated_reactive_power = str2val(value, 1);
}else if(is_string(name, "bms_info_source")) {
//字符串拷贝
strcpy(pECatData->cfg.bms_info_source, value);
}else if(is_string(name, "ffr_bind_eau")) {
pECatData->cfg.ffr_bind_eau = str2val(value, 1);
}else if(is_string(name, "pcs_number")) {
pECatData->cfg.pcs_number = str2val(value, 1);
}else if(is_string(name, "ccu_number")) {
pECatData->cfg.ccu_number = str2val(value, 1);
}else if(is_string(name, "eau_number")) {
pECatData->cfg.eau_number = str2val(value, 1);
}else if(is_string(name, "ccm_number")) {
pECatData->cfg.ccm_number = str2val(value, 1);
}
}else{
//以上都是 信息节点
//以下都是 目录节点
//通过判断名字来做不通的数据处理
// //cout << name << endl;
if(is_string(name, "signal_bind")) {
//将名为signal_bind的 目录节点 传入下面的函数 进行进一步处理
//其实就是再将其目录节点下的 信息节点再次解析存入 全局结构体中
parse_signal(ccs);
}else if(is_string(name, "ffr_config")) {
parse_ffr(ccs);
}else if(is_string(name, "fvr_config")) {
parse_fvr(ccs);
}else if(is_string(name, "fpu_config")) {
parse_fpu(ccs);
}else if(is_string(name, "ip_config")) {
parse_ip(ccs);
}else if(is_string(name, "network")) {
parse_network(ccs);
}
}
return 1;
}
//从ccm.xml文件中获取Ecat设备点表信息 将xml中的信息存储在 sECatData mData 中 解析xml文件
int parse_xml(const char* name, sECatData *p) {
//抽象出一个XML文档的实例化对象
XMLDocument doc;
//doc实例化对象去加载对应name的xml文件 并判断其是否加载成功对应的文件
if ( doc.LoadFile(name) ) {
doc.PrintError();
return -1;
}
//换名 其中pECatData 就是 ECatMain 中的 sECatData mData
pECatData = p;
XMLElement* ccs = NULL;
// 根元素 此时根据xml文件中得知其是EtherCATInfo的这个节点
XMLElement* ccm= doc.RootElement();
//获取根节点EtherCATInfo的这个节点中的Version的值
cout << "Version=" << ccm->Attribute( "Version" ) << endl << endl;
// 遍历<surface>元素
//从根节点中获取名为Descriptions的节点 并将这个节点赋值给XMLElement* descriptions
XMLElement* descriptions = ccm->FirstChildElement("Descriptions");
//查看Descriptions节点是否存在
if(descriptions !=NULL) {
//如果存在则 在Descriptions寻找名为CCS的节点
ccs = descriptions->FirstChildElement( "CCS" );
// printf(" find ccs = 0x%x\n", ccs);
}
while (ccs) {
// 遍历子元素
//XMLElement* ccsChild指向ccs节点下的第一个元素 例如:ct_signal_ration
XMLElement* ccsChild = ccs->FirstChildElement();
while (ccsChild) {
//将CCS节点下的所有子节点全部送去该函数进行处理
parse_ccs(ccsChild);
//此时ccsChild节点同级的下一个元素节点
ccsChild = ccsChild->NextSiblingElement();
}
//此时ccs节点同级的下一个元素节点
ccs = ccs->NextSiblingElement( "ccs" );
}
printf("parse xml finish.\n");
return 0;
}
void config_print(void) {
}