当前位置:网站首页>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 ,
 Insert picture description here
Its properties are as follows , It's an abstract type ,
 Insert picture description here

For customization enum, Need to go through 3 Step by step ,

  1. Define the corresponding DataType
  2. Then define the corresponding variable type
  3. 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 ,
 Insert picture description here
Its value is 2, because CC The corresponding value is 2
 Insert picture description here
Add custom DataType Also in the namespace in ,
 Insert picture description here


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 ,
 Insert picture description here
stay DataType in , You can also see EnumStrings,
 Insert picture description here
see EnumStrings Value , as follows , Is an array ,
 Insert picture description here
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 .

原网站

版权声明
本文为[Love is patience]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071648585094.html