private bool UpdateBrowseElement(
ITypeTable typeTree,
BrowseElement element,
ReadValueIdCollection nodesToRead,
DataValueCollection values,
NodeClass nodeClass,
bool onlyEssentialProperties,
int first)
{
// check for a valid range within the collection.
if (first < 0 || first >= nodesToRead.Count)
{
return false;
}
if (nodeClass == NodeClass.Unspecified)
{
// verify node class.
NodeClass actualNodeClass = (NodeClass)values[first++].GetValue<int>((int)NodeClass.Unspecified);
if (actualNodeClass != NodeClass.Variable && actualNodeClass != NodeClass.Object)
{
return false;
}
element.NodeClass = actualNodeClass;
// verify browse name.
QualifiedName browseName = values[first++].GetValue<QualifiedName>(null);
if (QualifiedName.IsNull(browseName))
{
return false;
}
element.BrowseName = element.UaBrowseName = m_mapper.GetLocalBrowseName(browseName);
// verify display name.
LocalizedText displayName = values[first++].GetValue<LocalizedText>(null);
if (LocalizedText.IsNullOrEmpty(displayName))
{
return false;
}
element.BrowseName = displayName.Text;
}
if (!onlyEssentialProperties)
{
// check if long description exists.
LocalizedText description = values[first++].GetValue<LocalizedText>(null);
if (!LocalizedText.IsNullOrEmpty(description))
{
element.UaDescription = description.Text;
}
else
{
element.UaDescription = "";
}
}
// update the masks.
SetElementMasks(element);
// nothing more to do.
if (nodeClass == NodeClass.Object)
{
return true;
}
// verify data type.
NodeId dataTypeId = values[first++].GetValue<NodeId>(null);
if (dataTypeId == null && element.NodeClass == NodeClass.Variable)
{
return false;
}
int valueRank = values[first++].GetValue<int>(ValueRanks.Scalar);
// update data type information.
if (dataTypeId != null)
{
element.BuiltInType = DataTypes.GetBuiltInType(dataTypeId, typeTree);
element.DataTypeId = m_mapper.GetLocalItemId(dataTypeId);
element.ValueRank = valueRank;
element.CanonicalDataType = (short)ComUtils.GetVarType(new TypeInfo(element.BuiltInType, element.ValueRank));
}
if (!onlyEssentialProperties)
{
// update scan rate.
element.ScanRate = (float)values[first++].GetValue<double>(MinimumSamplingIntervals.Indeterminate);
// update access rights.
byte userAccessLevel = values[first++].GetValue<byte>(0);
if ((userAccessLevel & AccessLevels.CurrentRead) != 0)
{
element.AccessRights |= OpcRcw.Da.Constants.OPC_READABLE;
}
if ((userAccessLevel & AccessLevels.CurrentWrite) != 0)
{
element.AccessRights |= OpcRcw.Da.Constants.OPC_WRITEABLE;
}
if ((userAccessLevel & AccessLevels.HistoryRead) != 0)
{
element.IsHistoricalItem = true;
}
// cache the latest value.
DataValue value = values[first++];
if (element.NodeClass == NodeClass.Variable)
{
element.LastValue = m_mapper.GetLocalDataValue(value);
}
// update HighEU and LowEU
element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
element.HighEU = Double.MaxValue;
element.LowEU = Double.MaxValue;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EURange))
{
Range euRange = values[first++].GetValue<Range>(null);
if (euRange != null)
{
element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG;
element.HighEU = euRange.High;
element.LowEU = euRange.Low;
}
}
// update HighIR and LowIR
element.HighIR = Double.MaxValue;
element.LowIR = Double.MaxValue;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.InstrumentRange))
{
Range instrumentRange = values[first++].GetValue<Range>(null);
if (instrumentRange != null)
{
element.HighIR = instrumentRange.High;
element.LowIR = instrumentRange.Low;
}
}
// update EngineeringUnits
element.EngineeringUnits = null;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EngineeringUnits))
{
EUInformation engineeringUnits = values[first++].GetValue<EUInformation>(null);
if (engineeringUnits != null && engineeringUnits.DisplayName != null)
{
element.EngineeringUnits = engineeringUnits.DisplayName.Text;
}
}
// update EUInfo
element.EuInfo = null;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.EnumStrings))
{
LocalizedText[] enumStrings = values[first++].GetValue<LocalizedText[]>(null);
if (enumStrings != null)
{
string[] strings = new string[enumStrings.Length];
for (int ii = 0; ii < enumStrings.Length; ii++)
{
if (enumStrings[ii] != null)
{
strings[ii] = enumStrings[ii].Text;
}
}
element.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED;
element.EuInfo = strings;
}
}
// update CloseLabel
element.CloseLabel = null;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.TrueState))
{
LocalizedText trueState = values[first++].GetValue<LocalizedText>(null);
if (trueState != null)
{
element.CloseLabel = trueState.Text;
}
}
// update OpenLabel
element.OpenLabel = null;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.FalseState))
{
LocalizedText falseState = values[first++].GetValue<LocalizedText>(null);
if (falseState != null)
{
element.OpenLabel = falseState.Text;
}
}
// update TimeZone
element.TimeZone = Int32.MaxValue;
if (element.ReferencesByName.ContainsKey(Opc.Ua.BrowseNames.LocalTime))
{
TimeZoneDataType timeZone = values[first++].GetValue<TimeZoneDataType>(null);
if (timeZone != null)
{
element.TimeZone = timeZone.Offset;
}
}
}
return true;
}