Skip to content

Commit

Permalink
✨ OPC UA 变量节点增加初始化列表的转换构造函数,并增加地址空间的单元测试
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaoxi-scut committed Feb 17, 2025
1 parent 79e9d53 commit 60e7551
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 28 deletions.
34 changes: 28 additions & 6 deletions modules/opcua/include/rmvl/opcua/variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class RMVL_EXPORTS_W VariableType final
* @param[in] str 字符串
*/
template <std::size_t N>
VariableType(const char (&str)[N]) : VariableType(std::string(str, N)) {}
VariableType(const char (&str)[N]) : VariableType(std::string(str)) {}

/**
* @brief 列表构造,设置默认值
Expand All @@ -72,6 +72,15 @@ class RMVL_EXPORTS_W VariableType final
RMVL_W_SUBST("VT_List")
VariableType(const std::vector<Tp> &arr) : _value(arr), _data_type(DataType(typeid(Tp))), _size(arr.size()) {}

/**
* @brief 初始化列表构造,设置默认值
*
* @tparam Tp 变量的存储数据类型,必须是基础类型
* @param[in] il 初始化列表
*/
template <typename Tp, typename Enable = std::enable_if_t<std::is_fundamental_v<Tp> && !std::is_same_v<bool, Tp>>>
VariableType(std::initializer_list<Tp> il) : VariableType(std::vector<Tp>(il)) {}

/**
* @brief 将变量类型节点转化为指定类型的数据
*
Expand Down Expand Up @@ -178,6 +187,15 @@ class RMVL_EXPORTS_W Variable final
RMVL_W_SUBST("V_List")
Variable(const std::vector<Tp> &arr) : _value(arr), _data_type(DataType(typeid(Tp))), _size(static_cast<UA_UInt32>(arr.size())) {}

/**
* @brief 初始化列表构造,设置默认值
*
* @tparam Tp 变量的存储数据类型,必须是基础类型
* @param[in] il 初始化列表
*/
template <typename Tp, typename Enable = std::enable_if_t<std::is_fundamental_v<Tp> && !std::is_same_v<bool, Tp>>>
Variable(std::initializer_list<Tp> il) : Variable(std::vector<Tp>(il)) {}

/**
* @brief 从变量类型创建新的变量节点
*
Expand All @@ -197,7 +215,7 @@ class RMVL_EXPORTS_W Variable final

/**
* @brief 比较两个变量是否不等
* @see `rm::Variable::operator==`
* @see rm::Variable::operator==()
*
* @param[in] val 另一个变量
* @return 是否不等
Expand Down Expand Up @@ -269,6 +287,8 @@ class RMVL_EXPORTS_W Variable final
* - 属于非服务器层面的 ID 号,可用于完成路径搜索
* @brief
* - 同一个命名空间 `ns` 下该名称不能重复
* @brief
* - 仅用于标识服务器上的变量节点,不参与变量的比较
*/
RMVL_W_RW std::string browse_name{};

Expand All @@ -278,6 +298,8 @@ class RMVL_EXPORTS_W Variable final
* - 在服务器上对外展示的名字 - `en-US`
* @brief
* - 同一个命名空间 `ns` 下该名称可以相同
* @brief
* - 仅用于标识服务器上的变量节点,不参与变量的比较
*/
RMVL_W_RW std::string display_name{};
//! 变量的描述
Expand All @@ -302,8 +324,8 @@ class RMVL_EXPORTS_W Variable final
* @param[in] val 变量类型的名称
* @param[in] ... 构造列表
*/
#define uaCreateVariableType(val, ...) \
rm::VariableType val{__VA_ARGS__}; \
#define uaCreateVariableType(val, ...) \
rm::VariableType val = __VA_ARGS__; \
val.browse_name = val.display_name = val.description = #val

/**
Expand All @@ -312,8 +334,8 @@ class RMVL_EXPORTS_W Variable final
* @param[in] val 变量的名称
* @param[in] ... 构造列表
*/
#define uaCreateVariable(val, ...) \
rm::Variable val{__VA_ARGS__}; \
#define uaCreateVariable(val, ...) \
rm::Variable val = __VA_ARGS__; \
val.browse_name = val.display_name = val.description = #val

//! 变量列表别名
Expand Down
105 changes: 105 additions & 0 deletions modules/opcua/test/test_opcua_addrspace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* @file test_opcua_addrspace.cpp
* @author zhaoxi ([email protected])
* @brief OPC UA 地址空间模型单元测试
* @version 1.0
* @date 2025-02-17
*
* @copyright Copyright 2025 (c), zhaoxi
*
*/

#include <gtest/gtest.h>

#include "rmvl/opcua/object.hpp"

