Files
dbp-exporter/DBPclient/DBPclient.cpp
2022-11-08 13:49:53 +08:00

228 lines
7.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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;
}
}
}