From 15163340cd02c191f539af8fbb50817d66b8ab5b Mon Sep 17 00:00:00 2001 From: zhaoxi <535394140@qq.com> Date: Fri, 31 May 2024 17:04:34 +0800 Subject: [PATCH] =?UTF-8?q?OPC=20UA=20=E6=A8=A1=E5=9D=97=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA=E7=AD=89=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- modules/opcua/include/rmvl/opcua/method.hpp | 14 ----- .../opcua/include/rmvl/opcua/utilities.hpp | 34 +++++------ modules/opcua/src/client.cpp | 25 ++++++--- modules/opcua/src/cvt.hpp | 10 ++++ modules/opcua/src/helper.cpp | 5 +- modules/opcua/src/publisher.cpp | 12 ++-- modules/opcua/src/server.cpp | 56 ++++++++++--------- modules/opcua/src/subscriber.cpp | 14 ++--- samples/opcua/opcua_client.cpp | 2 + samples/opcua/opcua_server.cpp | 7 +-- 11 files changed, 93 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index 3f09b137..7b52fef0 100755 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ devel *.jpg *.jpeg !rmvl-logo* -!doc/img/* +!doc/img/** # 模型文件 *.onnx diff --git a/modules/opcua/include/rmvl/opcua/method.hpp b/modules/opcua/include/rmvl/opcua/method.hpp index 0a76da26..14ba9960 100644 --- a/modules/opcua/include/rmvl/opcua/method.hpp +++ b/modules/opcua/include/rmvl/opcua/method.hpp @@ -105,18 +105,4 @@ struct Method final //! @} opcua -namespace helper -{ - -/** - * @brief `rm::Argument` 转化为 `UA_Argument` - * - * @warning 此方法一般不直接使用 - * @param[in] arg `rm::Argument` 表示的方法 - * @return `UA_Argument` 表示的方法 - */ -UA_Argument cvtArgument(const Argument &arg); - -} // namespace helper - } // namespace rm diff --git a/modules/opcua/include/rmvl/opcua/utilities.hpp b/modules/opcua/include/rmvl/opcua/utilities.hpp index 3476fc3c..1bd7d192 100644 --- a/modules/opcua/include/rmvl/opcua/utilities.hpp +++ b/modules/opcua/include/rmvl/opcua/utilities.hpp @@ -11,8 +11,9 @@ #pragma once -#include +#include #include +#include #include #include @@ -30,9 +31,10 @@ namespace rm //! @addtogroup opcua //! @{ +//! OPC UA 节点 ID struct NodeId final { - UA_NodeId nid{}; //!< 节点 ID + UA_NodeId nid{}; //!< open62541 的节点 ID 结构体 //! 默认构造节点 ID NodeId() = default; @@ -88,8 +90,8 @@ struct NodeId final */ struct UserConfig final { - ::std::string id; //!< 用户名 - ::std::string passwd; //!< 密码 + std::string id; //!< 用户名 + std::string passwd; //!< 密码 }; //! 类型标志位,可通过 `typeflag.at(xxx)` 进行获取 @@ -97,18 +99,18 @@ using UA_TypeFlag = UA_UInt32; //! 获取形如 `UA_TYPES_` 的类型标志位 inline const std::unordered_map typeflag = - {{::std::type_index(typeid(bool)), UA_TYPES_BOOLEAN}, - {::std::type_index(typeid(int8_t)), UA_TYPES_SBYTE}, - {::std::type_index(typeid(uint8_t)), UA_TYPES_BYTE}, - {::std::type_index(typeid(UA_Int16)), UA_TYPES_INT16}, - {::std::type_index(typeid(UA_UInt16)), UA_TYPES_UINT16}, - {::std::type_index(typeid(UA_Int32)), UA_TYPES_INT32}, - {::std::type_index(typeid(UA_UInt32)), UA_TYPES_UINT32}, - {::std::type_index(typeid(UA_Int64)), UA_TYPES_INT64}, - {::std::type_index(typeid(UA_UInt64)), UA_TYPES_UINT64}, - {::std::type_index(typeid(UA_Float)), UA_TYPES_FLOAT}, - {::std::type_index(typeid(UA_Double)), UA_TYPES_DOUBLE}, - {::std::type_index(typeid(const char *)), UA_TYPES_STRING}}; + {{std::type_index(typeid(bool)), UA_TYPES_BOOLEAN}, + {std::type_index(typeid(int8_t)), UA_TYPES_SBYTE}, + {std::type_index(typeid(uint8_t)), UA_TYPES_BYTE}, + {std::type_index(typeid(UA_Int16)), UA_TYPES_INT16}, + {std::type_index(typeid(UA_UInt16)), UA_TYPES_UINT16}, + {std::type_index(typeid(UA_Int32)), UA_TYPES_INT32}, + {std::type_index(typeid(UA_UInt32)), UA_TYPES_UINT32}, + {std::type_index(typeid(UA_Int64)), UA_TYPES_INT64}, + {std::type_index(typeid(UA_UInt64)), UA_TYPES_UINT64}, + {std::type_index(typeid(UA_Float)), UA_TYPES_FLOAT}, + {std::type_index(typeid(UA_Double)), UA_TYPES_DOUBLE}, + {std::type_index(typeid(const char *)), UA_TYPES_STRING}}; //! 传输协议 enum class TransportID : uint8_t diff --git a/modules/opcua/src/client.cpp b/modules/opcua/src/client.cpp index a45d2dbb..6d3e2f61 100644 --- a/modules/opcua/src/client.cpp +++ b/modules/opcua/src/client.cpp @@ -30,6 +30,13 @@ Client::Client(std::string_view address, UserConfig usr) { _client = UA_Client_new(); UA_ClientConfig *config = UA_Client_getConfig(_client); + // 修改日志 +#if OPCUA_VERSION < 10400 + config->logger = UA_Log_Stdout_withLevel(UA_LOGLEVEL_ERROR); +#else + config->logging = UA_Log_Stdout_new(UA_LOGLEVEL_ERROR); +#endif + // 设置默认配置 auto status = UA_ClientConfig_setDefault(config); if (status == UA_STATUSCODE_GOOD) { @@ -40,7 +47,7 @@ Client::Client(std::string_view address, UserConfig usr) } if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to create client"); + ERROR_("Failed to create client"); UA_Client_delete(_client); _client = nullptr; } @@ -96,7 +103,7 @@ bool Client::write(const NodeId &node, const Variable &val) UA_Variant_clear(&new_variant); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to write value to the specific node, error: %s", UA_StatusCode_name(status)); + ERROR_("Failed to write value to the specific node, error: %s", UA_StatusCode_name(status)); return false; } return true; @@ -115,7 +122,7 @@ bool Client::call(const NodeId &obj_node, const std::string &name, const std::ve NodeId method_node = obj_node | find(name); if (method_node.empty()) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to find the method node: %s", name.c_str()); + ERROR_("Failed to find the method node: %s", name.c_str()); return false; } // 调用方法 @@ -125,7 +132,7 @@ bool Client::call(const NodeId &obj_node, const std::string &name, const std::ve UA_Variant_clear(&input_variant); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to call the method, node id: %d, error code: %s", + ERROR_("Failed to call the method, node id: %d, error code: %s", method_node.nid.identifier.numeric, UA_StatusCode_name(status)); return false; } @@ -150,7 +157,7 @@ NodeId Client::addViewNode(const View &view) UA_QUALIFIEDNAME(view.ns, helper::to_char(view.browse_name)), attr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to add view node, error: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add view node, error: %s", UA_StatusCode_name(status)); return {}; } // 添加引用 @@ -161,7 +168,7 @@ NodeId Client::addViewNode(const View &view) status = UA_Client_addReference(_client, retval, nodeOrganizes, true, UA_STRING_NULL, exp, UA_NODECLASS_VARIABLE); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to add reference, error: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add reference, error: %s", UA_StatusCode_name(status)); return {}; } } @@ -186,7 +193,7 @@ bool Client::monitor(NodeId node, UA_Client_DataChangeNotificationCallback on_ch _client, resp.subscriptionId, UA_TIMESTAMPSTORETURN_BOTH, request, &node, on_change, nullptr); if (result.statusCode != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to create variable monitor, error: %s", UA_StatusCode_name(result.statusCode)); + ERROR_("Failed to create variable monitor, error: %s", UA_StatusCode_name(result.statusCode)); return false; } return true; @@ -234,7 +241,7 @@ bool Client::monitor(NodeId node, const std::vector &names, UA_Clie _client, sub_resp.subscriptionId, UA_TIMESTAMPSTORETURN_BOTH, request_item, &monitor_id, on_event, nullptr); if (result.statusCode != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to create event monitor, error: %s", UA_StatusCode_name(result.statusCode)); + ERROR_("Failed to create event monitor, error: %s", UA_StatusCode_name(result.statusCode)); return false; } else @@ -259,7 +266,7 @@ bool Client::createSubscription(UA_CreateSubscriptionResponse &response) response = UA_Client_Subscriptions_create(_client, request, nullptr, nullptr, nullptr); if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to create subscription, error: %s", + ERROR_("Failed to create subscription, error: %s", UA_StatusCode_name(response.responseHeader.serviceResult)); return false; } diff --git a/modules/opcua/src/cvt.hpp b/modules/opcua/src/cvt.hpp index be68511b..eaadb33e 100644 --- a/modules/opcua/src/cvt.hpp +++ b/modules/opcua/src/cvt.hpp @@ -12,6 +12,7 @@ #pragma once #include "rmvl/opcua/variable.hpp" +#include "rmvl/opcua/method.hpp" namespace rm::helper { @@ -43,4 +44,13 @@ Variable cvtVariable(const UA_Variant &p_val); */ UA_Variant cvtVariable(const VariableType &vtype); +/** + * @brief `rm::Argument` 转化为 `UA_Argument` + * + * @warning 此方法一般不直接使用 + * @param[in] arg `rm::Argument` 表示的方法 + * @return `UA_Argument` 表示的方法 + */ +UA_Argument cvtArgument(const Argument &arg); + } // namespace rm::helper diff --git a/modules/opcua/src/helper.cpp b/modules/opcua/src/helper.cpp index d9ad4147..fa7c6ad6 100644 --- a/modules/opcua/src/helper.cpp +++ b/modules/opcua/src/helper.cpp @@ -13,7 +13,6 @@ #include #include -#include "rmvl/opcua/method.hpp" #include "rmvl/opcua/utilities.hpp" #include "cvt.hpp" @@ -58,8 +57,8 @@ NodeId operator|(NodeId origin, FindNodeInClient &&fnic) if (response.resultsSize == 1 && response.results[0].targetsSize == 1) return response.results[0].targets[0].targetId.nodeId; - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to find node, name: %s, error code: %s", - browse_name.c_str(), UA_StatusCode_name(response.responseHeader.serviceResult)); + ERROR_("Failed to find node, name: %s, error code: %s", + browse_name.c_str(), UA_StatusCode_name(response.responseHeader.serviceResult)); return {}; } diff --git a/modules/opcua/src/publisher.cpp b/modules/opcua/src/publisher.cpp index 6307b2e9..67d366cd 100644 --- a/modules/opcua/src/publisher.cpp +++ b/modules/opcua/src/publisher.cpp @@ -60,7 +60,7 @@ Publisher::Publisher(const std::string &pub_name, const s auto status = UA_Server_addPubSubConnection(_server, &connect_config, &_connection_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add connection, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add connection, \"%s\"", UA_StatusCode_name(status)); return; } //////////// 添加 PublishedDataSet (PDS) ///////////// @@ -71,7 +71,7 @@ Publisher::Publisher(const std::string &pub_name, const s auto pds_status = UA_Server_addPublishedDataSet(_server, &pds_config, &_pds_id); if (pds_status.addResult != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add published dataset, \"%s\"", + ERROR_("Failed to add published dataset, \"%s\"", UA_StatusCode_name(pds_status.addResult)); return; } @@ -104,7 +104,7 @@ bool Publisher::publish(const std::vector::publish(const std::vector::publish(const std::vectorlogger = UA_Log_Stdout_withLevel(UA_LOGLEVEL_ERROR); +#else + config->logging = UA_Log_Stdout_new(UA_LOGLEVEL_ERROR); +#endif + // 设置服务器配置 UA_ServerConfig_setMinimal(config, port, nullptr); // 修改名字 if (!name.empty()) @@ -83,7 +90,7 @@ void Server::start() _run = std::thread([this]() { UA_StatusCode retval = UA_Server_run(_server, &_running); if (retval != UA_STATUSCODE_GOOD) - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to initialize server: %s", UA_StatusCode_name(retval)); + ERROR_("Failed to initialize server: %s", UA_StatusCode_name(retval)); }); } @@ -117,7 +124,7 @@ NodeId Server::addVariableTypeNode(const VariableType &vtype) UA_Variant_clear(&variant); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add variable type node: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add variable type node: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } return retval; @@ -148,7 +155,7 @@ NodeId Server::addVariableNode(const Variable &val, const NodeId &parent_id) type_id = type_id | find(p_type->browse_name); if (type_id.empty()) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to find the variable type ID during adding variable node"); + ERROR_("Failed to find the variable type ID during adding variable node"); type_id = nodeBaseDataVariableType; } } @@ -161,7 +168,7 @@ NodeId Server::addVariableNode(const Variable &val, const NodeId &parent_id) type_id, attr, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add variable node: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add variable node: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } UA_Variant_clear(&variant); @@ -186,7 +193,7 @@ bool Server::write(const NodeId &node, const Variable &val) auto status = UA_Server_writeValue(_server, node, variant); UA_Variant_clear(&variant); if (status != UA_STATUSCODE_GOOD) - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to write variable, error code: %s", UA_StatusCode_name(status)); + ERROR_("Failed to write variable, error code: %s", UA_StatusCode_name(status)); return status == UA_STATUSCODE_GOOD; } @@ -195,8 +202,7 @@ bool Server::addVariableNodeValueCallBack(NodeId id, ValueCallBackBeforeRead bef UA_ValueCallback callback{before_read, after_write}; auto status = UA_Server_setVariableNode_valueCallback(_server, id, callback); if (status != UA_STATUSCODE_GOOD) - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, - "Function addVariableNodeValueCallBack: %s", UA_StatusCode_name(status)); + ERROR_("Function addVariableNodeValueCallBack: %s", UA_StatusCode_name(status)); return status == UA_STATUSCODE_GOOD; } @@ -216,7 +222,7 @@ NodeId Server::addDataSourceVariableNode(const Variable &val, DataSourceRead on_ type_id = type_id | find(p_type->browse_name); if (type_id.empty()) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to find the variable type ID during adding variable node"); + ERROR_("Failed to find the variable type ID during adding variable node"); type_id = nodeBaseDataVariableType; } } @@ -231,7 +237,7 @@ NodeId Server::addDataSourceVariableNode(const Variable &val, DataSourceRead on_ type_id, attr, data_source, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add data source variable node: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add data source variable node: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } return retval; @@ -260,8 +266,7 @@ NodeId Server::addMethodNode(const Method &method, const NodeId &parent_id) attr, method.func, inputs.size(), inputs.data(), outputs.size(), outputs.data(), nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, - "Failed to add method node: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add method node: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 添加 Mandatory 属性 @@ -269,8 +274,7 @@ NodeId Server::addMethodNode(const Method &method, const NodeId &parent_id) UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, - "Failed to add the \"Mandatory\" reference node: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add the \"Mandatory\" reference node: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } return retval; @@ -304,7 +308,7 @@ NodeId Server::addObjectTypeNode(const ObjectType &otype) } if (parent_id.empty()) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to find the base object type ID during adding object type node"); + ERROR_("Failed to find the base object type ID during adding object type node"); parent_id = nodeBaseObjectType; } auto status = UA_Server_addObjectTypeNode( @@ -314,7 +318,7 @@ NodeId Server::addObjectTypeNode(const ObjectType &otype) attr, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add object type: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add object type: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 添加变量节点作为对象类型节点的子节点 @@ -372,7 +376,7 @@ NodeId Server::addObjectNode(const Object &obj, NodeId parent_id) type_id, attr, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add object node to server, error code: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add object node to server, error code: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 添加额外变量节点 @@ -409,7 +413,7 @@ NodeId Server::addViewNode(const View &view) UA_QUALIFIEDNAME(view.ns, helper::to_char(view.browse_name)), attr, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to add view node, error: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add view node, error: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 添加引用 @@ -420,7 +424,7 @@ NodeId Server::addViewNode(const View &view) status = UA_Server_addReference(_server, retval, nodeOrganizes, exp, true); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Failed to add reference, error: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add reference, error: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } } @@ -442,7 +446,7 @@ NodeId Server::addEventTypeNode(const EventType &etype) attr, nullptr, &retval); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add event type: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add event type: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 添加自定义数据(非默认属性) @@ -459,8 +463,7 @@ NodeId Server::addEventTypeNode(const EventType &etype) val_attr, nullptr, &sub_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, - "Failed to add event type property: %s", UA_StatusCode_name(status)); + ERROR_("Failed to add event type property: %s", UA_StatusCode_name(status)); return UA_NODEID_NULL; } // 设置子变量节点为强制生成 @@ -469,9 +472,8 @@ NodeId Server::addEventTypeNode(const EventType &etype) UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), true); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, - "Failed to add reference during adding event type node, browse name: %s, error code: %s", - browse_name.c_str(), UA_StatusCode_name(status)); + ERROR_("Failed to add reference during adding event type node, browse name: %s, error code: %s", + browse_name.c_str(), UA_StatusCode_name(status)); return UA_NODEID_NULL; } } @@ -483,7 +485,7 @@ bool Server::triggerEvent(const NodeId &node_id, const Event &event) NodeId type_id = nodeBaseEventType | find(event.type()->browse_name); if (type_id.empty()) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to find the event type ID during triggering event"); + ERROR_("Failed to find the event type ID during triggering event"); return false; } // 创建事件 @@ -491,7 +493,7 @@ bool Server::triggerEvent(const NodeId &node_id, const Event &event) auto status = UA_Server_createEvent(_server, type_id, &event_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to create event: %s", UA_StatusCode_name(status)); + ERROR_("Failed to create event: %s", UA_StatusCode_name(status)); return false; } @@ -516,7 +518,7 @@ bool Server::triggerEvent(const NodeId &node_id, const Event &event) status = UA_Server_triggerEvent(_server, event_id, node_id, nullptr, true); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to trigger event: %s", UA_StatusCode_name(status)); + ERROR_("Failed to trigger event: %s", UA_StatusCode_name(status)); return false; } return true; diff --git a/modules/opcua/src/subscriber.cpp b/modules/opcua/src/subscriber.cpp index 3958a847..1b5d9e2e 100644 --- a/modules/opcua/src/subscriber.cpp +++ b/modules/opcua/src/subscriber.cpp @@ -53,7 +53,7 @@ Subscriber::Subscriber(const std::string &sub_name, const auto status = UA_Server_addPubSubConnection(_server, &connect_config, &_connection_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add connection, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add connection, \"%s\"", UA_StatusCode_name(status)); return; } } @@ -67,13 +67,13 @@ std::vector Subscriber::subscribe(const std::stri auto status = UA_Server_addReaderGroup(_server, _connection_id, &rg_config, &_rg_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add reader group, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add reader group, \"%s\"", UA_StatusCode_name(status)); return {}; } status = UA_Server_setReaderGroupOperational(_server, _rg_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to set reader group operational, \"%s\"", + ERROR_("Failed to set reader group operational, \"%s\"", UA_StatusCode_name(status)); return {}; } @@ -105,7 +105,7 @@ std::vector Subscriber::subscribe(const std::stri status = UA_Server_addDataSetReader(_server, _rg_id, &dsr_config, &_dsr_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add data set reader, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add data set reader, \"%s\"", UA_StatusCode_name(status)); return {}; } @@ -115,7 +115,7 @@ std::vector Subscriber::subscribe(const std::stri auto obj_id = addObjectNode(sub_obj); if (UA_NodeId_isNull(&obj_id)) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add object node, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add object node, \"%s\"", UA_StatusCode_name(status)); return {}; } // 根据数据集元数据 DataSetMetaData 的字段创建 FieldTargetVariable @@ -137,7 +137,7 @@ std::vector Subscriber::subscribe(const std::stri nodeBaseDataVariableType, attr, nullptr, &node_id); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to add variable node, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to add variable node, \"%s\"", UA_StatusCode_name(status)); continue; } UA_FieldTargetDataType_init(&target_vars[i].targetVariable); @@ -148,7 +148,7 @@ std::vector Subscriber::subscribe(const std::stri status = UA_Server_DataSetReader_createTargetVariables(_server, _dsr_id, target_vars.size(), target_vars.data()); if (status != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to create target variables, \"%s\"", UA_StatusCode_name(status)); + ERROR_("Failed to create target variables, \"%s\"", UA_StatusCode_name(status)); return {}; } return retval; diff --git a/samples/opcua/opcua_client.cpp b/samples/opcua/opcua_client.cpp index 1f93d060..5a38f053 100644 --- a/samples/opcua/opcua_client.cpp +++ b/samples/opcua/opcua_client.cpp @@ -3,6 +3,8 @@ int main() { rm::Client client("opc.tcp://localhost:4840"); + if (!client.ok()) + return -1; auto position_id = rm::nodeObjectsFolder | client.find("position"); auto position = client.read(position_id); printf("\033[32mValue: %d\033[0m\n", position.cast()); diff --git a/samples/opcua/opcua_server.cpp b/samples/opcua/opcua_server.cpp index 599551b8..51a0a7ed 100644 --- a/samples/opcua/opcua_server.cpp +++ b/samples/opcua/opcua_server.cpp @@ -2,17 +2,14 @@ #include "rmvl/opcua/server.hpp" -rm::Server *p_server{nullptr}; +rm::Server server(4840); -inline void onHandle(int) { p_server->stop(); } +static inline void onHandle(int) { server.stop(); } int main() { signal(SIGINT, onHandle); - rm::Server server(4840); - p_server = &server; - rm::Variable position = 5500; position.display_name = "Position"; position.browse_name = "position";