Getting Property of the node

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

Moderator: uasdkcpp

Post Reply
mitch722
Jr. Member
Jr. Member
Posts: 1
Joined: 17 Oct 2019, 00:39

Getting Property of the node

Post by mitch722 »

Hi,

I'm using the CPP server SDK and I've built a model with UA modeler, I can build my server and UA expert finds and discovers everything correctly.

I have 2 different node types:
- BaseDataType -> Enumeration -> MyEnumType which has an EnumString Property
- BaseDataType -> Number -> UInteger -> Byte -> MyBitFieldType which has an OptionSetValues Property

On my server I when I read the value of variables which are of MyEnumType and MyBitFieldType they appear to both just be enumerations. I can retrieve the values and the enum fields but I can't work out how to tell if it's a bit field or an enum. UA expert can tell the difference so I know it's possible.

How can I tell if a node has an EnumString Property or an OptionSetValues Property and is that the best way to tell the difference?

I can see that the UA modeler generated code has added a OpcUa::PropertyType ("OptionSetValues") reference to the type node.

Code: Select all

    pOptionSetValues = new OpcUa::PropertyType(UaNodeId(myId_ButtonEnableType_OptionSetValues, getNameSpaceIndex()), "OptionSetValues", 0, defaultValue, 1, this);
    defaultValue.clear();

    // ButtonEnableType
    pDataType = new UaGenericDataTypeEnum(
                    UaNodeId(myId_ButtonEnableType, getNameSpaceIndex()),
                    UaQualifiedName("ButtonEnableType", getNameSpaceIndex()),
                    UaLocalizedText("", "ButtonEnableType"),
                    UaLocalizedText("", ""),
                    OpcUa_False,
                    enumFields);
    ret = addNodeAndReference(UaNodeId(OpcUaId_Byte), pDataType, OpcUaId_HasSubtype);
    UA_ASSERT(ret.isGood());

    ret = addNodeAndReference(pDataType, pOptionSetValues, OpcUaId_HasProperty);
    UA_ASSERT(ret.isGood());

    ...

    pEnumString = new OpcUa::PropertyType(UaNodeId(myId_DataStateType_EnumStrings, getNameSpaceIndex()), "EnumStrings", 0, defaultValue, 1, this);
    defaultValue.clear();

    // DataStateType
    pDataType = new UaGenericDataTypeEnum(
                    UaNodeId(myId_DataStateType, getNameSpaceIndex()),
                    UaQualifiedName("DataStateType", getNameSpaceIndex()),
                    UaLocalizedText("", "DataStateType"),
                    UaLocalizedText("", ""),
                    OpcUa_False,
                    UaEnumDefinitionDataType(enumFields));
    ret = addNodeAndReference(OpcUaId_Enumeration, pDataType, OpcUaId_HasSubtype);
    UA_ASSERT(ret.isGood());

    ret = addNodeAndReference(pDataType, pEnumString, OpcUaId_HasProperty);
    UA_ASSERT(ret.isGood());
I'm currently getting the enum type information and possible values as follows.

Code: Select all

void MyNodeManager::add_type_info_to_dict(Session *pSession, UaVariable *var, const UaDataValue &dataValue)
{
    if (var->nodeClass() != OpcUa_NodeClass_Variable)
    {
        return;
    }

    OpcUa_UInt32 type_nod_id = var->dataType().identifierNumeric();
    if (type_nod_id > 1000)
    {
        UaNode *type_node = getInstanceDeclarationNode(type_nod_id, OpcUa_NodeClass_DataType);
        if (type_node)
        {
            UaDataType *data_type = (UaDataType*) type_node;
            if (data_type->dataTypeDefinitionType() == UaDataType::DataTypeDefinitionType_Enum)
            {
                UaEnumFields fields;
                data_type->enumDefinition().getFields(fields);

                printf("Enum\n");
                for (int i = 0; i < fields.length(); i++)
                {
                     fields[i].Value;
                     fields[i].Name;
                }
            }
        }
    }
}

Post Reply