Пример #1
0
        private StatusCode DispatchControllerMethod(
            RequestContext context,
            MethodHandle methodHandle,
            IList <Variant> inputArguments,
            List <StatusCode> inputArgumentResults,
            List <Variant> outputArguments)
        {
            SystemFunction data = methodHandle.MethodData as SystemFunction;

            if (data != null)
            {
                this.currentData = "CALL " + data.Function + inputArguments[0].ToString();


                GenericEvent e = new GenericEvent(Server.FilterManager);
                e.Initialize(
                    null,
                    ObjectTypeIds.SystemEventType,
                    ParsedNodeId.Construct(0, "Jemima", DefaultNamespaceIndex),
                    "Jemima",
                    EventSeverity.Medium,
                    "A Jemima is CALL."
                    );
                //e.Set(e.ToPath(new QualifiedName("Jackey", DefaultNamespaceIndex)), currentData);
                ReportEvent(e.SourceNode, e);

                return(StatusCodes.Good);
            }

            return(StatusCodes.BadNotImplemented);
        }
Пример #2
0
        private BaseObjectState CreateFolderNode(string path)
        {
            DirectoryInfo info = new DirectoryInfo(path);

            if (!info.Exists)
            {
                return(null);
            }

            ParsedNodeId nodeId = new ParsedNodeId();

            nodeId.RootType       = 0;
            nodeId.RootId         = path;
            nodeId.NamespaceIndex = NamespaceIndex;

            FolderState node = new FolderState(null);

            node.NodeId           = nodeId.Construct();
            node.BrowseName       = new QualifiedName(info.Name, NamespaceIndex);
            node.DisplayName      = node.BrowseName.Name;
            node.TypeDefinitionId = ObjectTypeIds.FolderType;

            node.OnPopulateBrowser = OnPopulateBrowser;

            return(node);
        }
Пример #3
0
        /// <summary>
        /// Returns a unique handle for the node.
        /// </summary>
        protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache)
        {
            lock (Lock)
            {
                // quickly exclude nodes that are not in the namespace.
                if (!IsNodeIdInNamespace(nodeId))
                {
                    return(null);
                }

                // check for check for nodes that are being currently monitored.
                MonitoredNode monitoredNode = null;

                if (MonitoredNodes.TryGetValue(nodeId, out monitoredNode))
                {
                    NodeHandle handle = new NodeHandle();

                    handle.NodeId    = nodeId;
                    handle.Validated = true;
                    handle.Node      = monitoredNode.Node;

                    return(handle);
                }

                if (nodeId.IdType != IdType.String)
                {
                    NodeState node = null;

                    if (PredefinedNodes.TryGetValue(nodeId, out node))
                    {
                        NodeHandle handle = new NodeHandle();

                        handle.NodeId    = nodeId;
                        handle.Node      = node;
                        handle.Validated = true;

                        return(handle);
                    }
                }

                // parse the identifier.
                ParsedNodeId parsedNodeId = ParsedNodeId.Parse(nodeId);

                if (parsedNodeId != null)
                {
                    NodeHandle handle = new NodeHandle();

                    handle.NodeId       = nodeId;
                    handle.Validated    = false;
                    handle.Node         = null;
                    handle.ParsedNodeId = parsedNodeId;

                    return(handle);
                }

                return(null);
            }
        }
Пример #4
0
        /// <summary>
        /// Constructs a node identifier for a segment.
        /// </summary>
        /// <param name="segmentPath">The segment path.</param>
        /// <param name="namespaceIndex">Index of the namespace that qualifies the identifier.</param>
        /// <returns>The new node identifier.</returns>
        public static NodeId ConstructIdForSegment(string segmentPath, ushort namespaceIndex)
        {
            var parsedNodeId = new ParsedNodeId {
                RootId         = segmentPath,
                NamespaceIndex = namespaceIndex,
                RootType       = 0
            };

            return(parsedNodeId.Construct());
        }
Пример #5
0
        /// <summary>
        /// Constructs a NodeId for a block.
        /// </summary>
        /// <param name="blockId">The block id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns>The new NodeId.</returns>
        public static NodeId ConstructIdForBlock(string blockId, ushort namespaceIndex)
        {
            var parsedNodeId = new ParsedNodeId {
                RootId         = blockId,
                NamespaceIndex = namespaceIndex,
                RootType       = 1
            };

            return(parsedNodeId.Construct());
        }
        /// <summary>
        /// Constructs a node identifier for a folder object.
        /// </summary>
        public static NodeId ConstructId(string filePath, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId         = filePath;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType       = NodeTypes.Folder;

            return(parsedNodeId.Construct());
        }
        /// <summary>
        /// Constructs a node identifier for a item object.
        /// </summary>
        public static NodeId ConstructId(string filePath, ushort namespaceIndex)
        {
            var parsedNodeId = new ParsedNodeId {
                RootId         = filePath,
                NamespaceIndex = namespaceIndex,
                RootType       = NodeTypes.Item
            };

            return(parsedNodeId.Construct());
        }
