当前位置:网站首页>Learn open62541 -- [67] add custom enum and display name
Learn open62541 -- [67] add custom enum and display name
2022-07-07 18:50:00 【Love is patience】
Enum Variables of type are a little special , stay base data type in , You can see enum Cannot instantiate directly ,
Its properties are as follows , It's an abstract type ,
For customization enum, Need to go through 3 Step by step ,
- Define the corresponding DataType
- Then define the corresponding variable type
- Finally, use this variable type to create enum Variable
This article describes how to add customization Enum, And create corresponding variables
One Code
The code is as follows ,
#include "open62541.h"
static bool running = true;
static void stopHandler(int sig) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
running = false;
}
UA_UInt16 LocalServerNSIndex = 1;
typedef enum {
AA = 0,
BB = 1,
CC = 2,
DD = 3,
__MY_ENUM_FORCE32BIT = 0x7fffffff
} MyEnum;
// Definition DataType
static UA_DataType MyEnumDataType =
{
UA_TYPENAME("MyEnum") /* .typeName */
{
LocalServerNSIndex, UA_NODEIDTYPE_NUMERIC, {
0}}, /* .typeId */
{
LocalServerNSIndex, UA_NODEIDTYPE_NUMERIC, {
0}}, /* .binaryEncodingId */
sizeof(MyEnum), /* .memSize */
UA_DATATYPEKIND_ENUM, /* .typeKind */
true, /* .pointerFree */
1, /* .overlayable */
0, /* .membersSize */
NULL /* .members */
};
// hold enum Of datatype Add to namespace in
UA_StatusCode addMyEnumDataType(UA_Server* server)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
attr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Data Type");
ret = UA_Server_addDataTypeNode(
server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_ENUMERATION),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My.Enum"), attr, NULL, &MyEnumDataType.typeId);
return ret;
}
// hold enum The corresponding variable type is added to namespace in
UA_StatusCode addMyEnumVariableType(UA_Server *server, UA_NodeId& myEnumVarTypeId)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_VariableTypeAttributes dattr = UA_VariableTypeAttributes_default;
dattr.description = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var type");
dattr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var type");
dattr.dataType = MyEnumDataType.typeId;
dattr.valueRank = UA_VALUERANK_SCALAR;
MyEnum p = AA;
UA_Variant_setScalar(&dattr.value, &p, &MyEnumDataType);
ret = UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My Enum Var type"),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
dattr, NULL, &myEnumVarTypeId);
return ret;
}
// establish enum Variable , To add to namespace in
UA_StatusCode addMyEnumVariable(UA_Server *server, UA_NodeId myEnumVarTypeId)
{
MyEnum p = CC;
UA_VariableAttributes vattr = UA_VariableAttributes_default;
vattr.description = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var");
vattr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var");
vattr.dataType = MyEnumDataType.typeId;
vattr.valueRank = UA_VALUERANK_SCALAR;
UA_Variant_setScalar(&vattr.value, &p, &);
UA_StatusCode ret = UA_STATUSCODE_GOOD;
ret = UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My Enum Var"),
myEnumVarTypeId, vattr, NULL, NULL);
return ret;
}
int main(void)
{
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_Server *server = UA_Server_new();
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefault(config);
UA_StatusCode ret = addMyEnumDataType(server);
if (UA_StatusCode_isGood(ret))
{
UA_NodeId myEnumVarTypeId;
ret = addMyEnumVariableType(server, myEnumVarTypeId);
if (UA_StatusCode_isGood(ret))
{
ret = addMyEnumVariable(server, myEnumVarTypeId);
}
}
if (UA_StatusCode_isBad(ret))
{
printf("Error\n");
UA_Server_delete(server);
return 0;
}
UA_Server_run(server, &running);
UA_Server_delete(server);
return 0;
}
Run after successful compilation , You can see that the variable is added successfully ,
Its value is 2, because CC The corresponding value is 2
Add custom DataType Also in the namespace in ,
Two add to enum name
From the code above, we can see that although enum Variable added , Seems to be with a int There is no difference between types of data , It's better to reflect its name , Here is how to give enum Type add the corresponding name ,
Here we define a function addEnumString, For giving enum Of DataType Add name , as follows ,
UA_StatusCode addEnumString(UA_Server *server)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_VariableAttributes attr = UA_VariableAttributes_default;
attr.minimumSamplingInterval = 0.000000;
attr.userAccessLevel = 1;
attr.accessLevel = 1;
attr.valueRank = 1;
attr.arrayDimensionsSize = 1;
UA_UInt32 arrayDimensions[1];
arrayDimensions[0] = 0;
attr.arrayDimensions = &arrayDimensions[0];
attr.dataType = UA_NODEID_NUMERIC(0, 21LU);
UA_LocalizedText my_enum_variant_DataContents[4];
my_enum_variant_DataContents[0] = UA_LOCALIZEDTEXT((char*)"", (char*)"AA");
my_enum_variant_DataContents[1] = UA_LOCALIZEDTEXT((char*)"", (char*)"BB");
my_enum_variant_DataContents[2] = UA_LOCALIZEDTEXT((char*)"", (char*)"CC");
my_enum_variant_DataContents[3] = UA_LOCALIZEDTEXT((char*)"", (char*)"DD");
UA_Variant_setArray(&attr.value, &my_enum_variant_DataContents, (UA_Int32) 4, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
attr.displayName = UA_LOCALIZEDTEXT((char*)"", (char*)"EnumStrings");
UA_NodeId enumStringNodeId;
ret = UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE,
UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
MyEnumDataType.typeId,
UA_NODEID_NUMERIC(0, 46LU),
UA_QUALIFIEDNAME(0, (char*)"EnumStrings"),
UA_NODEID_NUMERIC(0, 68LU),
(const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL, &enumStringNodeId);
if (UA_StatusCode_isGood(ret))
{
ret = UA_Server_addNode_finish(server, enumStringNodeId);
}
return ret;
}
Yes 4 Elements are added 4 Names , Be careful enum The value of must be from 0 Start , The following is the sequence plus 1, Otherwise, the name cannot be displayed . In function addMyEnumDataType Call inside addEnumString, as follows ,
UA_StatusCode addMyEnumDataType(UA_Server* server)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
attr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Data Type");
ret = UA_Server_addDataTypeNode(
server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_ENUMERATION),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My.Enum"), attr, NULL, &MyEnumDataType.typeId);
if (UA_StatusCode_isGood(ret))
{
ret = addEnumString(server);
}
return ret;
}
Recompile run , You can see that the variable value is followed by its corresponding name ,
stay DataType in , You can also see EnumStrings,
see EnumStrings Value , as follows , Is an array ,
In this way, we have achieved our expectations
The complete code is as follows ,
#include "open62541.h"
static bool running = true;
static void stopHandler(int sig) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
running = false;
}
const UA_UInt16 LocalServerNSIndex = 1;
typedef enum {
AA = 0,
BB = 1,
CC = 2,
DD = 3,
__MY_ENUM_FORCE32BIT = 0x7fffffff
} MyEnum;
static UA_DataType MyEnumDataType =
{
UA_TYPENAME("MyEnum") /* .typeName */
{
LocalServerNSIndex, UA_NODEIDTYPE_NUMERIC, {
0}}, /* .typeId */
{
LocalServerNSIndex, UA_NODEIDTYPE_NUMERIC, {
0}}, /* .binaryEncodingId */
sizeof(MyEnum), /* .memSize */
UA_DATATYPEKIND_ENUM, /* .typeKind */
true, /* .pointerFree */
1, /* .overlayable */
0, /* .membersSize */
NULL /* .members */
};
UA_StatusCode addEnumString(UA_Server *server)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_VariableAttributes attr = UA_VariableAttributes_default;
attr.minimumSamplingInterval = 0.000000;
attr.userAccessLevel = 1;
attr.accessLevel = 1;
attr.valueRank = 1;
attr.arrayDimensionsSize = 1;
UA_UInt32 arrayDimensions[1];
arrayDimensions[0] = 0;
attr.arrayDimensions = &arrayDimensions[0];
attr.dataType = UA_NODEID_NUMERIC(0, 21LU);
UA_LocalizedText my_enum_variant_DataContents[4];
my_enum_variant_DataContents[0] = UA_LOCALIZEDTEXT((char*)"", (char*)"AA");
my_enum_variant_DataContents[1] = UA_LOCALIZEDTEXT((char*)"", (char*)"BB");
my_enum_variant_DataContents[2] = UA_LOCALIZEDTEXT((char*)"", (char*)"CC");
my_enum_variant_DataContents[3] = UA_LOCALIZEDTEXT((char*)"", (char*)"DD");
UA_Variant_setArray(&attr.value, &my_enum_variant_DataContents, (UA_Int32) 4, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
attr.displayName = UA_LOCALIZEDTEXT((char*)"", (char*)"EnumStrings");
UA_NodeId enumStringNodeId;
ret = UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE,
UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
MyEnumDataType.typeId,
UA_NODEID_NUMERIC(0, 46LU),
UA_QUALIFIEDNAME(0, (char*)"EnumStrings"),
UA_NODEID_NUMERIC(0, 68LU),
(const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL, &enumStringNodeId);
if (UA_StatusCode_isGood(ret))
{
ret = UA_Server_addNode_finish(server, enumStringNodeId);
}
return ret;
}
UA_StatusCode addMyEnumDataType(UA_Server* server)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
attr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Data Type");
ret = UA_Server_addDataTypeNode(
server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_ENUMERATION),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My.Enum"), attr, NULL, &MyEnumDataType.typeId);
if (UA_StatusCode_isGood(ret))
{
ret = addEnumString(server);
}
return ret;
}
UA_StatusCode addMyEnumVariableType(UA_Server *server, UA_NodeId& myEnumVarTypeId)
{
UA_StatusCode ret = UA_STATUSCODE_GOOD;
UA_VariableTypeAttributes dattr = UA_VariableTypeAttributes_default;
dattr.description = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var type");
dattr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var type");
dattr.dataType = MyEnumDataType.typeId;
dattr.valueRank = UA_VALUERANK_SCALAR;
MyEnum p = AA;
UA_Variant_setScalar(&dattr.value, &p, &MyEnumDataType);
ret = UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My Enum Var type"),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
dattr, NULL, &myEnumVarTypeId);
return ret;
}
UA_StatusCode addMyEnumVariable(UA_Server *server, UA_NodeId myEnumVarTypeId)
{
MyEnum p = CC;
UA_VariableAttributes vattr = UA_VariableAttributes_default;
vattr.description = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var");
vattr.displayName = UA_LOCALIZEDTEXT((char*)"en-US", (char*)"My Enum Var");
vattr.dataType = MyEnumDataType.typeId;
vattr.valueRank = UA_VALUERANK_SCALAR;
UA_Variant_setScalar(&vattr.value, &p, &UA_TYPES[UA_TYPES_INT32]);
UA_StatusCode ret = UA_STATUSCODE_GOOD;
ret = UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(LocalServerNSIndex, 0),
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(LocalServerNSIndex, (char*)"My Enum Var"),
myEnumVarTypeId, vattr, NULL, NULL);
return ret;
}
int main(void)
{
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_Server *server = UA_Server_new();
UA_ServerConfig *config = UA_Server_getConfig(server);
UA_ServerConfig_setDefault(config);
UA_StatusCode ret = addMyEnumDataType(server);
if (UA_StatusCode_isGood(ret))
{
UA_NodeId myEnumVarTypeId;
ret = addMyEnumVariableType(server, myEnumVarTypeId);
if (UA_StatusCode_isGood(ret))
{
ret = addMyEnumVariable(server, myEnumVarTypeId);
}
}
if (UA_StatusCode_isBad(ret))
{
printf("Error\n");
UA_Server_delete(server);
return 0;
}
UA_Server_run(server, &running);
UA_Server_delete(server);
return 0;
}
3、 ... and Summary
This article describes how to add customization enum, And create corresponding variables , Readers can draw a picture of gourd , Add what you need enum. One thing to note , Finally, create enum variable , The type used is int32, Just specify in the variable attribute data type Of id That's it .
边栏推荐
- “解密”华为机器视觉军团:华为向上,产业向前
- Is it safe to open an online futures account now? How many regular futures companies are there in China?
- Industry case | digital operation base helps the transformation of life insurance industry
- DataSimba推出微信小程序,DataNuza接受全场景考验? | StartDT Hackathon
- AntiSamy:防 XSS 攻击的一种解决方案使用教程
- Afghan interim government security forces launched military operations against a hideout of the extremist organization "Islamic state"
- More than 10000 units were offline within ten days of listing, and the strength of Auchan Z6 products was highly praised
- 嵌入式C语言程序调试和宏使用的技巧
- Datasimba launched wechat applet, and datanuza accepted the test of the whole scene| StartDT Hackathon
- socket编程之常用api介绍与socket、select、poll、epoll高并发服务器模型代码实现
猜你喜欢

