Exemplo n.º 1
0
        /// <summary>
        /// Validates the nodes and writes the value to the underlying system.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="nodesToWrite">The nodes to write.</param>
        /// <param name="errors">The errors.</param>
        /// <param name="nodesToValidate">The nodes to validate.</param>
        /// <param name="cache">The cache.</param>
        protected override void Write(
            ServerSystemContext context,
            IList <WriteValue> nodesToWrite,
            IList <ServiceResult> errors,
            List <NodeHandle> nodesToValidate,
            IDictionary <NodeId, NodeState> cache)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient((ServerSystemContext)SystemContext, false);

            WriteRequestCollection requests = new WriteRequestCollection();

            // validates the nodes and queues an write requests.
            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                NodeHandle handle = nodesToValidate[ii];

                lock (Lock)
                {
                    // validate node.
                    NodeState source = ValidateNode(context, handle, cache);

                    if (source == null)
                    {
                        continue;
                    }

                    // determine if request can be sent to the server.
                    bool       queued      = false;
                    WriteValue nodeToWrite = nodesToWrite[handle.Index];
                    errors[handle.Index] = requests.Add(source, nodeToWrite, handle.Index, out queued);

                    if (queued)
                    {
                        continue;
                    }

                    // write the attribute value.
                    errors[handle.Index] = source.WriteAttribute(
                        context,
                        nodeToWrite.AttributeId,
                        nodeToWrite.ParsedIndexRange,
                        nodeToWrite.Value);

                    // updates to source finished - report changes to monitored items.
                    source.ClearChangeMasks(context, false);
                }
            }

            // write to the server.
            client.Write(requests);

            // get the results from the requests sent to the server.
            for (int ii = 0; ii < requests.Count; ii++)
            {
                WriteRequest request = requests[ii];
                errors[request.Index] = request.GetResult();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates an empty group.
        /// </summary>
        /// <param name="server">The server that the group belongs to.</param>
        /// <param name="callbacksRequired">if set to <c>true</c> if the group will received callbacks.</param>
        public ComDaGroup(ComDaClient server, bool callbacksRequired)
        {
            m_server       = server;
            m_clientHandle = Utils.IncrementIdentifier(ref m_groupCounter);
            m_serverHandle = 0;
            m_items        = new List <GroupItem>();

            if (callbacksRequired)
            {
                m_monitoredItems = new Dictionary <int, DataChangeInfo>();
            }

            // Utils.Trace("GROUP {0}", m_clientHandle);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Handles a method call.
        /// </summary>
        private ServiceResult DoGenerateRandomValues(
            ISystemContext context,
            MethodState method,
            IList <object> inputArguments,
            IList <object> outputArguments)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient((ServerSystemContext)context, false);

            Opc.Ua.Test.DataGenerator generator = new Opc.Ua.Test.DataGenerator(null);

            IDaElementBrowser browser = client.CreateBrowser((string)method.Handle);

            // create write requests.
            WriteRequestCollection requests = new WriteRequestCollection();

            try
            {
                for (DaElement element = browser.Next(); element != null; element = browser.Next())
                {
                    if (element.ElementType == DaElementType.Branch)
                    {
                        continue;
                    }

                    // generate a random value of the correct data tyoe.
                    bool   isArray    = false;
                    NodeId dataTypeId = ComUtils.GetDataTypeId(element.DataType, out isArray);

                    object value = generator.GetRandom(
                        dataTypeId,
                        (isArray)?ValueRanks.OneDimension:ValueRanks.Scalar,
                        null,
                        context.TypeTable);

                    // create a request.
                    requests.Add(new Opc.Ua.Com.Client.WriteRequest(element.ItemId, new DataValue(new Variant(value)), 0));
                }
            }
            finally
            {
                browser.Dispose();
            }

            // write values.
            client.Write(requests);

            return(ServiceResult.Good);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Called when a batch of monitored items has been created.
        /// </summary>
        protected override void OnCreateMonitoredItemsComplete(ServerSystemContext context, IList <IMonitoredItem> monitoredItems)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient(context, false);

            // use locale for session to find a subscription manager.
            SubscribeRequestManager manager = null;

            if (!m_subscriptionManagers.TryGetValue(client.Key, out manager))
            {
                m_subscriptionManagers[client.Key] = manager = new SubscribeRequestManager(context, client, 1000);
            }

            manager.CreateItems(context, monitoredItems);

            for (int ii = 0; ii < monitoredItems.Count; ii++)
            {
                m_monitoredItems[monitoredItems[ii].Id] = manager;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Called when a batch of monitored items has been deleted.
        /// </summary>
        protected override void OnDeleteMonitoredItemsComplete(ServerSystemContext context, IList <IMonitoredItem> monitoredItems)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient(context, false);

            // sort monitored items by the locale id used to create them.
            Dictionary <string, List <IMonitoredItem> > monitoredItemsByLocaleId = new Dictionary <string, List <IMonitoredItem> >();

            for (int ii = 0; ii < monitoredItems.Count; ii++)
            {
                // look up the manager that was previously used to create the monitor item.
                SubscribeRequestManager manager = null;

                if (!m_monitoredItems.TryGetValue(monitoredItems[ii].Id, out manager))
                {
                    manager = m_subscriptionManagers[client.Key];
                }

                // add monitored item to a list of items for the locale of the manager.
                List <IMonitoredItem> subset = null;

                if (!monitoredItemsByLocaleId.TryGetValue(manager.Key, out subset))
                {
                    monitoredItemsByLocaleId[manager.Key] = subset = new List <IMonitoredItem>();
                }

                subset.Add(monitoredItems[ii]);
            }

            // delete the items.
            foreach (KeyValuePair <string, List <IMonitoredItem> > entry in monitoredItemsByLocaleId)
            {
                SubscribeRequestManager manager = null;

                if (m_subscriptionManagers.TryGetValue(entry.Key, out manager))
                {
                    manager.DeleteItems(context, entry.Value);
                }
            }
        }
        /// <summary>
        /// Updates the status node.
        /// </summary>
        protected override bool UpdateStatus()
        {
            // get the status from the server.
            ComDaClient     client = DefaultClient;
            OPCSERVERSTATUS?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);

                    StatusNode.ServerState.Value     = Utils.Format("{0}", status.Value.dwServerState);
                    StatusNode.CurrentTime.Value     = ComUtils.GetDateTime(status.Value.ftCurrentTime);
                    StatusNode.LastUpdateTime.Value  = ComUtils.GetDateTime(status.Value.ftLastUpdateTime);
                    StatusNode.StartTime.Value       = ComUtils.GetDateTime(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);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Validates the nodes and reads the values from the underlying source.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="nodesToRead">The nodes to read.</param>
        /// <param name="values">The values.</param>
        /// <param name="errors">The errors.</param>
        /// <param name="nodesToValidate">The nodes to validate.</param>
        /// <param name="cache">The cache.</param>
        protected override void Read(
            ServerSystemContext context,
            IList <ReadValueId> nodesToRead,
            IList <DataValue> values,
            IList <ServiceResult> errors,
            List <NodeHandle> nodesToValidate,
            IDictionary <NodeId, NodeState> cache)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient((ServerSystemContext)SystemContext, false);

            ReadRequestCollection requests = new ReadRequestCollection();

            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                NodeHandle handle = nodesToValidate[ii];

                lock (Lock)
                {
                    NodeState source = ValidateNode(context, handle, cache);

                    if (source == null)
                    {
                        continue;
                    }

                    DataValue   value      = values[handle.Index];
                    ReadValueId nodeToRead = nodesToRead[handle.Index];

                    // determine if request can be sent to the server.
                    bool queued = false;
                    errors[handle.Index] = requests.Add(source, nodeToRead, value, out queued);

                    if (queued)
                    {
                        continue;
                    }

                    // read built-in metadata.
                    errors[handle.Index] = source.ReadAttribute(
                        context,
                        nodeToRead.AttributeId,
                        nodeToRead.ParsedIndexRange,
                        nodeToRead.DataEncoding,
                        value);
                }
            }

            // read the values from the server.
            client.Read(requests);

            // extract the values from the results.
            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                NodeHandle  handle     = nodesToValidate[ii];
                DataValue   value      = values[handle.Index];
                ReadValueId nodeToRead = nodesToRead[handle.Index];

                lock (Lock)
                {
                    if (!requests.HasResult(nodeToRead))
                    {
                        continue;
                    }

                    errors[handle.Index] = requests.GetResult(context, handle.Node, nodeToRead, value, context.DiagnosticsMask);
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Verifies that the specified node exists.
        /// </summary>
        protected override NodeState ValidateNode(
            ServerSystemContext context,
            NodeHandle handle,
            IDictionary <NodeId, NodeState> cache)
        {
            // not valid if no root.
            if (handle == null)
            {
                return(null);
            }

            // check if previously validated.
            if (handle.Validated)
            {
                return(handle.Node);
            }

            NodeState target = null;

            // check if already in the cache.
            if (cache != null)
            {
                if (cache.TryGetValue(handle.NodeId, out target))
                {
                    // nulls mean a NodeId which was previously found to be invalid has been referenced again.
                    if (target == null)
                    {
                        return(null);
                    }

                    handle.Node      = target;
                    handle.Validated = true;
                    return(handle.Node);
                }

                target = null;
            }

            try
            {
                // check if the node id has been parsed.
                DaParsedNodeId parsedNodeId = handle.ParsedNodeId as DaParsedNodeId;

                if (parsedNodeId == null)
                {
                    return(null);
                }

                NodeState   root    = null;
                DaElement   element = null;
                ComDaClient client  = m_system.SelectClient(context, false);

                // validate a branch or item.
                if (parsedNodeId.RootType == DaModelUtils.DaElement)
                {
                    element = client.FindElement(parsedNodeId.RootId);

                    // branch does not exist.
                    if (element == null)
                    {
                        return(null);
                    }

                    // create a temporary object to use for the operation.
                    root        = DaModelUtils.ConstructElement(context, element, NamespaceIndex);
                    root.Handle = element;

                    AddAdditionalElementReferences(SystemContext, root);
                }

                // validate an property.
                else if (parsedNodeId.RootType == DaModelUtils.DaProperty)
                {
                    element = client.FindElement(parsedNodeId.RootId);

                    // branch does not exist.
                    if (element == null)
                    {
                        return(null);
                    }

                    // validate the property.
                    DaProperty property = client.FindProperty(parsedNodeId.RootId, parsedNodeId.PropertyId);

                    // property does not exist.
                    if (property == null)
                    {
                        return(null);
                    }

                    // create a temporary object to use for the operation.
                    root        = DaModelUtils.ConstructProperty(context, element.ItemId, property, NamespaceIndex);
                    root.Handle = property;

                    AddAdditionalElementReferences(SystemContext, root);
                }

                // unknown root type.
                else
                {
                    return(null);
                }

                // all done if no components to validate.
                if (String.IsNullOrEmpty(parsedNodeId.ComponentPath))
                {
                    handle.Validated = true;
                    handle.Node      = target = root;
                    return(handle.Node);
                }

                // validate component.
                NodeState component = root.FindChildBySymbolicName(context, parsedNodeId.ComponentPath);

                // component does not exist.
                if (component == null)
                {
                    return(null);
                }

                // found a valid component.
                handle.Validated = true;
                handle.Node      = target = component;
                return(handle.Node);
            }
            finally
            {
                // store the node in the cache to optimize subsequent lookups.
                if (cache != null)
                {
                    cache.Add(handle.NodeId, target);
                }
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Da20ElementBrowser"/> class.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="itemId">The item id.</param>
 public Da20ElementBrowser(
     ComDaClient client, 
     string itemId)
 {
     m_client = client;
     m_itemId = itemId;
     m_branches = false;
 }
Exemplo n.º 10
0
        /// <summary>
        /// Applies any changes to the groups.
        /// </summary>
        public void ApplyGroupChanges(ComDaClient client)
        {
            List<ComDaGroup> groups = null;
            List<SubscribeItemRequest> items = null;

            lock (m_lock)
            {
                items = new List<SubscribeItemRequest>(m_subscribedItems.Values);

                // modify or remove items.
                for (int ii = 0; ii < items.Count; ii++)
                {
                    SubscribeItemRequest request = items[ii];

                    // remove unused requests.
                    if (request.MonitoredItems.Count == 0)
                    {
                        if (request.Group != null && request.GroupItem != null)
                        {
                            request.Group.RemoveItem(request.GroupItem);
                        }

                        Remove(request);
                        continue;
                    }
                }

                // add any new items to groups.
                for (int ii = 0; ii < items.Count; ii++)
                {
                    SubscribeItemRequest request = items[ii];

                    if (!request.Changed)
                    {
                        continue;
                    }

                    UpdateGroup(client, request);
                }

                groups = new List<ComDaGroup>(m_groups.Count);

                // update group on the server.
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    if (m_groups[ii].ApplyChanges())
                    {
                        groups.Add(m_groups[ii]);
                    }
                    else
                    {
                        m_groups[ii].Delete();
                    }
                }

                m_groups = groups;

                // update request.
                for (int ii = 0; ii < items.Count; ii++)
                {
                    if (items[ii].Changed)
                    {
                        items[ii].ChangesComplete();
                    }
                }

                // modify or remove items.
                List<SubscribePropertyRequest> properties = new List<SubscribePropertyRequest>(m_subscribedProperties.Values);

                for (int ii = 0; ii < properties.Count; ii++)
                {
                    SubscribePropertyRequest request = properties[ii];

                    // remove unused requests.
                    if (request.MonitoredItems == null || request.MonitoredItems.Count == 0)
                    {
                        Remove(request);
                        continue;
                    }

                    request.ChangesComplete(m_propertySamplingInterval);
                }
                
                // check if the property scanner needs to be stopped/started.
                if (m_propertyScanTimer == null)
                {
                    if (m_subscribedProperties.Count > 0)
                    {
                        m_propertyScanTimer = new Timer(OnScanProperties, null, 0, m_propertySamplingInterval);
                    }
                }
                else
                {
                    if (m_subscribedProperties.Count == 0)
                    {
                        m_propertyScanTimer.Dispose();
                        m_propertyScanTimer = null;
                    }
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Assigns a request to a group.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="request">The request.</param>
        public void UpdateGroup(ComDaClient client, SubscribeItemRequest request)
        {
            lock (m_lock)
            {
                // check for empty request.
                if (request.MonitoredItems.Count == 0)
                {
                    return;
                }

                request.Update();

                // check if existing group can be used.
                if (request.Group != null)
                {
                    if (request.Group.ModifyItem(request.GroupItem, request.SamplingInterval, request.Deadband, request.Active))
                    {
                        if (request.GroupItem.Active != request.Active)
                        {
                            request.GroupItem.Active = request.Active;
                            request.GroupItem.ActiveChanged = true;
                        }

                        request.Group.SetMonitoredItems(request.GroupItem, request.MonitoredItems.ToArray());
                        return;
                    }
                }

                // clear link to existing group.
                request.Group = null;
                request.GroupItem = null;
                
                // assign to an existing group.
                for (int ii = 0; ii < m_groups.Count; ii++)
                {
                    ComDaGroup group = m_groups[ii];

                    request.GroupItem = group.CreateItem(request.ItemId, request.SamplingInterval, request.Deadband, request.Active);

                    if (request.GroupItem != null)
                    {
                        request.Group = group;
                        request.Group.SetMonitoredItems(request.GroupItem, request.MonitoredItems.ToArray());
                        return; 
                    }
                }

                // create a new group.
                request.Group = new ComDaGroup(client, true);
                request.GroupItem = request.Group.CreateItem(request.ItemId, request.SamplingInterval, request.Deadband, request.Active);
                request.Group.SetMonitoredItems(request.GroupItem, request.MonitoredItems.ToArray());
                m_groups.Add(request.Group);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Initializes the next stage of browsing.
        /// </summary>
        private void NextStage()
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = 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.Children)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

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

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

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

            m_position = 0;

            // start enumerating branches.
            if (m_stage == Stage.Children)
            {
                m_browser = client.CreateBrowser(m_itemId);
                return;
            }

            // start enumerating properties.
            if (m_stage == Stage.Properties)
            {
                m_properties = client.ReadAvailableProperties(m_itemId, true);
                m_position   = 0;
                return;
            }

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

            // all done.
        }
Exemplo n.º 13
0
        /// <summary>
        /// Returns the next child.
        /// </summary>
        private NodeStateReference NextChild(Stage stage)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient((ServerSystemContext)SystemContext, false);

            DaElement element = null;

            if (stage == Stage.Children)
            {
                if (m_browser == null)
                {
                    return(null);
                }

                element = m_browser.Next();

                if (element == null)
                {
                    return(null);
                }

                // construct the node.
                NodeState node = DaModelUtils.ConstructElement(SystemContext, element, m_namespaceIndex);

                // return the reference.
                return(new NodeStateReference(ReferenceTypeIds.Organizes, false, node));
            }

            if (stage == Stage.Properties)
            {
                if (m_properties == null)
                {
                    return(null);
                }

                for (int ii = m_position; ii < m_properties.Length; ii++)
                {
                    if (m_properties[ii].PropertyId <= PropertyIds.TimeZone)
                    {
                        continue;
                    }

                    m_position = ii + 1;

                    // construct the node.
                    NodeState node = DaModelUtils.ConstructProperty(SystemContext, m_itemId, m_properties[ii], m_namespaceIndex);

                    // return the reference.
                    return(new NodeStateReference(ReferenceTypeIds.HasProperty, false, node));
                }

                // all done.
                return(null);
            }

            if (stage == Stage.Parents)
            {
                if (m_parentId != null)
                {
                    NodeId parentId = DaModelUtils.ConstructIdForDaElement(m_parentId, -1, m_namespaceIndex);
                    m_parentId = null;
                    return(new NodeStateReference(ReferenceTypeIds.Organizes, true, parentId));
                }
            }

            return(null);
        }