Пример #8
0
        /// <summary>
        /// Constructs a node identifier for a area.
        /// </summary>
        /// <param name="areaPath">The area path.</param>
        /// <param name="namespaceIndex">Index of the namespace that qualifies the identifier.</param>
        /// <returns>The new node identifier.</returns>
        public static NodeId ConstructIdForArea(string areaPath, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId         = areaPath;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType       = 0;

            return(parsedNodeId.Construct());
        }
Пример #9
0
        /// <summary>
        /// Constructs a NodeId for a source.
        /// </summary>
        /// <param name="sourceId">The source id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns>The new NodeId.</returns>
        public static NodeId ConstructIdForSource(string sourceId, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId         = sourceId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType       = 1;

            return(parsedNodeId.Construct());
        }
Пример #10
0
        /// <summary>
        /// Constructs a NodeId from the BrowseName of an internal node.
        /// </summary>
        /// <param name="browseName">The browse name.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns>The node id.</returns>
        public static NodeId ConstructIdForInternalNode(QualifiedName browseName, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId = browseName.Name;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = InternalNode;

            return parsedNodeId.Construct();
        }
Пример #11
0
        /// <summary>
        /// Returns a unique handle for the node.
        /// </summary>
        protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache)
        {
            lock (Lock)
            {
                // quickly exclude nodes that are not in the namespace.
                if (!IsNodeIdInNamespace(nodeId))
                {
                    return(null);
                }

                NodeState node = null;

                // check cache (the cache is used because the same node id can appear many times in a single request).
                if (cache != null)
                {
                    if (cache.TryGetValue(nodeId, out node))
                    {
                        return(new NodeHandle(nodeId, node));
                    }
                }

                // look up predefined node.
                if (PredefinedNodes.TryGetValue(nodeId, out node))
                {
                    NodeHandle handle = new NodeHandle(nodeId, node);

                    if (cache != null)
                    {
                        cache.Add(nodeId, node);
                    }

                    return(handle);
                }


                #region Task #A5 - Add Support for External Nodes
                // parse the node id and return an unvalidated handle.
                if (nodeId.IdType == IdType.String)
                {
                    NodeHandle handle = new NodeHandle();
                    handle.NodeId       = nodeId;
                    handle.Validated    = false;
                    handle.ParsedNodeId = ParsedNodeId.Parse(nodeId);
                    return(handle);
                }
                #endregion

                // node not found.
                return(null);
            }
        }
Пример #12
0
        /// <summary>
        /// Creates the NodeId for the specified node.
        /// </summary>
        public override NodeId New(ISystemContext context, NodeState node)
        {
            if (node is BaseInstanceState instance && instance.Parent != null)
            {
                var pnd = ParsedNodeId.Parse(instance.Parent.NodeId);

                if (pnd != null)
                {
                    return(pnd.Construct(instance.SymbolicName));
                }
            }

            return(node.NodeId);
        }
Пример #13
0
        /// <summary>
        /// Creates the NodeId for the specified node.
        /// </summary>
        public override NodeId New(ISystemContext context, NodeState node)
        {
            BaseInstanceState instance = node as BaseInstanceState;

            if (instance != null && instance.Parent != null)
            {
                if (instance.Parent.NodeId.IdType == IdType.String)
                {
                    return(ParsedNodeId.CreateIdForComponent(instance, instance.Parent.NodeId.NamespaceIndex));
                }
            }

            return(node.NodeId);
        }
Пример #14
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);
            }

            // lookup in operation cache.
            NodeState target = FindNodeInCache(context, handle, cache);

            if (target != null)
            {
                handle.Node      = target;
                handle.Validated = true;
                return(handle.Node);
            }

            #region Task #A5 - Add Support for External Nodes
            ParsedNodeId    nodeId = (ParsedNodeId)handle.ParsedNodeId;
            BaseObjectState node   = CreateFolderNode(nodeId.RootId);

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

            target = node;
            #endregion

            // put root into operation cache.
            if (cache != null)
            {
                cache[handle.NodeId] = target;
            }

            handle.Node      = target;
            handle.Validated = true;
            return(handle.Node);
        }
