예제 #1
0
        //======================================================================
        // GetStatus

        /// <summary>
        /// Returns the current server status.
        /// </summary>
        /// <returns>The current server status.</returns>
        public ServerStatus GetStatus()
        {
            lock (this)
            {
                if (m_proxy == null)
                {
                    throw new NotConnectedException();
                }

                OpcXml.Da10.RequestOptions options      = OpcXml.Da10.Request.GetRequestOptions(m_options.Locale, m_options.Filters);
                OpcXml.Da10.ServerStatus   remoteStatus = null;

                OpcXml.Da10.ReplyBase reply = m_proxy.GetStatus(
                    options.LocaleID,
                    options.ClientRequestHandle,
                    out remoteStatus);

                CacheResponse(m_options.Locale, reply, null);

                // fill in the last update time.
                ServerStatus status = OpcXml.Da10.Request.GetServerStatus(reply, remoteStatus);

                status.LastUpdateTime = m_lastUpdateTime;

                return(status);
            }
        }
예제 #2
0
        /// <summary>
        /// Causes the server to send a data changed notification for all active items.
        /// </summary>
        /// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
        /// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
        /// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
        public virtual void Refresh(
            object requestHandle,
            out IRequest request)
        {
            lock (this)
            {
                request = null;

                // do nothing is subscription is no longer valid.
                if (m_state.ServerHandle == null)
                {
                    return;
                }

                // begin the polled refresh.
                OpcXml.Da10.RequestOptions options = OpcXml.Da10.Request.GetRequestOptions(m_state.Locale, m_filters);

                // send a polled refresh that requests all items.
                m_proxy.BeginSubscriptionPolledRefresh(
                    options,
                    new string [] { (string)m_state.ServerHandle },
                    m_server.ServerTime,
                    true,
                    0,
                    true,
                    new AsyncCallback(OnPollCompleted),
                    new string[] { (string)m_state.ServerHandle, options.LocaleID, null });
            }
        }
예제 #3
0
        //======================================================================
        // Write

        /// <summary>
        /// Writes the value, quality and timestamp for a set of items.
        /// </summary>
        /// <param name="items">The set of item values to write.</param>
        /// <returns>The results of the write operation for each item.</returns>
        public IdentifiedResult[] Write(ItemValue[] items)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }

            if (items.Length == 0)
            {
                return(new Opc.IdentifiedResult[0]);
            }

            lock (this)
            {
                if (m_proxy == null)
                {
                    throw new NotConnectedException();
                }

                ItemValueList list = new ItemValueList();
                list.AddRange(items);

                OpcXml.Da10.RequestOptions       options     = OpcXml.Da10.Request.GetRequestOptions(m_options.Locale, m_options.Filters);
                OpcXml.Da10.WriteRequestItemList requestList = OpcXml.Da10.Request.GetItemValueList(list);
                OpcXml.Da10.ReplyItemList        replyList   = null;
                OpcXml.Da10.OPCError[]           errors      = null;

                OpcXml.Da10.ReplyBase reply = m_proxy.Write(
                    options,
                    requestList,
                    false,
                    out replyList,
                    out errors);

                CacheResponse(m_options.Locale, reply, errors);

                ItemValueResultList valueList = OpcXml.Da10.Request.GetResultList(replyList);

                if (valueList == null)
                {
                    throw new InvalidResponseException();
                }

                IdentifiedResult[] results = new IdentifiedResult[valueList.Count];

                for (int ii = 0; ii < valueList.Count; ii++)
                {
                    ItemValueResult valueResult = valueList[ii];

                    results[ii]                = new IdentifiedResult(valueResult);
                    results[ii].ResultID       = valueResult.ResultID;
                    results[ii].DiagnosticInfo = valueResult.DiagnosticInfo;
                }

                return(results);
            }
        }
