Skip to content

Commit

Permalink
为 OPC UA 添加自定义命名空间
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaoxi-scut committed Mar 29, 2024
1 parent 64f6cad commit ad26ac7
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 66 deletions.
8 changes: 6 additions & 2 deletions modules/opcua/include/rmvl/opcua/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file event.hpp
* @author zhaoxi ([email protected])
* @brief OPC UA 事件
* @version 1.0
* @version 1.1
* @date 2023-11-13
*
* @copyright Copyright 2023 (c), zhaoxi
Expand All @@ -26,6 +26,9 @@ namespace rm
class EventType
{
public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down Expand Up @@ -68,7 +71,7 @@ class EventType
* @param[in] browse_name 非默认属性的浏览名 BrowseName
* @param[in] prop `int` 整型属性值
*/
inline void add(const std::string &browse_name, int prop) { _properties[browse_name] = prop; }
inline void add(const std::string &browse_name, int prop) { _properties.insert({browse_name, prop}); }

/**
* @brief 访问指定的非默认属性
Expand All @@ -91,6 +94,7 @@ class EventType
class Event
{
public:
uint16_t ns{1U}; //!< 命名空间索引,默认为 `1`
std::string source_name; //!< 默认属性:事件源名称
std::string message; //!< 默认属性:事件消息,包含关于事件的描述
uint16_t severity{}; //!< 默认属性:事件严重程度
Expand Down
7 changes: 5 additions & 2 deletions modules/opcua/include/rmvl/opcua/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file method.hpp
* @author zhaoxi ([email protected])
* @brief 方法节点
* @version 1.0
* @version 1.1
* @date 2023-10-23
*
* @copyright Copyright 2023 (c), zhaoxi
Expand Down Expand Up @@ -55,6 +55,9 @@ struct Argument final
//! OPC UA 方法
struct Method final
{
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down Expand Up @@ -93,7 +96,7 @@ struct Method final
* @endcode
*
*/
UA_MethodCallback func;
UA_MethodCallback func{nullptr};

Method() = default;

Expand Down
10 changes: 8 additions & 2 deletions modules/opcua/include/rmvl/opcua/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file object.hpp
* @author zhaoxi ([email protected])
* @brief 对象(类型)
* @version 1.0
* @date 2023-10-21
* @version 1.1
* @date 2024-03-29
*
* @copyright Copyright 2023 (c), zhaoxi
*
Expand All @@ -30,6 +30,9 @@ namespace rm
class ObjectType final
{
public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down Expand Up @@ -158,6 +161,9 @@ class Object final
std::unordered_map<std::string, Variable> _variables;

public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down
6 changes: 3 additions & 3 deletions modules/opcua/include/rmvl/opcua/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file server.hpp
* @author zhaoxi ([email protected])
* @brief OPC UA 服务器
* @version 2.1
* @date 2024-03-07
* @version 2.2
* @date 2024-03-29
*
* @copyright Copyright 2024 (c), zhaoxi
*
Expand Down Expand Up @@ -150,7 +150,7 @@ class Server
* - 数据源变量节点会把每次 IO 都绑定到各自的回调函数中,即可以重定向到一个实际的物理过程中,从而跟服务器本身的数据读写脱离关系
*
* @param[in] val `rm::Variable` 表示的变量,仅取 `browse_name`、`description`、`display_name`、`access_level`
* 字段,以及对应的变量类型节点
* 以及 `ns` 字段,以及对应的变量类型节点
* @param[in] on_read 重定向的读取回调函数
* @param[in] on_write 重定向的写入回调函数
* @param[in] parent_id 指定父节点的 `UA_NodeId`,默认为 `rm::nodeObjectsFolder`
Expand Down
16 changes: 10 additions & 6 deletions modules/opcua/include/rmvl/opcua/subscriber.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file subscriber.hpp
* @author zhaoxi ([email protected])
* @brief OPC UA 订阅者
* @version 2.1
* @date 2024-03-07
* @version 2.2
* @date 2024-03-29
*
* @copyright Copyright 2024 (c), zhaoxi
*
Expand All @@ -24,6 +24,9 @@ namespace rm
//! 数据集字段元数据
struct FieldMetaData final
{
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

//! 字段名称
std::string name;

Expand All @@ -34,7 +37,7 @@ struct FieldMetaData final
UA_TypeFlag type;

//! 字段 ValueRank
int value_rank;
int value_rank{};

FieldMetaData() = default;

Expand All @@ -44,8 +47,9 @@ struct FieldMetaData final
* @param[in] name_ 字段名称
* @param[in] type_ 字段类型,可参考 @ref UA_TypeFlag
* @param[in] value_rank_ 字段 ValueRank
* @param[in] ns_ 命名空间索引,默认为 `1`
*/
FieldMetaData(const std::string &name_, UA_TypeFlag type_, int value_rank_) : name(name_), type(type_), value_rank(value_rank_) {}
FieldMetaData(const std::string &name_, UA_TypeFlag type_, int value_rank_, uint16_t ns_ = 1U) : ns(ns_), name(name_), type(type_), value_rank(value_rank_) {}

/**
* @brief 从变量创建字段元数据
Expand All @@ -64,9 +68,9 @@ struct FieldMetaData final

/**
* @brief OPC UA 订阅者
*
*
* @tparam Tpid 传输协议 ID,可参考 `rm::TransportID`
*
*
* @details **特化**
* - @ref Subscriber<TransportID::UDP_UADP>
*/
Expand Down
41 changes: 18 additions & 23 deletions modules/opcua/include/rmvl/opcua/variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file variable.hpp
* @author zhaoxi ([email protected])
* @brief 变量(类型)
* @version 2.1
* @date 2024-03-07
* @version 2.2
* @date 2024-03-29
*
* @copyright Copyright 2024 (c), zhaoxi
*
Expand All @@ -30,6 +30,9 @@ namespace rm
class VariableType final
{
public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down Expand Up @@ -120,6 +123,9 @@ class VariableType final
class Variable final
{
public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand All @@ -139,6 +145,8 @@ class Variable final
std::string display_name{};
//! 变量的描述
std::string description{};
//! 访问性
uint8_t access_level{};

private:
/**
Expand All @@ -155,8 +163,6 @@ class Variable final
UA_TypeFlag _data_type{};
//! 数据大小
UA_UInt32 _size{};
//! 访问性
uint8_t _access_level{};

public:
Variable() = default;
Expand All @@ -167,7 +173,7 @@ class Variable final
* @param[in] str 字面量字符串
*/
template <unsigned int N>
Variable(const char (&str)[N]) : _value(str), _data_type(typeflag.at(typeid(const char *))), _size(1), _access_level(3U) {}
Variable(const char (&str)[N]) : access_level(3U), _value(str), _data_type(typeflag.at(typeid(const char *))), _size(1) {}

/**
* @brief 单值构造
Expand All @@ -176,7 +182,7 @@ class Variable final
* @param[in] val 标量、数量值
*/
template <typename Tp, typename Enable = std::enable_if_t<std::is_fundamental_v<Tp> || std::is_same_v<Tp, const char *>>>
Variable(const Tp &val) : _value(val), _data_type(typeflag.at(typeid(Tp))), _size(1), _access_level(3U) {}
Variable(const Tp &val) : access_level(3U), _value(val), _data_type(typeflag.at(typeid(Tp))), _size(1) {}

/**
* @brief 列表构造
Expand All @@ -185,22 +191,21 @@ class Variable final
* @param[in] arr 列表、数组
*/
template <typename Tp, typename Enable = std::enable_if_t<std::is_fundamental_v<Tp> && !std::is_same_v<bool, Tp>>>
Variable(const std::vector<Tp> &arr) : _value(arr), _data_type(typeflag.at(typeid(Tp))), _size(arr.size()), _access_level(3U) {}
Variable(const std::vector<Tp> &arr) : access_level(3U), _value(arr), _data_type(typeflag.at(typeid(Tp))), _size(arr.size()) {}

/**
* @brief 从变量类型构造新的变量节点
*
* @param[in] vtype 既存的待作为变量节点类型信息的使用 `rm::VariableType` 表示的变量类型
*/
explicit Variable(VariableType &vtype) : _type(&vtype), _value(vtype.data()), _data_type(vtype.getDataType()),
_size(vtype.size()), _access_level(3U) {}
explicit Variable(VariableType &vtype) : access_level(3U), _type(&vtype), _value(vtype.data()), _data_type(vtype.getDataType()), _size(vtype.size()) {}

Variable(const Variable &val) : browse_name(val.browse_name), display_name(val.display_name), description(val.description), _type(val._type),
_value(val._value), _data_type(val._data_type), _size(val._size), _access_level(val._access_level) {}
Variable(const Variable &val) : browse_name(val.browse_name), display_name(val.display_name), description(val.description),
access_level(val.access_level), _type(val._type), _value(val._value), _data_type(val._data_type), _size(val._size) {}

Variable(Variable &&val) : browse_name(std::move(val.browse_name)), display_name(std::move(val.display_name)), description(std::move(val.description)),
_type(std::exchange(val._type, nullptr)), _value(std::move(val._value)), _data_type(std::exchange(val._data_type, 0)),
_size(std::exchange(val._size, 0)), _access_level(std::exchange(val._access_level, 0)) {}
access_level(std::exchange(val.access_level, 0)), _type(std::exchange(val._type, nullptr)), _value(std::move(val._value)),
_data_type(std::exchange(val._data_type, 0)), _size(std::exchange(val._size, 0)) {}

Variable &operator=(const Variable &val);

Expand Down Expand Up @@ -262,16 +267,6 @@ class Variable final

//! 获取大小 @note 未初始化则返回 `0`
inline UA_UInt32 size() const { return _size; }

/**
* @brief 设置访问性
*
* @param[in] access_level 访问性
*/
inline void setAccessLevel(uint8_t access_level) { _access_level = access_level; }

//! 获取访问性
inline uint8_t getAccessLevel() const { return _access_level; }
};

/**
Expand Down
7 changes: 5 additions & 2 deletions modules/opcua/include/rmvl/opcua/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file view.hpp
* @author zhaoxi ([email protected])
* @brief 视图
* @version 1.0
* @date 2023-11-27
* @version 1.1
* @date 2024-03-29
*
* @copyright Copyright 2023 (c), zhaoxi
*
Expand All @@ -23,6 +23,9 @@ namespace rm
class View final
{
public:
//! 命名空间索引,默认为 `1`
uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
Expand Down
6 changes: 3 additions & 3 deletions modules/opcua/src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file client.cpp
* @author zhaoxi ([email protected])
* @brief OPC UA 客户端
* @version 1.0
* @date 2023-10-29
* @version 1.1
* @date 2024-03-29
*
* @copyright Copyright 2023 (c), zhaoxi
*
Expand Down Expand Up @@ -147,7 +147,7 @@ UA_NodeId Client::addViewNode(const View &view)
// 创建并添加 View 节点
auto status = UA_Client_addViewNode(
_client, UA_NODEID_NULL, nodeViewsFolder, nodeOrganizes,
UA_QUALIFIEDNAME(1, helper::to_char(view.browse_name)), attr, &retval);
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));
Expand Down
10 changes: 5 additions & 5 deletions modules/opcua/src/data.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* @file data.cpp
* @author zhaoxi ([email protected])
* @brief 对象(类型)
* @version 1.0
* @date 2023-10-23
* @brief OPC UA 数据,包括变量、方法、对象、事件、视图
* @version 1.1
* @date 2024-03-29
*
* @copyright Copyright 2023 (c), zhaoxi
*
Expand Down Expand Up @@ -43,11 +43,11 @@ Variable &Variable::operator=(const Variable &val)
browse_name = val.browse_name;
display_name = val.display_name;
description = val.description;
access_level = val.access_level;
_type = val._type;
_value = val._value;
_data_type = val._data_type;
_size = val._size;
_access_level = val._access_level;
return *this;
}

Expand All @@ -56,11 +56,11 @@ Variable &Variable::operator=(Variable &&val)
browse_name = std::move(val.browse_name);
display_name = std::move(val.display_name);
description = std::move(val.description);
access_level = std::exchange(val.access_level, 0);
_type = std::exchange(val._type, nullptr);
_value = std::move(val._value);
_data_type = std::exchange(val._data_type, 0);
_size = std::exchange(val._size, 0);
_access_level = std::exchange(val._access_level, 0);
return *this;
}

Expand Down
Loading

0 comments on commit ad26ac7

Please sign in to comment.