Пример #15
0
        /// <summary>
        /// Constructs a NodeId from the ItemId for a DA branch.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <param name="propertyId">The property id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns>The node id.</returns>
        public static NodeId ConstructIdForDaElement(string itemId, int propertyId, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId = itemId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = DaElement;

            if (propertyId >= 0)
            {
                parsedNodeId.PropertyId = propertyId;
                parsedNodeId.RootType = DaProperty;
            }

            return parsedNodeId.Construct();
        }
Пример #16
0
        /// <summary>
        /// Returns a item object for the specified node.
        /// </summary>
        public ArchiveItemState GetItemState(ISystemContext context, ParsedNodeId parsedNodeId)
        {
            if (parsedNodeId.RootType != NodeTypes.Item)
            {
                return(null);
            }

            var path = new StringBuilder();

            path.Append(_configuration.ArchiveRoot);
            path.Append('/');
            path.Append(parsedNodeId.RootId);

            var item = new ArchiveItem(parsedNodeId.RootId, new FileInfo(path.ToString()));

            return(new ArchiveItemState(context, item, _namespaceIndex));
        }
Пример #17
0
        /// <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)
            {
                base.CreateAddressSpace(externalReferences);

                NodeState root = FindPredefinedNode(new NodeId(Quickstarts.Views.Objects.Plant, NamespaceIndex), typeof(NodeState));

                Quickstarts.Views.BoilerState boiler1 = new Quickstarts.Views.BoilerState(null);
                ParsedNodeId pnd1 = new ParsedNodeId()
                {
                    NamespaceIndex = NamespaceIndex, RootId = "Boiler #1"
                };

                boiler1.Create(
                    SystemContext,
                    pnd1.Construct(),
                    new QualifiedName("Boiler #1", NamespaceIndex),
                    null,
                    true);

                boiler1.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, root.NodeId);
                root.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, boiler1.NodeId);

                AddPredefinedNode(SystemContext, boiler1);

                Quickstarts.Views.BoilerState boiler2 = new Quickstarts.Views.BoilerState(null);
                ParsedNodeId pnd2 = new ParsedNodeId()
                {
                    NamespaceIndex = NamespaceIndex, RootId = "Boiler #2"
                };

                boiler2.Create(
                    SystemContext,
                    pnd2.Construct(),
                    new QualifiedName("Boiler #2", NamespaceIndex),
                    null,
                    true);

                boiler2.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, root.NodeId);
                root.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, boiler2.NodeId);

                AddPredefinedNode(SystemContext, boiler2);
            }
        }
        /// <summary>
        /// Returns a unique handle for the node.
        /// </summary>
        protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache)
        {
            lock (Lock) {
                // quickly exclude nodes that are not in the namespace.
                if (!IsNodeIdInNamespace(nodeId))
                {
                    return(null);
                }

                // check for check for nodes that are being currently monitored.

                if (MonitoredNodes.TryGetValue(nodeId, out var monitoredNode))
                {
                    var handle = new NodeHandle {
                        NodeId    = nodeId,
                        Validated = true,
                        Node      = monitoredNode.Node
                    };

                    return(handle);
                }

                // parse the identifier.
                var parsedNodeId = ParsedNodeId.Parse(nodeId);

                if (parsedNodeId != null)
                {
                    var handle = new NodeHandle {
                        NodeId       = nodeId,
                        Validated    = false,
                        Node         = null,
                        ParsedNodeId = parsedNodeId
                    };

                    return(handle);
                }

                return(null);
            }
        }
Пример #19
0
        /// <summary>
        /// Used to receive notifications when a node is browsed.
        /// </summary>
        public void OnPopulateBrowser(
            ISystemContext context,
            NodeState node,
            NodeBrowser browser)
        {
            ParsedNodeId  nodeId = ParsedNodeId.Parse(node.NodeId);
            DirectoryInfo info   = new DirectoryInfo(nodeId.RootId);

            if (!info.Exists)
            {
                return;
            }

            if (browser.IsRequired(ReferenceTypeIds.Organizes, false))
            {
                foreach (DirectoryInfo child in info.GetDirectories())
                {
                    ParsedNodeId childId = new ParsedNodeId();
                    childId.RootType       = 0;
                    childId.RootId         = child.FullName;
                    childId.NamespaceIndex = NamespaceIndex;

                    browser.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, childId.Construct()));
                }
            }

            if (browser.IsRequired(ReferenceTypeIds.Organizes, true))
            {
                ParsedNodeId parentId = new ParsedNodeId();
                parentId.RootType       = 0;
                parentId.RootId         = info.Parent.FullName;
                parentId.NamespaceIndex = NamespaceIndex;

                browser.Add(new NodeStateReference(ReferenceTypeIds.Organizes, true, parentId.Construct()));
            }
        }
