Specifies the parameters used to create a DA group item.
예제 #1
0
        /// <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;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Validates the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="requests">The requests.</param>
        /// <returns>The items. May contain null is validation failed.</returns>
        public ComDaGroupItem[] ValidateItems(ComDaGroup group, ComDaCreateItemRequest[] requests)
        {
            TraceState("ValidateItems", group.Name);

            // get the session to use for the operation.
            Session session = m_session;

            if (session == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            // validate items.
            ComDaGroupItem[] items = new ComDaGroupItem[requests.Length];

            for (int ii = 0; ii < requests.Length; ii += 10000)
            {
                ValidateItems(session, group, requests, items, ii, 10000);
            }

            // process results.
            for (int ii = 0; ii < requests.Length; ii++)
            {
                // check for the results.
                ComDaCreateItemRequest request = requests[ii];

                if (request.Error < 0)
                {
                    items[ii] = null;
                    continue;
                }

                // check access path.
                if (!String.IsNullOrEmpty(request.AccessPath))
                {
                    items[ii]     = null;
                    request.Error = ResultIds.E_UNKNOWNPATH;
                    continue;
                }

                ComDaGroupItem item = items[ii];

                // validate the datatype.
                if (request.RequestedDataType != 0)
                {
                    NodeId dataTypeId = ComUtils.GetDataTypeId(request.RequestedDataType);

                    if (NodeId.IsNull(dataTypeId))
                    {
                        items[ii]     = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }

                    bool reqTypeIsArray    = (request.RequestedDataType & (short)VarEnum.VT_ARRAY) != 0;
                    bool actualTypeIsArray = (item.CanonicalDataType & (short)VarEnum.VT_ARRAY) != 0;

                    if (reqTypeIsArray != actualTypeIsArray)
                    {
                        items[ii]     = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }
                }

                // create a new monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.StartNodeId      = item.NodeId;
                monitoredItem.RelativePath     = null;
                monitoredItem.AttributeId      = Attributes.Value;
                monitoredItem.MonitoringMode   = (request.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled;
                monitoredItem.SamplingInterval = group.UpdateRate / 2;
                monitoredItem.QueueSize        = 0;
                monitoredItem.DiscardOldest    = true;
                monitoredItem.Filter           = null;

                // update item.
                item.ServerHandle  = (int)monitoredItem.ClientHandle;
                item.MonitoredItem = monitoredItem;

                // link the monitored item back to the group item.
                monitoredItem.Handle = item;

                // update return parameters.
                request.ServerHandle      = item.ServerHandle;
                request.CanonicalDataType = item.CanonicalDataType;
                request.AccessRights      = item.AccessRights;
                request.Error             = ResultIds.S_OK;
            }

            return(items);
        }
예제 #3
0
        /// <summary>
        /// Validates the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="requests">The requests.</param>
        /// <returns>The items. May contain null is validation failed.</returns>
        public ComDaGroupItem[] ValidateItems(ComDaGroup group, ComDaCreateItemRequest[] requests)
        {
            TraceState("ValidateItems", group.Name);

            // get the session to use for the operation.
            Session session = m_session;

            if (session == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            // validate items.
            ComDaGroupItem[] items = new ComDaGroupItem[requests.Length];

            for (int ii = 0; ii < requests.Length; ii += 10000)
            {
                ValidateItems(session, group, requests, items, ii, 10000);
            }

            // process results.
            for (int ii = 0; ii < requests.Length; ii++)
            {
                // check for the results.
                ComDaCreateItemRequest request = requests[ii];

                if (request.Error < 0)
                {
                    items[ii] = null;
                    continue;
                }

                // check access path.
                if (!String.IsNullOrEmpty(request.AccessPath))
                {
                    items[ii] = null;
                    request.Error = ResultIds.E_UNKNOWNPATH;
                    continue;
                }

                ComDaGroupItem item = items[ii];

                // validate the datatype.
                if (request.RequestedDataType != 0)
                {
                    NodeId dataTypeId = ComUtils.GetDataTypeId(request.RequestedDataType);

                    if (NodeId.IsNull(dataTypeId))
                    {
                        items[ii] = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }

                    bool reqTypeIsArray = (request.RequestedDataType & (short)VarEnum.VT_ARRAY) != 0;
                    bool actualTypeIsArray = (item.CanonicalDataType & (short)VarEnum.VT_ARRAY) != 0;

                    if (reqTypeIsArray != actualTypeIsArray)
                    {
                        items[ii] = null;
                        request.Error = ResultIds.E_BADTYPE;
                        continue;
                    }
                }

                // create a new monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.StartNodeId = item.NodeId;
                monitoredItem.RelativePath = null;
                monitoredItem.AttributeId = Attributes.Value;
                monitoredItem.MonitoringMode = (request.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled;
                monitoredItem.SamplingInterval = group.UpdateRate/2;
                monitoredItem.QueueSize = 0;
                monitoredItem.DiscardOldest = true;
                monitoredItem.Filter = null;

                // update item.
                item.ServerHandle = (int)monitoredItem.ClientHandle;
                item.MonitoredItem = monitoredItem;

                // link the monitored item back to the group item.
                monitoredItem.Handle = item;
                
                // update return parameters.
                request.ServerHandle = item.ServerHandle;
                request.CanonicalDataType = item.CanonicalDataType;
                request.AccessRights = item.AccessRights;
                request.Error = ResultIds.S_OK;
            }

            return items;
        }
예제 #4
0
        /// <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;
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Creates the items.
        /// </summary>
        /// <param name="requests">The requests.</param>
        /// <param name="validateOnly">if set to <c>true</c> if the items only need to be validated.</param>
        public void CreateItems(ComDaCreateItemRequest[] requests, bool validateOnly)
        {
            TraceState("CreateItems", this.Name, this.Active, this.UpdateRate);
            ThrowIfDisposed();

            // validates the items.
            ComDaGroupItem[] items = m_manager.ValidateItems(this, requests);

            // check if nothing more to do.
            if (validateOnly)
            {
                return;
            }

            if (this.Deadband > 0)
            {
                // need the EU Info if the deadband is specified.
                m_manager.UpdateItemEuInfo(this, items);
            }

            // create the items on the server.
            lock (m_lock)
            {
                // update the filters.
                UpdateDeadbandFilters(items);

                // add the monitored items to the group's subscription.
                for (int ii = 0; ii < items.Length; ii++)
                {
                    ComDaGroupItem item = items[ii];

                    if (item != null)
                    {
                        AddItemToSubscription(item);
                    }
                }

                // update the server.
                try
                {
                    m_subscription.ApplyChanges();
                }
                catch (Exception e)
                {
                    // set fatal error for remaining items.
                    for (int ii = 0; ii < items.Length; ii++)
                    {
                        ComDaGroupItem item = items[ii];

                        if (items[ii] != null)
                        {
                            requests[ii].Error = ComUtils.GetErrorCode(e, ResultIds.E_FAIL);
                        }
                    }

                    return;
                }

                // build results.
                for (int ii = 0; ii < items.Length; ii++)
                {
                    // check for valid item.
                    ComDaGroupItem item = items[ii];

                    if (item == null)
                    {
                        continue;
                    }

                    // check for error.
                    ServiceResult error = item.MonitoredItem.Status.Error;

                    if (ServiceResult.IsBad(error))
                    {
                        RemoveItemFromSubscription(item);
                        requests[ii].Error = ComDaProxy.MapReadStatusToErrorCode(error.StatusCode);
                        continue;
                    }

                    TraceState(
                        "ItemCreated",
                        m_subscription.CurrentPublishingEnabled, 
                        m_subscription.CurrentPublishingInterval, 
                        item.MonitoredItem.Status.MonitoringMode, 
                        item.MonitoredItem.Status.SamplingInterval);

                    // save the item.
                    m_itemsByHandle.Add(item.ServerHandle, item);
                    m_items.Add(item);
                }
                
                // start the update timer.
                CheckUpdateTimerStatus();
            }
        }