/// <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);
        }
Exemple #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DaItemState"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        public DaItemState(
            ISystemContext context, 
            DaElement element, 
            ushort namespaceIndex) 
        : 
            base(null)
        {
            this.TypeDefinitionId = Opc.Ua.VariableTypeIds.DataItemType;
            this.Description = null;
            this.WriteMask = 0;
            this.UserWriteMask = 0;

            if (element != null)
            {
                Initialize(context, element, namespaceIndex);               
            }
        }
        /// <summary>
        /// Constructs a branch or item node from a DaElement returned from the COM server.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="namespaceIndex">Index of the namespace for the NodeId.</param>
        /// <returns>The node.</returns>
        public static NodeState ConstructElement(ISystemContext context, DaElement element, ushort namespaceIndex)
        {
            if (element.ElementType == DaElementType.Branch)
            {
                return new DaBranchState(context, element, namespaceIndex);
            }

            return new DaItemState(context, element, namespaceIndex);
        }
        /// <summary>
        /// Does any initialization required before the address space can be used.
        /// </summary>
        /// <remarks>
        /// The externalReferences is an out parameter that allows the node manager to link to nodes
        /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
        /// should have a reference to the root folder node(s) exposed by this node manager.  
        /// </remarks>
        public override void CreateAddressSpace(IDictionary<NodeId, IList<IReference>> externalReferences)
        {
            lock (Lock)
            {
                // check if the type model needs to be loaded.
                if (NamespaceIndexes.Length > 1)
                {
                    LoadPredefinedNodes(SystemContext, externalReferences);
                }

                // create the root node.
                string serverName = m_configuration.ServerName;

                if (String.IsNullOrEmpty(serverName))
                {
                    serverName = "ComDaServer";
                }

                DaElement element = new DaElement();
                element.ItemId = String.Empty;
                element.Name = serverName;
                element.ElementType = DaElementType.Branch;

                DaBranchState root = new DaBranchState(SystemContext, element, NamespaceIndex);
                root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);

                // link root to objects folder.
                IList<IReference> references = null;

                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List<IReference>();
                }

                references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId));

                // create the status node.
                ComServerStatusState status = new ComServerStatusState(root);
                status.ReferenceTypeId = ReferenceTypeIds.Organizes;

                // get the type namepace for the browse name.
                int typeNamepaceIndex = Server.NamespaceUris.GetIndex(Namespaces.ComInterop);

                if (typeNamepaceIndex < 0)
                {
                    typeNamepaceIndex = NamespaceIndex;
                }

                status.Create(
                    SystemContext,
                    DaModelUtils.ConstructIdForInternalNode("ServerStatus", NamespaceIndex),
                    new QualifiedName("ServerStatus", (ushort)typeNamepaceIndex),
                    null,
                    true);

                root.AddChild(status);

                // store root folder in the pre-defined nodes.
                AddPredefinedNode(SystemContext, root);

                // create the COM server.
                m_system.Initialize(SystemContext, m_configuration, status, Lock, OnServerReconnected);
                StartMetadataUpdates(null, null, 5000, m_configuration.MaxReconnectWait);
            }
        }
Exemple #5
0
        /// <summary>
        /// Updates a element.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="name">The name.</param>
        /// <param name="parentId">The parent id.</param>
        private void UpdateElement(DaElement element, string name, string parentId)
        {      
            // only update the name if specified.         
            if (name != null)
            {
                element.Name = name;
            }

            // same for the parent id.
            if (parentId != null)
            {
                element.ParentId = parentId;
            }

            // read item property values.
            DaValue[] values = ReadPropertyValues(element.ItemId, m_CoreProperties);

            // must be an item if the data type property exists.
            if (values[0].Error >= 0)
            {
                element.ElementType = DaElementType.Item;
                element.DataType = values[0].GetValue<short>();
                element.AccessRights = values[1].GetValue<int>();
                element.ScanRate = values[2].GetValue<float>();
                element.Description = values[3].GetValue<string>();
                element.EngineeringUnits = values[4].GetValue<string>();
                element.EuInfo = values[5].GetValue<string[]>();
                element.EuType = values[6].GetValue<int>();
                element.HighEU = values[7].GetValue<double>();
                element.LowEU = values[8].GetValue<double>();
                element.OpenLabel = values[9].GetValue<string>();
                element.CloseLabel = values[10].GetValue<string>();
                element.HighIR = values[11].GetValue<double>();
                element.LowIR = values[12].GetValue<double>();

                // check if the time zone is specified.
                if (values[13].Error >= 0)
                {
                    element.TimeZone = values[13].GetValue<int>();
                }

                // check for analog item (checks for HighEU if EuType property not supported).
                if ((values[7].Error < 0 && values[7].Error >= 0) || element.EuType == (int)OPCEUTYPE.OPC_ANALOG)
                {
                    element.ElementType = DaElementType.AnalogItem;
                }

                // check for enumerated item.
                else if (element.EuType == (int)OPCEUTYPE.OPC_ENUMERATED)
                {
                    element.ElementType = DaElementType.EnumeratedItem;
                }

                // check for digital item (checks for CloseLabel property).
                else if (values[10].Error >= 0)
                {
                    element.ElementType = DaElementType.DigitalItem;
                }
            }

            // the element must be a branch. 
            else
            {
                element.ElementType = DaElementType.Branch;

                // branches could have description property.
                element.Description = values[3].GetValue<string>();
            }
        }