Пример #20
0
        public GodNodManager(ServerManager server, params string[] namespaceUris) : base(server, namespaceUris)
        {
            InstanceNamespaceIndex = AddNamespaceUri("http://namespaceuri/");
            TypeNamespaceIndex     = AddNamespaceUri("http://namespaceuri/");

            // Load();
            NodeId alarmId = ParsedNodeId.Construct(1, "Jemima", DefaultNamespaceIndex, "Jemima Alarm");

            alarm.NodeId               = alarmId;
            alarm.EventType            = ObjectTypeIds.ExclusiveLimitAlarmType;
            alarm.SourceNode           = new NodeId("Root", DefaultNamespaceIndex);
            alarm.SourceName           = "Jemima";
            alarm.Message              = "Jemima say's Hello World.";
            alarm.Severity             = (ushort)EventSeverity.Low;
            alarm.ConditionName        = "Jemima";
            alarm.ConditionClassId     = ObjectTypeIds.ProcessConditionClassType;
            alarm.ConditionClassName   = BrowseNames.ProcessConditionClassType;
            alarm.Retain               = false;
            alarm.EnabledState.Value   = ConditionStateNames.Enabled;
            alarm.EnabledState.Id      = true;
            alarm.AckedState.Value     = ConditionStateNames.Acknowledged;
            alarm.AckedState.Id        = true;
            alarm.ConfirmedState       = new TwoStateVariableModel();
            alarm.ConfirmedState.Value = ConditionStateNames.Confirmed;
            alarm.ConfirmedState.Id    = true;
            alarm.ActiveState.Value    = ConditionStateNames.Inactive;
            alarm.ActiveState.Id       = false;
            alarm.SuppressedOrShelved  = false;
            alarm.HighLimit            = 35;
            alarm.LowLimit             = 15;
            alarm.InputNode            = new NodeId("Jackey", DefaultNamespaceIndex);
            alarm.UserData             = new SystemAddress()
            {
                Address = 10, Offset = 1000
            };
        }
