Files
EJM_Display/DataCenter/OpcUaManager - 副本.h
2025-09-15 22:28:43 +08:00

115 lines
3.8 KiB
C++
Raw Permalink 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.

#ifndef OPCUAMANAGER_H
#define OPCUAMANAGER_H
#include <QObject>
#include <QOpcUaClient>
#include <QOpcUaNode>
#include <QOpcUaEndpointDescription>
#include <QVector>
#include <QUrl>
#include <QTimer>
#include <QMutex> // 新增:线程安全锁
#include <QEventLoop>
#include <QThread>
struct WriteWaiter : QObject {
Q_OBJECT
public:
bool ok = false;
QEventLoop loop;
public slots:
void done(bool success, const QString &) { ok = success; loop.quit(); }
};
class OpcUaManager : public QObject
{
Q_OBJECT
public:
static OpcUaManager* instance(QObject* parent = nullptr); // 全局唯一获取方式
// 禁止拷贝和赋值(避免创建多个实例)
OpcUaManager(const OpcUaManager&) = delete;
OpcUaManager& operator=(const OpcUaManager&) = delete;
~OpcUaManager();
// 连接服务器
bool connectToServer(const QString &url, const QString &username, const QString &password);
// 断开连接
void disconnectFromServer();
// 读取节点值
bool readNodeValue(const QString &nodeId);
// 写入节点值
bool writeNodeValue(const QString &nodeId, const QVariant &value);
// 获取连接状态
QOpcUaClient::ClientState connectionState() const;
QOpcUaClient* getClient() const; // 添加这个方法
bool writeNodeValue(const QString &nodeId,
const QVariant &value,
int maxRetry /* = 3 */,
int retryIntervalMs /* = 200 */);
signals:
// 状态变化信号
void stateChanged(QOpcUaClient::ClientState state);
// 读取完成信号返回值和节点ID
void readCompleted(const QVariant &value, const QString &nodeId);
// 写入完成信号返回是否成功和节点ID
void writeCompleted(bool success, const QString &nodeId);
// 错误信号(返回错误信息)
void errorOccurred(const QString &errorString);
void reconnected(); // 新增:重连成功后广播
private slots:
// 端点请求完成处理
void onEndpointsRequestFinished(QVector<QOpcUaEndpointDescription> endpoints,
QOpcUa::UaStatusCode statusCode,
QUrl requestedUrl);
// 客户端状态变化处理
void onClientStateChanged(QOpcUaClient::ClientState state);
// 属性读取完成处理(用于普通读取)
void onAttributeRead(QOpcUa::NodeAttributes attrs);
// 属性写入完成处理
void onAttributeWritten(QOpcUa::NodeAttribute attribute, QOpcUa::UaStatusCode statusCode);
// 写入前读取值类型(用于动态类型适配)
void onPreWriteValueTypeRead(QOpcUa::NodeAttributes attrs);
void tryReconnect(); // 新增:真正执行重连
private:
explicit OpcUaManager(QObject *parent = nullptr); // 私有构造函数(仅允许 instance() 创建)
static OpcUaManager* m_instance; // 静态单例实例
static QMutex m_mutex; // 线程安全锁(避免多线程冲突)
// 创建客户端实例
void createClient();
/** @brief OPC UA客户端实例 */
QOpcUaClient *mClient;
/** @brief 当前操作的节点 */
QOpcUaNode *mCurrentNode;
/** @brief 当前节点ID */
QString mCurrentNodeId;
/** @brief 服务器地址 */
QUrl mServerUrl;
/** @brief 登录用户名 */
QString mUserName;
/** @brief 登录密码 */
QString mPassword;
/** @brief 节点数据类型(备用) */
int mNodeDataType;
/** @brief 待写入的值(临时存储) */
QVariant mPendingWriteValue;
/** @brief 重连定时器 */
QTimer *mReconnectTimer = nullptr;
/** @brief 每次重连的时间间隔 */
const int RECONNECT_INTERVAL = 3000; //
};
#endif // OPCUAMANAGER_H