当前位置:网站首页>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 .
边栏推荐
- 不能忽略的现货白银短线操作小技巧
- Discuss | what preparations should be made before ar application is launched?
- Wireshark analyzes packet capture data * cap
- sqlite sql 异常 near “with“: syntax error
- Thread pool and singleton mode and file operation
- Using stored procedures, timers, triggers to solve data analysis problems
- 【C语言】字符串函数
- 直播预约通道开启!解锁音视频应用快速上线的秘诀
- DataSimba推出微信小程序,DataNuza接受全场景考验? | StartDT Hackathon
- Download, installation and development environment construction of "harmonyos" deveco
猜你喜欢
Three forms of multimedia technology commonly used in enterprise exhibition hall design
[C language] string function
gsap动画库
Kirk Borne的本周学习资源精选【点击标题直接下载】
Static routing configuration
The report of the state of world food security and nutrition was released: the number of hungry people in the world increased to 828million in 2021
Summary of evaluation indicators and important knowledge points of regression problems
标准ACL与扩展ACL
强化学习-学习笔记8 | Q-learning
你真的理解粘包与半包吗?3分钟搞懂它
随机推荐
[sword finger offer] 59 - I. maximum value of sliding window
Charles+drony的APP抓包
The report of the state of world food security and nutrition was released: the number of hungry people in the world increased to 828million in 2021
Sports Federation: resume offline sports events in a safe and orderly manner, and strive to do everything possible for domestic events
Will low code help enterprises' digital transformation make programmers unemployed?
Three forms of multimedia technology commonly used in enterprise exhibition hall design
通过 Play Integrity API 的 nonce 字段提高应用安全性
Kirk Borne的本周学习资源精选【点击标题直接下载】
海量数据去重的hash,bitmap与布隆过滤器Bloom Filter
线程池和单例模式以及文件操作
Will domestic software testing be biased
【软件测试】从企业版BOSS直聘,看求职简历,你没被面上是有原因的
用存储过程、定时器、触发器来解决数据分析问题
高考填志愿规则
Tips for short-term operation of spot silver that cannot be ignored
[principles and technologies of network attack and Defense] Chapter 5: denial of service attack
Standard ACL and extended ACL
Hash, bitmap and bloom filter for mass data De duplication
直播预约通道开启!解锁音视频应用快速上线的秘诀
2022年理财有哪些产品?哪些适合新手?