예제 #4
0
        //======================================================================
        // Read

        /// <summary>
        /// Reads the current values for a set of items.
        /// </summary>
        /// <param name="items">The set of items to read.</param>
        /// <returns>The results of the read operation for each item.</returns>
        public Opc.Da.ItemValueResult[] Read(Item[] items)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }

            if (items.Length == 0)
            {
                return(new Opc.Da.ItemValueResult[0]);
            }

            lock (this)
            {
                if (m_proxy == null)
                {
                    throw new NotConnectedException();
                }

                ItemList list = new ItemList();
                list.AddRange(items);

                OpcXml.Da10.RequestOptions      options     = OpcXml.Da10.Request.GetRequestOptions(m_options.Locale, m_options.Filters);
                OpcXml.Da10.ReadRequestItemList requestList = OpcXml.Da10.Request.GetItemList(list);
                OpcXml.Da10.ReplyItemList       replyList   = null;
                OpcXml.Da10.OPCError[]          errors      = null;

                OpcXml.Da10.ReplyBase reply = m_proxy.Read(
                    options,
                    requestList,
                    out replyList,
                    out errors);

                CacheResponse(m_options.Locale, reply, errors);

                ItemValueResultList valueList = OpcXml.Da10.Request.GetResultList(replyList);

                if (valueList == null)
                {
                    throw new InvalidResponseException();
                }

                return((ItemValueResult[])valueList.ToArray(typeof(ItemValueResult)));
            }
        }
예제 #5
0
        /// <summary>
        /// Starts polling for the current subscription.
        /// </summary>
        private void Poll(object state)
        {
            lock (this)
            {
                // do nothing is subscription is no longer valid.
                if (m_state.ServerHandle == null)
                {
                    return;
                }

                TimeSpan holdTime = TimeSpan.Zero;
                TimeSpan waitTime = TimeSpan.Zero;

                // use simple client side polling if not enabled.
                if (m_enabled)
                {
                    // hold time is the ping rate and the wait time is zero.
                    if (m_pingRate < m_state.UpdateRate)
                    {
                        holdTime = new TimeSpan(m_pingRate * 10000);
                        waitTime = TimeSpan.Zero;
                    }

                    // hold time is the update rate and the wait time is ping rate minus the update rate.
                    else
                    {
                        holdTime = new TimeSpan(m_state.UpdateRate * 10000);
                        waitTime = new TimeSpan((m_pingRate - m_state.UpdateRate) * 10000);
                    }
                }

                // begin the polled refresh.
                OpcXml.Da10.RequestOptions options = OpcXml.Da10.Request.GetRequestOptions(m_state.Locale, m_filters);

                m_proxy.BeginSubscriptionPolledRefresh(
                    options,
                    new string [] { (string)m_state.ServerHandle },
                    m_server.ServerTime.Add(holdTime),
                    true,
                    (int)waitTime.TotalMilliseconds,
                    false,
                    new AsyncCallback(OnPollCompleted),
                    new string[] { (string)m_state.ServerHandle, options.LocaleID, "" });
            }
        }
예제 #6
0
        //======================================================================
        // GetProperties

        /// <summary>
        /// Returns the item properties for a set of items.
        /// </summary>
        /// <param name="itemIDs">A list of item identifiers.</param>
        /// <param name="propertyIDs">A list of properties to fetch for each item.</param>
        /// <param name="returnValues">Whether the property values should be returned with the properties.</param>
        /// <returns>A list of properties for each item.</returns>
        public ItemPropertyCollection[] GetProperties(
            ItemIdentifier[] itemIDs,
            PropertyID[]     propertyIDs,
            bool returnValues)
        {
            if (itemIDs == null)
            {
                throw new ArgumentNullException("itemIDs");
            }
            if (m_proxy == null)
            {
                throw new NotConnectedException();
            }

            lock (this)
            {
                OpcXml.Da10.RequestOptions      options    = OpcXml.Da10.Request.GetRequestOptions(m_options.Locale, m_options.Filters);
                OpcXml.Da10.PropertyReplyList[] properties = null;
                OpcXml.Da10.OPCError[]          errors     = null;

                OpcXml.Da10.ReplyBase reply = m_proxy.GetProperties(
                    OpcXml.Da10.Request.GetItemIdentifiers(itemIDs),
                    OpcXml.Da10.Request.GetPropertyNames(propertyIDs),
                    options.LocaleID,
                    options.ClientRequestHandle,
                    null,
                    (propertyIDs == null),
                    returnValues,
                    options.ReturnErrorText,
                    out properties,
                    out errors);

                CacheResponse(options.LocaleID, reply, errors);

                return(OpcXml.Da10.Request.GetItemPropertyCollections(properties));
            }
        }
