/// <summary> /// Collects instance declarations nodes from with a type. /// </summary> public static void CollectInstanceDeclarations( Session session, ComNamespaceMapper mapper, NodeState node, AeEventAttribute parent, List <AeEventAttribute> instances, IDictionary <string, AeEventAttribute> map) { List <BaseInstanceState> children = new List <BaseInstanceState>(); node.GetChildren(session.SystemContext, children); if (children.Count == 0) { return; } // process the children. for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState instance = children[ii]; // only interested in objects and variables. if (instance.NodeClass != NodeClass.Object && instance.NodeClass != NodeClass.Variable) { return; } // ignore instances without a modelling rule. if (NodeId.IsNull(instance.ModellingRuleId)) { return; } // create a new declaration. AeEventAttribute declaration = new AeEventAttribute(); declaration.RootTypeId = (parent != null)?parent.RootTypeId:node.NodeId; declaration.NodeId = (NodeId)instance.NodeId; declaration.BrowseName = instance.BrowseName; declaration.NodeClass = instance.NodeClass; declaration.Description = (instance.Description != null)?instance.Description.ToString():null; // get data type information. BaseVariableState variable = instance as BaseVariableState; if (variable != null) { declaration.DataType = variable.DataType; declaration.ValueRank = variable.ValueRank; if (!NodeId.IsNull(variable.DataType)) { declaration.BuiltInType = DataTypes.GetBuiltInType(declaration.DataType, session.TypeTree); } } if (!LocalizedText.IsNullOrEmpty(instance.DisplayName)) { declaration.DisplayName = instance.DisplayName.Text; } else { declaration.DisplayName = instance.BrowseName.Name; } if (parent != null) { declaration.BrowsePath = new QualifiedNameCollection(parent.BrowsePath); declaration.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(instance.BrowseName)); declaration.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, instance.DisplayName); } else { declaration.BrowsePath = new QualifiedNameCollection(); declaration.BrowsePathDisplayText = Utils.Format("{0}", instance.BrowseName); declaration.DisplayPath = Utils.Format("{0}", instance.DisplayName); } declaration.BrowsePath.Add(instance.BrowseName); // check if reading an overridden declaration. AeEventAttribute overriden = null; if (map.TryGetValue(declaration.BrowsePathDisplayText, out overriden)) { declaration.OverriddenDeclaration = overriden; } map[declaration.BrowsePathDisplayText] = declaration; // only interested in variables. if (instance.NodeClass == NodeClass.Variable) { instances.Add(declaration); } // recusively build tree. CollectInstanceDeclarations(session, mapper, instance, declaration, instances, map); } }
/// <summary> /// Finds the targets for the specified reference. /// </summary> private static void UpdateInstanceDescriptions(Session session, List <InstanceDeclaration> instances, bool throwOnError) { try { ReadValueIdCollection nodesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < instances.Count; ii++) { ReadValueId nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.Description; nodesToRead.Add(nodeToRead); nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.DataType; nodesToRead.Add(nodeToRead); nodeToRead = new ReadValueId(); nodeToRead.NodeId = instances[ii].NodeId; nodeToRead.AttributeId = Attributes.ValueRank; nodesToRead.Add(nodeToRead); } // start the browse operation. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Read( null, 0, TimestampsToReturn.Neither, nodesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead); // update the instances. for (int ii = 0; ii < nodesToRead.Count; ii += 3) { InstanceDeclaration instance = instances[ii / 3]; instance.Description = results[ii].GetValue <LocalizedText>(LocalizedText.Null).Text; instance.DataType = results[ii + 1].GetValue <NodeId>(NodeId.Null); instance.ValueRank = results[ii + 2].GetValue <int>(ValueRanks.Any); if (!NodeId.IsNull(instance.DataType)) { instance.BuiltInType = DataTypes.GetBuiltInType(instance.DataType); instance.DataTypeDisplayText = session.NodeCache.GetDisplayText(instance.DataType); if (instance.ValueRank >= 0) { instance.DataTypeDisplayText += "[]"; } } } } catch (Exception exception) { if (throwOnError) { throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError); } } }
/// <summary> /// Validates the items by reading the attributes required to add them to the group. /// </summary> /// <param name="session">The session.</param> /// <param name="group">The group.</param> /// <param name="requests">The requests.</param> /// <param name="items">The items.</param> /// <param name="start">The start index.</param> /// <param name="count">The number of items to process.</param> private void ValidateItems( Session session, ComDaGroup group, ComDaCreateItemRequest[] requests, ComDaGroupItem[] items, int start, int count) { // build list of the UA attributes that need to be read. ReadValueIdCollection attributesToRead = new ReadValueIdCollection(); for (int ii = start; ii < start + count && ii < requests.Length; ii++) { // create the group item. ComDaCreateItemRequest request = requests[ii]; ComDaGroupItem item = items[ii] = new ComDaGroupItem(group, request.ItemId); item.NodeId = m_mapper.GetRemoteNodeId(request.ItemId); item.Active = request.Active; item.ClientHandle = request.ClientHandle; item.RequestedDataType = request.RequestedDataType; item.SamplingRate = -1; item.Deadband = -1; // add attributes. ReadValueId attributeToRead; attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.NodeClass; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.DataType; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.ValueRank; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.UserAccessLevel; attributesToRead.Add(attributeToRead); } // read attribute values from the server. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.Read( null, 0, TimestampsToReturn.Neither, attributesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, attributesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, attributesToRead); } catch (Exception e) { Utils.Trace(e, "Unexpected error reading attributes for items."); // set default values on error. for (int ii = start; ii < start + count && ii < requests.Length; ii++) { requests[ii].Error = ResultIds.E_INVALIDITEMID; } return; } // process results. int first = 0; for (int ii = start; ii < start + count && ii < requests.Length; ii++, first += 4) { ComDaGroupItem item = items[ii]; // verify node class. NodeClass nodeClass = (NodeClass)results[first].GetValue <int>((int)NodeClass.Unspecified); if (nodeClass != NodeClass.Variable) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // verify data type. NodeId dataTypeId = results[first + 1].GetValue <NodeId>(null); if (dataTypeId == null) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // get value rank. int valueRank = results[first + 2].GetValue <int>(ValueRanks.Scalar); // update datatypes. BuiltInType builtInType = DataTypes.GetBuiltInType(dataTypeId, session.TypeTree); item.RemoteDataType = new TypeInfo(builtInType, valueRank); item.CanonicalDataType = (short)ComUtils.GetVarType(item.RemoteDataType); // update access rights. byte userAccessLevel = results[first + 3].GetValue <byte>(0); if ((userAccessLevel & AccessLevels.CurrentRead) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_READABLE; } if ((userAccessLevel & AccessLevels.CurrentWrite) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_WRITEABLE; } } }