Code: Select all
variableNode->setEngineeringUnits(uaUnit);
This produces automatically stringified node ids like
ns=2;s=6044.EngineeringUnits
When browsing the AnalogItemType nodes I am using
Code: Select all
UaNodeId unitNodeId(variableNodeId.toString()+".EngineeringUnits", _nsIndex);
// The magic converting the extension object to UAVariant happens inside readNodeIdAsUaVariant
UaVariant unitAsUaVariant(readNodeIdAsUaVariant(unitNodeId));
return UaEUInformation(unitAsUaVariant);
This is already rather complex but works nicely.
2. Currently I need to decode the extension objects from analog items that are generated by the https://www.arburg.com/WaterManifoldDevices/ model namespace. There also all sensor data is beeing stored as AnalogItemType, but the node ids of the extension objects are just numerical like
ns=4,i=6074
Most of the time the numerical node Id just is one higher than its corresponding AnalogItemType node, but this is not allways the case. This model does not carry the InstrumentRange but if I would need to decode the extensions objects now the code is rather complicated as below. Specifically I need to rely on the browsename to decode the items.
Code: Select all
UaEUInformation unit;
UaRange range;
UaRange instrumentRange;
UaStatus result = uaSession->browse(
serviceSettings,
nodeToBrowse,
browseContext,
continuationPoint,
variableReferenceDescriptions
);
if (result.isGood()) {
for (unsigned int i = 0; i < variableReferenceDescriptions.length(); i++) {
OpcUa_ReferenceDescription rd = variableReferenceDescriptions[i];
AnalogItemTypeExtensionHashes selector = hash(rd.BrowseName.Name.strContent);
UaVariant extensionAsUaVariant(readNodeId(rd.NodeId.NodeId));
UaExtensionObject extensionObject;
extensionAsUaVariant.toExtensionObject(extensionObject);
switch (extensionObject.encoding()) {
case UaExtensionObject::EncodeableObject:
switch (extensionObject.dataTypeId().identifierNumeric()) {
case OpcUaId_EUInformation:
switch (selector) {
case EngineeringUnits:
unit = UaEUInformation(extensionObject);
break;
}
break;
case OpcUaId_Range:
switch (selector) {
case EURange:
range = UaRange(extensionObject);
break;
case InstrumentRange:
instrumentRange = UaRange(extensionObject);
break;
}
break;
default:
break;
}
break;
default:
break;
}
}
}
Is this correct or I am doing something wrong ? The printExtensionObject from the example files is even more complicated, but still does not distinguish whether the item is a EURange, EngineeringUnits or InstrumentRange and comment says it should not be used in productive code.
ATTENTION: Code will not compile directly as it uses some pseudo code