Example #1
0
	    /// <summary>
	    /// Initializes the object with the containing subscription object.
	    /// </summary>
	    public ComDaDataCallback(ComDaGroup group)
	    { 
            // save group.
            m_group = group;

		    // create connection point.
		    m_connectionPoint = new ConnectionPoint(group.Unknown, typeof(OpcRcw.Da.IOPCDataCallback).GUID);

		    // advise.
		    m_connectionPoint.Advise(this);
	    }
 /// <summary>
 /// Initializes a new instance of the <see cref="ComDaGroupItem"/> class.
 /// </summary>
 public ComDaGroupItem(ComDaGroup group, string itemId)
 {
     m_group         = group;
     m_itemId        = itemId;
     m_serverHandle  = 0;
     m_active        = true;
     m_euType        = -1;
     m_samplingRate  = -1;
     m_bufferEnabled = false;
     m_deadband      = -1;
 }
Example #3
0
        /// <summary>
        /// Recovers the session context.
        /// </summary>
        /// <param name="group">The group.</param>
        public void RecoverSessionContext(ComDaGroup group)
        {
            // create a new subscription and copy existing one.
            Subscription discardSubscription = group.Subscription;
            Subscription subscription        = new Subscription();

            subscription.DisplayName                = discardSubscription.DisplayName;
            subscription.PublishingInterval         = discardSubscription.PublishingInterval;
            subscription.KeepAliveCount             = discardSubscription.KeepAliveCount;
            subscription.LifetimeCount              = discardSubscription.LifetimeCount;
            subscription.MaxNotificationsPerPublish = discardSubscription.MaxNotificationsPerPublish;
            subscription.Priority                  = discardSubscription.Priority;
            subscription.PublishingEnabled         = discardSubscription.PublishingEnabled;
            subscription.DisableMonitoredItemCache = discardSubscription.DisableMonitoredItemCache;

            try
            {
                discardSubscription.Dispose();
            }
            catch (Exception)
            {
            }

            m_session.AddSubscription(subscription);

            try
            {
                // create the initial subscription.
                subscription.Create();

                // set the keep alive interval to 30 seconds and the the lifetime interval to 5 minutes.
                subscription.KeepAliveCount = (uint)((30000 / (int)subscription.CurrentPublishingInterval) + 1);
                subscription.LifetimeCount  = (uint)((600000 / (int)subscription.CurrentPublishingInterval) + 1);

                // update the subscription.
                subscription.Modify();
            }
            catch (Exception e)
            {
                m_session.RemoveSubscription(subscription);
                throw ComUtils.CreateComException(e, ResultIds.E_FAIL);
            }

            // update the group.
            group.ActualUpdateRate = (int)(subscription.CurrentPublishingInterval * 2);
            group.Subscription     = subscription;
            group.RecreateItems();
        }
Example #4
0
        /// <summary>
        /// Returns the current set of groups.
        /// </summary>
        /// <returns>The list of groups.</returns>
        public ComDaGroup[] GetGroups()
        {
            TraceState("GetGroups");

            lock (m_lock)
            {
                ComDaGroup[] groups = new ComDaGroup[m_groups.Count];

                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    groups[ii] = m_groups[ii];
                }

                return(groups);
            }
        }
Example #5
0
        /// <summary>
        /// Gets the group by handle.
        /// </summary>
        /// <param name="serverHandle">The server handle.</param>
        /// <returns>The group.</returns>
        public ComDaGroup GetGroupByHandle(int serverHandle)
        {
            TraceState("GetGroupByHandle", serverHandle);

            lock (m_lock)
            {
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    ComDaGroup group = m_groups[ii];

                    if (group.ServerHandle == serverHandle)
                    {
                        return(group);
                    }
                }

                return(null);
            }
        }
Example #6
0
        /// <summary>
        /// Gets the group with the specified name.
        /// </summary>
        /// <param name="groupName">Name of the group.</param>
        /// <returns>The group. Null if it does not exist.</returns>
        public ComDaGroup GetGroupByName(string groupName)
        {
            TraceState("GetGroupByName", groupName);

            lock (m_lock)
            {
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    ComDaGroup group = m_groups[ii];

                    if (group.Name == groupName)
                    {
                        return(group);
                    }
                }

                return(null);
            }
        }
