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
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) { |
|
|
|
} |