Пример #21
0
        /// <summary>
        /// Constructs the node id for a branch.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        public static NodeId ConstructIdForHdaBranch(string itemId, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId = itemId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = HdaBranch;

            return parsedNodeId.Construct();
        }
        /// <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)
            {
                dynamicNodes_ = new List <BaseDataVariableState>();

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

                LoadPredefinedNodes(SystemContext, externalReferences);

                // Create the root folder for all nodes of this server
                var root = CreateFolderState(null, "My Data", new LocalizedText("en", "My Data"),
                                             new LocalizedText("en", "Root folder of the Sample Server. All nodes must be placed under this root."));
                References.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId));
                root.EventNotifier = EventNotifiers.SubscribeToEvents;
                opcServer_.AddRootNotifier(root);

                try
                {
                    #region Static
                    var          staticFolder = CreateFolderState(root, "Static", "Static", "A folder with a sample static variable.");
                    const string scalarStatic = "Static_";
                    CreateBaseDataVariableState(staticFolder, scalarStatic + "String", "String", null, DataTypeIds.String, ValueRanks.Scalar, AccessLevels.CurrentReadOrWrite, null);
                    #endregion

                    #region Simulation
                    var          simulationFolder = CreateFolderState(root, "Simulation", "Simulation", "A folder with simulated variables.");
                    const string simulation       = "Simulation_";

                    var simulatedVariable = CreateDynamicVariable(simulationFolder, simulation + "Double", "Double", "A simulated variable of type Double. If Enabled is true this value changes based on the defined Interval.", DataTypeIds.Double, ValueRanks.Scalar, AccessLevels.CurrentReadOrWrite, null);

                    var intervalVariable = CreateBaseDataVariableState(simulationFolder, simulation + "Interval", "Interval", "The Interval used for changing the simulated values.", DataTypeIds.UInt16, ValueRanks.Scalar, AccessLevels.CurrentReadOrWrite, simulationInterval_);
                    intervalVariable.OnSimpleWriteValue = OnWriteInterval;

                    var enabledVariable = CreateBaseDataVariableState(simulationFolder, simulation + "Enabled", "Enabled", "Specifies whether the simulation is enabled (true) or disabled (false).", DataTypeIds.Boolean, ValueRanks.Scalar, AccessLevels.CurrentReadOrWrite, simulationEnabled_);
                    enabledVariable.OnSimpleWriteValue = OnWriteEnabled;
                    #endregion

                    #region Plant
                    var plantFolder = CreateFolderState(root, "Plant", "Plant", null);

                    // Create an instance for machine 1
                    var parsedNodeId = new ParsedNodeId()
                    {
                        NamespaceIndex = NamespaceIndex, RootId = "Machine #1"
                    };
                    machine1_.Create(
                        SystemContext,
                        parsedNodeId.Construct(),
                        new QualifiedName("Machine #1", NamespaceIndex),
                        null,
                        true);
                    // Initialize the property value of MachineData
                    machine1_.MachineData.Value = new MachineDataType
                    {
                        MachineName  = "Machine #1",
                        Manufacturer = "SampleCompany",
                        SerialNumber = "SN 1079",
                        MachineState = MachineStateDataType.Inactive
                    };

                    machine1_.AddReference(ReferenceTypeIds.Organizes, true, plantFolder.NodeId);
                    plantFolder.AddReference(ReferenceTypeIds.Organizes, false, machine1_.NodeId);
                    AddPredefinedNode(SystemContext, machine1_);

                    // Create an instance for machine 2
                    parsedNodeId = new ParsedNodeId()
                    {
                        NamespaceIndex = NamespaceIndex, RootId = "Machine #2"
                    };
                    machine2_.Create(
                        SystemContext,
                        parsedNodeId.Construct(),
                        new QualifiedName("Machine #2", NamespaceIndex),
                        null,
                        true);
                    // Initialize the property value of MachineData
                    machine2_.MachineData.Value = new MachineDataType
                    {
                        MachineName  = "Machine #2",
                        Manufacturer = "Unknown",
                        SerialNumber = "SN 1312",
                        MachineState = MachineStateDataType.PrepareRemove
                    };

                    machine2_.AddReference(ReferenceTypeIds.Organizes, true, plantFolder.NodeId);
                    plantFolder.AddReference(ReferenceTypeIds.Organizes, false, machine2_.NodeId);
                    AddPredefinedNode(SystemContext, machine2_);

                    // Create an instance of GetMachineDataMethodState
                    parsedNodeId = new ParsedNodeId()
                    {
                        NamespaceIndex = NamespaceIndex, RootId = "GetMachineData"
                    };
                    Model.GetMachineDataMethodState getMachineDataMethod = new Model.GetMachineDataMethodState(null);
                    getMachineDataMethod.Create(
                        SystemContext,
                        parsedNodeId.Construct(),
                        new QualifiedName("GetMachineData", NamespaceIndex),
                        null,
                        true);
                    getMachineDataMethod.AddReference(ReferenceTypeIds.Organizes, true, plantFolder.NodeId);
                    plantFolder.AddReference(ReferenceTypeIds.Organizes, false, getMachineDataMethod.NodeId);
                    plantFolder.AddChild(getMachineDataMethod);


                    // Add the event handler if the method is called
                    getMachineDataMethod.OnCall = OnGetMachineData;
                    AddPredefinedNode(SystemContext, getMachineDataMethod);
                    #endregion
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Error creating the address space.");
                }
                // Add all nodes under root to the server
                AddPredefinedNode(SystemContext, root);
                simulationTimer_ = new Timer(DoSimulation, null, 1000, 1000);
            }
        }
Пример #23
0
        /// <summary>
        /// Constructs the id for a source.
        /// </summary>
        /// <param name="areaId">The area id.</param>
        /// <param name="sourceName">Name of the source.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns></returns>
        public static NodeId ConstructIdForSource(string areaId, string sourceName, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootType = AeSource;
            parsedNodeId.RootId = areaId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.ComponentPath = sourceName;

            return parsedNodeId.Construct();
        }
Пример #24
0
        /// <summary>
        /// Constructs the id for an area.
        /// </summary>
        /// <param name="areaId">The area id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns></returns>
        public static NodeId ConstructIdForArea(string areaId, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId = areaId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = AeArea;

            return parsedNodeId.Construct();
        }
