Ejemplo n.º 1
0
        /// <summary>
        /// Releases the handles.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="requests">The requests.</param>
        private void ReleaseHandles(ComHdaClient client, List <HdaSubscribeAttributeRequest> requests)
        {
            List <int> serverHandles = null;

            lock (m_lock)
            {
                for (int ii = 0; ii < requests.Count; ii++)
                {
                    if (requests[ii].ServerHandle != null)
                    {
                        if (serverHandles == null)
                        {
                            serverHandles = new List <int>();
                        }

                        serverHandles.Add(requests[ii].ServerHandle.Value);
                        requests[ii].ServerHandle = null;
                    }
                }
            }

            if (serverHandles == null)
            {
                return;
            }

            client.ReleaseItemHandles(serverHandles.ToArray());
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ComHdaBrowserClient"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="itemId">The qualified area name.</param>
 public ComHdaBrowserClient(
     ComHdaClient client,
     string itemId)
 {
     m_client = client;
     m_itemId = itemId;
 }
        /// <summary>
        /// Initializes the object with the containing subscription object.
        /// </summary>
        public ComHdaDataCallback(ComHdaClient server)
        {
            // save group.
            m_server = server;

            // create connection point.
            m_connectionPoint = new ConnectionPoint(server.Unknown, typeof(OpcRcw.Hda.IOPCHDA_DataCallback).GUID);

            // advise.
            m_connectionPoint.Advise(this);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Assigns the handles to the requests.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="requests">The requests.</param>
        private void AssignHandles(ComHdaClient client, Dictionary <string, HdaSubscribeAttributeRequest> requests)
        {
            List <string> itemIds = null;

            lock (m_lock)
            {
                foreach (KeyValuePair <string, HdaSubscribeAttributeRequest> entry in requests)
                {
                    if (entry.Value.ServerHandle == null)
                    {
                        if (itemIds == null)
                        {
                            itemIds = new List <string>();
                        }

                        itemIds.Add(entry.Key);
                    }
                }
            }

            if (itemIds == null)
            {
                return;
            }

            HdaItem[] items = client.GetItems(itemIds.ToArray());

            lock (m_lock)
            {
                for (int ii = 0; ii < items.Length; ii++)
                {
                    HdaSubscribeAttributeRequest request = null;

                    if (!requests.TryGetValue(itemIds[ii], out request))
                    {
                        continue;
                    }

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

                    request.ServerHandle = items[ii].ServerHandle;
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Updates the status node.
        /// </summary>
        protected override bool UpdateStatus()
        {
            // get the status from the server.
            ComHdaClient client = DefaultClient;

            ComHdaClient.ServerStatus?status = client.GetStatus();

            // check the client has been abandoned.
            if (!Object.ReferenceEquals(client, DefaultClient))
            {
                return(false);
            }

            // update the server status.
            lock (StatusNodeLock)
            {
                StatusNode.ServerUrl.Value = Configuration.ServerUrl;

                if (status != null)
                {
                    StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.Good, DateTime.UtcNow);

                    if (String.IsNullOrEmpty(status.Value.szStatusString))
                    {
                        StatusNode.ServerState.Value = Utils.Format("{0}", status.Value.wStatus);
                    }
                    else
                    {
                        StatusNode.ServerState.Value = Utils.Format("{0} '{1}'", status.Value.wStatus, status.Value.szStatusString);
                    }

                    StatusNode.CurrentTime.Value     = status.Value.ftCurrentTime;
                    StatusNode.LastUpdateTime.Value  = DateTime.MinValue;
                    StatusNode.StartTime.Value       = status.Value.ftStartTime;
                    StatusNode.VendorInfo.Value      = status.Value.szVendorInfo;
                    StatusNode.SoftwareVersion.Value = Utils.Format("{0}.{1}.{2}", status.Value.wMajorVersion, status.Value.wMinorVersion, status.Value.wBuildNumber);
                }
                else
                {
                    StatusNode.SetStatusCode(DefaultSystemContext, StatusCodes.BadOutOfService, DateTime.UtcNow);
                }

                StatusNode.ClearChangeMasks(DefaultSystemContext, true);
                return(status != null);
            }
        }
        /// <summary>
        /// Finds the children for hda item configuration.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="children">The children.</param>
        /// <param name="attributes">The attribute values.</param>
        private void FindChildrenForHdaItemConfiguration(ComHdaClient client, List <BaseInstanceState> children, HdaAttributeValue[] attributes)
        {
            BaseInstanceState child = null;

            if (IsRequired(ReferenceTypeIds.HasProperty, false))
            {
                for (int ii = 0; ii < attributes.Length; ii++)
                {
                    if (attributes[ii].Error < 0 || attributes[ii].Error == ResultIds.S_NODATA)
                    {
                        continue;
                    }

                    bool skip = true;

                    switch (attributes[ii].AttributeId)
                    {
                    case Constants.OPCHDA_DERIVE_EQUATION:
                    case Constants.OPCHDA_STEPPED:
                    case Constants.OPCHDA_MAX_TIME_INT:
                    case Constants.OPCHDA_MIN_TIME_INT:
                    case Constants.OPCHDA_EXCEPTION_DEV:
                    case Constants.OPCHDA_EXCEPTION_DEV_TYPE:
                    {
                        skip = false;
                        break;
                    }
                    }

                    if (skip)
                    {
                        continue;
                    }

                    child = client.FindItemAttribute(m_itemId, attributes[ii].AttributeId, m_namespaceIndex);

                    if (child != null)
                    {
                        children.Add(child);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Called when the scan attributes timer expires.
        /// </summary>
        private void DoScan(Dictionary <string, HdaSubscribeAttributeRequest> requests, bool initialUpdate)
        {
            try
            {
                ComHdaClientManager system = (ComHdaClientManager)m_context.SystemHandle;
                ComHdaClient        client = (ComHdaClient)system.SelectClient(m_context, false);

                // ensure all requests have valid handles.
                AssignHandles(client, requests);

                // collect the list of attributes that need reading.
                HdaReadRequestCollection            itemsToRead        = new HdaReadRequestCollection();
                List <HdaSubscribeAttributeRequest> subscribeRequests  = new List <HdaSubscribeAttributeRequest>();
                List <HdaReadRequest> readRequestsForSubscribeRequests = new List <HdaReadRequest>();

                lock (m_lock)
                {
                    DateTime now = DateTime.UtcNow;

                    foreach (KeyValuePair <string, HdaSubscribeAttributeRequest> entry in requests)
                    {
                        // check if it is time for an update.
                        if (!initialUpdate && entry.Value.NextUpdateTime > now)
                        {
                            continue;
                        }

                        // create a read request for each monitored item.
                        bool somethingToDo = false;

                        for (int ii = 0; ii < entry.Value.MonitoredItems.Count; ii++)
                        {
                            MonitoredItem monitoredItem = entry.Value.MonitoredItems[ii];

                            NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle;

                            if (handle == null)
                            {
                                continue;
                            }

                            // check if item is not valid.
                            if (entry.Value.ServerHandle == null)
                            {
                                monitoredItem.QueueValue(null, StatusCodes.BadNodeIdUnknown);
                                continue;
                            }

                            ReadValueId valueToRead = monitoredItem.GetReadValueId();

                            bool       queued = false;
                            StatusCode error  = itemsToRead.Add(handle.Node, valueToRead, out queued);

                            if (StatusCode.IsBad(error))
                            {
                                monitoredItem.QueueValue(null, error);
                                continue;
                            }

                            if (!somethingToDo && queued)
                            {
                                // add server handle to read request.
                                HdaReadRequest request = (HdaReadRequest)valueToRead.Handle;
                                request.ServerHandle = entry.Value.ServerHandle.Value;

                                // save mapping between subscribe request and read requests.
                                subscribeRequests.Add(entry.Value);
                                readRequestsForSubscribeRequests.Add(request);
                                somethingToDo = true;
                            }
                        }
                    }

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

                // read the attributes from the server.
                client.Read(itemsToRead, true);

                // update the monitored items.
                lock (m_lock)
                {
                    for (int ii = 0; ii < subscribeRequests.Count; ii++)
                    {
                        subscribeRequests[ii].QueueValues(m_context, readRequestsForSubscribeRequests[ii], initialUpdate);
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error scanning attributes in HDA COM server.");
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Applies any changes to the subscriptions.
        /// </summary>
        private void ApplyChanges(Dictionary <string, HdaSubscribeAttributeRequest> requests, bool initialUpdateRequired)
        {
            List <HdaSubscribeAttributeRequest> requestsToRemove = null;

            lock (m_lock)
            {
                // update existing requests.
                foreach (KeyValuePair <string, HdaSubscribeAttributeRequest> entry in requests)
                {
                    HdaSubscribeAttributeRequest request = entry.Value;

                    // remove unused requests.
                    if (request.MonitoredItems == null || request.MonitoredItems.Count == 0)
                    {
                        if (requestsToRemove == null)
                        {
                            requestsToRemove = new List <HdaSubscribeAttributeRequest>();
                        }

                        requestsToRemove.Add(entry.Value);
                        continue;
                    }

                    request.ChangesComplete(m_configuration.AttributeSamplingInterval);
                }

                // remove deleted requests from dictionary.
                if (requestsToRemove != null)
                {
                    for (int ii = 0; ii < requestsToRemove.Count; ii++)
                    {
                        m_requests.Remove(requestsToRemove[ii].ItemId);
                    }
                }

                // check if the attribute scanner needs to be stopped/started.
                if (m_attributeScanTimer == null)
                {
                    if (m_requests.Count > 0)
                    {
                        m_attributeScanTimer = new Timer(OnScanAttributes, null, m_configuration.AttributeSamplingInterval, m_configuration.AttributeSamplingInterval);
                    }
                }
                else
                {
                    if (m_requests.Count == 0)
                    {
                        m_attributeScanTimer.Dispose();
                        m_attributeScanTimer = null;
                    }
                }
            }

            // release any unused handles.
            if (requestsToRemove != null)
            {
                ComHdaClientManager system = (ComHdaClientManager)m_context.SystemHandle;
                ComHdaClient        client = (ComHdaClient)system.SelectClient(m_context, false);
                ReleaseHandles(client, requestsToRemove);
            }

            // send initial update.
            if (initialUpdateRequired)
            {
                DoScan(requests, true);
            }
        }
        /// <summary>
        /// Initializes the next stage of browsing.
        /// </summary>
        private void NextStage()
        {
            ComHdaClientManager system = (ComHdaClientManager)this.SystemContext.SystemHandle;
            ComHdaClient        client = (ComHdaClient)system.SelectClient((ServerSystemContext)SystemContext, false);

            // determine which stage is next based on the reference types requested.
            for (Stage next = m_stage + 1; next <= Stage.Done; next++)
            {
                if (next == Stage.Browse)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Children)
                {
                    if (IsRequired(ReferenceTypeIds.HasProperty, false) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Parents)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, true) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, true))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Done)
                {
                    m_stage = next;
                    break;
                }
            }

            // start enumerating areas.
            if (m_stage == Stage.Browse)
            {
                m_browser = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    m_browser = new ComHdaBrowserClient(client, m_itemId);
                }

                return;
            }

            // start enumerating attributes.
            if (m_stage == Stage.Children)
            {
                m_position = 0;
                m_children = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    return;
                }

                List <BaseInstanceState> children = new List <BaseInstanceState>();

                // check if browsing aggregate functions.
                if (m_sourceBrowseName == Opc.Ua.BrowseNames.AggregateFunctions)
                {
                    if (IsRequired(ReferenceTypeIds.HasComponent, false))
                    {
                        BaseObjectState[] aggregates = client.GetSupportedAggregates(m_namespaceIndex);

                        if (aggregates != null)
                        {
                            children.AddRange(aggregates);
                        }

                        m_children = children.ToArray();
                    }

                    return;
                }

                // must be browsing children of an item.
                HdaItem[] items = client.GetItems(m_itemId);

                if (items[0].Error < 0)
                {
                    return;
                }

                try
                {
                    HdaAttributeValue[] attributes = client.ReadAvailableAttributes(items[0]);

                    if (m_sourceTypeDefinitionId == Opc.Ua.VariableTypeIds.DataItemType)
                    {
                        FindChildrenForHdaItem(client, children, attributes);
                    }

                    if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.HistoricalDataConfigurationType)
                    {
                        FindChildrenForHdaItemConfiguration(client, children, attributes);
                    }
                }
                finally
                {
                    client.ReleaseItemHandles(items);
                }

                m_children = children.ToArray();
                return;
            }

            // start enumerating parents.
            if (m_stage == Stage.Parents)
            {
                return;
            }

            // all done.
        }