// // Created by test on 2022/11/3. // #include "DBPclient.h" #include #include DBPclient::DBPclient(std::string endpoint, std::string username, std::string password) : dbp_endpoint(std::move(endpoint)), dbp_username(std::move(username)), dbp_password(std::move(password)) { m_dwHandle = 0; } DBPclient::~DBPclient() { } bool DBPclient::connect() { // 设置连接参数 WORD wport = 12084; m_dwHandle = DBPCreate2(dbp_endpoint.data(), dbp_username.data(), dbp_password.data(), wport, false); //创建对象 std::chrono::steady_clock::time_point t_begin = std::chrono::steady_clock::now(); //创建对象 启动连接 DWORD ret; if (m_dwHandle) { ret = DBPConnect(m_dwHandle); if (ret == 0) { //取连接信息 char sip[16]; int pnNum; DBPGetSvrConInfo(m_dwHandle, sip, &pnNum); std::chrono::steady_clock::time_point t_end = std::chrono::steady_clock::now(); std::chrono::duration time_used = std::chrono::duration_cast < std::chrono::duration < double >> ( t_end - t_begin); std::cout << "connect use:" << time_used << std::endl; return true; } else { std::cout << "connect failed"; // std::chrono::steady_clock::time_point t_end = std::chrono::steady_clock::now(); // std::chrono::duration time_used = std::chrono::duration_cast>( // t_end - t_begin); // std::cout << "connect failed use:" << time_used << std::endl; return false; } } return true; } void DBPclient::disconnect() { int pnCon; DWORD ret; ret = DBPIsConnect(m_dwHandle, &pnCon); if (ret == 0 && pnCon != 0) //连接 { DBPDisConnect(m_dwHandle);//关闭连接 DBPDestroy(m_dwHandle);//删除对象 std::cout << "disconnected"; } } struct DataInfo { std::array szSName = {0}; std::array szSDBName = {0}; std::array szSDBTagName = {0}; std::array szSDes = {0}; std::array szSUnit = {0}; DWORD szDWid; WORD szWType; }; void DBPclient::readValue(const std::vector &node_ids) { std::vector vData; std::vector vTags; // 读全部标签 if (m_dwHandle) { // 查询标签,获取标签个数 DWORD ret; long ltagnum, count = 0, nIndex = 0; ret = DBPQueryTagFromDbp(//查询标签,查询后结果保存在对象中,下次用EnumTagAttr逐个取属性 m_dwHandle, NULL, //标签名过滤传,NULL或空串表示全部 NULL, //描述过滤传,NULL或空串表示全部 -1, //类型,-1表示全部 <agnum //查询到的标签数 );//返回错误码 if (ret != 0) { std::cout << "query tag error"; return; } std::cout << "tag num:" << ltagnum << std::endl; vData.resize(ltagnum); // 读标签属性 short errcode0; //错误代码 long ltagflag0; //标签标志, std::chrono::steady_clock::time_point t_begin = std::chrono::steady_clock::now(); std::cout << "read tag" << std::endl; for (long i = 0; i < vData.size(); i++) { ret = DBPEnumTagAttr( //枚举查询后标签属性 m_dwHandle, vData[i].szSName.data(), //标签名 80 vData[i].szSDBName.data(), //数据库实例名 16 vData[i].szSDBTagName.data(), //数据库标签名 80 vData[i].szSDes.data(), //描述 80 vData[i].szSUnit.data(), //单位 16 &vData[i].szDWid, //标签ID &vData[i].szWType, //数据类型 &errcode0, //错误代码 <agflag0, //标签标志, i //位置 0到查询的标签数-1 ); //返回 DBP_OK表示成功,否则错误或没有了} if (ret == 0) { // for (auto const &t: vData[i].szSName) { // std::cout << t; // } // std::cout << std::endl; } else { std::cout << i << "error code:" << errcode0 << std::endl; return; } } std::chrono::steady_clock::time_point t_end = std::chrono::steady_clock::now(); std::chrono::duration time_used = std::chrono::duration_cast < std::chrono::duration < double >> ( t_end - t_begin); std::cout << "read tag use:" << time_used << std::endl; for (auto &d: vData) { vTags.emplace_back(d.szSName.data()); } std::vector ltimes; std::vector snqas; std::vector dblals; std::vector lvals; std::vector ntypes; std::vector errs; ltimes.resize(ltagnum); snqas.resize(ltagnum); dblals.resize(ltagnum); lvals.resize(ltagnum); ntypes.resize(ltagnum); errs.resize(ltagnum); std::cout << "read value" << std::endl; std::chrono::steady_clock::time_point v_begin = std::chrono::steady_clock::now(); ret = DBPGetSnapshot( //读快照 m_dwHandle, vTags.data(), //标签名数组 ltimes.data(), //in/out, 时标 snqas.data(), //in/out, 质量 dblals.data(), //in/out, 存放double值,DT_FLOAT32,DT_FLOAT64存放区 lvals.data(), //in/out, 存放Long值,DT_DIGITAL,DT_INT32,DT_INT64存放区 ntypes.data(), //in/out, 数据类型,DT_INT32,DT_FLOAT32等。 errs.data(), //in/out, 错误码 ltagnum //in, 个数 );//返回错误码 if (ret != 0) { return; } std::chrono::steady_clock::time_point v_end = std::chrono::steady_clock::now(); std::chrono::duration read_value_time_used = std::chrono::duration_cast < std::chrono::duration < double >> ( v_end - v_begin); std::cout << "read value use:" << read_value_time_used << std::endl; for (int j = 0; j < ltagnum; j++) { //std::cout << j << ":" << ntypes[j] << std::endl; switch (ntypes[j]) { case DT_DIGITAL: dbp_read_value[vTags[j]] = lvals[j]; case DT_INT32: dbp_read_value[vTags[j]] = lvals[j]; case DT_INT64: //std::cout << lvals[j] << std::endl; dbp_read_value[vTags[j]] = lvals[j]; break; case DT_FLOAT32: dbp_read_value[vTags[j]] = lvals[j]; case DT_FLOAT64: //std::cout << dblals[j] << std::endl; dbp_read_value[vTags[j]] = dblals[j]; break; default: dbp_read_value[vTags[j]] = 0; } } } std::fstream fs; fs.open("value.txt", std::ios::ate | std::ios::out); for (auto iter: dbp_read_value) { fs << iter.first << ":" << iter.second << std::endl; } fs.close(); } void DBPclient::stop() { running = false; disconnect(); } void DBPclient::run() { while (running) { if (!connect()) { //disconnect(); // spdlog::error("OPC-UA Server({}) not connected({}). Retrying to connect in 1 second.", ua_endpoint, // retval); std::cout << "Retrying to connect in 1 second." << std::endl; Sleep(1000); continue; } } }