Пример #25
0
        public override void Startup()
        {
            try
            {
                Console.WriteLine("Starting Lesson3bNodeManager.");

                base.Startup();

                // save the namespaces used by this node manager.
                AddNamespaceUri("http://yourcompany.com/lesson03b/");

                // initialize the underlying system.

                // create root folder.
                NodeId rootId = ParsedNodeId.Construct(0, "Root", DefaultNamespaceIndex);

                CreateObjectSettings settings = new CreateObjectSettings()
                {
                    ParentNodeId     = ObjectIds.ObjectsFolder,
                    ReferenceTypeId  = ReferenceTypeIds.Organizes,
                    RequestedNodeId  = rootId,
                    BrowseName       = new QualifiedName("Root", DefaultNamespaceIndex),
                    TypeDefinitionId = ObjectTypeIds.FolderType,

                    NotifierParent = ObjectIds.Server,
                };

                CreateObject(Server.DefaultRequestContext, settings);

                // add controllers.

                NodeId controllerId = ParsedNodeId.Construct(0, "Jemima", DefaultNamespaceIndex);

                // create object.
                settings = new CreateObjectSettings()
                {
                    ParentNodeId     = rootId,
                    ReferenceTypeId  = ReferenceTypeIds.Organizes,
                    RequestedNodeId  = controllerId,
                    BrowseName       = new QualifiedName("Jemima", DefaultNamespaceIndex),
                    TypeDefinitionId = ObjectTypeIds.BaseObjectType,

                    NotifierParent = new NodeId("Root", DefaultNamespaceIndex),
                };

                CreateObject(Server.DefaultRequestContext, settings);


                NodeId variableId = ParsedNodeId.Construct(0, "Jemima", DefaultNamespaceIndex, "Jackey");

                // configure the variable so the SDK will automatically poll the system when it is subscribed.
                // this node manager needs to implement the read/write requests.
                CreateVariableSettings settings2 = new CreateVariableSettings()
                {
                    ParentNodeId     = controllerId,
                    ReferenceTypeId  = ReferenceTypeIds.HasComponent,
                    RequestedNodeId  = variableId,
                    BrowseName       = new QualifiedName("Jackey", DefaultNamespaceIndex),
                    TypeDefinitionId = (true) ? VariableTypeIds.AnalogItemType : VariableTypeIds.DataItemType,
                    DataType         = NodeId.Parse("i=12"),
                    ValueRank        = ValueRanks.Scalar,
                    AccessLevel      = AccessLevels.CurrentReadOrWrite,
                    ValueType        = NodeHandleType.ExternalPolled,
                    ValueData        = new SystemAddress()
                    {
                        Address = 10, Offset = 100
                    },
                    // Value = "Hello World.",
                };

                CreateVariable(Server.DefaultRequestContext, settings2);

                NodeId methodId = ParsedNodeId.Construct(0, "Jemima", DefaultNamespaceIndex, "WriteValue");

                var settings3 = new CreateMethodSettings()
                {
                    ParentNodeId    = controllerId,
                    ReferenceTypeId = ReferenceTypeIds.HasComponent,
                    RequestedNodeId = methodId,
                    BrowseName      = new QualifiedName("WriteValue", DefaultNamespaceIndex),
                    NodeData        = new SystemFunction()
                    {
                        Address = "Address", Function = "WriteValue"
                    },

                    InputArguments = new[]
                    {
                        new Argument()
                        {
                            Name = "Value_String", DataType = DataTypeIds.String, ValueRank = ValueRanks.Any
                        },
                    }
                };
                CreateMethod(Server.DefaultRequestContext, settings3);
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to start Lesson3bNodeManager. " + e.Message);
            }
        }