namespace rm_test
{

TEST(OPC_UA_AddressSpace, Variable)
{
// 单值构造
rm::Variable val1 = 42;
EXPECT_EQ(val1.size(), 1);
EXPECT_EQ(val1.getDataType(), rm::tpInt32);

rm::Variable val2 = 3.1415;
EXPECT_EQ(val2.size(), 1);
EXPECT_EQ(val2.getDataType(), rm::tpDouble);

rm::Variable val3 = false;
EXPECT_EQ(val3.size(), 1);
EXPECT_EQ(val3.getDataType(), rm::tpBoolean);

rm::Variable val4 = "test";
EXPECT_EQ(val4.size(), 1);
EXPECT_EQ(val4.getDataType(), rm::tpString);

rm::Variable val5 = std::string("test");
EXPECT_EQ(val5.size(), 1);
EXPECT_EQ(val5.getDataType(), rm::tpString);

// 列表构造
rm::Variable arr1 = {1, 2, 3};
EXPECT_EQ(arr1.size(), 3);
EXPECT_EQ(arr1.getDataType(), rm::tpInt32);

rm::Variable arr2 = {3.142, 2.718, 1.414};
EXPECT_EQ(arr2.size(), 3);
EXPECT_EQ(arr2.getDataType(), rm::tpDouble);

rm::Variable arr3 = std::vector{1, 2, 3};
EXPECT_EQ(arr3.size(), 3);
EXPECT_EQ(arr3.getDataType(), rm::tpInt32);

// 单值比较
EXPECT_EQ(val1, 42);
EXPECT_EQ(val2, 3.1415);
EXPECT_EQ(val3, false);
EXPECT_EQ(val4, "test");
EXPECT_EQ(val5, val4);

// 列表比较
EXPECT_EQ(arr1, arr3);
std::vector<double> arr{3.142, 2.718, 1.414};
EXPECT_EQ(arr2, arr);
}

TEST(OPC_UA_AddressSpace, VariableType)
{
// 单值构造
rm::VariableType vt1 = 42;
EXPECT_EQ(vt1.size(), 1);
EXPECT_EQ(vt1.getDataType(), rm::tpInt32);

rm::VariableType vt2 = 3.1415;
EXPECT_EQ(vt2.size(), 1);
EXPECT_EQ(vt2.getDataType(), rm::tpDouble);

rm::VariableType vt3 = false;
EXPECT_EQ(vt3.size(), 1);
EXPECT_EQ(vt3.getDataType(), rm::tpBoolean);

rm::VariableType vt4 = "test";
EXPECT_EQ(vt4.size(), 1);
EXPECT_EQ(vt4.getDataType(), rm::tpString);

rm::VariableType vt5 = std::string("test");
EXPECT_EQ(vt5.size(), 1);
EXPECT_EQ(vt5.getDataType(), rm::tpString);

// 列表构造
rm::VariableType at1 = {1, 2, 3};
EXPECT_EQ(at1.size(), 3);
EXPECT_EQ(at1.getDataType(), rm::tpInt32);

rm::VariableType at2 = {3.142, 2.718, 1.414};
EXPECT_EQ(at2.size(), 3);
EXPECT_EQ(at2.getDataType(), rm::tpDouble);

rm::VariableType at3 = std::vector{1, 2, 3};
EXPECT_EQ(at3.size(), 3);
EXPECT_EQ(at3.getDataType(), rm::tpInt32);
}

} // namespace rm_test
25 changes: 3 additions & 22 deletions modules/opcua/test/test_opcua_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,11 @@
namespace rm_test
{

// 变量(类型)配置
TEST(OPC_UA_Server, variable_config)
{
// 变量类型节点、字符串
rm::VariableType variable_type = "string_test";
EXPECT_EQ(variable_type.size(), 1);
EXPECT_EQ(variable_type.getDataType(), UA_TYPES_STRING);
// 添加变量节点、双精度浮点数
rm::Variable variable = 3.1415;
EXPECT_EQ(variable.size(), 1);
EXPECT_EQ(variable.getDataType(), UA_TYPES_DOUBLE);
// 添加变量节点、数组
rm::Variable variable_array = std::vector<int>{1, 2, 3};
EXPECT_EQ(variable_array.size(), 3);
EXPECT_EQ(variable_array.getDataType(), UA_TYPES_INT32);
}

// 服务器添加变量节点
TEST(OPC_UA_Server, add_variable_node)
{
rm::Server srv(4810, "TestServer");
rm::Variable variable{3.1415};
rm::Variable variable = 3.1415;
variable.browse_name = "test_double";
variable.description = "this is test double";
variable.display_name = "测试双精度浮点数";
Expand Down Expand Up @@ -68,9 +51,7 @@ TEST(OPC_UA_Server, add_data_source_variable_node)
v.browse_name = v.display_name = "test_int";
v.description = "this is test int";
v.on_read = [&](const rm::NodeId &) -> rm::Variable { return data_source; };
v.on_write = [&](const rm::NodeId &, const rm::Variable &val) {
data_source = val.cast<int>();
};
v.on_write = [&](const rm::NodeId &, const rm::Variable &val) { data_source = val.cast<int>(); };
auto node = srv.addDataSourceVariableNode(v);
EXPECT_FALSE(node.empty());
srv.spinOnce();
Expand All @@ -80,7 +61,7 @@ TEST(OPC_UA_Server, add_data_source_variable_node)
TEST(OPC_UA_Server, add_variable_type_node)
{
rm::Server srv(4830);
rm::VariableType variable_type{"string_test"};
rm::VariableType variable_type = "string_test";
variable_type.browse_name = "test_string";
variable_type.description = "this is test string";
variable_type.display_name = "测试字符串";
Expand Down

0 comments on commit 60e7551

Please sign in to comment.