Exemple #6
0
 /// <summary>
 /// Creates a new element.
 /// </summary>
 /// <param name="itemId">The item id.</param>
 /// <param name="name">The name.</param>
 /// <param name="parentId">The parent id.</param>
 /// <returns>The element.</returns>
 private DaElement CreateElement(string itemId, string name, string parentId)
 {
     DaElement element = new DaElement();
     element.ItemId = itemId;            
     UpdateElement(element, name, parentId);
     return element;
 }
Exemple #7
0
 /// <summary>
 /// Saves the element in cache.
 /// </summary>
 /// <param name="element">The element.</param>
 private void SaveElementInCache(DaElement element)
 {
     lock (m_cache)
     {
         m_cache[element.ItemId] = element;
     }
 }
Exemple #8
0
        /// <summary>
        /// Initializes the node from the element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        public void Initialize(ISystemContext context, DaElement element, ushort namespaceIndex)
        {
            m_element = element;

            if (element == null)
            {
                return;
            }

            this.NodeId = DaModelUtils.ConstructIdForDaElement(element.ItemId, -1, namespaceIndex);
            this.BrowseName = new QualifiedName(element.Name, namespaceIndex);
            this.DisplayName = new LocalizedText(element.Name);

            // check if TimeZone is supported.
            if (element.TimeZone != null)
            {
                PropertyState property = this.AddProperty<Range>(Opc.Ua.BrowseNames.LocalTime, DataTypeIds.TimeZoneDataType, ValueRanks.Scalar);
                property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
                property.Value = new Range(element.HighIR, element.LowIR);
            }

            // set the TypeDefinition based on the ElementType.
            switch (element.ElementType)
            {
                case DaElementType.AnalogItem:
                {
                    this.TypeDefinitionId = Opc.Ua.VariableTypeIds.AnalogItemType;

                    // EURange is always present.
                    PropertyState property = this.AddProperty<Range>(Opc.Ua.BrowseNames.EURange, DataTypeIds.Range, ValueRanks.Scalar);
                    property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex); 
                    property.Value = new Range(element.HighEU, element.LowEU);

                    // check if InstrumentRange is supported.
                    if (element.HighIR != 0 || element.LowIR != 0)
                    {
                        property = this.AddProperty<Range>(Opc.Ua.BrowseNames.InstrumentRange, DataTypeIds.Range, ValueRanks.Scalar);
                        property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex);
                        property.Value = new Range(element.HighIR, element.LowIR);
                    }

                    // check if EngineeringUnits is supported.
                    if (element.EngineeringUnits != null)
                    {
                        property = this.AddProperty<EUInformation>(Opc.Ua.BrowseNames.EngineeringUnits, DataTypeIds.EUInformation, ValueRanks.Scalar);
                        property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex); 

                        // use the server's namespace uri to qualify the engineering units.
                        string namespaceUri = context.NamespaceUris.GetString(namespaceIndex);
                        property.Value = new EUInformation(element.EngineeringUnits, namespaceUri);
                    }

                    break;
                }

                case DaElementType.DigitalItem:
                {
                    this.TypeDefinitionId = Opc.Ua.VariableTypeIds.TwoStateDiscreteType;

                    // check if CloseLabel is supported.
                    if (element.CloseLabel != null)
                    {
                        PropertyState property = this.AddProperty<LocalizedText>(Opc.Ua.BrowseNames.TrueState, DataTypeIds.LocalizedText, ValueRanks.Scalar);
                        property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex); 
                        property.Value = element.CloseLabel;
                    }

                    // check if OpenLabel is supported.
                    if (element.OpenLabel != null)
                    {
                        PropertyState property = this.AddProperty<LocalizedText>(Opc.Ua.BrowseNames.FalseState, DataTypeIds.LocalizedText, ValueRanks.Scalar);
                        property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex); 
                        property.Value = element.OpenLabel;
                    }

                    break;
                }

                case DaElementType.EnumeratedItem:
                {
                    this.TypeDefinitionId = Opc.Ua.VariableTypeIds.MultiStateDiscreteType;

                    // check if EuInfo is supported.
                    if (element.EuInfo != null)
                    {
                        PropertyState property = this.AddProperty<LocalizedText[]>(Opc.Ua.BrowseNames.EnumStrings, DataTypeIds.LocalizedText, ValueRanks.OneDimension);
                        property.NodeId = DaModelUtils.ConstructIdForComponent(property, namespaceIndex); 

                        LocalizedText[] strings = new LocalizedText[element.EuInfo.Length];

                        for (int ii = 0; ii < strings.Length; ii++)
                        {
                            strings[ii] = element.EuInfo[ii];
                        }

                        property.Value = strings;
                    }

                    break;
                }
            }

            if (element.Description != null)
            {
                this.Description = element.Description;
            }

            this.Value = null;
            this.StatusCode = StatusCodes.BadWaitingForInitialData;
            this.Timestamp = DateTime.UtcNow;

            bool isArray = false;
            this.DataType = ComUtils.GetDataTypeId(element.DataType, out isArray);
            this.ValueRank = (isArray)?ValueRanks.OneOrMoreDimensions:ValueRanks.Scalar;

            this.AccessLevel = AccessLevels.None;

            if ((element.AccessRights & OpcRcw.Da.Constants.OPC_READABLE) != 0)
            {
                this.AccessLevel |= AccessLevels.CurrentRead;
            }

            if ((element.AccessRights & OpcRcw.Da.Constants.OPC_WRITEABLE) != 0)
            {
                this.AccessLevel |= AccessLevels.CurrentWrite;
            }

            this.UserAccessLevel = this.AccessLevel;
            this.MinimumSamplingInterval = element.ScanRate;
        }