Пример #26
0
        /// <summary>
        /// Called when the node manager is started.
        /// </summary>
        public override void Startup()
        {
            try
            {
                Console.WriteLine("Starting Lesson3bNodeManager.");

                base.Startup();

                // save the namespaces used by this node manager.
                AddNamespaceUri("http://yourcompany.com/lesson03b/");

                // initialize the underlying system.
                m_system.Initialize();

                // create root folder.
                NodeId rootId = ParsedNodeId.Construct(0, "3b", DefaultNamespaceIndex);

                CreateObjectSettings settings = new CreateObjectSettings()
                {
                    ParentNodeId     = ObjectIds.ObjectsFolder,
                    ReferenceTypeId  = ReferenceTypeIds.Organizes,
                    RequestedNodeId  = rootId,
                    BrowseName       = new QualifiedName("3b", DefaultNamespaceIndex),
                    TypeDefinitionId = ObjectTypeIds.FolderType
                };

                CreateObject(Server.DefaultRequestContext, settings);

                // add controllers.
                foreach (BlockConfiguration block in m_system.GetBlocks())
                {
                    NodeId controllerId = ParsedNodeId.Construct(0, block.Name, DefaultNamespaceIndex);

                    // create object.
                    settings = new CreateObjectSettings()
                    {
                        ParentNodeId     = rootId,
                        ReferenceTypeId  = ReferenceTypeIds.Organizes,
                        RequestedNodeId  = controllerId,
                        BrowseName       = new QualifiedName(block.Name, DefaultNamespaceIndex),
                        TypeDefinitionId = ObjectTypeIds.BaseObjectType
                    };

                    CreateObject(Server.DefaultRequestContext, settings);

                    foreach (BlockProperty property in block.Properties)
                    {
                        NodeId variableId = ParsedNodeId.Construct(0, block.Name, DefaultNamespaceIndex, property.Name);

                        // configure the variable so the SDK will automatically poll the system when it is subscribed.
                        // this node manager needs to implement the read/write requests.
                        CreateVariableSettings settings2 = new CreateVariableSettings()
                        {
                            ParentNodeId     = controllerId,
                            ReferenceTypeId  = ReferenceTypeIds.HasComponent,
                            RequestedNodeId  = variableId,
                            BrowseName       = new QualifiedName(property.Name, DefaultNamespaceIndex),
                            TypeDefinitionId = (property.Range != null) ? VariableTypeIds.AnalogItemType : VariableTypeIds.DataItemType,
                            DataType         = property.DataType,
                            ValueRank        = ValueRanks.Scalar,
                            AccessLevel      = (property.Writeable) ? AccessLevels.CurrentReadOrWrite : AccessLevels.CurrentRead,
                            ValueType        = NodeHandleType.ExternalPolled,
                            ValueData        = new SystemAddress()
                            {
                                Address = block.Address, Offset = property.Offset
                            }
                        };

                        CreateVariable(Server.DefaultRequestContext, settings2);

                        // check if an EURange property needs to be created.
                        // the value is stored internally by the SDK so no additional work to support read is required.
                        //if (property.Range != null)
                        //{
                        //    NodeId propertyId = ParsedNodeId.Construct(0, block.Name, DefaultNamespaceIndex, property.Name, BrowseNames.EURange);

                        //    settings2 = new CreateVariableSettings()
                        //    {
                        //        ParentNodeId = variableId,
                        //        ReferenceTypeId = ReferenceTypeIds.HasProperty,
                        //        RequestedNodeId = propertyId,
                        //        BrowseName = new QualifiedName(BrowseNames.EURange),
                        //        TypeDefinitionId = VariableTypeIds.PropertyType,
                        //        DataType = DataTypeIds.Range,
                        //        ValueRank = ValueRanks.Scalar,
                        //        AccessLevel = AccessLevels.CurrentRead,
                        //        Value = new Variant(property.Range)
                        //    };

                        //    CreateVariable(Server.DefaultRequestContext, settings2);
                        //}
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to start Lesson3bNodeManager. " + e.Message);
            }
        }
Пример #27
0
        /// <summary>
        /// Parses the specified node identifier.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <returns>The parsed node identifier. Null if the identifier cannot be parsed.</returns>
        public static new ParsedNodeId Parse(NodeId nodeId)
        {
            // can only parse non-null string node identifiers.
            if (NodeId.IsNull(nodeId))
            {
                return null;
            }

            string identifier = nodeId.Identifier as string;

            if (String.IsNullOrEmpty(identifier))
            {
                return null;
            }

            ParsedNodeId parsedNodeId = new ParsedNodeId();
            parsedNodeId.NamespaceIndex = nodeId.NamespaceIndex;

            // extract the type of identifier.
            parsedNodeId.RootType = 0;

            int start = 0;

            for (int ii = 0; ii < identifier.Length; ii++)
            {
                if (!Char.IsDigit(identifier[ii]))
                {
                    start = ii;
                    break;
                }

                parsedNodeId.RootType *= 10;
                parsedNodeId.RootType += (byte)(identifier[ii] - '0');
            }

            if (start >= identifier.Length || identifier[start] != ':')
            {
                return null;
            }

            // extract any component path.
            StringBuilder buffer = new StringBuilder();

            int index = start+1;
            int end = identifier.Length;

            bool escaped = false;

            while (index < end)
            {
                char ch = identifier[index++];

                // skip any escape character but keep the one after it.
                if (ch == '&')
                {
                    escaped = true;
                    continue;
                }

                if (!escaped && ch == '?')
                {
                    end = index;
                    break;
                }

                buffer.Append(ch);
                escaped = false;
            }

            // extract any component.
            parsedNodeId.RootId = buffer.ToString();
            parsedNodeId.ComponentPath = null;

            if (parsedNodeId.RootType == ModelUtils.DaProperty)
            {
                // must have the property id.
                if (end >= identifier.Length)
                {
                    return null;
                }

                // extract the property id.
                for (int ii = end; ii < identifier.Length; ii++)
                {
                    end++;

                    if (!Char.IsDigit(identifier[ii]))
                    {
                        // check for terminator.
                        if (identifier[ii] != ':')
                        {
                            return null;
                        }

                        break;
                    }

                    parsedNodeId.PropertyId *= 10;
                    parsedNodeId.PropertyId += (byte)(identifier[ii] - '0');
                }
            }

            // extract the component path.
            if (end < identifier.Length)
            {
                parsedNodeId.ComponentPath = identifier.Substring(end);
            }

            return parsedNodeId;
        }
Пример #28
0
        /// <summary>
        /// Constructs the node id for an item attribute.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <param name="attributeId">The attribute id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns></returns>
        public static NodeId ConstructIdForHdaItemAttribute(string itemId, uint attributeId, ushort namespaceIndex)
        {
            ParsedNodeId parsedNodeId = new ParsedNodeId();

            parsedNodeId.RootId = itemId;
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = HdaItemAttribute;
            parsedNodeId.ComponentPath = attributeId.ToString();

            return parsedNodeId.Construct();
        }
Пример #29
0
        /// <summary>
        /// Constructs the node id for an aggregate function.
        /// </summary>
        /// <param name="aggregateId">The aggregate id.</param>
        /// <param name="namespaceIndex">Index of the namespace.</param>
        /// <returns></returns>
        public static NodeId ConstructIdForHdaAggregate(uint aggregateId, ushort namespaceIndex)
        {
            // check for built in aggregates.
            NodeId nodeId = ComUtils.GetHdaAggregateId(aggregateId);

            if (nodeId != null)
            {
                return nodeId;
            }

            // server specific aggregates.
            ParsedNodeId parsedNodeId = new ParsedNodeId();
            
            parsedNodeId.RootId = aggregateId.ToString();
            parsedNodeId.NamespaceIndex = namespaceIndex;
            parsedNodeId.RootType = HdaAggregate;

            return parsedNodeId.Construct();
        }
Пример #30
0
        /// <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)
            {
                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out var references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = References = new List <IReference>();
                }
                else
                {
                    References = references;
                }

                LoadPredefinedNodes(SystemContext, externalReferences);

                var root = CreateFolderState(null, "My Data", new LocalizedText("en", "My Data"), new LocalizedText("en", "Root folder of Workshop Server"));
                References.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId));
                root.EventNotifier = EventNotifiers.SubscribeToEvents;
                opcServer_.AddRootNotifier(root);

                try
                {
                    #region Plant
                    var plantFolder = CreateFolderState(root, "Plant", "Plant", null);
                    var machine1    = new Model.MachineState(null);
                    var pnd1        = new ParsedNodeId()
                    {
                        NamespaceIndex = NamespaceIndex, RootId = "Machine #1"
                    };

                    machine1.Create(
                        SystemContext,
                        pnd1.Construct(),
                        new QualifiedName("Machine #1", NamespaceIndex),
                        null,
                        true);

                    machine1.AddReference(ReferenceTypeIds.Organizes, true, plantFolder.NodeId);
                    plantFolder.AddReference(ReferenceTypeIds.Organizes, false, machine1.NodeId);

                    AddPredefinedNode(SystemContext, machine1);

                    var machine2 = new Model.MachineState(null);
                    var pnd2     = new ParsedNodeId()
                    {
                        NamespaceIndex = NamespaceIndex, RootId = "Machine #2"
                    };

                    machine2.Create(
                        SystemContext,
                        pnd2.Construct(),
                        new QualifiedName("Machine #2", NamespaceIndex),
                        null,
                        true);

                    machine2.AddReference(ReferenceTypeIds.Organizes, true, plantFolder.NodeId);
                    plantFolder.AddReference(ReferenceTypeIds.Organizes, false, machine2.NodeId);

                    AddPredefinedNode(SystemContext, machine2);

                    #endregion
                }
                catch (Exception e)
                {
                    Utils.Trace(e, "Error creating the address space.");
                }

                AddPredefinedNode(SystemContext, root);
            }
        }