예제 #7
0
        /// <summary>
        /// Establishes a subscription for the current set of items.
        /// </summary>
        private ItemValueResultList Subscribe(ArrayList items)
        {
            lock (this)
            {
                // cancel any current subscription.
                Unsubscribe();

                // check if there is nothing to do.
                if (items == null || items.Count == 0)
                {
                    return(new ItemValueResultList());
                }

                // create a single item list and use the subscription state to set list level parameters.
                ItemList itemList = new ItemList();

                itemList.ClientHandle             = Guid.NewGuid().ToString();
                itemList.ItemPath                 = null;
                itemList.ReqType                  = null;
                itemList.Deadband                 = m_state.Deadband;
                itemList.DeadbandSpecified        = true;
                itemList.SamplingRate             = m_state.UpdateRate;
                itemList.SamplingRateSpecified    = true;
                itemList.EnableBuffering          = false;
                itemList.EnableBufferingSpecified = false;

                // set the ping rate based on the keep alive (if specified) or five times update rate.
                m_pingRate = (m_state.KeepAlive != 0)?m_state.KeepAlive:m_state.UpdateRate * 5;

                // stop any existing timer.
                if (m_pollTimer != null)
                {
                    m_pollTimer.Dispose();
                    m_pollTimer = null;
                }

                // create copies of each and replace the client handle with the server handle.
                foreach (Item item in items)
                {
                    Item clone = (Item)item.Clone();
                    clone.ClientHandle = clone.ServerHandle;
                    itemList.Add(clone);
                }

                string subscription = null;

                // establish the subscription on the server.
                OpcXml.Da10.RequestOptions         options   = OpcXml.Da10.Request.GetRequestOptions(m_state.Locale, m_filters);
                OpcXml.Da10.SubscribeReplyItemList replyList = null;
                OpcXml.Da10.OPCError[]             errors    = null;

                OpcXml.Da10.ReplyBase reply = m_proxy.Subscribe(
                    options,
                    OpcXml.Da10.Request.GetSubscribeList(itemList),
                    true,
                    m_pingRate * 2,
                    out replyList,
                    out errors,
                    out subscription);

                // cache results with the server object.
                m_server.CacheResponse(m_state.Locale, reply, errors);

                // save subscription handle.
                m_state.ServerHandle = subscription;

                // check for valid response.
                if (replyList == null)
                {
                    throw new InvalidResponseException();
                }

                // save the revised update rate.
                if (replyList.RevisedSamplingRateSpecified)
                {
                    m_state.UpdateRate = (int)replyList.RevisedSamplingRate;
                }

                // update items.
                ItemValueResultList resultList = OpcXml.Da10.Request.GetSubscribeResultList(replyList);

                for (int ii = 0; ii < itemList.Count; ii++)
                {
                    SubscribeItemValueResult resultItem = (SubscribeItemValueResult)resultList[ii];

                    // restore the client/server handles in the result.
                    resultItem.ServerHandle = resultItem.ClientHandle;
                    resultItem.ClientHandle = ((Item)items[ii]).ClientHandle;

                    // check if the requested sampling rate was accepted.
                    if (!resultItem.SamplingRateSpecified)
                    {
                        resultItem.SamplingRate          = itemList[ii].SamplingRate;
                        resultItem.SamplingRateSpecified = itemList[ii].SamplingRateSpecified;
                    }
                }

                // schedule polling.
                SchedulePoll();

                // return result list.
                return(resultList);
            }
        }