Example #7
0
        /// <summary>
        /// Removes the group.
        /// </summary>
        /// <param name="group">The group.</param>
        public void RemoveGroup(ComDaGroup group)
        {
            TraceState("RemoveGroup", group.Name);

            lock (m_lock)
            {
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    if (Object.ReferenceEquals(group, m_groups[ii]))
                    {
                        m_groups.RemoveAt(ii);

                        if (group.Subscription != null && group.Subscription.Session != null)
                        {
                            group.Subscription.Session.RemoveSubscription(group.Subscription);
                        }
                    }
                }

                group.Dispose();
            }
        }
        /// <summary>
        /// Clones the item.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <returns>The new item.</returns>
        public ComDaGroupItem CloneItem(ComDaGroup group)
        {
            ComDaGroupItem copy = new ComDaGroupItem(group, this.ItemId);

            copy.m_nodeId             = this.m_nodeId;
            copy.m_serverHandle       = this.m_serverHandle;
            copy.m_clientHandle       = this.m_clientHandle;
            copy.m_active             = this.m_active;
            copy.m_requestedDataType  = this.m_requestedDataType;
            copy.m_canonicalDataType  = this.m_canonicalDataType;
            copy.m_accessRights       = this.m_accessRights;
            copy.m_euType             = this.m_euType;
            copy.m_euInfo             = this.m_euInfo;
            copy.m_samplingRate       = this.m_samplingRate;
            copy.m_bufferEnabled      = this.m_bufferEnabled;
            copy.m_actualSamplingRate = this.m_actualSamplingRate;
            copy.m_deadband           = this.m_deadband;

            // create new monitored item and use its client handle as the server handle.
            copy.m_monitoredItem = new MonitoredItem(this.MonitoredItem);

            return(copy);
        }
Example #9
0
        /// <summary>
        /// Sets the name.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="groupName">Name of the group.</param>
        public void SetGroupName(ComDaGroup group, string groupName)
        {
            TraceState("SetGroupName", group.Name, groupName);

            if (String.IsNullOrEmpty(groupName))
            {
                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
            }

            lock (m_lock)
            {
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    ComDaGroup target = m_groups[ii];

                    if (target.ServerHandle != group.ServerHandle && target.Name == groupName)
                    {
                        throw ComUtils.CreateComException(ResultIds.E_DUPLICATENAME);
                    }

                    group.Name = groupName;
                }
            }
        }
Example #10
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;
                }
            }
        }
Example #11
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);
        }
