I use translateBrowsePathsToNodeIds to get to the NodeId via the browse path.
If I have an array in the path I get the message BadNoMatch.
How do I have to supply UaBrowsePaths so that this also works with arrays?
One of the path elements has e.g. the name 0,1,2 ... etc.
For Example:
The string NodeId is this like
"DB_TPM_Counter"."TPM_Counter"."Daten"[0]."TPM_Counter"
I know the NodeId for "TPM_Counter"
My UaBrowsepath consits of
"Daten"
"0"
"TPM_Counter"
The browse names where checked by UAExpert...
Annother example:
"DB_TPM_Zaehler_ZLT_Transfer"."TPM_Zaehler"."Daten"[0]
I know the NodeId for "TPM_Zaehler"
My UaBrowsepath consits of
"Daten"
"0"
Handling of translateBrowsePathsToNodeIds on arrays
Moderator: uasdkcpp
-
- Jr. Member
- Posts: 4
- Joined: 12 Oct 2022, 14:40
- Support Team
- Hero Member
- Posts: 3069
- Joined: 18 Mar 2011, 15:09
Re: Handling of translateBrowsePathsToNodeIds on arrays
Hello Arthur,
I did a quick test with the "model" you provided and it works fine.
Testcode in server - NodeManager derived from NodeManagerBase
I did a quick test with the "model" you provided and it works fine.
Testcode in server - NodeManager derived from NodeManagerBase
Code: Select all
UaVariant value;
UaString sName;
UaString sNodeId;
UaStatus addResult;
OpcUa::BaseDataVariableType* pVariable = NULL;
OpcUa::BaseDataVariableType* pVariable2 = NULL;
// "DB_TPM_Counter"."TPM_Counter".
value.setUInt16(123);
sName = "\"DB_TPM_Counter\".\"TPM_Counter\"";
sNodeId = sName;
pVariable = new OpcUa::BaseDataVariableType(
UaNodeId(sNodeId, getNameSpaceIndex()),
sName,
getNameSpaceIndex(),
value,
OpcUa_AccessLevels_CurrentReadOrWrite,
this,
m_pSharedNodeMutex);
addResult = addNodeAndReference(OpcUaId_ObjectsFolder, pVariable, OpcUaId_Organizes);
if (addResult.isBad())
{
pVariable->deleteAllChildren(this);
pVariable->releaseReference();
}
// "Daten"
sName = "\"Daten\"";
sNodeId = UaString("%1.%2").arg(sNodeId).arg(sName);
pVariable2 = new OpcUa::BaseDataVariableType(
UaNodeId(sNodeId, getNameSpaceIndex()),
sName,
getNameSpaceIndex(),
value,
OpcUa_AccessLevels_CurrentReadOrWrite,
this,
m_pSharedNodeMutex);
addResult = addNodeAndReference(pVariable, pVariable2, OpcUaId_HasComponent);
if (addResult.isBad())
{
pVariable2->deleteAllChildren(this);
pVariable2->releaseReference();
}
pVariable = pVariable2;
// [0]
sName = "[0]";
sNodeId = UaString("%1%2").arg(sNodeId).arg(sName);
pVariable2 = new OpcUa::BaseDataVariableType(
UaNodeId(sNodeId, getNameSpaceIndex()),
sName,
getNameSpaceIndex(),
value,
OpcUa_AccessLevels_CurrentReadOrWrite,
this,
m_pSharedNodeMutex);
pVariable2->setBrowseName(UaQualifiedName("\"0\"", getNameSpaceIndex()));
addResult = addNodeAndReference(pVariable, pVariable2, OpcUaId_HasComponent);
if (addResult.isBad())
{
pVariable2->deleteAllChildren(this);
pVariable2->releaseReference();
}
pVariable = pVariable2;
// "TPM_Counter"
sName = "\"TPM_Counter\"";
sNodeId = UaString("%1.%2").arg(sNodeId).arg(sName);
pVariable2 = new OpcUa::BaseDataVariableType(
UaNodeId(sNodeId, getNameSpaceIndex()),
sName,
getNameSpaceIndex(),
value,
OpcUa_AccessLevels_CurrentReadOrWrite,
this,
m_pSharedNodeMutex);
addResult = addNodeAndReference(pVariable, pVariable2, OpcUaId_HasComponent);
if (addResult.isBad())
{
pVariable2->deleteAllChildren(this);
pVariable2->releaseReference();
}
pVariable = pVariable2;
Best regards
Unified Automation Support Team
Unified Automation Support Team
- Support Team
- Hero Member
- Posts: 3069
- Joined: 18 Mar 2011, 15:09
Re: Handling of translateBrowsePathsToNodeIds on arrays
testcode in client:
Did you check if you set the correct namespaceIndexes in the BrowsePathElements? Dependent on your model the namespaceIndex in the NodeId and the namespaceIndex in the BrowseName may be different.
Code: Select all
UaStatus status;
UaDiagnosticInfos diagnosticInfos;
ServiceSettings serviceSettings;
UaBrowsePaths browsePaths;
UaBrowsePathResults browsePathResults;
UaRelativePathElements pathElements;
OpcUa_UInt32 i;
OpcUa_UInt32 itemCount;
itemCount = 1;
browsePaths.create(itemCount);
// Set path
OpcUa_UInt16 namespaceIndex = 2; // set the correct namespaceIndex here
UaString sNodeId = "\"DB_TPM_Counter\".\"TPM_Counter\"";
UaNodeId startingNode(sNodeId, namespaceIndex);
printf("** Path[0] start \"DB_TPM_Counter\".\"TPM_Counter\"\n");
startingNode.copyTo(&browsePaths[0].StartingNode);
pathElements.create(3);
// element "Daten"
pathElements[0].IncludeSubtypes = OpcUa_True;
pathElements[0].IsInverse = OpcUa_False;
pathElements[0].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[0].TargetName.Name, "\"Daten\"");
pathElements[0].TargetName.NamespaceIndex = namespaceIndex;
// element "0"
pathElements[1].IncludeSubtypes = OpcUa_True;
pathElements[1].IsInverse = OpcUa_False;
pathElements[1].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[1].TargetName.Name, "\"0\"");
pathElements[1].TargetName.NamespaceIndex = namespaceIndex;
// element "TPM_Counter"
pathElements[2].IncludeSubtypes = OpcUa_True;
pathElements[2].IsInverse = OpcUa_False;
pathElements[2].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[2].TargetName.Name, "\"TPM_Counter\"");
pathElements[2].TargetName.NamespaceIndex = namespaceIndex;
browsePaths[0].RelativePath.NoOfElements = pathElements.length();
browsePaths[0].RelativePath.Elements = pathElements.detach();
status = g_pUaSession->translateBrowsePathsToNodeIds(
serviceSettings,
browsePaths,
browsePathResults,
diagnosticInfos);
Best regards
Unified Automation Support Team
Unified Automation Support Team
-
- Jr. Member
- Posts: 4
- Joined: 12 Oct 2022, 14:40
Re: Handling of translateBrowsePathsToNodeIds on arrays
Thank you for the answer.
I have checked the namspaces again. They are ok.
There are also other nodes in the structure, which I can translate. It just always fails when an array comes into play.
I copied your code and called it as a test function. There I get also with the other nodes, which worked before, the error BadNoMatch. The difference to my code is the use of the apostrophe.
Can it be that here rather the server has a problem? It is a Siemens S7-1500.
DB_TPM_Counter.TPM_Counter.Handshake.DatenAnGateway.Daten_bereit works
DB_TPM_Counter.TPM_Counter.Daten.0.TPM_Counter don't work
I have checked the namspaces again. They are ok.
There are also other nodes in the structure, which I can translate. It just always fails when an array comes into play.
I copied your code and called it as a test function. There I get also with the other nodes, which worked before, the error BadNoMatch. The difference to my code is the use of the apostrophe.
Can it be that here rather the server has a problem? It is a Siemens S7-1500.
Code: Select all
// element "Daten"
pathElements[0].IncludeSubtypes = OpcUa_True;
pathElements[0].IsInverse = OpcUa_False;
pathElements[0].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[0].TargetName.Name, "Daten");
// OpcUa_String_AttachReadOnly(&pathElements[0].TargetName.Name, "Handshake");
pathElements[0].TargetName.NamespaceIndex = namespaceIndex;
// element "0"
pathElements[1].IncludeSubtypes = OpcUa_True;
pathElements[1].IsInverse = OpcUa_False;
pathElements[1].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[1].TargetName.Name, "0");
// OpcUa_String_AttachReadOnly(&pathElements[1].TargetName.Name, "DatenAnGateway");
pathElements[1].TargetName.NamespaceIndex = namespaceIndex;
// element "TPM_Counter"
pathElements[2].IncludeSubtypes = OpcUa_True;
pathElements[2].IsInverse = OpcUa_False;
pathElements[2].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences;
OpcUa_String_AttachReadOnly(&pathElements[2].TargetName.Name, "TPM_Counter");
// OpcUa_String_AttachReadOnly(&pathElements[2].TargetName.Name, "Daten_bereit");
pathElements[2].TargetName.NamespaceIndex = namespaceIndex;
DB_TPM_Counter.TPM_Counter.Daten.0.TPM_Counter don't work
- Support Team
- Hero Member
- Posts: 3069
- Joined: 18 Mar 2011, 15:09
Re: Handling of translateBrowsePathsToNodeIds on arrays
Hello Arthur,
the NodeId you posted contains quotation marks. The question is if the BrowseNames also contain quotation marks or not.
Dependent on that you need to set the string also with or without quotation:
In UaExpert the attribute widget puts a quotation around the string part of the BrowseName. So it will either display "Daten" or ""Daten"".
If that still does not help you need to contact the server vendor and find out if translate is supposed to work for arrays.
the NodeId you posted contains quotation marks. The question is if the BrowseNames also contain quotation marks or not.
Dependent on that you need to set the string also with or without quotation:
Code: Select all
OpcUa_String_AttachReadOnly(&pathElements[0].TargetName.Name, "\"Daten\"");
vs.
OpcUa_String_AttachReadOnly(&pathElements[0].TargetName.Name, "Daten");
If that still does not help you need to contact the server vendor and find out if translate is supposed to work for arrays.
Best regards
Unified Automation Support Team
Unified Automation Support Team