小试牛刀之NunJucks模板引擎

Wireshark analyzes packet capture data * cap

清华、剑桥、UIC联合推出首个中文事实核查数据集:基于证据、涵盖医疗社会等多个领域

Kubernetes DevOps CD工具对比选型

AI 击败了人类,设计了更好的经济机制

『HarmonyOS』DevEco的下载安装与开发环境搭建

More than 10000 units were offline within ten days of listing, and the strength of Auchan Z6 products was highly praised

Disk storage chain B-tree and b+ tree

Tips for short-term operation of spot silver that cannot be ignored

单臂路由和三层交换的简单配置
随机推荐
【剑指 Offer】59 - I. 滑动窗口的最大值
Performance test process and plan
Unlike the relatively short-lived industrial chain of consumer Internet, the industrial chain of industrial Internet is quite long
Classification of regression tests
云景网络科技面试题【杭州多测师】【杭州多测师_王sir】
行业案例|数字化经营底座助力寿险行业转型
[trusted computing] Lesson 12: TPM authorization and conversation
你真的理解粘包与半包吗?3分钟搞懂它
Reinforcement learning - learning notes 8 | Q-learning
C语言中匿名的最高境界
2022年推荐免费在线接收短信平台(国内、国外)
2022-07-04 matlab读取视频帧并保存
磁盘存储链式的B树与B+树
来了!GaussDB(for Cassandra)新特性亮相
String type, constant type and container type of go language
如何选择合适的自动化测试工具?
AI defeated mankind and designed a better economic mechanism
debian10编译安装mysql
[paddleseg source code reading] add boundary IOU calculation in paddleseg validation (1) -- val.py file details tips
[software test] from the direct employment of the boss of the enterprise version, looking at the resume, there is a reason why you are not covered