Enumeration variables not showing the textual value

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
stenil
Sr. Member
Sr. Member
Posts: 12
Joined: 14 Sep 2016, 14:00

Enumeration variables not showing the textual value

Post by stenil »

Hi,
I've implemented some Enumeration data types, using your example code in server_cpp_demo/nmbuildingautomation.cpp as a starting point.
But while in your demo server I can see both the numeric and textual value in a variable using the enumeration type ControlState, for my own variables I only see the numerical value (in UA Expert).
My variables do point to the correct enumeration type (the types are using string node ids, that is one difference compareed to the demo).
When setting the values, there is only the setInt32 option right, there is no "setEnumValue(number, string)" ?
Any ideas of what I have missed?

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Enumeration variables not showing the textual value

Post by Support Team »

Hello stenil,

1) Browse to Types->DataTypes->BaseDataType->Enumeration
Check if your Enum Type is visible and check if the property [Edit:] EnumStrings / EnumValues contains the correct names

2) Check the DataType attribute of the variable instance
Should not be Int32 but point to your Enum type.


Create an enum type:

Code: Select all

    // MyEnumeration Enumeration
    UaEnumDefinition myEnumType;
    myEnumType.setName("MyOnOffEnum");
    myEnumType.setDataTypeId(UaNodeId("MyOnOffEnum", getNameSpaceIndex()));
    UaEnumValue enumValue;
    enumValue.setName("On");
    enumValue.setValue(0);
    myEnumType.addChild(enumValue);
    enumValue.setName("Off");
    enumValue.setValue(1);
    myEnumType.addChild(enumValue);
    addEnumeratedType(myEnumType);

initialize a variable using that data type

Code: Select all

    UaVariant defaultValue;
    defaultValue.setInt32(0);
    OpcUa::BaseDataVariableType* pVariable =
        new OpcUa::BaseDataVariableType(
            UaNodeId("MyEnumVar", getNameSpaceIndex()),
            "MyEnumVar",
            getNameSpaceIndex(),
            defaultValue,
            OpcUa_AccessLevels_CurrentReadOrWrite,
            this,
            NULL);
    pVariable->setDataType(UaNodeId("MyOnOffEnum", getNameSpaceIndex()));
    pVariable->setValueRank(OpcUa_ValueRanks_Scalar);
    addNodeAndReference(OpcUaId_ObjectsFolder, pVariable, OpcUaId_Organizes);
Last edited by Support Team on 13 Dec 2016, 07:10, edited 4 times in total.
Best regards
Unified Automation Support Team

stenil
Sr. Member
Sr. Member
Posts: 12
Joined: 14 Sep 2016, 14:00

Re: Enumeration variables not showing the textual value

Post by stenil »

Hi Support team,
thanks for your quick response.
However I can not still figure out what the problem is.
See attached screen shots showing the variable and the enum type.
(Edit: No attachments added it seems due to "Sorry, the board attachment quota has been reached.").