Example #12
0
        /// <summary>
        /// Updates the EUInfo for the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="items">The items. Null entries are ignored.</param>
        public void UpdateItemEuInfo(
            ComDaGroup group,
            IList <ComDaGroupItem> items)
        {
            // get the session to use for the operation.
            Session session = m_session;

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

            // build list of properties that need to be read.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            for (int ii = 0; ii < items.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)items[ii];

                // ignore invalid items or items which have already checked their EU type.
                if (item == null || item.EuType >= 0)
                {
                    continue;
                }

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EURange;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);

                browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EnumStrings;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);
            }

            // check if nothing to do.
            if (browsePaths.Count == 0)
            {
                return;
            }

            // translate browse paths.
            BrowsePathResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            try
            {
                session.TranslateBrowsePathsToNodeIds(
                    null,
                    browsePaths,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, browsePaths);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < browsePaths.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // build list of properties that need to be read.
            ReadValueIdCollection propertiesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                ComDaGroupItem   item   = (ComDaGroupItem)browsePaths[ii].Handle;
                BrowsePathResult result = results[ii];

                if (StatusCode.IsBad(result.StatusCode))
                {
                    if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute)
                {
                    if (item.EuType < 0)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                ReadValueId propertyToRead = new ReadValueId();
                propertyToRead.NodeId      = (NodeId)result.Targets[0].TargetId;
                propertyToRead.AttributeId = Attributes.Value;
                propertyToRead.Handle      = item;
                propertiesToRead.Add(propertyToRead);

                if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange)
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG;
                }
                else
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED;
                }
            }

            // check if nothing to do.
            if (propertiesToRead.Count == 0)
            {
                return;
            }

            // read attribute values from the server.
            DataValueCollection values = null;

            try
            {
                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    propertiesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(values, propertiesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < propertiesToRead.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // process results.
            for (int ii = 0; ii < values.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;

                if (StatusCode.IsBad(values[ii].StatusCode))
                {
                    item.EuType = 0;
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG)
                {
                    Range range = (Range)values[ii].GetValue <Range>(null);

                    if (range == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    item.EuInfo = new double[] { range.Low, range.High };
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED)
                {
                    LocalizedText[] texts = (LocalizedText[])values[ii].GetValue <LocalizedText[]>(null);

                    if (texts == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    string[] strings = new string[texts.Length];

                    for (int jj = 0; jj < strings.Length; jj++)
                    {
                        if (!LocalizedText.IsNullOrEmpty(texts[jj]))
                        {
                            strings[jj] = texts[jj].Text;
                        }
                    }

                    item.EuInfo = strings;
                    continue;
                }
            }
        }
Example #13
0
        /// <summary>
        /// Reads the item values and stores the results in the request object.
        /// </summary>
        /// <param name="requests">The requests.</param>
        private void Da20ReadItemValues(List<ReadRequest> requests)
        {
            // lock (m_groupLock)
            {
                // if (m_group == null)
                //{                
                    ComDaGroup m_group = new ComDaGroup(this, false);
                //}

                try
                {
                    int count1 = 0;
                    GroupItem[] items = new GroupItem[requests.Count];
                    ReadRequest[] addItemRequests = new ReadRequest[requests.Count];

                    // create the items in the temporary group.
                    for (int ii = 0; ii < requests.Count; ii++)
                    {
                        ReadRequest request = requests[ii];

                        if (request == null)
                        {
                            continue;
                        }

                        if (!request.ValueRequired)
                        {
                            continue;
                        }

                        // add the item.
                        items[count1] = m_group.CreateItem(request.ItemId, 0, 0, true);
                        addItemRequests[count1] = request;
                        count1++;
                    }

                    // create the items on the server.
                    m_group.ApplyChanges();

                    // build the list of values to write.
                    int count2 = 0;
                    int[] serverHandles = new int[count1];
                    ReadRequest[] readRequests = new ReadRequest[count1];

                    for (int ii = 0; ii < count1; ii++)
                    {
                        // check for error on create.
                        GroupItem item = items[ii];
                        ReadRequest request = addItemRequests[ii];

                        if (item.ErrorId < 0)
                        {
                            request.Value = new DaValue();
                            request.Value.Error = item.ErrorId;
                            continue;
                        }

                        serverHandles[count2] = item.ServerHandle;
                        readRequests[count2] = request;
                        count2++;
                    }

                    if (count2 > 0)
                    {
                        // write values to the server.
                        DaValue[] values = m_group.SyncRead(serverHandles, count2);

                        // read the values.
                        for (int ii = 0; ii < count2; ii++)
                        {
                            if (values != null && values.Length > ii)
                            {
                                readRequests[ii].Value = values[ii];
                            }
                            else
                            {
                                readRequests[ii].Value = new DaValue() { Error = ResultIds.E_FAIL, Timestamp = DateTime.UtcNow };
                            }
                        }

                        // delete the items.
                        for (int ii = 0; ii < count1; ii++)
                        {
                            GroupItem item = items[ii];

                            if (item.ErrorId >= 0)
                            {
                                m_group.RemoveItem(item);
                            }
                        }

                        m_group.ApplyChanges();
                    }
                }
                finally
                {
                    // delete the group and items.
                   m_group.Delete();
                }
            }
        }
Example #14
0
 /// <summary>
 /// Removes the group.
 /// </summary>
 /// <param name="group">The group.</param>
 public void RemoveGroup(ComDaGroup group)
 {
     m_groupManager.RemoveGroup(group);
 }
Example #15
0
        /// <summary>
        /// Reads the item values and stores the results in the request object.
        /// </summary>
        /// <param name="requests">The requests.</param>
        public void ReadItemValues(List<ReadRequest> requests)
        {
            ComDaGroup group = new ComDaGroup(this, false);

            try
            {
                int count1 = 0;
                GroupItem[] items = new GroupItem[requests.Count];
                ReadRequest[] addItemRequests = new ReadRequest[requests.Count];

                // create the items in the temporary group.
                for (int ii = 0; ii < requests.Count; ii++)
                {
                    ReadRequest request = requests[ii];

                    if (request == null)
                    {
                        continue;
                    }

                    if (!request.ValueRequired)
                    {
                        continue;
                    }

                    // add the item.
                    items[count1] = group.CreateItem(request.ItemId, 0, 0, true);
                    addItemRequests[count1] = request;
                    count1++;
                }

                // create the items on the server.
                group.ApplyChanges();

                // build the list of values to write.
                int count2 = 0;
                int[] serverHandles = new int[count1];
                ReadRequest[] readRequests = new ReadRequest[count1];

                for (int ii = 0; ii < count1; ii++)
                {
                    // check for error on create.
                    GroupItem item = items[ii];
                    ReadRequest request = addItemRequests[ii];

                    if (item.ErrorId < 0)
                    {
                        request.Value.Error = item.ErrorId;
                        continue;
                    }

                    serverHandles[count2] = item.ServerHandle;
                    readRequests[count2] = request;
                    count2++;
                }

                // write values to the server.
                DaValue[] values = group.SyncRead(serverHandles, count2);

                // read the values.
                for (int ii = 0; ii < count2; ii++)
                {
                    readRequests[ii].Value = values[ii];
                }
            }
            finally
            {
                // delete the group and items.
                group.Delete();
            }
        }
Example #16
0
        /// <summary>
        /// Writes the item values to servers.
        /// </summary>
        /// <param name="requests">The requests.</param>
        private void WriteItemValues(List<WriteRequest> requests)
        {
            ComDaGroup group = new ComDaGroup(this, false);

            try
            {
                int count1 = 0;
                GroupItem[] items = new GroupItem[requests.Count];
                WriteRequest[] addItemRequests = new WriteRequest[requests.Count];

                // create the items in the temporary group.
                for (int ii = 0; ii < requests.Count; ii++)
                {
                    WriteRequest request = requests[ii];

                    if (request == null)
                    {
                        continue;
                    }

                    // status code writes not supported.
                    if (request.Value.StatusCode != StatusCodes.Good)
                    {
                        request.Error = ResultIds.E_NOTSUPPORTED;
                        continue;
                    }

                    // timestamp writes not supported.
                    if (request.Value.SourceTimestamp != DateTime.MinValue)
                    {
                        request.Error = ResultIds.E_NOTSUPPORTED;
                        continue;
                    }

                    // add the item.
                    items[count1] = group.CreateItem(request.ItemId, 0, 0, true);
                    addItemRequests[count1] = request;
                    count1++;
                }

                // create the items on the server.
                group.ApplyChanges();

                // build the list of values to write.
                int count2 = 0;
                int[] serverHandles = new int[count1];
                object[] values = new object[count1];
                WriteRequest[] writeRequests = new WriteRequest[count1];

                for (int ii = 0; ii < count1; ii++)
                {
                    // check for error on create.
                    GroupItem item = items[ii];
                    WriteRequest request = addItemRequests[ii];

                    if (item.ErrorId < 0)
                    {
                        request.Error = item.ErrorId;
                        continue;
                    }

                    serverHandles[count2] = item.ServerHandle;
                    values[count2] = ComUtils.GetVARIANT(request.Value.Value);
                    writeRequests[count2] = request;
                    count2++;
                }

                // write values to the server.
                int[] errors = group.SyncWrite(serverHandles, values, count2);

                // read the errors.
                for (int ii = 0; ii < count2; ii++)
                {
                    writeRequests[ii].Error = errors[ii];
                }
            }
            finally
            {
                // delete the group and items.
                group.Delete();
            }
        }
Example #17
0
        /// <summary>
        /// Adds the group.
        /// </summary>
        /// <param name="groupName">The group name.</param>
        /// <param name="active">if set to <c>true</c> the group is active.</param>
        /// <param name="updateRate">The update rate.</param>
        /// <param name="clientHandle">The client handle.</param>
        /// <param name="timeBias">The time bias.</param>
        /// <param name="deadband">The deadband.</param>
        /// <param name="lcid">The lcid.</param>
        /// <returns>The new group.</returns>
        public ComDaGroup AddGroup(
            string groupName,
            bool active,
            int updateRate,
            int clientHandle,
            int timeBias,
            float deadband,
            int lcid)
        {
            TraceState("AddGroup", groupName, active, updateRate, clientHandle, timeBias, deadband, lcid);

            // check for valid session.
            Session session = m_session;

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

            ComDaGroup group = null;

            // check for duplicate name.
            lock (m_lock)
            {
                // ensure the name is unique.
                if (!String.IsNullOrEmpty(groupName))
                {
                    if (GetGroupByName(groupName) != null)
                    {
                        throw ComUtils.CreateComException(ResultIds.E_DUPLICATENAME);
                    }
                }

                // assign a unique name.
                else
                {
                    groupName = Utils.Format("Group{0}", m_groupCounter + 1);
                }

                // validate the deadband.
                if (deadband < 0 || deadband > 100)
                {
                    throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                }

                // create the group.
                group = new ComDaGroup(this, groupName, ++m_groupCounter);
                m_groups.Add(group);

                group.ClientHandle = clientHandle;
                group.Active       = active;
                group.UpdateRate   = updateRate;
                group.TimeBias     = timeBias;
                group.Deadband     = deadband;
                group.Lcid         = lcid;

                if (updateRate < 100)
                {
                    updateRate = 100;
                }

                // create a new subscription.
                Subscription subscription = new Subscription();
                subscription.DisplayName                = groupName;
                subscription.PublishingInterval         = updateRate / 2;
                subscription.KeepAliveCount             = 30;
                subscription.LifetimeCount              = 600;
                subscription.MaxNotificationsPerPublish = 10000;
                subscription.Priority                  = 1;
                subscription.PublishingEnabled         = active;
                subscription.DisableMonitoredItemCache = true;

                // create the subscription on the server.
                session.AddSubscription(subscription);

                try
                {
                    // create the initial subscription.
                    subscription.Create();

                    // set the keep alive interval to 30 seconds and the the lifetime interval to 5 minutes.
                    subscription.KeepAliveCount = (uint)((30000 / (int)subscription.CurrentPublishingInterval) + 1);
                    subscription.LifetimeCount  = (uint)((600000 / (int)subscription.CurrentPublishingInterval) + 1);

                    // update the subscription.
                    subscription.Modify();
                }
                catch (Exception e)
                {
                    session.RemoveSubscription(subscription);
                    Utils.Trace((int)Utils.TraceMasks.Error, "Create subscription failed: {0}", e.Message);
                    throw ComUtils.CreateComException(e, ResultIds.E_FAIL);
                }

                // update the group.
                group.ActualUpdateRate = (int)(subscription.CurrentPublishingInterval * 2);
                group.Subscription     = subscription;
            }

            return(group);
        }
Example #18
0
        /// <summary>
        /// Writes the item values to servers.
        /// </summary>
        /// <param name="requests">The requests.</param>
        private void Da20WriteItemValues(List<WriteRequest> requests)
        {
            //lock (m_groupLock)
            {
                //if (m_group == null)
                //{
                    ComDaGroup m_group = new ComDaGroup(this, false);
                //}

                try
                {
                    int count1 = 0;
                    GroupItem[] items = new GroupItem[requests.Count];
                    WriteRequest[] addItemRequests = new WriteRequest[requests.Count];
                    object[] convertedValues = new object[requests.Count];

                    // create the items in the temporary group.
                    for (int ii = 0; ii < requests.Count; ii++)
                    {
                        WriteRequest request = requests[ii];

                        if (request == null)
                        {
                            continue;
                        }

                        // status code writes not supported.
                        if (request.Value.StatusCode != StatusCodes.Good)
                        {
                            request.Error = ResultIds.E_NOTSUPPORTED;
                            continue;
                        }

                        // timestamp writes not supported.
                        if (request.Value.ServerTimestamp != DateTime.MinValue)
                        {
                            request.Error = ResultIds.E_NOTSUPPORTED;
                            continue;
                        }

                        // timestamp writes not supported.
                        if (request.Value.SourceTimestamp != DateTime.MinValue)
                        {
                            request.Error = ResultIds.E_NOTSUPPORTED;
                            continue;
                        }

                        // convert to a DA compatible type.
                        object convertedValue = null;
                        request.Error = ComDaClientNodeManager.LocalToRemoteValue(request.Value.WrappedValue, out convertedValue);

                        if (request.Error < 0)
                        {
                            continue;
                        }

                        // add the item.
                        items[count1] = m_group.CreateItem(request.ItemId, 0, 0, true);
                        addItemRequests[count1] = request;
                        convertedValues[count1] = convertedValue;
                        count1++;
                    }

                    // create the items on the server.
                    m_group.ApplyChanges();

                    // build the list of values to write.
                    int count2 = 0;
                    int[] serverHandles = new int[count1];
                    object[] values = new object[count1];
                    WriteRequest[] writeRequests = new WriteRequest[count1];

                    for (int ii = 0; ii < count1; ii++)
                    {
                        // check for error on create.
                        GroupItem item = items[ii];
                        WriteRequest request = addItemRequests[ii];

                        if (item.ErrorId < 0)
                        {
                            request.Error = item.ErrorId;
                            continue;
                        }

                        serverHandles[count2] = item.ServerHandle;
                        values[count2] = convertedValues[ii];
                        writeRequests[count2] = request;
                        count2++;
                    }

                    if (count2 > 0)
                    {
                        // write values to the server.
                        int[] errors = m_group.SyncWrite(serverHandles, values, count2);

                        // read the errors.
                        for (int ii = 0; ii < count2; ii++)
                        {
                            if (errors != null && errors.Length > ii)
                            {
                                writeRequests[ii].Error = errors[ii];
                            }
                            else
                            {
                                writeRequests[ii].Error = ResultIds.E_FAIL;
                            }
                        }

                        // delete the items.
                        for (int ii = 0; ii < count1; ii++)
                        {
                            GroupItem item = items[ii];

                            if (item.ErrorId >= 0)
                            {
                                m_group.RemoveItem(item);
                            }
                        }

                        m_group.ApplyChanges();
                    }
                }
                finally
                {
                    // delete the group and items.
                    m_group.Delete();
                }
            }
        }