dbpclient OK

This commit is contained in:
2022-11-08 13:49:53 +08:00
commit 53d6c7efe7
13 changed files with 1000 additions and 0 deletions

227
DBPclient/DBPclient.cpp Normal file
View File

@@ -0,0 +1,227 @@
//
// Created by test on 2022/11/3.
//
#include "DBPclient.h"
#include <fstream>
#include <windows.h>
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<double> 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<double> time_used = std::chrono::duration_cast<std::chrono::duration<double>>(
// 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<char, 80> szSName = {0};
std::array<char, 16> szSDBName = {0};
std::array<char, 80> szSDBTagName = {0};
std::array<char, 80> szSDes = {0};
std::array<char, 16> szSUnit = {0};
DWORD szDWid;
WORD szWType;
};
void DBPclient::readValue(const std::vector <std::string> &node_ids) {
std::vector <DataInfo> vData;
std::vector<char *> vTags;
// 读全部标签
if (m_dwHandle) {
// 查询标签,获取标签个数
DWORD ret;
long ltagnum, count = 0, nIndex = 0;
ret = DBPQueryTagFromDbp(//查询标签,查询后结果保存在对象中下次用EnumTagAttr逐个取属性
m_dwHandle,
NULL, //标签名过滤传NULL或空串表示全部
NULL, //描述过滤传NULL或空串表示全部
-1, //类型,-1表示全部
&ltagnum //查询到的标签数
);//返回错误码
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, //错误代码
&ltagflag0, //标签标志,
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<double> 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<long> ltimes;
std::vector<short> snqas;
std::vector<double> dblals;
std::vector<long> lvals;
std::vector<int> ntypes;
std::vector<short> 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<double> 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;
}
}
}