I tried also to use a numeric id for the enum type but made no difference.
I added a call "setValueRank(OpcUa_ValueRanks_Scalar);" as you did below (not part of the demo code, but made no difference.

In your answer you refer to the property EnumValues.
But, both in my server and the demo server, the property is called EnumStrings.
I see no way in the SDK classes that let me decide to "use" EnumValues instead of EnumStrings, and by this text I'd say using EnumStrings is preferred (our enums are "zero based and has no gaps" ):
"” In OPC UA the enumerated data types are defined as subtypes of Enumeration. The data has an EnumStrings Property that contains the possible string values. The value is transferred as integer on the wire where the integer defines the index into the EnumStrings array. The index is zero based and has no gaps. Another option is to provide the possible string values in the Property EnumValues. This option is used if individual integer values are assigned to the string. The used option depends on the way the string enumeration is defin ed in the Controller program. If integer values are assigned to the string values the Property EnumValues is used to represent the enumeration values. If the integer value is zero based and has no gaps the EnumStrings Property should be used since the processing on the client side is more efficient.”"

To read out the textual value of an enum variable, is that possible using the UaSessiion.read()/UaDataValues (if so, do you have example code)? Is that what UA Expert does or does it lookup the string value from the type?
I'm interested in trying to read out the value in my own test client.

BTW, I noted that in the Data Access View, the Datatype field displays "Int32" (both for my variable and the demo server variable), could perhaps be considered a UA Expert bug?

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Enumeration variables not showing the textual value

Post by Support Team »

Hello stenil,

if the enum is zero based without gaps the SDK sets the EnumStrings property. If the enum is not zero based or contains gaps the SDK fills the EnumValues property. You don't really any control over that if you use the Toolkit classes - but that is fine and conform to the spec anyway.
To display the textual value of an enum variable you need to read the EnumStrings or EnumValues property once from the type. If you use the Unified Automation C++ Client SDK the UaSession class does this for you automatically. On connect the SDK is reading the TypeDictionary and all Enum definitions from the server and keeps them in a TypeCache. You can access this TypeCache from your application.
See here:
http://documentation.unified-automation ... 4d1f84c128

Concerning UaExpert:
The DataType field in the DataAccessView always shows the DataType of the value that is currently displayed. So when a DataChangeNotification is processed for an EnumeratedType the DAView just receives an Int32. This is the intended behaviour.

So we still don't know why this doesn't work for you. Did you try to use exactly the code I posted above? Does that work for you?
Do you see the correct DataType in the Attribute Widget if you click on the variable in the BrowseTree?
Best regards
Unified Automation Support Team

stenil
Sr. Member
Sr. Member
Posts: 12
Joined: 14 Sep 2016, 14:00

Re: Enumeration variables not showing the textual value

Post by stenil »

Hi Support Team,
thanks for the clarifications.
When I use your example code in my application, it does not work, only the integer value is displayed in MyEnumVar.
See code below that I used.
So, the only difference is that we have our node manager class that inherits from NodeManagerBase ,and the name space index for both the variable and the type is 2 (as we have our own node manager with a separate URI).

Hmm...?

Code:
"void EnumTypes::createEnumTypesTest()
{
UaStatus add_status;
// MyEnumeration Enumeration
UaEnumDefinition myEnumType;
myEnumType.setName("MyOnOffEnum");
myEnumType.setDataTypeId(UaNodeId("MyOnOffEnum", 2));
UaEnumValue enumValue;
enumValue.setName("On");
enumValue.setValue(0);
myEnumType.addChild(enumValue);
enumValue.setName("Off");
enumValue.setValue(1);
myEnumType.addChild(enumValue);

add_status = node_manager.addEnumeratedType(myEnumType);
if (!add_status.isGood()) {
XXS_EXIT("Could not add enumerated test type to OPC UA type dictionary, errorCode: " +
std::string(add_status.toString().toUtf8()));
}
//addEnumeratedType(myEnumType);


UaVariant defaultValue;
defaultValue.setInt32(0);
OpcUa::BaseDataVariableType* pVariable =
new OpcUa::BaseDataVariableType(
UaNodeId("MyEnumVar", 2),
"MyEnumVar",
2,
defaultValue,
OpcUa_AccessLevels_CurrentReadOrWrite,
&node_manager,
NULL);
pVariable->setDataType(UaNodeId("MyOnOffEnum", 2));
pVariable->setValueRank(OpcUa_ValueRanks_Scalar);
node_manager.addNodeAndReference(OpcUaId_ObjectsFolder, pVariable, OpcUaId_Organizes);
//addNodeAndReference(OpcUaId_ObjectsFolder, pVariable, OpcUaId_Organizes);
}"

stenil
Sr. Member
Sr. Member
Posts: 12
Joined: 14 Sep 2016, 14:00

Re: Enumeration variables not showing the textual value

Post by stenil »

Hi,
I also created a variable in my name space 2 using the pre-defined enumeration type IdType in name space 0 (I thought maybe the reason was that UA Expert code did not read the type dictionary from my node manager, but I guess "UaSession::loadDataTypeDictionaries" loads all dictionaries), but the result is the same, just the integer value is shown.

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Enumeration variables not showing the textual value

Post by Support Team »

When I try your code it works fine. So you obviously do something different than I do.

2 Things you should check:

1) Never use coded namespace indexes.
Always use getNamespaceIndex() to get it from the NodeManager during runtime. The namespaceindex depends on the order how the nodemanagers are started in the server.

2) The order of creating types and instances
I see you put that code into methods outside the nodemanager. So the question is when do you call this code in which order?
First create the enum type then create the variable.
Typically you call this in the afterStartUp() method of the NodeManager. See sample in DemoServer.
Best regards
Unified Automation Support Team

stenil
Sr. Member
Sr. Member
Posts: 12
Joined: 14 Sep 2016, 14:00

Re: Enumeration variables not showing the textual value

Post by stenil »

Hi,

1. we do use getNameSpaceIndex in the real code.
2. Yes, the createEnumTypes method is called from the node manager's afterStartup method. As the test function included a creation of a enum type followed by creation of the variable using the type (and it did not work), it seems clear that reason is something else. Also I double-checked that for our own "real" variables they get created after the types.

I tried to enable some tracing ( <UaAppTraceLevel>Data</UaAppTraceLevel>, <UaStackTraceLevel>DEBUG</UaStackTraceLevel> ) in the config file but could not see anything evident.
I guess this option is not something that shall have an effect?
" Static configuration information UA Stack:
15:52:38.504Z|3|DAA3780* Force32BitEnums:!0"

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Enumeration variables not showing the textual value

Post by Support Team »

No this should not have any effect on the issue.
For some compilers this flag is required to make sure the enum size is 32bit.
Best regards
Unified Automation Support Team

s_schmidt
Full Member
Full Member
Posts: 7
Joined: 22 Mar 2019, 09:34

Re: Enumeration variables not showing the textual value

Post by s_schmidt »

Hello,
I have a similar problem just that I am not defining the Enumeration in the server SDK through code, but loading a Nodeset with defined Enumerations from an xml directly to the Server c++ SDK.
I tried to load an xml nodeset that contains an Instance with a variable, that has a predefined EnumerationStrinValue (for example "off" = 0). In the UaExpert Client I only see the IntegerValue not the StringValue. How am I able to change that in code, if I did not define the Enumeration in the code but only loaded it in from a xml nodeset. If there is a possibility could you provide some sample code for doing this?

Thank you!
Best Regards

devOPCgg
Jr. Member
Jr. Member
Posts: 1
Joined: 23 Feb 2021, 19:48

Re: Enumeration variables not showing the textual value

Post by devOPCgg »

Hello,
I have exactly the same issue - Enum Type defined in NodeSet xml file. Variable with enum type points to correct NodeId but the EnumString is not shown when the client connects to the server and reads the variable. Also, in my case, the type definitions do not appear in the Address Space under BaseDataType/Enumeration. For loading the xml file I followed your guide on
https://documentation.unified-automation.com/uasdkcpp/1.7.1/html/L2DemoServer.html#L3DemoServer_3
Loading Address Space from UANodeSet XML File.

BR

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Enumeration variables not showing the textual value

Post by Support Team »

Hello,

There is no known problem with importing enumeration DataTypes from a UANodeSet XML file.

We recently investigated such a problem with not existing enumeration DataTypes imported from a UANodeSet XML file and this was caused by another problem during import. In this case a depending node for an imported object type was missing and the import was not completed.

Please make sure you import the depending namespaces first and that the SDK supports the necessary OPC UA namespace nodes. Nodes introduced in newer versions of the specification may require a SDK update.

We will also enhance the node factory in C++ SDK 1.7.4 to cover more use cases of creation of missing nodes during XML import. Depending base types from generated code and OPC UA namespaces are already created in previous versions with the node factory. But other dependencies like GeneratesEvents or HasInterface were not created before.
Best regards
Unified Automation Support Team

Post Reply